cast_test.cxx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //
  2. // cast_test.cxx
  3. // string_utils-test
  4. //
  5. // Created by Sam Jaffe on 2/14/21.
  6. // Copyright © 2021 Sam Jaffe. All rights reserved.
  7. //
  8. #include "string_utils/cast.h"
  9. #include "xcode_gtest_helper.h"
  10. using testing::ElementsAre;
  11. using testing::FieldsAre;
  12. using testing::Pair;
  13. using namespace string_utils;
  14. TEST(CastIntegerTest, CastsWithBase10) {
  15. auto [value, success] = cast<int>("10");
  16. EXPECT_TRUE(success);
  17. EXPECT_THAT(value, 10);
  18. }
  19. TEST(CastIntegerTest, DoesNotCastBase8) {
  20. auto [value, success] = cast<int>("010");
  21. EXPECT_TRUE(success);
  22. EXPECT_THAT(value, 10);
  23. }
  24. TEST(CastIntegerTest, DoesNotCastHex) {
  25. auto [value, success] = cast<int>("0x10");
  26. EXPECT_FALSE(success);
  27. EXPECT_THAT(value, 0);
  28. }
  29. TEST(CastIntegerTest, FailsOnBadData) {
  30. auto [value, success] = cast<int>("x");
  31. EXPECT_FALSE(success);
  32. EXPECT_THAT(value, 0);
  33. }
  34. TEST(CastIntegerTest, FailsOnBadSuffix) {
  35. auto [value, success] = cast<int>("10x");
  36. EXPECT_FALSE(success);
  37. EXPECT_THAT(value, 10);
  38. }
  39. TEST(CastIntegerTest, FailsOnOutOfBounds) {
  40. auto [_, success] = cast<int>("2147483648");
  41. EXPECT_FALSE(success);
  42. }
  43. TEST(CastBooleanTest, CastsVariousTrueValues) {
  44. EXPECT_THAT(cast<bool>("true"), Pair(true, true));
  45. EXPECT_THAT(cast<bool>("TRUE"), Pair(true, true));
  46. EXPECT_THAT(cast<bool>("YES"), Pair(true, true));
  47. EXPECT_THAT(cast<bool>("1"), Pair(true, true));
  48. }
  49. TEST(CastBooleanTest, CastsVariousFalseValues) {
  50. EXPECT_THAT(cast<bool>("false"), Pair(false, true));
  51. EXPECT_THAT(cast<bool>("FALSE"), Pair(false, true));
  52. EXPECT_THAT(cast<bool>("NO"), Pair(false, true));
  53. EXPECT_THAT(cast<bool>("0"), Pair(false, true));
  54. }
  55. TEST(CastBooleanTest, DoesNotCastAllIntegers) {
  56. auto [_, success] = cast<bool>("2");
  57. EXPECT_FALSE(success);
  58. }
  59. MATCHER_P(HoldsAlternative, typearg,
  60. std::string("holds a value of type ") + typeid(typearg).name()) {
  61. using T = std::remove_const_t<std::decay_t<decltype(typearg)>>;
  62. return std::holds_alternative<T>(arg);
  63. }
  64. template <typename T> auto HoldsAlternative() { return HoldsAlternative(T()); }
  65. TEST(CastVariantTest, StringVariantWillAlwaysMatchWhenEncountered) {
  66. auto [value, success] = cast<std::variant<std::string, int>>("2");
  67. EXPECT_THAT(value, HoldsAlternative<std::string>());
  68. }
  69. TEST(CastVariantTest, EvaluatesTypesLeftToRight) {
  70. auto [value, success] = cast<std::variant<int, std::string>>("2");
  71. EXPECT_THAT(value, HoldsAlternative<int>());
  72. }
  73. using pair_t = std::pair<std::string, std::string>;
  74. using tuple_t = std::tuple<int, int, std::string>;
  75. TEST(CastKeyValTest, FailsOnTooFewTokens) {
  76. auto [value, success] = cast<pair_t>(std::vector{"key"});
  77. EXPECT_FALSE(success);
  78. }
  79. TEST(CastKeyValTest, ParsesTokens) {
  80. auto [value, success] = cast<pair_t>(std::vector{"key", "value"});
  81. EXPECT_TRUE(success);
  82. EXPECT_THAT(value, Pair("key", "value"));
  83. }
  84. TEST(CastKeyValTest, FailsOnTooManyTokens) {
  85. auto [value, success] = cast<pair_t>(std::vector{"key", "value", "mapping"});
  86. EXPECT_FALSE(success);
  87. }
  88. TEST(CastTupleTest, FailsOnTooFewTokens) {
  89. auto [value, success] = cast<tuple_t>(std::vector{"0", "A"});
  90. EXPECT_FALSE(success);
  91. }
  92. TEST(CastTupleTest, FailsOnTooManyTokens) {
  93. auto [value, success] = cast<tuple_t>(std::vector{"0", "1", "A", "B"});
  94. EXPECT_FALSE(success);
  95. }
  96. TEST(CastTupleTest, ParsesIfAllGood) {
  97. auto [value, success] = cast<tuple_t>(std::vector{"0", "1", "A"});
  98. EXPECT_TRUE(success);
  99. EXPECT_THAT(value, FieldsAre(0, 1, "A"));
  100. }
  101. TEST(CastTupleTest, FailsOnAnyParseError) {
  102. auto [value, success] = cast<tuple_t>(std::vector{"0", "Q", "A"});
  103. EXPECT_FALSE(success);
  104. }
  105. struct Bindable {
  106. int a;
  107. std::string b;
  108. };
  109. bool cast(Bindable & out, std::vector<std::string_view> const & strs) {
  110. return strs.size() == 2 && cast(out.a, strs[0]) && cast(out.b, strs[1]);
  111. }
  112. struct Positive {
  113. int value;
  114. };
  115. bool cast(Positive & out, std::string_view str) {
  116. return cast(out.value, str) && out.value > 0;
  117. }
  118. TEST(CastTest, UsesADL) {
  119. auto [value, success] = cast<Bindable>(std::vector{"0", "Q"});
  120. EXPECT_TRUE(success);
  121. }
  122. TEST(CastTest, CanImposeConstraint) {
  123. auto [value, success] = cast<Positive>("0");
  124. EXPECT_FALSE(success);
  125. }
  126. TEST(CastContainerTest, CanCastVector) {
  127. auto [value, success] =
  128. cast<std::vector<std::string>>(std::vector{"0", "Q", "A"});
  129. EXPECT_TRUE(success);
  130. EXPECT_THAT(value, ElementsAre("0", "Q", "A"));
  131. }
  132. TEST(CastContainerTest, FailsIfBadValueCast) {
  133. auto [value, success] = cast<std::vector<int>>(std::vector{"0", "Q", "A"});
  134. EXPECT_FALSE(success);
  135. }
  136. TEST(CastContainerTest, CanCastSet) {
  137. auto [value, success] =
  138. cast<std::set<std::string>>(std::vector{"0", "0", "A"});
  139. EXPECT_TRUE(success);
  140. EXPECT_THAT(value, ElementsAre("0", "A"));
  141. }
  142. TEST(CastContainerTest, CanCastMap) {
  143. auto [value, success] = cast<std::map<std::string, std::string>>(
  144. std::vector{"0=1", "0=2", "A=B"});
  145. EXPECT_TRUE(success);
  146. EXPECT_THAT(value, ElementsAre(Pair("0", "1"), Pair("A", "B")));
  147. }
  148. TEST(CastContainerTest, FailsIfBadCastOnKey) {
  149. auto [value, success] =
  150. cast<std::map<int, std::string>>(std::vector{"0=1", "0=2", "A=B"});
  151. EXPECT_FALSE(success);
  152. }
  153. TEST(CastContainerTest, FailsIfBadCastOnValue) {
  154. auto [value, success] =
  155. cast<std::map<std::string, int>>(std::vector{"0=1", "0=2", "A=B"});
  156. EXPECT_FALSE(success);
  157. }