tccssscanner.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. {
  2. This file is part of the Free Pascal Run time library.
  3. Copyright (c) 2022- by Michael Van Canneyt ([email protected])
  4. This file contains the tests for the CSS Scanner
  5. See the File COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit tcCSSScanner;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. TypInfo, Classes, SysUtils, fpcunit, testregistry, fpcssscanner, fpCSSTree;
  16. type
  17. { TTestLineReader }
  18. TTestLineReader = Class(TTestCase)
  19. Private
  20. FData: TStringStream;
  21. FReader : TStreamLineReader;
  22. protected
  23. Procedure CreateReader(AInput : String);
  24. procedure TearDown; override;
  25. published
  26. Procedure TestEmpty;
  27. Procedure TestReadLine;
  28. Procedure TestReadLines13;
  29. Procedure TestReadLines10;
  30. Procedure TestReadLines1310;
  31. procedure TestReadLinesEOF13;
  32. procedure TestReadLinesEOF10;
  33. procedure TestReadLinesEOF1310;
  34. procedure TestReadEmptyLines101010;
  35. end;
  36. TTestCSSWarning = record
  37. Msg: string;
  38. Row, Col: integer;
  39. end;
  40. { TTestCSSScanner }
  41. TTestCSSScanner = class(TTestCase)
  42. Private
  43. FCollectWarnings: boolean;
  44. FPSeudoDisabled,
  45. FNeedWhiteSpace : Boolean;
  46. FStream : TStream;
  47. FLineReader : TLineReader;
  48. FScanner : TCSSScanner;
  49. FErrorSource : String;
  50. FWarnings: array of TTestCSSWarning;
  51. procedure AssertEquals(AMessage: String; AExpected, AActual : TCSSToken); overload;
  52. procedure CheckToken(AToken: TCSSToken; ASource: String);
  53. procedure CheckTokens(ASource: String; ATokens: array of TCSSToken);
  54. procedure CheckWarning(Msg: string; Row, Col: integer);
  55. procedure DoTestFloat(F: Double);
  56. procedure DoTestFloat(F: Double; S: String);
  57. procedure DoTestString(S: String);
  58. function OnScannerWarn(Sender: TObject; Msg: TCSSString; aRow, aCol: integer): boolean;
  59. procedure SetCollectWarnings(const AValue: boolean);
  60. protected
  61. Function CreateScanner(AInput : String) : TCSSScanner;
  62. procedure FreeScanner;
  63. procedure SetUp; override;
  64. procedure TearDown; override;
  65. property Scanner : TCSSScanner Read FScanner;
  66. property CollectWarnings: boolean read FCollectWarnings write SetCollectWarnings;
  67. published
  68. procedure TestEmpty;
  69. Procedure TestEOF;
  70. Procedure TestWhiteSpace;
  71. Procedure TestComment1;
  72. Procedure TestComment2;
  73. Procedure TestComment3;
  74. Procedure TestID1;
  75. Procedure TestIDUnderscore;
  76. Procedure TestIDMinus;
  77. Procedure TestIDMinusMinus;
  78. Procedure TestIDEscape;
  79. Procedure TestIDEscapeStart;
  80. procedure TestPSEUDO;
  81. procedure TestPSEUDO2;
  82. procedure TestPSEUDOMinus;
  83. procedure TestPSEUDO2Minus;
  84. procedure TestPSEUDODisabled;
  85. procedure TestUNICODERANGE;
  86. procedure TestUNICODERANGE2;
  87. procedure TestFUNCTION;
  88. procedure TestPSEUDOFUNCTION;
  89. procedure TestPSEUDOFUNCTION2;
  90. Procedure TestSEMI;
  91. Procedure TestLPAREN;
  92. Procedure TestRPAREN;
  93. Procedure TestLBRACE;
  94. Procedure TestRBRACE;
  95. Procedure TestLBRACKET;
  96. Procedure TestRBRACKET;
  97. Procedure TestSTR;
  98. Procedure TestSTRExceedsLine;
  99. Procedure TestStrEscapeUnicode;
  100. procedure TestStrEscapeUnicode2;
  101. Procedure TestCOMMA;
  102. Procedure TestEQUALS;
  103. Procedure TestAND;
  104. Procedure TestTILDE;
  105. Procedure TestPLUS;
  106. Procedure TestCOLON;
  107. Procedure TestDOUBLECOLON;
  108. Procedure TestDOT;
  109. Procedure TestINT;
  110. Procedure TestFLOAT;
  111. Procedure TestFLOATNegDot;
  112. Procedure TestFLOATNegAndExp;
  113. Procedure TestDOUBLE;
  114. Procedure TestHASH1;
  115. Procedure TestHASH2;
  116. Procedure TestDIV;
  117. Procedure TestSTATEMENT;
  118. Procedure TestGT;
  119. Procedure TestLT;
  120. Procedure TestPERCENTAGE;
  121. Procedure TestMINUS;
  122. Procedure TestIMPORTANT;
  123. Procedure TestCLASSNAME;
  124. Procedure TestSTAR;
  125. Procedure TestURL;
  126. Procedure TestURLAltQuote;
  127. Procedure TestURL2;
  128. Procedure TestBADURL;
  129. Procedure TestBADEOF;
  130. Procedure TestJUNK;
  131. Procedure TestSQUARED;
  132. end;
  133. implementation
  134. function TTestCSSScanner.CreateScanner(AInput: String): TCSSScanner;
  135. begin
  136. FreeScanner;
  137. FStream:=TStringStream.Create(AInput);
  138. FLineReader:=TStreamLineReader.Create(Fstream);
  139. FScanner:=TCSSScanner.Create(FLineReader);
  140. FScanner.DisablePseudo:=FPSeudoDisabled;
  141. Result:=FScanner;
  142. if FNeedWhiteSpace then
  143. FScanner.ReturnWhiteSpace:=True;
  144. FScanner.OnWarn:=@OnScannerWarn;
  145. end;
  146. procedure TTestCSSScanner.FreeScanner;
  147. begin
  148. FreeAndNil(FScanner);
  149. FreeAndNil(FLineReader);
  150. FreeAndNil(FStream);
  151. end;
  152. procedure TTestCSSScanner.SetUp;
  153. begin
  154. inherited SetUp;
  155. CollectWarnings:=false;
  156. FNeedWhiteSpace:=False;
  157. FPSeudoDisabled:=False;
  158. end;
  159. procedure TTestCSSScanner.TearDown;
  160. begin
  161. FWarnings:=[];
  162. FreeScanner;
  163. Inherited;
  164. end;
  165. procedure TTestCSSScanner.DoTestFloat(F : Double);
  166. Var
  167. S : String;
  168. begin
  169. Str(F,S);
  170. DoTestFloat(F,S);
  171. end;
  172. procedure TTestCSSScanner.DoTestFloat(F : Double; S : String);
  173. Var
  174. J : TCSSToken;
  175. C : Double;
  176. I : integer;
  177. V : String;
  178. begin
  179. CreateScanner(S);
  180. try
  181. J:=FScanner.FetchToken;
  182. AssertEquals(S+' is a number',ctkFloat,J);
  183. V:=FScanner.CurTokenString;
  184. If (Copy(V,1,2)='0x') then
  185. begin
  186. Flush(output);
  187. V:='$'+Copy(V,3,Length(V)-2);
  188. C:=StrToInt(V);
  189. end
  190. else
  191. begin
  192. Val(V,C,I);
  193. If (I<>0) then
  194. Fail(FScanner.CurTokenString+' does not contain a float value');
  195. end;
  196. AssertEquals('Parsed float equals original float',F,C);
  197. finally
  198. FreeScanner;
  199. end;
  200. end;
  201. procedure TTestCSSScanner.DoTestString(S: String);
  202. Var
  203. J : TCSSToken;
  204. begin
  205. CreateScanner(S);
  206. try
  207. J:=FScanner.FetchToken;
  208. AssertEquals(S+' is a string',ctkSTRING,J);
  209. If (Length(S)>0) and (S[1] in ['"','''','`']) then
  210. S:=Copy(S,2,Length(S)-2);
  211. AssertEquals('Correct string is returned',S,FScanner.CurTokenString);
  212. finally
  213. FreeScanner;
  214. end;
  215. end;
  216. function TTestCSSScanner.OnScannerWarn(Sender: TObject; Msg: TCSSString; aRow, aCol: integer
  217. ): boolean;
  218. var
  219. Item: TTestCSSWarning;
  220. begin
  221. if not CollectWarnings then
  222. exit(false); // raise exception
  223. Result:=true;
  224. Item.Msg:=Msg;
  225. Item.Row:=aRow;
  226. Item.Col:=aCol;
  227. Insert(Item,FWarnings,length(FWarnings));
  228. end;
  229. procedure TTestCSSScanner.SetCollectWarnings(const AValue: boolean);
  230. begin
  231. if FCollectWarnings=AValue then Exit;
  232. FCollectWarnings:=AValue;
  233. FWarnings:=[];
  234. end;
  235. procedure TTestCSSScanner.TestEmpty;
  236. Var
  237. J : TCSSToken;
  238. begin
  239. CreateScanner('');
  240. J:=Scanner.FetchToken;
  241. If (J<>ctkEOF) then
  242. Fail('Empty returns EOF');
  243. end;
  244. procedure TTestCSSScanner.TestEOF;
  245. Var
  246. C : TCSSToken;
  247. begin
  248. CreateScanner('');
  249. C:=Scanner.FetchToken;
  250. If (C<>ctkEOF) then
  251. Fail('Empty returns EOF');
  252. end;
  253. procedure TTestCSSScanner.TestWhiteSpace;
  254. Var
  255. C : TCSSToken;
  256. begin
  257. FNeedWhiteSpace:=True;
  258. CreateScanner(' ');
  259. C:=Scanner.FetchToken;
  260. If (C<>ctkWHITESPACE) then
  261. Fail('Empty returns EOF');
  262. end;
  263. procedure TTestCSSScanner.TestComment1;
  264. begin
  265. CreateScanner('/* some comment string */');
  266. AssertEquals('Comment line is skipped',ctkEOF,FScanner.FetchToken);
  267. end;
  268. procedure TTestCSSScanner.TestComment2;
  269. begin
  270. CreateScanner('/* some comment string */');
  271. FScanner.ReturnComments:=True;
  272. AssertEquals('Comment line is returned',ctkComment,FScanner.FetchToken);
  273. AssertEquals('Comment contents is returned',' some comment string ',FScanner.CurTokenString);
  274. end;
  275. procedure TTestCSSScanner.TestComment3;
  276. begin
  277. CreateScanner('/* some multiline comment '#10' string */');
  278. FScanner.ReturnComments:=True;
  279. AssertEquals('Comment line is returned',ctkComment,FScanner.FetchToken);
  280. AssertEquals('Comment contents is returned',' some multiline comment '#10' string ',FScanner.CurTokenString);
  281. end;
  282. procedure TTestCSSScanner.TestID1;
  283. begin
  284. CheckToken(ctkIDENTIFIER,'anid');
  285. end;
  286. procedure TTestCSSScanner.TestIDUnderscore;
  287. begin
  288. CheckToken(ctkIDENTIFIER,'_anid');
  289. end;
  290. procedure TTestCSSScanner.TestIDMinus;
  291. begin
  292. CheckToken(ctkIDENTIFIER,'-anid');
  293. end;
  294. procedure TTestCSSScanner.TestIDMinusMinus;
  295. begin
  296. CheckToken(ctkIDENTIFIER,'--anid');
  297. end;
  298. procedure TTestCSSScanner.TestIDEscape;
  299. begin
  300. CheckToken(ctkIDENTIFIER,'an\(id');
  301. end;
  302. procedure TTestCSSScanner.TestIDEscapeStart;
  303. begin
  304. CheckToken(ctkIDENTIFIER,'\(anid');
  305. end;
  306. procedure TTestCSSScanner.TestSEMI;
  307. begin
  308. CheckToken(ctkSEMICOLON,';');
  309. end;
  310. procedure TTestCSSScanner.TestLPAREN;
  311. begin
  312. CheckToken(ctkLPARENTHESIS,'(');
  313. end;
  314. procedure TTestCSSScanner.TestRPAREN;
  315. begin
  316. CheckToken(ctkRPARENTHESIS,')');
  317. end;
  318. procedure TTestCSSScanner.TestLBRACE;
  319. begin
  320. CheckToken(ctkLBRACE,'{');
  321. end;
  322. procedure TTestCSSScanner.TestRBRACE;
  323. begin
  324. CheckToken(ctkRBRACE,'}');
  325. end;
  326. procedure TTestCSSScanner.TestLBRACKET;
  327. begin
  328. CheckToken(ctkLBRACKET,'[');
  329. end;
  330. procedure TTestCSSScanner.TestRBRACKET;
  331. begin
  332. CheckToken(ctkRBRACKET,']');
  333. end;
  334. procedure TTestCSSScanner.TestSTR;
  335. begin
  336. CheckToken(ctkSTRING,'"abc"');
  337. end;
  338. procedure TTestCSSScanner.TestSTRExceedsLine;
  339. begin
  340. CollectWarnings:=true;
  341. CheckToken(ctkINVALID,'"bla');
  342. CheckWarning('String exceeds end of line',1,4);
  343. end;
  344. procedure TTestCSSScanner.TestStrEscapeUnicode;
  345. begin
  346. CheckToken(ctkSTRING,'"\00a0\00a0\00a0\00a0"');
  347. CheckToken(ctkSTRING,'"\2a"');
  348. end;
  349. procedure TTestCSSScanner.TestStrEscapeUnicode2;
  350. begin
  351. CheckToken(ctkSTRING,'"\2a"');
  352. end;
  353. procedure TTestCSSScanner.TestCOMMA;
  354. begin
  355. CheckToken(ctkCOMMA,',');
  356. end;
  357. procedure TTestCSSScanner.TestEQUALS;
  358. begin
  359. CheckToken(ctkEQUALS,'=');
  360. end;
  361. procedure TTestCSSScanner.TestAND;
  362. begin
  363. CheckToken(ctkAND,'&');
  364. end;
  365. procedure TTestCSSScanner.TestTILDE;
  366. begin
  367. CheckToken(ctkTILDE,'~');
  368. end;
  369. procedure TTestCSSScanner.TestPLUS;
  370. begin
  371. CheckToken(ctkPLUS,'+');
  372. end;
  373. procedure TTestCSSScanner.TestCOLON;
  374. begin
  375. CheckToken(ctkCOLON,':');
  376. end;
  377. procedure TTestCSSScanner.TestDOUBLECOLON;
  378. begin
  379. CheckToken(ctkDOUBLECOLON,'::');
  380. end;
  381. procedure TTestCSSScanner.TestDOT;
  382. begin
  383. CheckToken(ctkDOT,'.');
  384. end;
  385. procedure TTestCSSScanner.TestINT;
  386. begin
  387. CheckToken(ctkINTEGER,'123');
  388. end;
  389. procedure TTestCSSScanner.TestFLOAT;
  390. begin
  391. DoTestFloat(123.3,'123.3');
  392. end;
  393. procedure TTestCSSScanner.TestFLOATNegDot;
  394. begin
  395. DoTestFloat(-0.123,'-.123');
  396. end;
  397. procedure TTestCSSScanner.TestFLOATNegAndExp;
  398. begin
  399. DoTestFloat(-1020.0,'-10.2e+2');
  400. end;
  401. procedure TTestCSSScanner.TestDOUBLE;
  402. begin
  403. DoTestFloat(123.3,'123.3');
  404. end;
  405. procedure TTestCSSScanner.TestHASH1;
  406. begin
  407. CheckToken(ctkHASH,'#1231');
  408. end;
  409. procedure TTestCSSScanner.TestHASH2;
  410. begin
  411. CheckToken(ctkHASH,'#AFAFAF');
  412. end;
  413. procedure TTestCSSScanner.TestDIV;
  414. begin
  415. CheckToken(ctkDIV,'/');
  416. end;
  417. procedure TTestCSSScanner.TestSTATEMENT;
  418. begin
  419. CheckToken(ctkATKEYWORD,'@media');
  420. end;
  421. procedure TTestCSSScanner.TestGT;
  422. begin
  423. CheckToken(ctkGT,'>');
  424. end;
  425. procedure TTestCSSScanner.TestLT;
  426. begin
  427. CheckToken(ctkLT,'<');
  428. end;
  429. procedure TTestCSSScanner.TestPERCENTAGE;
  430. begin
  431. CheckToken(ctkPERCENTAGE,'%');
  432. end;
  433. procedure TTestCSSScanner.TestMINUS;
  434. begin
  435. CheckToken(ctkMinus,'-');
  436. end;
  437. procedure TTestCSSScanner.TestIMPORTANT;
  438. begin
  439. CheckToken(ctkIMPORTANT,'!important');
  440. end;
  441. procedure TTestCSSScanner.TestCLASSNAME;
  442. begin
  443. CheckToken(ctkCLASSNAME,'.classname');
  444. end;
  445. procedure TTestCSSScanner.TestSTAR;
  446. begin
  447. CheckToken(ctkSTAR,'*');
  448. end;
  449. procedure TTestCSSScanner.TestURL;
  450. begin
  451. CheckToken(ctkURL,'url("abc")');
  452. end;
  453. procedure TTestCSSScanner.TestURLAltQuote;
  454. begin
  455. CheckToken(ctkURL,'url(''abc'')');
  456. end;
  457. procedure TTestCSSScanner.TestURL2;
  458. begin
  459. CheckToken(ctkURL,'url(abc)');
  460. end;
  461. procedure TTestCSSScanner.TestBADURL;
  462. begin
  463. CheckToken(ctkBADURL,'url(de f)');
  464. end;
  465. procedure TTestCSSScanner.TestBADEOF;
  466. begin
  467. CheckToken(ctkEOF,'url(def');
  468. end;
  469. procedure TTestCSSScanner.TestPSEUDO;
  470. begin
  471. CheckToken(ctkPSEUDO,':name');
  472. end;
  473. procedure TTestCSSScanner.TestPSEUDO2;
  474. begin
  475. CheckTokens('::name',[ctkDOUBLECOLON,ctkIDENTIFIER]);
  476. end;
  477. procedure TTestCSSScanner.TestPSEUDOMinus;
  478. begin
  479. CheckToken(ctkPSEUDO,':-name');
  480. end;
  481. procedure TTestCSSScanner.TestPSEUDO2Minus;
  482. begin
  483. CheckTokens('::-name',[ctkDOUBLECOLON,ctkIDENTIFIER]);
  484. end;
  485. procedure TTestCSSScanner.TestPSEUDODisabled;
  486. begin
  487. FPseudoDisabled:=True;
  488. CheckTokens(':me',[ctkColon,ctkIDENTIFIER]);
  489. end;
  490. procedure TTestCSSScanner.TestUNICODERANGE;
  491. begin
  492. CheckToken(ctkUNICODERANGE,'U+124');
  493. end;
  494. procedure TTestCSSScanner.TestUNICODERANGE2;
  495. begin
  496. CheckToken(ctkUNICODERANGE,'U+124-128');
  497. end;
  498. procedure TTestCSSScanner.TestFUNCTION;
  499. begin
  500. CheckToken(ctkFUNCTION,'name(');
  501. end;
  502. procedure TTestCSSScanner.TestPSEUDOFUNCTION;
  503. begin
  504. CheckToken(ctkPSEUDOFUNCTION,':name(');
  505. end;
  506. procedure TTestCSSScanner.TestPSEUDOFUNCTION2;
  507. begin
  508. CheckTokens('::name(',[ctkDOUBLECOLON,ctkFUNCTION]);
  509. end;
  510. procedure TTestCSSScanner.TestJUNK;
  511. var
  512. HasUnknown: Boolean;
  513. begin
  514. FErrorSource:='?';
  515. HasUnknown:=false;
  516. CreateScanner(FErrorSource);
  517. try
  518. While (FScanner.FetchToken<>ctkEOF) do
  519. if FScanner.CurToken=ctkUNKNOWN then HasUnknown:=true;
  520. finally
  521. FreeScanner;
  522. end;
  523. if not HasUnknown then
  524. Fail('missing unknown');
  525. end;
  526. procedure TTestCSSScanner.TestSQUARED;
  527. begin
  528. CheckToken(ctkSQUARED,'^');
  529. end;
  530. procedure TTestCSSScanner.AssertEquals(AMessage : String; AExpected, AActual: TCSSToken);
  531. Var
  532. S,EN1,EN2 : String;
  533. begin
  534. If (AActual<>AExpected) then
  535. begin
  536. EN1:=GetEnumName(TypeINfo(TCSSToken),Ord(AExpected));
  537. EN2:=GetEnumName(TypeINfo(TCSSToken),Ord(AActual));
  538. S:=Format('%s : %s <> %s',[AMessage,EN1,EN2]);
  539. Fail(S);
  540. end;
  541. end;
  542. procedure TTestCSSScanner.CheckToken(AToken: TCSSToken; ASource: String);
  543. Var
  544. J : TCSSToken;
  545. EN2 : String;
  546. begin
  547. CreateScanner(ASource);
  548. J:=Scanner.FetchToken;
  549. EN2:=GetEnumName(TypeINfo(TCSSToken),Ord(AToken));
  550. AssertEquals(Format('Source %s should result in %s.',[ASource,EN2]),AToken,J);
  551. end;
  552. procedure TTestCSSScanner.CheckTokens(ASource: String;
  553. ATokens: array of TCSSToken);
  554. Var
  555. I : Integer;
  556. J : TCSSToken;
  557. S : String;
  558. begin
  559. CreateScanner(ASource);
  560. For I:=Low(ATokens) to High(ATokens) do
  561. begin
  562. J:=FScanner.FetchToken;
  563. S:=GetEnumName(TypeINfo(TCSSToken),Ord(ATokens[i]));
  564. S:=Format('Source "%s", token %d (%s): expected %s',[ASource,I,FScanner.CurTokenString,S]);
  565. AssertEquals(S,ATokens[i],J);
  566. end;
  567. end;
  568. procedure TTestCSSScanner.CheckWarning(Msg: string; Row, Col: integer);
  569. var
  570. Actual, Expected: String;
  571. begin
  572. AssertEquals('Expected one warning',1,length(FWarnings));
  573. Actual:='('+IntToStr(FWarnings[0].Row)+','+IntToStr(FWarnings[0].Col)+'): '+FWarnings[0].Msg;
  574. Expected:='('+IntToStr(Row)+','+IntToStr(Col)+'): '+Msg;
  575. AssertEquals('Expected Warning',Expected,Actual);
  576. end;
  577. { TTestLineReader }
  578. procedure TTestLineReader.CreateReader(AInput: String);
  579. begin
  580. FData:=TStringStream.Create(AInput);
  581. FReader:=TStreamLineReader.Create(FData);
  582. end;
  583. procedure TTestLineReader.TearDown;
  584. begin
  585. FreeAndNil(FReader);
  586. FreeAndNil(FData);
  587. end;
  588. procedure TTestLineReader.TestEmpty;
  589. begin
  590. CreateReader('');
  591. AssertEquals('Empty reader returns EOF',True,FReader.IsEOF);
  592. AssertEquals('Empty reader returns empty string','',FReader.ReadLine);
  593. end;
  594. procedure TTestLineReader.TestReadLine;
  595. begin
  596. CreateReader('Something');
  597. AssertEquals('Reader with 1 line returns 1 line','Something',FReader.ReadLine);
  598. AssertEquals('EOF true after reading line',True,FReader.IsEOF);
  599. end;
  600. procedure TTestLineReader.TestReadLines13;
  601. begin
  602. CreateReader('Something'#13'else');
  603. AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
  604. AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
  605. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  606. end;
  607. procedure TTestLineReader.TestReadLines10;
  608. begin
  609. CreateReader('Something'#10'else');
  610. AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
  611. AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
  612. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  613. end;
  614. procedure TTestLineReader.TestReadLines1310;
  615. begin
  616. CreateReader('Something'#13#10'else');
  617. AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
  618. AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
  619. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  620. end;
  621. procedure TTestLineReader.TestReadLinesEOF13;
  622. begin
  623. CreateReader('Something'#13);
  624. AssertEquals('Reader with 2 lines + CR returns 1st line','Something',FReader.ReadLine);
  625. AssertEquals('Reader with 1 lines + CR returns empty 2nd line','',FReader.ReadLine);
  626. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  627. end;
  628. procedure TTestLineReader.TestReadLinesEOF10;
  629. begin
  630. CreateReader('Something'#10);
  631. AssertEquals('Reader with 2 lines + LF returns 1st line','Something',FReader.ReadLine);
  632. AssertEquals('Reader with 1 lines + LF returns empty 2nd line','',FReader.ReadLine);
  633. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  634. end;
  635. procedure TTestLineReader.TestReadLinesEOF1310;
  636. begin
  637. CreateReader('Something'#13#10);
  638. AssertEquals('Reader with 2 lines + CRLF returns 1st line','Something',FReader.ReadLine);
  639. AssertEquals('Reader with 1 lines + CRLF returns empty 2nd line','',FReader.ReadLine);
  640. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  641. end;
  642. procedure TTestLineReader.TestReadEmptyLines101010;
  643. begin
  644. CreateReader('Something'#10#10#10);
  645. AssertEquals('Reader with 1 line + LFLFLF returns 1st line','Something',FReader.ReadLine);
  646. AssertEquals('EOF false after reading line 1',False,FReader.IsEOF);
  647. AssertEquals('Reader with 1 line + LFLFLF returns empty 2nd line','',FReader.ReadLine);
  648. AssertEquals('EOF false after reading line 2',False,FReader.IsEOF);
  649. AssertEquals('Reader with 1 line + LFLFLF returns empty 3nd line','',FReader.ReadLine);
  650. AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
  651. end;
  652. initialization
  653. RegisterTests([TTestLineReader,TTestCSSScanner]);
  654. end.