1#pragma GCC diagnostic ignored "-Wmissing-declarations"
2#include <gtest/gtest.h>
3
4#include <Core/DecimalFunctions.h>
5
6namespace
7{
8using namespace DB;
9
10struct DecimalUtilsSplitAndCombineTestParam
11{
12 const char * description;
13
14 Decimal64 decimal_value;
15 UInt8 scale;
16
17 DecimalUtils::DecimalComponents<typename Decimal64::NativeType> components;
18};
19
20std::ostream & operator << (std::ostream & ostr, const DecimalUtilsSplitAndCombineTestParam & param)
21{
22 return ostr << param.description;
23}
24
25class DecimalUtilsSplitAndCombineTest : public ::testing::TestWithParam<DecimalUtilsSplitAndCombineTestParam>
26{};
27
28template <typename DecimalType>
29void testSplit(const DecimalUtilsSplitAndCombineTestParam & param)
30{
31 const DecimalType decimal_value = param.decimal_value;
32 const auto & actual_components = DecimalUtils::split(decimal_value, param.scale);
33
34 EXPECT_EQ(param.components.whole, actual_components.whole);
35 EXPECT_EQ(param.components.fractional, actual_components.fractional);
36}
37
38template <typename DecimalType>
39void testDecimalFromComponents(const DecimalUtilsSplitAndCombineTestParam & param)
40{
41 EXPECT_EQ(param.decimal_value,
42 DecimalUtils::decimalFromComponents<DecimalType>(param.components.whole, param.components.fractional, param.scale));
43}
44
45template <typename DecimalType>
46void testGetWhole(const DecimalUtilsSplitAndCombineTestParam & param)
47{
48 EXPECT_EQ(param.components.whole,
49 DecimalUtils::getWholePart(DecimalType{param.decimal_value}, param.scale));
50}
51
52template <typename DecimalType>
53void testGetFractional(const DecimalUtilsSplitAndCombineTestParam & param)
54{
55 EXPECT_EQ(param.components.fractional,
56 DecimalUtils::getFractionalPart(DecimalType{param.decimal_value}, param.scale));
57}
58
59// unfortunatelly typed parametrized tests () are not supported in this version of gtest, so I have to emulate by hand.
60TEST_P(DecimalUtilsSplitAndCombineTest, split_Decimal32)
61{
62 testSplit<Decimal32>(GetParam());
63}
64
65TEST_P(DecimalUtilsSplitAndCombineTest, split_Decimal64)
66{
67 testSplit<Decimal64>(GetParam());
68}
69
70TEST_P(DecimalUtilsSplitAndCombineTest, split_Decimal128)
71{
72 testSplit<Decimal128>(GetParam());
73}
74
75TEST_P(DecimalUtilsSplitAndCombineTest, combine_Decimal32)
76{
77 testDecimalFromComponents<Decimal32>(GetParam());
78}
79
80TEST_P(DecimalUtilsSplitAndCombineTest, combine_Decimal64)
81{
82 testDecimalFromComponents<Decimal64>(GetParam());
83}
84
85TEST_P(DecimalUtilsSplitAndCombineTest, combine_Decimal128)
86{
87 testDecimalFromComponents<Decimal64>(GetParam());
88}
89
90TEST_P(DecimalUtilsSplitAndCombineTest, getWholePart_Decimal32)
91{
92 testGetWhole<Decimal32>(GetParam());
93}
94
95TEST_P(DecimalUtilsSplitAndCombineTest, getWholePart_Decimal64)
96{
97 testGetWhole<Decimal64>(GetParam());
98}
99
100TEST_P(DecimalUtilsSplitAndCombineTest, getWholePart_Decimal128)
101{
102 testGetWhole<Decimal128>(GetParam());
103}
104
105TEST_P(DecimalUtilsSplitAndCombineTest, getFractionalPart_Decimal32)
106{
107 testGetFractional<Decimal32>(GetParam());
108}
109
110TEST_P(DecimalUtilsSplitAndCombineTest, getFractionalPart_Decimal64)
111{
112 testGetFractional<Decimal64>(GetParam());
113}
114
115TEST_P(DecimalUtilsSplitAndCombineTest, getFractionalPart_Decimal128)
116{
117 testGetFractional<Decimal128>(GetParam());
118}
119
120}
121
122// Intentionally small values that fit into 32-bit in order to cover Decimal32, Decimal64 and Decimal128 with single set of data.
123INSTANTIATE_TEST_CASE_P(Basic,
124 DecimalUtilsSplitAndCombineTest,
125 ::testing::ValuesIn(std::initializer_list<DecimalUtilsSplitAndCombineTestParam>{
126 {
127 "Positive value with non-zero scale, whole, and fractional parts.",
128 1234567'89,
129 2,
130 {
131 1234567,
132 89
133 }
134 },
135 {
136 "When scale is 0, fractional part is 0.",
137 1234567'89,
138 0,
139 {
140 123456789,
141 0
142 }
143 },
144 {
145 "When scale is not 0 and fractional part is 0.",
146 1234567'00,
147 2,
148 {
149 1234567,
150 0
151 }
152 },
153 {
154 "When scale is not 0 and whole part is 0.",
155 123,
156 3,
157 {
158 0,
159 123
160 }
161 },
162 {
163 "For negative Decimal value whole part is negative, fractional is non-negative.",
164 -1234567'89,
165 2,
166 {
167 -1234567,
168 89
169 }
170 }
171 }
172),);
173