aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/misc/unittests/enum_ut.cpp
blob: 1b1b6d0be23247e151744ff30a9ffbcf867517a4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#include <library/cpp/testing/gtest/gtest.h>

#include <library/cpp/yt/misc/enum.h>

namespace NYT {
namespace {

////////////////////////////////////////////////////////////////////////////////

DEFINE_ENUM(ESimple,
    (X)
    (Y)
    (Z)
);

DEFINE_ENUM(EColor,
    ((Red)  (10))
    ((Green)(20))
    ((Blue) (30))
     (Black)
     (White)
);

DEFINE_BIT_ENUM(EFlag,
    ((_1)(0x0001))
    ((_2)(0x0002))
    ((_3)(0x0004))
    ((_4)(0x0008))
);

DEFINE_AMBIGUOUS_ENUM_WITH_UNDERLYING_TYPE(EMultipleNames, int,
     (A1)
    ((A2)(0))
     (B)
     (C)
    ((D1)(100))
    ((D2)(100))
);

DEFINE_ENUM(ECustomString,
    ((A) (1) ("1_a"))
    ((B) (2) ("1_b"))
);

////////////////////////////////////////////////////////////////////////////////

template <class T, size_t N>
std::vector<T> ToVector(std::array<T, N> array)
{
    return std::vector<T>(array.begin(), array.end());
}

TEST(TEnumTest, Domain)
{
    EXPECT_EQ(3, TEnumTraits<ESimple>::GetDomainSize());
    std::vector<ESimple> v {
        ESimple::X,
        ESimple::Y,
        ESimple::Z
    };
    EXPECT_EQ(v, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
    EXPECT_EQ(ESimple::X, TEnumTraits<ESimple>::GetMinValue());
    EXPECT_EQ(ESimple::Z, TEnumTraits<ESimple>::GetMaxValue());
}

TEST(TEnumTest, Basic)
{
    EXPECT_EQ(0, static_cast<int>(ESimple::X));
    EXPECT_EQ(1, static_cast<int>(ESimple::Y));
    EXPECT_EQ(2, static_cast<int>(ESimple::Z));

    EXPECT_EQ(0, static_cast<int>(EColor( )));
    EXPECT_EQ(5, static_cast<int>(EColor(5)));

    EXPECT_EQ(10, static_cast<int>(EColor::Red  ));
    EXPECT_EQ(20, static_cast<int>(EColor::Green));
    EXPECT_EQ(30, static_cast<int>(EColor::Blue ));
    EXPECT_EQ(31, static_cast<int>(EColor::Black));
    EXPECT_EQ(32, static_cast<int>(EColor::White));
}

TEST(TEnumTest, ToString)
{
    EXPECT_EQ("EColor(0)", ToString(EColor( )));
    EXPECT_EQ("EColor(5)", ToString(EColor(5)));

    EXPECT_EQ("Red",   ToString(EColor(EColor::Red  )));
    EXPECT_EQ("Green", ToString(EColor::Green));
    EXPECT_EQ("Blue",  ToString(EColor(EColor::Blue )));
    EXPECT_EQ("Black", ToString(EColor::Black));
    EXPECT_EQ("White", ToString(EColor::White));
}

TEST(TEnumTest, FromString)
{
    EXPECT_EQ(EColor::Red  , TEnumTraits<EColor>::FromString("Red"  ));
    EXPECT_EQ(EColor::Green, TEnumTraits<EColor>::FromString("Green"));
    EXPECT_EQ(EColor::Blue , TEnumTraits<EColor>::FromString("Blue" ));
    EXPECT_EQ(EColor::Black, TEnumTraits<EColor>::FromString("Black"));
    EXPECT_EQ(EColor::White, TEnumTraits<EColor>::FromString("White"));

    EXPECT_THROW(TEnumTraits<EColor>::FromString("Pink"), std::exception);

    EXPECT_EQ(EColor::Red, TEnumTraits<EColor>::FindValueByLiteral("Red"));
    EXPECT_EQ(std::nullopt, TEnumTraits<EColor>::FindValueByLiteral("Pink"));
}

TEST(TEnumTest, Ordering)
{
    ESimple a(ESimple::X);
    ESimple b(ESimple::Y);
    ESimple c(ESimple::Y);
    ESimple d(ESimple::Z);

    EXPECT_FALSE(a < a); EXPECT_FALSE(a > a);
    EXPECT_TRUE (a < b); EXPECT_TRUE (b > a);
    EXPECT_TRUE (a < c); EXPECT_TRUE (c > a);
    EXPECT_TRUE (a < d); EXPECT_TRUE (d > a);

    EXPECT_FALSE(b < a); EXPECT_FALSE(a > b);
    EXPECT_FALSE(b < b); EXPECT_FALSE(b > b);
    EXPECT_FALSE(b < c); EXPECT_FALSE(c > b);
    EXPECT_TRUE (b < d); EXPECT_TRUE (d > b);

    EXPECT_FALSE(c < a); EXPECT_FALSE(a > c);
    EXPECT_FALSE(c < b); EXPECT_FALSE(b > c);
    EXPECT_FALSE(c < c); EXPECT_FALSE(c > c);
    EXPECT_TRUE (c < d); EXPECT_TRUE (d > c);

    EXPECT_FALSE(d < a); EXPECT_FALSE(a > d);
    EXPECT_FALSE(d < b); EXPECT_FALSE(b > d);
    EXPECT_FALSE(d < c); EXPECT_FALSE(c > d);
    EXPECT_FALSE(d < d); EXPECT_FALSE(d > d);

    EXPECT_TRUE (a <= b);
    EXPECT_TRUE (b <= c);
    EXPECT_TRUE (c <= d);

    EXPECT_TRUE (a == a);
    EXPECT_FALSE(a == b);
    EXPECT_TRUE (b == c);
    EXPECT_FALSE(c == d);
    EXPECT_FALSE(d == a);

    EXPECT_FALSE(a != a);
    EXPECT_TRUE (a != b);
    EXPECT_FALSE(b != c);
    EXPECT_TRUE (c != d);
    EXPECT_TRUE (d != a);
}

TEST(TEnumTest, OrderingWithDomainValues)
{
    EColor color(EColor::Black);

    EXPECT_LT(EColor::Red, color);
    EXPECT_LT(color, EColor::White);

    EXPECT_GT(color, EColor::Red);
    EXPECT_GT(EColor::White, color);

    EXPECT_LE(EColor::Red, color);
    EXPECT_LE(color, EColor::White);

    EXPECT_GE(EColor::White, color);
    EXPECT_GE(color, EColor::Red);

    EXPECT_EQ(color, EColor::Black);
    EXPECT_EQ(EColor::Black, color);

    EXPECT_NE(color, EColor::Blue);
    EXPECT_NE(EColor::Blue, color);
}

TEST(TEnumTest, DomainSize)
{
    EXPECT_EQ(3, TEnumTraits<ESimple>::GetDomainSize());
    EXPECT_EQ(5, TEnumTraits<EColor>::GetDomainSize());
}

TEST(TEnumTest, DomainValues)
{
    std::vector<ESimple> simpleValues;
    simpleValues.push_back(ESimple::X);
    simpleValues.push_back(ESimple::Y);
    simpleValues.push_back(ESimple::Z);
    EXPECT_EQ(simpleValues, ToVector(TEnumTraits<ESimple>::GetDomainValues()));

    std::vector<EColor> colorValues;
    colorValues.push_back(EColor::Red);
    colorValues.push_back(EColor::Green);
    colorValues.push_back(EColor::Blue);
    colorValues.push_back(EColor::Black);
    colorValues.push_back(EColor::White);
    EXPECT_EQ(colorValues, ToVector(TEnumTraits<EColor>::GetDomainValues()));
}

TEST(TEnumTest, Decompose1)
{
    auto f = EFlag(0);
    std::vector<EFlag> ff { };
    EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
}

TEST(TEnumTest, Decompose2)
{
    auto f = EFlag::_1;
    std::vector<EFlag> ff {EFlag::_1};
    EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
}

TEST(TEnumTest, Decompose3)
{
    auto f = EFlag(EFlag::_1|EFlag::_2);
    std::vector<EFlag> ff{EFlag::_1, EFlag::_2};
    EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
}

TEST(TEnumTest, Decompose4)
{
    auto f = EFlag(EFlag::_2|EFlag::_4);
    std::vector<EFlag> ff{EFlag::_2, EFlag::_4};
    EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
}

TEST(TEnumTest, MultipleNames)
{
    EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A1"));
    EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A2"));
    EXPECT_EQ(EMultipleNames::B,  TEnumTraits<EMultipleNames>::FromString("B"));
    EXPECT_EQ(EMultipleNames::C,  TEnumTraits<EMultipleNames>::FromString("C"));
    EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D1"));
    EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D2"));

    EXPECT_EQ("A1", ToString(EMultipleNames::A1));
    EXPECT_EQ("A1", ToString(EMultipleNames::A2));
    EXPECT_EQ("B",  ToString(EMultipleNames::B));
    EXPECT_EQ("C",  ToString(EMultipleNames::C));
    EXPECT_EQ("D1", ToString(EMultipleNames::D1));
    EXPECT_EQ("D1", ToString(EMultipleNames::D2));
}

TEST(TEnumTest, CustomString)
{
    EXPECT_EQ(ECustomString::A, TEnumTraits<ECustomString>::FromString("1_a"));
    EXPECT_EQ(ECustomString::B, TEnumTraits<ECustomString>::FromString("1_b"));

    EXPECT_EQ("1_a", ToString(ECustomString::A));
    EXPECT_EQ("1_b", ToString(ECustomString::B));
}

////////////////////////////////////////////////////////////////////////////////

} // namespace
} // namespace NYT