You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.1 KiB

3 months ago
  1. #include "regex_yaml.h"
  2. #include "stream.h"
  3. #include "gtest/gtest.h"
  4. using YAML::RegEx;
  5. using YAML::Stream;
  6. namespace {
  7. const auto MIN_CHAR = Stream::eof() + 1;
  8. TEST(RegExTest, Empty) {
  9. RegEx empty;
  10. EXPECT_TRUE(empty.Matches(std::string()));
  11. EXPECT_EQ(0, empty.Match(std::string()));
  12. for (int i = MIN_CHAR; i < 128; ++i) {
  13. auto str = std::string(1, char(i));
  14. EXPECT_FALSE(empty.Matches(str));
  15. EXPECT_EQ(-1, empty.Match(str));
  16. }
  17. }
  18. TEST(RegExTest, Range) {
  19. for (int i = MIN_CHAR; i < 128; ++i) {
  20. for (int j = MIN_CHAR; j < 128; ++j) {
  21. RegEx ex((char)i, (char)j);
  22. for (int k = MIN_CHAR; k < 128; ++k) {
  23. auto str = std::string(1, char(k));
  24. if (i <= k && k <= j) {
  25. EXPECT_TRUE(ex.Matches(str));
  26. EXPECT_EQ(1, ex.Match(str));
  27. } else {
  28. EXPECT_FALSE(ex.Matches(str));
  29. EXPECT_EQ(-1, ex.Match(str));
  30. }
  31. }
  32. }
  33. }
  34. }
  35. TEST(RegExTest, EmptyString) {
  36. RegEx ex = RegEx(std::string());
  37. EXPECT_TRUE(ex.Matches(std::string()));
  38. EXPECT_EQ(0, ex.Match(std::string()));
  39. // Matches anything, unlike RegEx()!
  40. EXPECT_TRUE(ex.Matches(std::string("hello")));
  41. EXPECT_EQ(0, ex.Match(std::string("hello")));
  42. }
  43. TEST(RegExTest, SingleCharacterString) {
  44. for (int i = MIN_CHAR; i < 128; ++i) {
  45. RegEx ex(std::string(1, (char)i));
  46. for (int j = MIN_CHAR; j < 128; ++j) {
  47. auto str = std::string(1, char(j));
  48. if (j == i) {
  49. EXPECT_TRUE(ex.Matches(str));
  50. EXPECT_EQ(1, ex.Match(str));
  51. // Match at start of string only!
  52. std::string prefixed =
  53. std::string(1, i + 1) + std::string("prefix: ") + str;
  54. EXPECT_FALSE(ex.Matches(prefixed));
  55. EXPECT_EQ(-1, ex.Match(prefixed));
  56. } else {
  57. EXPECT_FALSE(ex.Matches(str));
  58. EXPECT_EQ(-1, ex.Match(str));
  59. }
  60. }
  61. }
  62. }
  63. TEST(RegExTest, MultiCharacterString) {
  64. RegEx ex(std::string("ab"));
  65. EXPECT_FALSE(ex.Matches(std::string("a")));
  66. EXPECT_EQ(-1, ex.Match(std::string("a")));
  67. EXPECT_TRUE(ex.Matches(std::string("ab")));
  68. EXPECT_EQ(2, ex.Match(std::string("ab")));
  69. EXPECT_TRUE(ex.Matches(std::string("abba")));
  70. EXPECT_EQ(2, ex.Match(std::string("abba")));
  71. // match at start of string only!
  72. EXPECT_FALSE(ex.Matches(std::string("baab")));
  73. EXPECT_EQ(-1, ex.Match(std::string("baab")));
  74. }
  75. TEST(RegExTest, OperatorNot) {
  76. RegEx ex = !RegEx(std::string("ab"));
  77. EXPECT_TRUE(ex.Matches(std::string("a")));
  78. EXPECT_EQ(1, ex.Match(std::string("a")));
  79. EXPECT_FALSE(ex.Matches(std::string("ab")));
  80. EXPECT_EQ(-1, ex.Match(std::string("ab")));
  81. EXPECT_FALSE(ex.Matches(std::string("abba")));
  82. EXPECT_EQ(-1, ex.Match(std::string("abba")));
  83. // match at start of string only!
  84. EXPECT_TRUE(ex.Matches(std::string("baab")));
  85. // Operator not causes only one character to be matched.
  86. EXPECT_EQ(1, ex.Match(std::string("baab")));
  87. }
  88. TEST(RegExTest, OperatorOr) {
  89. for (int i = MIN_CHAR; i < 127; ++i) {
  90. for (int j = i + 1; j < 128; ++j) {
  91. auto iStr = std::string(1, char(i));
  92. auto jStr = std::string(1, char(j));
  93. RegEx ex1 = RegEx(iStr) | RegEx(jStr);
  94. RegEx ex2 = RegEx(jStr) | RegEx(iStr);
  95. for (int k = MIN_CHAR; k < 128; ++k) {
  96. auto str = std::string(1, char(k));
  97. if (i == k || j == k) {
  98. EXPECT_TRUE(ex1.Matches(str));
  99. EXPECT_TRUE(ex2.Matches(str));
  100. EXPECT_EQ(1, ex1.Match(str));
  101. EXPECT_EQ(1, ex2.Match(str));
  102. } else {
  103. EXPECT_FALSE(ex1.Matches(str));
  104. EXPECT_FALSE(ex2.Matches(str));
  105. EXPECT_EQ(-1, ex1.Match(str));
  106. EXPECT_EQ(-1, ex2.Match(str));
  107. }
  108. }
  109. }
  110. }
  111. }
  112. TEST(RegExTest, OperatorOrShortCircuits) {
  113. RegEx ex1 = RegEx(std::string("aaaa")) | RegEx(std::string("aa"));
  114. RegEx ex2 = RegEx(std::string("aa")) | RegEx(std::string("aaaa"));
  115. EXPECT_TRUE(ex1.Matches(std::string("aaaaa")));
  116. EXPECT_EQ(4, ex1.Match(std::string("aaaaa")));
  117. EXPECT_TRUE(ex2.Matches(std::string("aaaaa")));
  118. EXPECT_EQ(2, ex2.Match(std::string("aaaaa")));
  119. }
  120. TEST(RegExTest, OperatorAnd) {
  121. RegEx emptySet = RegEx('a') & RegEx();
  122. EXPECT_FALSE(emptySet.Matches(std::string("a")));
  123. }
  124. TEST(RegExTest, OperatorAndShortCircuits) {
  125. RegEx ex1 = RegEx(std::string("aaaa")) & RegEx(std::string("aa"));
  126. RegEx ex2 = RegEx(std::string("aa")) & RegEx(std::string("aaaa"));
  127. EXPECT_TRUE(ex1.Matches(std::string("aaaaa")));
  128. EXPECT_EQ(4, ex1.Match(std::string("aaaaa")));
  129. EXPECT_TRUE(ex2.Matches(std::string("aaaaa")));
  130. EXPECT_EQ(2, ex2.Match(std::string("aaaaa")));
  131. }
  132. TEST(RegExTest, OperatorPlus) {
  133. RegEx ex = RegEx(std::string("hello ")) + RegEx(std::string("there"));
  134. EXPECT_TRUE(ex.Matches(std::string("hello there")));
  135. EXPECT_FALSE(ex.Matches(std::string("hello ")));
  136. EXPECT_FALSE(ex.Matches(std::string("there")));
  137. EXPECT_EQ(11, ex.Match(std::string("hello there")));
  138. }
  139. TEST(RegExTest, StringOr) {
  140. std::string str = "abcde";
  141. RegEx ex = RegEx(str, YAML::REGEX_OR);
  142. for (size_t i = 0; i < str.size(); ++i) {
  143. EXPECT_TRUE(ex.Matches(str.substr(i, 1)));
  144. EXPECT_EQ(1, ex.Match(str.substr(i, 1)));
  145. }
  146. EXPECT_EQ(1, ex.Match(str));
  147. }
  148. } // namespace