enum_ut.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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. ////////////////////////////////////////////////////////////////////////////////
  44. template <class T, size_t N>
  45. std::vector<T> ToVector(std::array<T, N> array)
  46. {
  47. return std::vector<T>(array.begin(), array.end());
  48. }
  49. TEST(TEnumTest, Domain)
  50. {
  51. EXPECT_EQ(3, TEnumTraits<ESimple>::GetDomainSize());
  52. std::vector<ESimple> v {
  53. ESimple::X,
  54. ESimple::Y,
  55. ESimple::Z
  56. };
  57. EXPECT_EQ(v, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
  58. EXPECT_EQ(ESimple::X, TEnumTraits<ESimple>::GetMinValue());
  59. EXPECT_EQ(ESimple::Z, TEnumTraits<ESimple>::GetMaxValue());
  60. }
  61. TEST(TEnumTest, Basic)
  62. {
  63. EXPECT_EQ(0, static_cast<int>(ESimple::X));
  64. EXPECT_EQ(1, static_cast<int>(ESimple::Y));
  65. EXPECT_EQ(2, static_cast<int>(ESimple::Z));
  66. EXPECT_EQ(0, static_cast<int>(EColor( )));
  67. EXPECT_EQ(5, static_cast<int>(EColor(5)));
  68. EXPECT_EQ(10, static_cast<int>(EColor::Red ));
  69. EXPECT_EQ(20, static_cast<int>(EColor::Green));
  70. EXPECT_EQ(30, static_cast<int>(EColor::Blue ));
  71. EXPECT_EQ(31, static_cast<int>(EColor::Black));
  72. EXPECT_EQ(32, static_cast<int>(EColor::White));
  73. }
  74. TEST(TEnumTest, ToString)
  75. {
  76. EXPECT_EQ("EColor(0)", ToString(EColor( )));
  77. EXPECT_EQ("EColor(5)", ToString(EColor(5)));
  78. EXPECT_EQ("Red", ToString(EColor(EColor::Red )));
  79. EXPECT_EQ("Green", ToString(EColor::Green));
  80. EXPECT_EQ("Blue", ToString(EColor(EColor::Blue )));
  81. EXPECT_EQ("Black", ToString(EColor::Black));
  82. EXPECT_EQ("White", ToString(EColor::White));
  83. }
  84. TEST(TEnumTest, FromString)
  85. {
  86. EXPECT_EQ(EColor::Red , TEnumTraits<EColor>::FromString("Red" ));
  87. EXPECT_EQ(EColor::Green, TEnumTraits<EColor>::FromString("Green"));
  88. EXPECT_EQ(EColor::Blue , TEnumTraits<EColor>::FromString("Blue" ));
  89. EXPECT_EQ(EColor::Black, TEnumTraits<EColor>::FromString("Black"));
  90. EXPECT_EQ(EColor::White, TEnumTraits<EColor>::FromString("White"));
  91. EXPECT_THROW(TEnumTraits<EColor>::FromString("Pink"), std::exception);
  92. EXPECT_EQ(EColor::Red, TEnumTraits<EColor>::FindValueByLiteral("Red"));
  93. EXPECT_EQ(std::nullopt, TEnumTraits<EColor>::FindValueByLiteral("Pink"));
  94. }
  95. TEST(TEnumTest, Ordering)
  96. {
  97. ESimple a(ESimple::X);
  98. ESimple b(ESimple::Y);
  99. ESimple c(ESimple::Y);
  100. ESimple d(ESimple::Z);
  101. EXPECT_FALSE(a < a); EXPECT_FALSE(a > a);
  102. EXPECT_TRUE (a < b); EXPECT_TRUE (b > a);
  103. EXPECT_TRUE (a < c); EXPECT_TRUE (c > a);
  104. EXPECT_TRUE (a < d); EXPECT_TRUE (d > a);
  105. EXPECT_FALSE(b < a); EXPECT_FALSE(a > b);
  106. EXPECT_FALSE(b < b); EXPECT_FALSE(b > b);
  107. EXPECT_FALSE(b < c); EXPECT_FALSE(c > b);
  108. EXPECT_TRUE (b < d); EXPECT_TRUE (d > b);
  109. EXPECT_FALSE(c < a); EXPECT_FALSE(a > c);
  110. EXPECT_FALSE(c < b); EXPECT_FALSE(b > c);
  111. EXPECT_FALSE(c < c); EXPECT_FALSE(c > c);
  112. EXPECT_TRUE (c < d); EXPECT_TRUE (d > c);
  113. EXPECT_FALSE(d < a); EXPECT_FALSE(a > d);
  114. EXPECT_FALSE(d < b); EXPECT_FALSE(b > d);
  115. EXPECT_FALSE(d < c); EXPECT_FALSE(c > d);
  116. EXPECT_FALSE(d < d); EXPECT_FALSE(d > d);
  117. EXPECT_TRUE (a <= b);
  118. EXPECT_TRUE (b <= c);
  119. EXPECT_TRUE (c <= d);
  120. EXPECT_TRUE (a == a);
  121. EXPECT_FALSE(a == b);
  122. EXPECT_TRUE (b == c);
  123. EXPECT_FALSE(c == d);
  124. EXPECT_FALSE(d == a);
  125. EXPECT_FALSE(a != a);
  126. EXPECT_TRUE (a != b);
  127. EXPECT_FALSE(b != c);
  128. EXPECT_TRUE (c != d);
  129. EXPECT_TRUE (d != a);
  130. }
  131. TEST(TEnumTest, OrderingWithDomainValues)
  132. {
  133. EColor color(EColor::Black);
  134. EXPECT_LT(EColor::Red, color);
  135. EXPECT_LT(color, EColor::White);
  136. EXPECT_GT(color, EColor::Red);
  137. EXPECT_GT(EColor::White, color);
  138. EXPECT_LE(EColor::Red, color);
  139. EXPECT_LE(color, EColor::White);
  140. EXPECT_GE(EColor::White, color);
  141. EXPECT_GE(color, EColor::Red);
  142. EXPECT_EQ(color, EColor::Black);
  143. EXPECT_EQ(EColor::Black, color);
  144. EXPECT_NE(color, EColor::Blue);
  145. EXPECT_NE(EColor::Blue, color);
  146. }
  147. TEST(TEnumTest, DomainSize)
  148. {
  149. EXPECT_EQ(3, TEnumTraits<ESimple>::GetDomainSize());
  150. EXPECT_EQ(5, TEnumTraits<EColor>::GetDomainSize());
  151. }
  152. TEST(TEnumTest, DomainValues)
  153. {
  154. std::vector<ESimple> simpleValues;
  155. simpleValues.push_back(ESimple::X);
  156. simpleValues.push_back(ESimple::Y);
  157. simpleValues.push_back(ESimple::Z);
  158. EXPECT_EQ(simpleValues, ToVector(TEnumTraits<ESimple>::GetDomainValues()));
  159. std::vector<EColor> colorValues;
  160. colorValues.push_back(EColor::Red);
  161. colorValues.push_back(EColor::Green);
  162. colorValues.push_back(EColor::Blue);
  163. colorValues.push_back(EColor::Black);
  164. colorValues.push_back(EColor::White);
  165. EXPECT_EQ(colorValues, ToVector(TEnumTraits<EColor>::GetDomainValues()));
  166. }
  167. TEST(TEnumTest, Decompose1)
  168. {
  169. auto f = EFlag(0);
  170. std::vector<EFlag> ff { };
  171. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  172. }
  173. TEST(TEnumTest, Decompose2)
  174. {
  175. auto f = EFlag::_1;
  176. std::vector<EFlag> ff {EFlag::_1};
  177. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  178. }
  179. TEST(TEnumTest, Decompose3)
  180. {
  181. auto f = EFlag(EFlag::_1|EFlag::_2);
  182. std::vector<EFlag> ff{EFlag::_1, EFlag::_2};
  183. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  184. }
  185. TEST(TEnumTest, Decompose4)
  186. {
  187. auto f = EFlag(EFlag::_2|EFlag::_4);
  188. std::vector<EFlag> ff{EFlag::_2, EFlag::_4};
  189. EXPECT_EQ(TEnumTraits<EFlag>::Decompose(f), ff);
  190. }
  191. TEST(TEnumTest, MultipleNames)
  192. {
  193. EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A1"));
  194. EXPECT_EQ(EMultipleNames::A1, TEnumTraits<EMultipleNames>::FromString("A2"));
  195. EXPECT_EQ(EMultipleNames::B, TEnumTraits<EMultipleNames>::FromString("B"));
  196. EXPECT_EQ(EMultipleNames::C, TEnumTraits<EMultipleNames>::FromString("C"));
  197. EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D1"));
  198. EXPECT_EQ(EMultipleNames::D1, TEnumTraits<EMultipleNames>::FromString("D2"));
  199. EXPECT_EQ("A1", ToString(EMultipleNames::A1));
  200. EXPECT_EQ("A1", ToString(EMultipleNames::A2));
  201. EXPECT_EQ("B", ToString(EMultipleNames::B));
  202. EXPECT_EQ("C", ToString(EMultipleNames::C));
  203. EXPECT_EQ("D1", ToString(EMultipleNames::D1));
  204. EXPECT_EQ("D1", ToString(EMultipleNames::D2));
  205. }
  206. TEST(TEnumTest, CustomString)
  207. {
  208. EXPECT_EQ(ECustomString::A, TEnumTraits<ECustomString>::FromString("1_a"));
  209. EXPECT_EQ(ECustomString::B, TEnumTraits<ECustomString>::FromString("1_b"));
  210. EXPECT_EQ("1_a", ToString(ECustomString::A));
  211. EXPECT_EQ("1_b", ToString(ECustomString::B));
  212. }
  213. TEST(TEnumTest, Cast)
  214. {
  215. ECardinal cardinal;
  216. {
  217. char validValue = 2;
  218. EXPECT_TRUE(TryEnumCast(validValue, &cardinal));
  219. EXPECT_EQ(cardinal, ECardinal::East);
  220. }
  221. {
  222. char invalidValue = 100;
  223. EXPECT_FALSE(TryEnumCast(invalidValue, &cardinal));
  224. }
  225. {
  226. int widerTypeValidValue = 3;
  227. EXPECT_TRUE(TryEnumCast(widerTypeValidValue, &cardinal));
  228. EXPECT_EQ(cardinal, ECardinal::South);
  229. }
  230. {
  231. int widerTypeInvalueValue = (1 << 8) + 100;
  232. EXPECT_FALSE(TryEnumCast(widerTypeInvalueValue, &cardinal));
  233. }
  234. }
  235. ////////////////////////////////////////////////////////////////////////////////
  236. } // namespace
  237. } // namespace NYT