tcregexp.pp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. unit tcregexp;
  2. {$mode objfpc}{$H+}
  3. { $DEFINE DUMPTESTS} //define this to dump a
  4. interface
  5. uses
  6. Classes, SysUtils, fpcunit, testregistry, regexpr;
  7. type
  8. { TTestRegexpr }
  9. TTestRegexpr= class(TTestCase)
  10. private
  11. FRE: TRegExpr;
  12. protected
  13. class function PrintableString(AString: string): string;
  14. Procedure RunRETest(aIndex : Integer);
  15. procedure SetUp; override;
  16. procedure TearDown; override;
  17. Property RE : TRegExpr read FRE;
  18. published
  19. procedure TestEmpty;
  20. Procedure RunTest1;
  21. Procedure RunTest2;
  22. Procedure RunTest3;
  23. Procedure RunTest4;
  24. Procedure RunTest5;
  25. Procedure RunTest6;
  26. Procedure RunTest7;
  27. Procedure RunTest8;
  28. Procedure RunTest9;
  29. Procedure RunTest10;
  30. Procedure RunTest11;
  31. Procedure RunTest12;
  32. Procedure RunTest13;
  33. Procedure RunTest14;
  34. Procedure RunTest15;
  35. Procedure RunTest16;
  36. Procedure RunTest17;
  37. Procedure RunTest18;
  38. Procedure RunTest19;
  39. Procedure RunTest20;
  40. Procedure RunTest21;
  41. Procedure RunTest22;
  42. Procedure RunTest23;
  43. Procedure RunTest24;
  44. Procedure RunTest25;
  45. end;
  46. implementation
  47. Type
  48. TRegExTest = record
  49. Expression: string;
  50. InputText: string;
  51. SubstitutionText: string;
  52. ExpectedResult: string;
  53. MatchStart: integer;
  54. end;
  55. const
  56. testCases: array [1..25] of TRegExTest = (
  57. (
  58. expression: '\nd';
  59. inputText: 'abc'#13#10'def';
  60. substitutionText: '\n\x{10}\r\\';
  61. expectedResult: 'abc'#13#10#16#13'\ef'
  62. ),
  63. (
  64. expression: '(\w*)';
  65. inputText: 'name.ext';
  66. substitutionText: '$1.new';
  67. expectedResult: 'name.new.new.ext.new.new'
  68. ),
  69. (
  70. expression: #$d'('#$a')';
  71. inputText: 'word'#$d#$a;
  72. substitutionText: '$1';
  73. expectedResult: 'word'#$a
  74. ),
  75. (
  76. expression: '(word)';
  77. inputText: 'word';
  78. substitutionText: '\U$1\\r';
  79. expectedResult: 'WORD\r'
  80. ),
  81. (
  82. expression: '(word)';
  83. inputText: 'word';
  84. substitutionText: '$1\n';
  85. expectedResult: 'word'#$a
  86. ),
  87. (
  88. expression: '[A-Z]';
  89. inputText: '234578923457823659GHJK38';
  90. substitutionText: '';
  91. expectedResult: 'G';
  92. matchStart: 19;
  93. ),
  94. (
  95. expression: '[A-Z]*?';
  96. inputText: '234578923457823659ARTZU38';
  97. substitutionText: '';
  98. expectedResult: '';
  99. matchStart: 1
  100. ),
  101. (
  102. expression: '[A-Z]+';
  103. inputText: '234578923457823659ARTZU38';
  104. substitutionText: '';
  105. expectedResult: 'ARTZU';
  106. matchStart: 19
  107. ),
  108. (
  109. expression: '[A-Z][A-Z]*';
  110. inputText: '234578923457823659ARTZU38';
  111. substitutionText: '';
  112. expectedResult: 'ARTZU';
  113. matchStart: 19
  114. ),
  115. (
  116. expression: '[A-Z][A-Z]?';
  117. inputText: '234578923457823659ARTZU38';
  118. substitutionText: '';
  119. expectedResult: 'AR';
  120. matchStart: 19
  121. ),
  122. (
  123. expression: '[^\d]+';
  124. inputText: '234578923457823659ARTZU38';
  125. substitutionText: '';
  126. expectedResult: 'ARTZU';
  127. matchStart: 19
  128. ),
  129. (
  130. expression: '[A-Z][A-Z]?[A-Z]';
  131. inputText: '234578923457823659ARTZU38';
  132. substitutionText: '';
  133. expectedResult: 'ART';
  134. matchStart: 19
  135. ),
  136. (
  137. expression: '[A-Z][A-Z]*[0-9]';
  138. inputText: '234578923457823659ARTZU38';
  139. substitutionText: '';
  140. expectedResult: 'ARTZU3';
  141. matchStart: 19
  142. ),
  143. (
  144. expression: '[A-Z]+[0-9]';
  145. inputText: '234578923457823659ARTZU38';
  146. substitutionText: '';
  147. expectedResult: 'ARTZU3';
  148. matchStart: 19
  149. ),
  150. (
  151. expression: '(?i)[A-Z]';
  152. inputText: '234578923457823659a38';
  153. substitutionText: '';
  154. expectedResult: 'a';
  155. matchStart: 19
  156. ),
  157. (
  158. expression: '(?i)[a-z]';
  159. inputText: '234578923457823659A38';
  160. substitutionText: '';
  161. expectedResult: 'A';
  162. matchStart: 19
  163. ),
  164. (
  165. expression: '(foo)1234';
  166. inputText: '1234 foo1234XXXX';
  167. substitutionText: '';
  168. expectedResult: 'foo1234';
  169. matchStart: 8
  170. ),
  171. (
  172. expression: '(((foo)))1234';
  173. inputText: '1234 foo1234XXXX';
  174. substitutionText: '';
  175. expectedResult: 'foo1234';
  176. matchStart: 8
  177. ),
  178. (
  179. expression: '(foo)(1234)';
  180. inputText: '1234 foo1234XXXX';
  181. substitutionText: '';
  182. expectedResult: 'foo1234';
  183. matchStart: 8
  184. ),
  185. (
  186. expression: 'nofoo|foo';
  187. inputText: '1234 foo1234XXXX';
  188. substitutionText: '';
  189. expectedResult: 'foo';
  190. matchStart: 8
  191. ),
  192. (
  193. expression: '(nofoo|foo)1234';
  194. inputText: '1234 nofoo1234XXXX';
  195. substitutionText: '';
  196. expectedResult: 'nofoo1234';
  197. matchStart: 8
  198. ),
  199. (
  200. expression: '(nofoo|foo|anotherfoo)1234';
  201. inputText: '1234 nofoo1234XXXX';
  202. substitutionText: '';
  203. expectedResult: 'nofoo1234';
  204. matchStart: 8
  205. ),
  206. (
  207. expression: 'nofoo1234|foo1234';
  208. inputText: '1234 foo1234XXXX';
  209. substitutionText: '';
  210. expectedResult: 'foo1234';
  211. matchStart: 8
  212. ),
  213. (
  214. expression: '(\w*)';
  215. inputText: 'name.ext';
  216. substitutionText: '';
  217. expectedResult: 'name';
  218. matchStart: 1
  219. ),
  220. (
  221. expression: '\r(\n)';
  222. inputText: #$d#$a;
  223. substitutionText: '';
  224. expectedResult: #$d#$a;
  225. matchStart: 1
  226. )
  227. );
  228. procedure TTestRegexpr.TestEmpty;
  229. begin
  230. AssertNotNull('Have RE',RE);
  231. AssertFalse('UseOsLineEndOnReplace correcly set', RE.UseOsLineEndOnReplace);
  232. end;
  233. procedure TTestRegexpr.RunTest1;
  234. begin
  235. RunRETest(1);
  236. end;
  237. procedure TTestRegexpr.RunTest2;
  238. begin
  239. RunRETest(2);
  240. end;
  241. procedure TTestRegexpr.RunTest3;
  242. begin
  243. RunRETest(3);
  244. end;
  245. procedure TTestRegexpr.RunTest4;
  246. begin
  247. RunRETest(4);
  248. end;
  249. procedure TTestRegexpr.RunTest5;
  250. begin
  251. RunRETest(5);
  252. end;
  253. procedure TTestRegexpr.RunTest6;
  254. begin
  255. RunRETest(6);
  256. end;
  257. procedure TTestRegexpr.RunTest7;
  258. begin
  259. RunRETest(7);
  260. end;
  261. procedure TTestRegexpr.RunTest8;
  262. begin
  263. RunRETest(8);
  264. end;
  265. procedure TTestRegexpr.RunTest9;
  266. begin
  267. RunRETest(9);
  268. end;
  269. procedure TTestRegexpr.RunTest10;
  270. begin
  271. RunRETest(10);
  272. end;
  273. procedure TTestRegexpr.RunTest11;
  274. begin
  275. RunRETest(11);
  276. end;
  277. procedure TTestRegexpr.RunTest12;
  278. begin
  279. RunRETest(12);
  280. end;
  281. procedure TTestRegexpr.RunTest13;
  282. begin
  283. RunRETest(13);
  284. end;
  285. procedure TTestRegexpr.RunTest14;
  286. begin
  287. RunRETest(14);
  288. end;
  289. procedure TTestRegexpr.RunTest15;
  290. begin
  291. RunRETest(15);
  292. end;
  293. procedure TTestRegexpr.RunTest16;
  294. begin
  295. RunRETest(16);
  296. end;
  297. procedure TTestRegexpr.RunTest17;
  298. begin
  299. RunRETest(17);
  300. end;
  301. procedure TTestRegexpr.RunTest18;
  302. begin
  303. RunRETest(18);
  304. end;
  305. procedure TTestRegexpr.RunTest19;
  306. begin
  307. RunRETest(19);
  308. end;
  309. procedure TTestRegexpr.RunTest20;
  310. begin
  311. RunRETest(20);
  312. end;
  313. procedure TTestRegexpr.RunTest21;
  314. begin
  315. RunRETest(21);
  316. end;
  317. procedure TTestRegexpr.RunTest22;
  318. begin
  319. RunRETest(22);
  320. end;
  321. procedure TTestRegexpr.RunTest23;
  322. begin
  323. RunRETest(23);
  324. end;
  325. procedure TTestRegexpr.RunTest24;
  326. begin
  327. RunRETest(24);
  328. end;
  329. procedure TTestRegexpr.RunTest25;
  330. begin
  331. RunRETest(25);
  332. end;
  333. Class function TTestRegexpr.PrintableString(AString: string): string;
  334. var
  335. ch: Char;
  336. begin
  337. Result := '';
  338. for ch in AString do
  339. if ch < #31 then
  340. Result := Result + '#' + IntToStr(Ord(ch))
  341. else
  342. Result := Result + ch;
  343. end;
  344. procedure TTestRegexpr.RunRETest(aIndex: Integer);
  345. var
  346. T: TRegExTest;
  347. act : String;
  348. begin
  349. T:=testCases[aIndex];
  350. RE.Expression:=T.Expression;
  351. RE.Compile;
  352. {$IFDEF DUMPTESTS}
  353. Writeln('Test: ',TestName);
  354. writeln(' Modifiers "', RE.ModifierStr, '"');
  355. writeln(' Regular expression: ', T.Expression,' ,');
  356. writeln(' compiled into p-code: ');
  357. writeln(' ',RE.Dump);
  358. writeln(' Input text: "', PrintableString(T.inputText), '"');
  359. if (T.substitutionText <> '') then
  360. Writeln(' Substitution text: "', PrintableString(T.substitutionText), '"');
  361. {$ENDIF}
  362. if (T.SubstitutionText <> '') then
  363. begin
  364. act:=RE.Replace(T.InputText,T.SubstitutionText,True);
  365. AssertEquals('Replace failed', T.ExpectedResult,Act)
  366. end
  367. else
  368. begin
  369. RE.Exec(T.inputText);
  370. AssertEquals('Search position',T.MatchStart,RE.MatchPos[0]);
  371. AssertEquals('Matched text',T.ExpectedResult,RE.Match[0]);
  372. end;
  373. end;
  374. procedure TTestRegexpr.SetUp;
  375. begin
  376. Inherited;
  377. FRE := TRegExpr.Create;
  378. FRE.UseOsLineEndOnReplace:=False;
  379. end;
  380. procedure TTestRegexpr.TearDown;
  381. begin
  382. FreeAndNil(FRE);
  383. Inherited;
  384. end;
  385. initialization
  386. RegisterTest(TTestRegexpr);
  387. end.