ClickHouse
261 строка · 6.7 Кб
1#include <gtest/gtest.h>
2
3#include <Core/DecimalFunctions.h>
4
5namespace
6{
7using namespace DB;
8
9struct DecimalUtilsSplitAndCombineTestParam
10{
11const char * description;
12
13Decimal64 decimal_value;
14uint8_t scale;
15
16DecimalUtils::DecimalComponents<Decimal64> components;
17};
18
19class DecimalUtilsSplitAndCombineTest : public ::testing::TestWithParam<DecimalUtilsSplitAndCombineTestParam>
20{};
21
22template <typename DecimalType>
23void testSplit(const DecimalUtilsSplitAndCombineTestParam & param)
24{
25const DecimalType decimal_value(static_cast<typename DecimalType::NativeType>(param.decimal_value.value));
26const auto & actual_components = DecimalUtils::split(decimal_value, param.scale);
27
28EXPECT_EQ(param.components.whole, actual_components.whole);
29EXPECT_EQ(param.components.fractional, actual_components.fractional);
30}
31
32template <typename DecimalType>
33void testDecimalFromComponents(const DecimalUtilsSplitAndCombineTestParam & param)
34{
35EXPECT_EQ(param.decimal_value,
36DecimalUtils::decimalFromComponents<DecimalType>(
37static_cast<typename DecimalType::NativeType>(param.components.whole),
38static_cast<typename DecimalType::NativeType>(param.components.fractional),
39param.scale));
40}
41
42template <typename DecimalType>
43void testGetWhole(const DecimalUtilsSplitAndCombineTestParam & param)
44{
45EXPECT_EQ(param.components.whole,
46DecimalUtils::getWholePart(
47DecimalType{static_cast<typename DecimalType::NativeType>(param.decimal_value.value)},
48param.scale));
49}
50
51template <typename DecimalType>
52void testGetFractional(const DecimalUtilsSplitAndCombineTestParam & param)
53{
54EXPECT_EQ(param.components.fractional,
55DecimalUtils::getFractionalPart(
56DecimalType{static_cast<typename DecimalType::NativeType>(param.decimal_value.value)},
57param.scale));
58}
59
60// Unfortunately typed parametrized tests () are not supported in this version of gtest, so I have to emulate by hand.
61TEST_P(DecimalUtilsSplitAndCombineTest, splitDecimal32)
62{
63testSplit<Decimal32>(GetParam());
64}
65
66TEST_P(DecimalUtilsSplitAndCombineTest, splitDecimal64)
67{
68testSplit<Decimal64>(GetParam());
69}
70
71TEST_P(DecimalUtilsSplitAndCombineTest, splitDecimal128)
72{
73testSplit<Decimal128>(GetParam());
74}
75
76TEST_P(DecimalUtilsSplitAndCombineTest, combineDecimal32)
77{
78testDecimalFromComponents<Decimal32>(GetParam());
79}
80
81TEST_P(DecimalUtilsSplitAndCombineTest, combineDecimal64)
82{
83testDecimalFromComponents<Decimal64>(GetParam());
84}
85
86TEST_P(DecimalUtilsSplitAndCombineTest, combineDecimal128)
87{
88testDecimalFromComponents<Decimal64>(GetParam());
89}
90
91TEST_P(DecimalUtilsSplitAndCombineTest, getWholePartDecimal32)
92{
93testGetWhole<Decimal32>(GetParam());
94}
95
96TEST_P(DecimalUtilsSplitAndCombineTest, getWholePartDecimal64)
97{
98testGetWhole<Decimal64>(GetParam());
99}
100
101TEST_P(DecimalUtilsSplitAndCombineTest, getWholePartDecimal128)
102{
103testGetWhole<Decimal128>(GetParam());
104}
105
106TEST_P(DecimalUtilsSplitAndCombineTest, getFractionalPartDecimal32)
107{
108testGetFractional<Decimal32>(GetParam());
109}
110
111TEST_P(DecimalUtilsSplitAndCombineTest, getFractionalPartDecimal64)
112{
113testGetFractional<Decimal64>(GetParam());
114}
115
116TEST_P(DecimalUtilsSplitAndCombineTest, getFractionalPartDecimal128)
117{
118testGetFractional<Decimal128>(GetParam());
119}
120
121class DecimalUtilsSplitAndCombineForDateTime64Test : public ::testing::TestWithParam<DecimalUtilsSplitAndCombineTestParam>
122{};
123
124
125// Unfortunately typed parametrized tests () are not supported in this version of gtest, so I have to emulate by hand.
126TEST_P(DecimalUtilsSplitAndCombineForDateTime64Test, splitDateTime64)
127{
128testSplit<DateTime64>(GetParam());
129}
130
131TEST_P(DecimalUtilsSplitAndCombineForDateTime64Test, combineDateTime64)
132{
133testDecimalFromComponents<DateTime64>(GetParam());
134}
135
136TEST_P(DecimalUtilsSplitAndCombineForDateTime64Test, getWholePartDateTime64)
137{
138testGetWhole<DateTime64>(GetParam());
139}
140
141TEST_P(DecimalUtilsSplitAndCombineForDateTime64Test, getFractionalPartDateTime64)
142{
143testGetFractional<DateTime64>(GetParam());
144}
145
146}
147
148namespace std // NOLINT(cert-dcl58-cpp)
149{
150
151std::ostream & operator << (std::ostream & ostr, const DecimalUtilsSplitAndCombineTestParam & param) // NOLINT(cert-dcl58-cpp)
152{
153return ostr << param.description;
154}
155
156}
157
158
159// Intentionally small values that fit into 32-bit in order to cover Decimal32, Decimal64 and Decimal128 with single set of data.
160INSTANTIATE_TEST_SUITE_P(Basic,
161DecimalUtilsSplitAndCombineTest,
162::testing::ValuesIn(std::initializer_list<DecimalUtilsSplitAndCombineTestParam>{
163{
164"Positive value with non-zero scale, whole, and fractional parts.",
1651234567'89,
1662,
167{
1681234567,
16989
170}
171},
172{
173"When scale is 0, fractional part is 0.",
1741234567'89,
1750,
176{
177123456789,
1780
179}
180},
181{
182"When scale is not 0 and fractional part is 0.",
1831234567'00,
1842,
185{
1861234567,
1870
188}
189},
190{
191"For positive Decimal value, with scale not 0, and whole part is 0.",
192123,
1933,
194{
1950,
196123
197}
198},
199{
200"For negative Decimal value, with scale not 0, and whole part is 0.",
201-123,
2023,
203{
2040,
205-123
206}
207},
208
209{
210"For negative Decimal value whole part is negative, fractional is non-negative.",
211-1234567'89,
2122,
213{
214-1234567,
21589
216}
217}
218})
219);
220
221INSTANTIATE_TEST_SUITE_P(Basic,
222DecimalUtilsSplitAndCombineForDateTime64Test,
223::testing::ValuesIn(std::initializer_list<DecimalUtilsSplitAndCombineTestParam>{
224{
225"Negative timestamp 1965-12-12 12:12:12.123 UTC",
226DateTime64(-127943267877),
2273,
228{
229-127943267,
230877
231}
232},
233{
234"Positive timestamp 1975-12-12 12:12:12.123 UTC",
235DateTime64(187618332123),
2363,
237{
238187618332,
239123
240}
241},
242{
243"Negative timestamp 1969-12-31 23:59:59.123 UTC",
244DateTime64(-877),
2453,
246{
2470,
248-877
249}
250},
251{
252"Positive timestamp 1970-01-01 00:00:00.123 UTC",
253DateTime64(123),
2543,
255{
2560,
257123
258}
259}
260})
261);
262