tccssscanner.pp 16 KB

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