enum_ut.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. #include <library/cpp/testing/gtest/gtest.h>
  2. #include <library/cpp/yt/misc/cast.h>
  3. #include <library/cpp/yt/misc/enum.h>
  4. namespace NYT {
  5. namespace {
  6. ////////////////////////////////////////////////////////////////////////////////
  7. DEFINE_ENUM(ESimple,
  8. (X)
  9. (Y)
  10. (Z)
  11. );
  12. DEFINE_ENUM(EColor,
  13. ((Red) (10))
  14. ((Green)(20))
  15. ((Blue) (30))
  16. (Black)
  17. (White)
  18. );
  19. DEFINE_BIT_ENUM(EFlag,
  20. ((_1)(0x0001))
  21. ((_2)(0x0002))
  22. ((_3)(0x0004))
  23. ((_4)(0x0008))
  24. );
  25. DEFINE_AMBIGUOUS_ENUM_WITH_UNDERLYING_TYPE(EMultipleNames, int,
  26. (A1)
  27. ((A2)(0))
  28. (B)
  29. (C)
  30. ((D1)(100))
  31. ((D2)(100))
  32. );
  33. DEFINE_ENUM(ECustomString,
  34. ((A) (1) ("1_a"))
  35. ((B) (2) ("1_b"))
  36. );
  37. DEFINE_ENUM_WITH_UNDERLYING_TYPE(ECardinal, char,
  38. ((West) (0))
  39. ((North) (1))
  40. ((East) (2))
  41. ((South) (3))
  42. );
  43. DEFINE_ENUM(EWithUnknown,
  44. (First)
  45. (Second)
  46. (Unknown)
  47. );
  48. DEFINE_ENUM_UNKNOWN_VALUE(EWithUnknown, Unknown);
  49. ////////////////////////////////////////////////////////////////////////////////
  50. template <class T, size_t N>
  51. std::vector<T> ToVector(std::array<T, N> array)
  52. {
  53. return std::vector<T>(array.begin(), array.end());
  54. }
  55. TEST(TEnumTest, Domain)
  56. {
  57. EXPECT_EQ(3, TEnumTraits<ESimple>::GetDomainSize());
  58. std::vector<ESimple> v {
  59. ESimple::X,
  60. ESimple::Y,
  61. ESimple::Z
  62. };
  63. EXPECT_EQ(v, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
  64. EXPECT_EQ(ESimple::X, TEnumTraits<ESimple>::GetMinValue());
  65. EXPECT_EQ(ESimple::Z, TEnumTraits<ESimple>::GetMaxValue());
  66. }
  67. TEST(TEnumTest, Basic)
  68. {
  69. EXPECT_EQ(0, static_cast<int>(ESimple::X));
  70. EXPECT_EQ(1, static_cast<int>(ESimple::Y));
  71. EXPECT_EQ(2, static_cast<int>(ESimple::Z));
  72. EXPECT_EQ(0, static_cast<int>(EColor( )));
  73. EXPECT_EQ(5, static_cast<int>(EColor(5)));
  74. EXPECT_EQ(10, static_cast<int>(EColor::Red ));
  75. EXPECT_EQ(20, static_cast<int>(EColor::Green));
  76. EXPECT_EQ(30, static_cast<int>(EColor::Blue ));
  77. EXPECT_EQ(31, static_cast<int>(EColor::Black));
  78. EXPECT_EQ(32, static_cast<int>(EColor::White));
  79. }
  80. TEST(TEnumTest, ToString)
  81. {
  82. EXPECT_EQ("EColor(0)", ToString(EColor( )));
  83. EXPECT_EQ("EColor(5)", ToString(EColor(5)));
  84. EXPECT_EQ("Red", ToString(EColor(EColor::Red )));
  85. EXPECT_EQ("Green", ToString(EColor::Green));
  86. EXPECT_EQ("Blue", ToString(EColor(EColor::Blue )));
  87. EXPECT_EQ("Black", ToString(EColor::Black));
  88. EXPECT_EQ("White", ToString(EColor::White));
  89. }
  90. TEST(TEnumTest, FromString)
  91. {
  92. EXPECT_EQ(EColor::Red , TEnumTraits<EColor>::FromString("Red" ));
  93. EXPECT_EQ(EColor::Green, TEnumTraits<EColor>::FromString("Green"));
  94. EXPECT_EQ(EColor::Blue , TEnumTraits<EColor>::FromString("Blue" ));
  95. EXPECT_EQ(EColor::Black, TEnumTraits<EColor>::FromString("Black"));
  96. EXPECT_EQ(EColor::White, TEnumTraits<EColor>::FromString("White"));
  97. EXPECT_THROW(TEnumTraits<EColor>::FromString("Pink"), std::exception);
  98. EXPECT_EQ(EColor::Red, TEnumTraits<EColor>::FindValueByLiteral("Red"));
  99. EXPECT_EQ(std::nullopt, TEnumTraits<EColor>::FindValueByLiteral("Pink"));
  100. }
  101. TEST(TEnumTest, Ordering)
  102. {
  103. ESimple a(ESimple::X);
  104. ESimple b(ESimple::Y);
  105. ESimple c(ESimple::Y);
  106. ESimple d(ESimple::Z);
  107. EXPECT_FALSE(a < a); EXPECT_FALSE(a > a);
  108. EXPECT_TRUE (a < b); EXPECT_TRUE (b > a);
  109. EXPECT_TRUE (a < c); EXPECT_TRUE (c > a);
  110. EXPECT_TRUE (a < d); EXPECT_TRUE (d > a);
  111. EXPECT_FALSE(b < a); EXPECT_FALSE(a > b);
  112. EXPECT_FALSE(b < b); EXPECT_FALSE(b > b);
  113. EXPECT_FALSE(b < c); EXPECT_FALSE(c > b);
  114. EXPECT_TRUE (b < d); EXPECT_TRUE (d > b);
  115. EXPECT_FALSE(c < a); EXPECT_FALSE(a > c);
  116. EXPECT_FALSE(c < b); EXPECT_FALSE(b > c);
  117. EXPECT_FALSE(c < c); EXPECT_FALSE(c > c);
  118. EXPECT_TRUE (c < d); EXPECT_TRUE (d > c);
  119. EXPECT_FALSE(d < a); EXPECT_FALSE(a > d);
  120. EXPECT_FALSE(d < b); EXPECT_FALSE(b > d);
  121. EXPECT_FALSE(d < c); EXPECT_FALSE(c > d);
  122. EXPECT_FALSE(d < d); EXPECT_FALSE(d > d);
  123. EXPECT_TRUE (a <= b);
  124. EXPECT_TRUE (b <= c);
  125. EXPECT_TRUE (c <= d);
  126. EXPECT_TRUE (a == a);
  127. EXPECT_FALSE(a == b);
  128. EXPECT_TRUE (b == c);
  129. EXPECT_FALSE(c == d);
  130. EXPECT_FALSE(d == a);
  131. EXPECT_FALSE(a != a);
  132. EXPECT_TRUE (a != b);
  133. EXPECT_FALSE(b != c);
  134. EXPECT_TRUE (c != d);
  135. EXPECT_TRUE (d != a);
  136. }
  137. TEST(TEnumTest, OrderingWithDomainValues)
  138. {
  139. EColor color(EColor::Black);
  140. EXPECT_LT(EColor::Red, color);
  141. EXPECT_LT(color, EColor::White);
  142. EXPECT_GT(color, EColor::Red);
  143. EXPECT_GT(EColor::White, color);
  144. EXPECT_LE(EColor::Red, color);
  145. EXPECT_LE(color, EColor::White);
  146. EXPECT_GE(EColor::White, color);
  147. EXPECT_GE(color, EColor::Red);
  148. EXPECT_EQ(color, EColor::Black);
  149. EXPECT_EQ(EColor::Black, color);
  150. EXPECT_NE(color, EColor::Blue);
  151. EXPECT_NE(EColor::Blue, color);
  152. }
  153. TEST(TEnumTest, DomainSize)
  154. {
  155. EXPECT_EQ(3, TEnumTraits<ESimple>::GetDomainSize());
  156. EXPECT_EQ(5, TEnumTraits<EColor>::GetDomainSize());
  157. }
  158. TEST(TEnumTest, DomainValues)
  159. {
  160. std::vector<ESimple> simpleValues;
  161. simpleValues.push_back(ESimple::X);
  162. simpleValues.push_back(ESimple::Y);
  163. simpleValues.push_back(ESimple::Z);
  164. EXPECT_EQ(simpleValues, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
  165. std::vector<EColor> colorValues;
  166. colorValues.push_back(EColor::Red);
  167. colorValues.push_back(EColor::Green);
  168. colorValues.push_back(EColor::Blue);
  169. colorValues.push_back(EColor::Black);
  170. colorValues.push_back(EColor::White);
  171. EXPECT_EQ(colorValues, ToVector(TEnumTraits<EColor>::GetDomainValues()));
  172. }
  173. TEST(TEnumTest, IsKnownValue)
  174. {
  175. EXPECT_TRUE(TEnumTraits<ESimple>::IsKnownValue(ESimple::X));
  176. EXPECT_TRUE(TEnumTraits<ESimple>::IsKnownValue(ESimple::Y));
  177. EXPECT_TRUE(TEnumTraits<ESimple>::IsKnownValue(ESimple::Z));
  178. EXPECT_FALSE(TEnumTraits<ESimple>::IsKnownValue(static_cast<ESimple>(100)));
  179. }
  180. TEST(TEnumTest, IsValidValue)
  181. {
  182. EXPECT_TRUE(TEnumTraits<ESimple>::IsValidValue(ESimple::X));
  183. EXPECT_TRUE(TEnumTraits<ESimple>::IsValidValue(ESimple::Y));
  184. EXPECT_TRUE(TEnumTraits<ESimple>::IsValidValue(ESimple::Z));
  185. EXPECT_FALSE(TEnumTraits<ESimple>::IsValidValue(static_cast<ESimple>(100)));
  186. EXPECT_TRUE(TEnumTraits<EFlag>::IsValidValue(EFlag()));
  187. EXPECT_TRUE(TEnumTraits<EFlag>::IsValidValue(EFlag::_1));
  188. EXPECT_TRUE(TEnumTraits<EFlag>::IsValidValue(EFlag::_1 | EFlag::_2));
  189. EXPECT_TRUE(TEnumTraits<EFlag>::IsValidValue(EFlag::_1 | EFlag::_2 | EFlag::_3 | EFlag::_4));
  190. EXPECT_FALSE(TEnumTraits<EFlag>::IsValidValue(static_cast<EFlag>(0x10)));
  191. }
  192. TEST(TEnumTest, AllSetValue)
  193. {
  194. EXPECT_EQ(TEnumTraits<EFlag>::GetAllSetValue(), EFlag::_1 | EFlag::_2 | EFlag::_3 | EFlag::_4);
  195. }
  196. TEST(TEnumTest, Decompose1)
  197. {
  198. auto f = EFlag(0);
  199. std::vector<EFlag> ff { };
  200. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  201. }
  202. TEST(TEnumTest, Decompose2)
  203. {
  204. auto f = EFlag::_1;
  205. std::vector<EFlag> ff {EFlag::_1};
  206. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  207. }
  208. TEST(TEnumTest, Decompose3)
  209. {
  210. auto f = EFlag(EFlag::_1|EFlag::_2);
  211. std::vector<EFlag> ff{EFlag::_1, EFlag::_2};
  212. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  213. }
  214. TEST(TEnumTest, Decompose4)
  215. {
  216. auto f = EFlag(EFlag::_2|EFlag::_4);
  217. std::vector<EFlag> ff{EFlag::_2, EFlag::_4};
  218. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  219. }
  220. TEST(TEnumTest, MultipleNames)
  221. {
  222. EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A1"));
  223. EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A2"));
  224. EXPECT_EQ(EMultipleNames::B, TEnumTraits<EMultipleNames>::FromString("B"));
  225. EXPECT_EQ(EMultipleNames::C, TEnumTraits<EMultipleNames>::FromString("C"));
  226. EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D1"));
  227. EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D2"));
  228. EXPECT_EQ("A1", ToString(EMultipleNames::A1));
  229. EXPECT_EQ("A1", ToString(EMultipleNames::A2));
  230. EXPECT_EQ("B", ToString(EMultipleNames::B));
  231. EXPECT_EQ("C", ToString(EMultipleNames::C));
  232. EXPECT_EQ("D1", ToString(EMultipleNames::D1));
  233. EXPECT_EQ("D1", ToString(EMultipleNames::D2));
  234. }
  235. TEST(TEnumTest, CustomString)
  236. {
  237. EXPECT_EQ(ECustomString::A, TEnumTraits<ECustomString>::FromString("1_a"));
  238. EXPECT_EQ(ECustomString::B, TEnumTraits<ECustomString>::FromString("1_b"));
  239. EXPECT_EQ("1_a", ToString(ECustomString::A));
  240. EXPECT_EQ("1_b", ToString(ECustomString::B));
  241. }
  242. TEST(TEnumTest, UnknownValue)
  243. {
  244. EXPECT_EQ(TEnumTraits<EColor>::TryGetUnknownValue(), std::nullopt);
  245. EXPECT_EQ(TEnumTraits<EWithUnknown>::TryGetUnknownValue(), EWithUnknown::Unknown);
  246. }
  247. ////////////////////////////////////////////////////////////////////////////////
  248. } // namespace
  249. } // namespace NYT