Regex.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include "pch.h"
  2. #include <Regex.h>
  3. #include "CppUnitTest.h"
  4. using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  5. namespace FrameworkTests
  6. {
  7. TEST_CLASS (RegexTests)
  8. {
  9. TEST_METHOD (MatchTest1)
  10. {
  11. auto parser = Framework::Regex::parse("ab+(c{3,6})?|b(a)");
  12. auto result = parser->match("abccccab", (int)strlen("abccccab"));
  13. Assert::IsTrue(result->getEintragAnzahl() == 2,
  14. L"Invalid result count while matching 'abccccab' against "
  15. L"'ab+(c{3,6})?|b(a)'");
  16. auto* first = result->z(0);
  17. auto* second = result->z(1);
  18. Assert::IsTrue(first->getStart() == 0 && first->getEnd() == 6,
  19. L"Invalid first result while matching 'abccccab' against "
  20. L"'ab+(c{3,6})?|b(a)'");
  21. Assert::IsTrue(first->getGroup(1).getStart() == 2
  22. && first->getGroup(1).getEnd() == 6,
  23. L"Invalid group 1 in result 1 while matching 'abccccab' "
  24. L"against "
  25. L"'ab+(c{3,6})?|b(a)'");
  26. Assert::IsTrue(first->getGroupCount() == 2,
  27. L"Invalid group count in result 1 while matching 'abccccab' "
  28. L"against "
  29. L"'ab+(c{3,6})?|b(a)'");
  30. Assert::IsTrue(second->getStart() == 6 && second->getEnd() == 8,
  31. L"Invalid second result while matching 'abccccab' against "
  32. L"'ab+(c{3,6})?|b(a)'");
  33. Assert::IsTrue(second->getGroupCount() == 1,
  34. L"Invalid group count in result 2 while matching 'abccccab' "
  35. L"against "
  36. L"'ab+(c{3,6})?|b(a)'");
  37. result->release();
  38. parser->release();
  39. }
  40. TEST_METHOD (MatchTest2)
  41. {
  42. auto parser = Framework::Regex::parse("abc");
  43. auto result
  44. = parser->match(" aabc abcc", (int)strlen(" aabc abcc"));
  45. Assert::IsTrue(result->getEintragAnzahl() == 2,
  46. L"Invalid result count while matching ' aabc abcc' against "
  47. L"'abc'");
  48. auto* first = result->z(0);
  49. auto* second = result->z(1);
  50. Assert::IsTrue(first->getStart() == 2 && first->getEnd() == 5,
  51. L"Invalid first result while matching ' aabc abcc' against "
  52. L"'abc'");
  53. Assert::IsTrue(first->getGroupCount() == 1,
  54. L"Invalid group count in result 1 while matching ' aabc abcc' "
  55. L"against "
  56. L"'abc'");
  57. Assert::IsTrue(second->getStart() == 6 && second->getEnd() == 9,
  58. L"Invalid second result while matching ' aabc abcc' against "
  59. L"'abc'");
  60. Assert::IsTrue(second->getGroupCount() == 1,
  61. L"Invalid group count in result 2 while matching ' aabc abcc' "
  62. L"against "
  63. L"'abc'");
  64. result->release();
  65. parser->release();
  66. }
  67. TEST_METHOD (MatchTest3)
  68. {
  69. auto parser = Framework::Regex::parse("(?:abc)*");
  70. auto result = parser->match("_aabcabcc", (int)strlen(" aabcabcc"));
  71. Assert::IsTrue(result->getEintragAnzahl() == 5,
  72. L"Invalid result count while matching '_aabcabcc' against "
  73. L"'(?:abc)*'");
  74. auto* first = result->z(0);
  75. auto* second = result->z(1);
  76. auto* third = result->z(2);
  77. auto* forth = result->z(3);
  78. auto* fifth = result->z(4);
  79. Assert::IsTrue(first->getStart() == 0 && first->getEnd() == 0,
  80. L"Invalid first result while matching '_aabcabcc' against "
  81. L"'(?:abc)*'");
  82. Assert::IsTrue(first->getGroupCount() == 1,
  83. L"Invalid group count in result 1 while matching '_aabcabcc' "
  84. L"against "
  85. L"'(?:abc)*'");
  86. Assert::IsTrue(second->getStart() == 1 && second->getEnd() == 1,
  87. L"Invalid second result while matching '_aabcabcc' against "
  88. L"'(?:abc)*'");
  89. Assert::IsTrue(second->getGroupCount() == 1,
  90. L"Invalid group count in result 2 while matching '_aabcabcc' "
  91. L"against "
  92. L"'(?:abc)*'");
  93. Assert::IsTrue(third->getStart() == 2 && third->getEnd() == 8,
  94. L"Invalid third result while matching '_aabcabcc' against "
  95. L"'(?:abc)*'");
  96. Assert::IsTrue(third->getGroupCount() == 1,
  97. L"Invalid group count in result 3 while matching '_aabcabcc' "
  98. L"against "
  99. L"'(?:abc)*'");
  100. Assert::IsTrue(forth->getStart() == 8 && forth->getEnd() == 8,
  101. L"Invalid result 4 while matching '_aabcabcc' against "
  102. L"'(?:abc)*'");
  103. Assert::IsTrue(forth->getGroupCount() == 1,
  104. L"Invalid group count in result 4 while matching '_aabcabcc' "
  105. L"against "
  106. L"'(?:abc)*'");
  107. Assert::IsTrue(fifth->getStart() == 9 && fifth->getEnd() == 9,
  108. L"Invalid result 5 while matching '_aabcabcc' against "
  109. L"'(?:abc)*'");
  110. Assert::IsTrue(fifth->getGroupCount() == 1,
  111. L"Invalid group count in result 5 while matching '_aabcabcc' "
  112. L"against "
  113. L"'(?:abc)*'");
  114. result->release();
  115. parser->release();
  116. }
  117. TEST_METHOD (MatchTest4)
  118. {
  119. auto parser = Framework::Regex::parse("(?:abc)*?");
  120. auto result = parser->match("_aabcabcc", (int)strlen(" aabcabcc"));
  121. Assert::IsTrue(result->getEintragAnzahl() == 8,
  122. L"Invalid result count while matching '_aabcabcc' against "
  123. L"'(?:abc)*?'");
  124. auto* _0 = result->z(0);
  125. auto* _1 = result->z(1);
  126. auto* _2 = result->z(2);
  127. auto* _3 = result->z(3);
  128. auto* _4 = result->z(4);
  129. auto* _5 = result->z(5);
  130. auto* _6 = result->z(6);
  131. auto* _7 = result->z(7);
  132. Assert::IsTrue(_0->getStart() == 0 && _0->getEnd() == 0,
  133. L"Invalid result 1 while matching '_aabcabcc' against "
  134. L"'(?:abc)*?'");
  135. Assert::IsTrue(_0->getGroupCount() == 1,
  136. L"Invalid group count in result 1 while matching '_aabcabcc' "
  137. L"against "
  138. L"'(?:abc)*?'");
  139. Assert::IsTrue(_1->getStart() == 1 && _1->getEnd() == 1,
  140. L"Invalid result 2 while matching '_aabcabcc' against "
  141. L"'(?:abc)*?'");
  142. Assert::IsTrue(_1->getGroupCount() == 1,
  143. L"Invalid group count in result 2 while matching '_aabcabcc' "
  144. L"against "
  145. L"'(?:abc)*?'");
  146. Assert::IsTrue(_2->getStart() == 2 && _2->getEnd() == 2,
  147. L"Invalid result 3 while matching '_aabcabcc' against "
  148. L"'(?:abc)*?'");
  149. Assert::IsTrue(_2->getGroupCount() == 1,
  150. L"Invalid group count in result 3 while matching '_aabcabcc' "
  151. L"against "
  152. L"'(?:abc)*?'");
  153. Assert::IsTrue(_3->getStart() == 2 && _3->getEnd() == 5,
  154. L"Invalid result 4 while matching '_aabcabcc' against "
  155. L"'(?:abc)*?'");
  156. Assert::IsTrue(_3->getGroupCount() == 1,
  157. L"Invalid group count in result 4 while matching '_aabcabcc' "
  158. L"against "
  159. L"'(?:abc)*'");
  160. Assert::IsTrue(_4->getStart() == 5 && _4->getEnd() == 5,
  161. L"Invalid result 5 while matching '_aabcabcc' against "
  162. L"'(?:abc)*?'");
  163. Assert::IsTrue(_4->getGroupCount() == 1,
  164. L"Invalid group count in result 5 while matching '_aabcabcc' "
  165. L"against "
  166. L"'(?:abc)*'");
  167. Assert::IsTrue(_5->getStart() == 5 && _5->getEnd() == 8,
  168. L"Invalid result 6 while matching '_aabcabcc' against "
  169. L"'(?:abc)*?'");
  170. Assert::IsTrue(_5->getGroupCount() == 1,
  171. L"Invalid group count in result 6 while matching '_aabcabcc' "
  172. L"against "
  173. L"'(?:abc)*'");
  174. Assert::IsTrue(_6->getStart() == 8 && _6->getEnd() == 8,
  175. L"Invalid result 7 while matching '_aabcabcc' against "
  176. L"'(?:abc)*?'");
  177. Assert::IsTrue(_6->getGroupCount() == 1,
  178. L"Invalid group count in result 7 while matching '_aabcabcc' "
  179. L"against "
  180. L"'(?:abc)*'");
  181. Assert::IsTrue(_7->getStart() == 9 && _7->getEnd() == 9,
  182. L"Invalid result 8 while matching '_aabcabcc' against "
  183. L"'(?:abc)*?'");
  184. Assert::IsTrue(_7->getGroupCount() == 1,
  185. L"Invalid group count in result 8 while matching '_aabcabcc' "
  186. L"against "
  187. L"'(?:abc)*?'");
  188. result->release();
  189. parser->release();
  190. }
  191. TEST_METHOD (MatchTest5)
  192. {
  193. auto parser = Framework::Regex::parse("(a|b)+");
  194. auto result
  195. = parser->match("cabaccccbab", (int)strlen("cabaccccbab"));
  196. Assert::IsTrue(result->getEintragAnzahl() == 2,
  197. L"Invalid result count while matching 'cabaccccbab' against "
  198. L"'a|b'");
  199. auto* first = result->z(0);
  200. auto* second = result->z(1);
  201. Assert::IsTrue(first->getStart() == 1 && first->getEnd() == 4,
  202. L"Invalid first result while matching 'cabaccccbab' against "
  203. L"'a|b'");
  204. Assert::IsTrue(first->getGroupCount() == 2,
  205. L"Invalid group count in result 1 while matching 'cabaccccbab' "
  206. L"against "
  207. L"'a|b'");
  208. Assert::IsTrue(first->getGroup(1).getStart() == 3
  209. && first->getGroup(1).getEnd() == 4,
  210. L"Invalid group 1 in result 1 while matching 'cabaccccbab' "
  211. L"against "
  212. L"'a|b'");
  213. Assert::IsTrue(second->getStart() == 8 && second->getEnd() == 11,
  214. L"Invalid second result while matching 'cabaccccbab' against "
  215. L"'a|b'");
  216. Assert::IsTrue(second->getGroupCount() == 2,
  217. L"Invalid group count in result 2 while matching 'cabaccccbab' "
  218. L"against "
  219. L"'a|b'");
  220. Assert::IsTrue(second->getGroup(1).getStart() == 10
  221. && second->getGroup(1).getEnd() == 11,
  222. L"Invalid group 1 in result 2 while matching 'cabaccccbab' "
  223. L"against "
  224. L"'a|b'");
  225. result->release();
  226. parser->release();
  227. }
  228. TEST_METHOD (MatchTest6)
  229. {
  230. auto parser = Framework::Regex::parse("(?:^|c)ab");
  231. auto result = parser->match("abcabcasd", (int)strlen("abcabcasd"));
  232. Assert::IsTrue(result->getEintragAnzahl() == 2,
  233. L"Invalid result count while matching 'abcabcasd' against "
  234. L"'(?:^|c)ab'");
  235. auto* first = result->z(0);
  236. auto* second = result->z(1);
  237. Assert::IsTrue(first->getStart() == 0 && first->getEnd() == 2,
  238. L"Invalid first result while matching 'abcabcasd' against "
  239. L"'(?:^|c)ab'");
  240. Assert::IsTrue(first->getGroupCount() == 1,
  241. L"Invalid group count in result 1 while matching 'abcabcasd' "
  242. L"against "
  243. L"'(?:^|c)ab'");
  244. Assert::IsTrue(second->getStart() == 2 && second->getEnd() == 5,
  245. L"Invalid second result while matching 'abcabcasd' against "
  246. L"'(?:^|c)ab'");
  247. Assert::IsTrue(second->getGroupCount() == 1,
  248. L"Invalid group count in result 2 while matching 'abcabcasd' "
  249. L"against "
  250. L"'(?:^|c)ab'");
  251. result->release();
  252. parser->release();
  253. }
  254. TEST_METHOD (MatchTestComplexity)
  255. {
  256. Framework::Text regex = "";
  257. Framework::Text str = "";
  258. for (int i = 0; i < 20; ++i)
  259. {
  260. regex += "a?";
  261. str += "a";
  262. }
  263. for (int i = 0; i < 20; ++i)
  264. {
  265. regex += "a";
  266. }
  267. auto parser = Framework::Regex::parse(regex);
  268. auto result = parser->match(str, str.getLength());
  269. Assert::IsTrue(result->getEintragAnzahl() == 1,
  270. L"Invalid result count while matching 'a^20' against "
  271. L"a?^20a^20");
  272. auto* first = result->z(0);
  273. Assert::IsTrue(first->getStart() == 0 && first->getEnd() == 20,
  274. L"Invalid first result while matching 'a^20' against "
  275. L"'a?^20a^20'");
  276. result->release();
  277. parser->release();
  278. }
  279. TEST_METHOD (TestNumber0)
  280. {
  281. auto parser = Framework::Regex::parse("^[0-9]+$");
  282. auto* results = parser->match("0", 1);
  283. bool ok = results->getEintragAnzahl() == 1;
  284. results->release();
  285. parser->release();
  286. Assert::IsTrue(
  287. ok, L"no result found while matcging '0' against '^[0-9]+$'");
  288. }
  289. TEST_METHOD (TestNumber1)
  290. {
  291. auto parser = Framework::Regex::parse("^[0-9]+(\\.[0-9]+)?$");
  292. auto* results = parser->match("0", 1);
  293. bool ok = results->getEintragAnzahl() == 1;
  294. results->release();
  295. parser->release();
  296. Assert::IsTrue(ok,
  297. L"no result found while matcging '0' against "
  298. L"'^[0-9]+(\\.[0-9]+)?$'");
  299. }
  300. TEST_METHOD (TestNumber2)
  301. {
  302. auto parser = Framework::Regex::parse(
  303. "^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$");
  304. auto* results = parser->match("0", 1);
  305. bool ok = results->getEintragAnzahl() == 1;
  306. results->release();
  307. parser->release();
  308. Assert::IsTrue(ok,
  309. L"no result found while matcging '0' against "
  310. L"'^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$'");
  311. }
  312. TEST_METHOD (TestNumber3)
  313. {
  314. auto parser = Framework::Regex::parse(
  315. "^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$");
  316. auto* results = parser->match("1e-3", 1);
  317. bool ok = results->getEintragAnzahl() == 1;
  318. results->release();
  319. parser->release();
  320. Assert::IsTrue(ok,
  321. L"no result found while matcging '1e-3' against "
  322. L"'^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$'");
  323. }
  324. };
  325. } // namespace FrameworkTests