ClickHouse
157 строк · 4.2 Кб
1#include <gtest/gtest.h>
2
3#include <base/types.h>
4#include <type_traits>
5#include <Core/MultiEnum.h>
6
7namespace
8{
9
10enum class TestEnum : UInt8
11{
12// name represents which bit is going to be set
13ZERO,
14ONE,
15TWO,
16THREE,
17FOUR,
18FIVE
19};
20}
21
22GTEST_TEST(MultiEnum, WithDefault)
23{
24MultiEnum<TestEnum, UInt8> multi_enum;
25ASSERT_EQ(0, multi_enum.getValue());
26ASSERT_EQ(0, multi_enum);
27
28ASSERT_FALSE(multi_enum.isSet(TestEnum::ZERO));
29ASSERT_FALSE(multi_enum.isSet(TestEnum::ONE));
30ASSERT_FALSE(multi_enum.isSet(TestEnum::TWO));
31ASSERT_FALSE(multi_enum.isSet(TestEnum::THREE));
32ASSERT_FALSE(multi_enum.isSet(TestEnum::FOUR));
33ASSERT_FALSE(multi_enum.isSet(TestEnum::FIVE));
34}
35
36GTEST_TEST(MultiEnum, WitheEnum)
37{
38MultiEnum<TestEnum, UInt8> multi_enum(TestEnum::FOUR);
39ASSERT_EQ(16, multi_enum.getValue());
40ASSERT_EQ(16, multi_enum);
41
42ASSERT_FALSE(multi_enum.isSet(TestEnum::ZERO));
43ASSERT_FALSE(multi_enum.isSet(TestEnum::ONE));
44ASSERT_FALSE(multi_enum.isSet(TestEnum::TWO));
45ASSERT_FALSE(multi_enum.isSet(TestEnum::THREE));
46ASSERT_TRUE(multi_enum.isSet(TestEnum::FOUR));
47ASSERT_FALSE(multi_enum.isSet(TestEnum::FIVE));
48}
49
50GTEST_TEST(MultiEnum, WithValue)
51{
52const MultiEnum<TestEnum> multi_enum(13u); // (1 | (1 << 2 | 1 << 3)
53
54ASSERT_TRUE(multi_enum.isSet(TestEnum::ZERO));
55ASSERT_FALSE(multi_enum.isSet(TestEnum::ONE));
56ASSERT_TRUE(multi_enum.isSet(TestEnum::TWO));
57ASSERT_TRUE(multi_enum.isSet(TestEnum::THREE));
58ASSERT_FALSE(multi_enum.isSet(TestEnum::FOUR));
59ASSERT_FALSE(multi_enum.isSet(TestEnum::FIVE));
60}
61
62GTEST_TEST(MultiEnum, WithMany)
63{
64MultiEnum<TestEnum> multi_enum{TestEnum::ONE, TestEnum::FIVE};
65ASSERT_EQ(1 << 1 | 1 << 5, multi_enum.getValue());
66ASSERT_EQ(1 << 1 | 1 << 5, multi_enum);
67
68ASSERT_FALSE(multi_enum.isSet(TestEnum::ZERO));
69ASSERT_TRUE(multi_enum.isSet(TestEnum::ONE));
70ASSERT_FALSE(multi_enum.isSet(TestEnum::TWO));
71ASSERT_FALSE(multi_enum.isSet(TestEnum::THREE));
72ASSERT_FALSE(multi_enum.isSet(TestEnum::FOUR));
73ASSERT_TRUE(multi_enum.isSet(TestEnum::FIVE));
74}
75
76GTEST_TEST(MultiEnum, WithCopyConstructor)
77{
78const MultiEnum<TestEnum> multi_enum_source{TestEnum::ONE, TestEnum::FIVE};
79MultiEnum<TestEnum> multi_enum{multi_enum_source};
80
81ASSERT_EQ(1 << 1 | 1 << 5, multi_enum.getValue());
82}
83
84GTEST_TEST(MultiEnum, SetAndUnSet)
85{
86MultiEnum<TestEnum> multi_enum;
87multi_enum.set(TestEnum::ONE);
88ASSERT_EQ(1 << 1, multi_enum);
89
90multi_enum.set(TestEnum::TWO);
91ASSERT_EQ(1 << 1| (1 << 2), multi_enum);
92
93multi_enum.unSet(TestEnum::ONE);
94ASSERT_EQ(1 << 2, multi_enum);
95}
96
97GTEST_TEST(MultiEnum, SetValueOnDifferentTypes)
98{
99MultiEnum<TestEnum> multi_enum;
100
101multi_enum.setValue(static_cast<UInt8>(1));
102ASSERT_EQ(1, multi_enum);
103
104multi_enum.setValue(static_cast<UInt16>(2));
105ASSERT_EQ(2, multi_enum);
106
107multi_enum.setValue(static_cast<UInt32>(3));
108ASSERT_EQ(3, multi_enum);
109
110multi_enum.setValue(static_cast<UInt64>(4));
111ASSERT_EQ(4, multi_enum);
112}
113
114// shouldn't compile
115//GTEST_TEST(MultiEnum, WithOtherEnumType)
116//{
117// MultiEnum<TestEnum> multi_enum;
118
119// enum FOO {BAR, FOOBAR};
120// MultiEnum<TestEnum> multi_enum2(BAR);
121// MultiEnum<TestEnum> multi_enum3(BAR, FOOBAR);
122// multi_enum.setValue(FOO::BAR);
123// multi_enum == FOO::BAR;
124// FOO::BAR == multi_enum;
125//}
126
127GTEST_TEST(MultiEnum, SetSameValueMultipleTimes)
128{
129// Setting same value is idempotent.
130MultiEnum<TestEnum> multi_enum;
131multi_enum.set(TestEnum::ONE);
132ASSERT_EQ(1 << 1, multi_enum);
133
134multi_enum.set(TestEnum::ONE);
135ASSERT_EQ(1 << 1, multi_enum);
136}
137
138GTEST_TEST(MultiEnum, UnSetValuesThatWerentSet)
139{
140// Unsetting values that weren't set shouldn't change other flags nor aggregate value.
141MultiEnum<TestEnum> multi_enum{TestEnum::ONE, TestEnum::THREE};
142multi_enum.unSet(TestEnum::TWO);
143ASSERT_EQ(1 << 1 | 1 << 3, multi_enum);
144
145multi_enum.unSet(TestEnum::FOUR);
146ASSERT_EQ(1 << 1 | 1 << 3, multi_enum);
147
148multi_enum.unSet(TestEnum::FIVE);
149ASSERT_EQ(1 << 1 | 1 << 3, multi_enum);
150}
151
152GTEST_TEST(MultiEnum, Reset)
153{
154MultiEnum<TestEnum> multi_enum{TestEnum::ONE, TestEnum::THREE};
155multi_enum.reset();
156ASSERT_EQ(0, multi_enum);
157}
158