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
|
#include <library/cpp/testing/gtest/gtest.h>
#include <library/cpp/yt/string/enum.h>
#include <library/cpp/yt/string/format.h>
#include <limits>
namespace NYT {
namespace {
////////////////////////////////////////////////////////////////////////////////
// Some compile-time sanity checks.
DEFINE_ENUM(ESample, (One)(Two));
static_assert(CFormattable<ESample>);
static_assert(CFormattable<TEnumIndexedArray<ESample, int>>);
DEFINE_ENUM(EColor,
(Red)
(BlackAndWhite)
);
DEFINE_BIT_ENUM(ELangs,
((None) (0x00))
((Cpp) (0x01))
((Go) (0x02))
((Rust) (0x04))
((Python) (0x08))
((JavaScript) (0x10))
((CppGo) (0x03))
((All) (0x1f))
);
DEFINE_BIT_ENUM(ELangsWithUnknown,
((None) (0x00))
((Cpp) (0x01))
((Go) (0x02))
((Rust) (0x04))
((Python) (0x08))
((JavaScript) (0x10))
((CppGo) (0x03))
((All) (0x1f))
((Unknown) (0x20))
);
DEFINE_ENUM_UNKNOWN_VALUE(ELangsWithUnknown, Unknown);
DEFINE_ENUM(ECustomDomainName,
((A) (1) ("value_a"))
((B) (2) ("value_b"))
);
DEFINE_ENUM(EColorWithUnknown,
(Red)
(Green)
(Unknown)
);
DEFINE_ENUM_UNKNOWN_VALUE(EColorWithUnknown, Unknown);
DEFINE_BIT_ENUM(EBitEnumWithoutNone,
((Some)(1))
);
TEST(TFormatTest, Enum)
{
EXPECT_EQ("Red", Format("%v", EColor::Red));
EXPECT_EQ("red", Format("%lv", EColor::Red));
EXPECT_EQ("BlackAndWhite", Format("%v", EColor::BlackAndWhite));
EXPECT_EQ("black_and_white", Format("%lv", EColor::BlackAndWhite));
EXPECT_EQ("EColor::unknown-100", Format("%v", EColor(100)));
EXPECT_EQ("Cpp | ELangs::unknown-32", Format("%v", ELangs(0x21)));
EXPECT_EQ("JavaScript", Format("%v", ELangs::JavaScript));
EXPECT_EQ("java_script", Format("%lv", ELangs::JavaScript));
EXPECT_EQ("None", Format("%v", ELangs::None));
EXPECT_EQ("none", Format("%lv", ELangs::None));
EXPECT_EQ("", Format("%v", EBitEnumWithoutNone()));
EXPECT_EQ("Cpp | Go", Format("%v", ELangs::Cpp | ELangs::Go));
EXPECT_EQ("cpp | go", Format("%lv", ELangs::Cpp | ELangs::Go));
auto four = ELangs::Cpp | ELangs::Go | ELangs::Python | ELangs::JavaScript;
EXPECT_EQ("Cpp | Go | Python | JavaScript", Format("%v", four));
EXPECT_EQ("cpp | go | python | java_script", Format("%lv", four));
}
TEST(TFormatEnumTest, FormatEnumWithCustomDomainName)
{
EXPECT_EQ("value_a", FormatEnum(ECustomDomainName::A));
EXPECT_EQ("value_b", FormatEnum(ECustomDomainName::B));
}
TEST(TParseEnumTest, ParseUnknown)
{
EXPECT_EQ(std::nullopt, TryParseEnum<EColor>("yellow"));
EXPECT_THROW(ParseEnum<EColor>("yellow"), TSimpleException);
EXPECT_EQ(std::nullopt, TryParseEnum<EColorWithUnknown>("yellow"));
EXPECT_EQ(EColorWithUnknown::Unknown, TryParseEnum<EColorWithUnknown>("yellow", /*enableUnknown*/ true));
EXPECT_EQ(EColorWithUnknown::Unknown, ParseEnum<EColorWithUnknown>("yellow"));
EXPECT_EQ(std::nullopt, TryParseEnum<ELangs>("cpp | haskell"));
EXPECT_THROW(ParseEnum<ELangs>("cpp | haskell"), TSimpleException);
EXPECT_EQ(ELangsWithUnknown::Cpp | ELangsWithUnknown::Unknown, TryParseEnum<ELangsWithUnknown>("cpp | haskell", /*enableUnknown*/ true));
EXPECT_EQ(ELangsWithUnknown::Cpp | ELangsWithUnknown::Unknown, ParseEnum<ELangsWithUnknown>("cpp | haskell"));
}
TEST(TParseEnumTest, ParseEnumWithCustomDomainName)
{
EXPECT_EQ(ECustomDomainName::A, TryParseEnum<ECustomDomainName>("value_a"));
EXPECT_EQ(ECustomDomainName::B, TryParseEnum<ECustomDomainName>("value_b"));
EXPECT_EQ(std::nullopt, TryParseEnum<ECustomDomainName>("b"));
}
TEST(TParseEnumTest, ParseBitEnum)
{
EXPECT_EQ(ELangs::None, TryParseEnum<ELangs>(""));
EXPECT_EQ(ELangs::Cpp, TryParseEnum<ELangs>("cpp"));
EXPECT_EQ(ELangs::Cpp | ELangs::Rust, TryParseEnum<ELangs>("cpp|rust"));
EXPECT_EQ(ELangs::Cpp | ELangs::Rust, TryParseEnum<ELangs>("cpp | rust"));
EXPECT_EQ(std::nullopt, TryParseEnum<ELangs>("haskell | rust"));
}
////////////////////////////////////////////////////////////////////////////////
} // namespace
} // namespace NYT
|