1unit tcscanner;
2
3{$mode objfpc}{$H+}
4
5interface
6
7uses
8  Classes, SysUtils, Typinfo, fpcunit, testregistry, jstoken, jsscanner;
9
10type
11
12  { TTestLineReader }
13
14  TTestLineReader = Class(TTestCase)
15  Private
16    FData: TStringStream;
17    FReader : TStreamLineReader;
18  protected
19    Procedure CreateReader(AInput : String);
20    procedure TearDown; override;
21  published
22    Procedure TestEmpty;
23    Procedure TestReadLine;
24    Procedure TestReadLines13;
25    Procedure TestReadLines10;
26    Procedure TestReadLines1310;
27    procedure TestReadLinesEOF13;
28    procedure TestReadLinesEOF10;
29    procedure TestReadLinesEOF1310;
30    procedure TestReadEmptyLines101010;
31  end;
32
33  { TTestJSScanner }
34
35  TTestJSScanner = class(TTestCase)
36  Private
37    FStream : TStream;
38    FLineReader : TLineReader;
39    FScanner : TJSScanner;
40    FErrorSource : String;
41    procedure AssertEquals(AMessage: String; AExpected, AActual : TJSToken); overload;
42    procedure CheckToken(AToken: TJSToken; ASource: String);
43    procedure CheckTokens(ASource: String; ATokens: array of TJSToken);
44    procedure DoTestFloat(F: Double);
45    procedure DoTestFloat(F: Double; S: String);
46    procedure DoTestString(S: String);
47    procedure TestErrorSource;
48  protected
49    Function CreateScanner(AInput : String) : TJSScanner;
50    procedure FreeScanner;
51    procedure SetUp; override;
52    procedure TearDown; override;
53
54    Property Scanner : TJSScanner Read FScanner;
55  published
56    Procedure TestEmpty;
57    procedure TestAndAnd;
58    procedure TestAndEq;
59    procedure TestAssign;
60    procedure TestBraceClose;
61    procedure TestBraceOpen;
62    procedure TestColon;
63    procedure TestComma;
64    procedure TestCurlyBraceClose;
65    procedure TestCurlyBraceOpen;
66    procedure TestDiv;
67    procedure TestDiveq;
68    procedure TestXor;
69    procedure TestXoreq;
70    procedure TestDot;
71    procedure TestEq;
72    procedure TestGE;
73    procedure TestFalse;
74    procedure TestInv;
75    procedure TestNot;
76    procedure TestString;
77    procedure TestTrue;
78    procedure TestGreaterThan;
79    procedure TestLE;
80    procedure TestLessThan;
81    procedure TestLSHIFT;
82    procedure TestLSHIFTEQ;
83    procedure TestMinus;
84    procedure TestMinusEQ;
85    procedure TestMinusMinus;
86    procedure TestModeq;
87    procedure TestMul;
88    procedure TestNE;
89    procedure TestNSE;
90    procedure TestOREQ;
91    procedure TestOROR;
92    procedure TestPlus;
93    procedure TestPlusEq;
94    procedure TestPlusPlus;
95    procedure TestRShift;
96    procedure TestRShiftEq;
97    procedure TestSemicolon;
98    procedure TestSEq;
99    procedure TestSquaredBraceClose;
100    procedure TestSquaredBraceOpen;
101    procedure TestStarEq;
102    procedure TestURShift;
103    procedure TestURShiftEq;
104    procedure TestBreak;
105    procedure TestCase;
106    procedure TestCatch;
107    procedure TestContinue;
108    procedure TestDefault;
109    procedure TestDelete;
110    procedure TestDO;
111    procedure TestElse;
112    procedure TestFinally;
113    procedure TestFor;
114    procedure TestFunction;
115    procedure TestIf;
116    procedure TestIn;
117    procedure TestInstanceOf;
118    procedure TestNew;
119    procedure TestReturn;
120    procedure TestSwitch;
121    procedure TestThis;
122    procedure TestThrow;
123    procedure TestTry;
124    procedure TestTypeOf;
125    procedure TestVar;
126    procedure TestVoid;
127    procedure TestWhile;
128    procedure TestWith;
129    Procedure Test2Words;
130    procedure Test3Words;
131    procedure TestIdentifier;
132    procedure TestIdentifier2;
133    procedure TestIdentifier3;
134    procedure TestIdentifier4;
135    procedure TestIdentifier5;
136    procedure TestIdentifierDotIdentifier;
137    procedure TestEOLN;
138    procedure TestEOLN2;
139    procedure TestEOLN3;
140    procedure TestEOLN4;
141    procedure TestComment1;
142    procedure TestComment2;
143    procedure TestComment3;
144    procedure TestComment4;
145    procedure TestComment5;
146    procedure TestComment6;
147    procedure TestFloat;
148    procedure TestStringError;
149    procedure TestFloatError;
150  end;
151
152
153implementation
154
155Function TTestJSScanner.CreateScanner(AInput : String) : TJSScanner;
156
157begin
158  FStream:=TStringStream.Create(AInput);
159  FLineReader:=TStreamLineReader.Create(Fstream);
160  FScanner:=TJSScanner.Create(FLineReader);
161  Result:=FScanner;
162end;
163
164procedure TTestJSScanner.FreeScanner;
165begin
166  FreeAndNil(FScanner);
167  FreeAndNil(FLineReader);
168  FreeAndNil(FStream);
169end;
170
171procedure TTestJSScanner.SetUp;
172begin
173  inherited SetUp;
174end;
175
176
177
178procedure TTestJSScanner.TestEmpty;
179
180Var
181  J : TJSToken;
182
183begin
184  CreateScanner('');
185  J:=Scanner.FetchToken;
186  If (J<>tjsEOF) then
187    Fail('Empty returns EOF');
188end;
189
190procedure TTestJSScanner.AssertEquals(AMessage : String; AExpected, AActual: TJSToken);
191
192Var
193  S,EN1,EN2 : String;
194
195begin
196  If (AActual<>AExpected) then
197    begin
198    EN1:=GetEnumName(TypeINfo(TJSToken),Ord(AExpected));
199    EN2:=GetEnumName(TypeINfo(TJSToken),Ord(AActual));
200    S:=Format('%s : %s <> %s',[AMessage,EN1,EN2]);
201    Fail(S);
202    end;
203end;
204
205procedure TTestJSScanner.CheckToken(AToken : TJSToken; ASource : String);
206
207Var
208  J : TJSToken;
209  EN2 : String;
210
211begin
212  CreateScanner(ASource);
213  J:=Scanner.FetchToken;
214  EN2:=GetEnumName(TypeINfo(TJSToken),Ord(AToken));
215  AssertEquals(Format('Source %s should result in %s.',[ASource,EN2]),AToken,J);
216end;
217
218
219procedure TTestJSScanner.TestAndAnd;
220
221begin
222  CheckToken(tjsAndAnd,'&&');
223end;
224
225procedure TTestJSScanner.TestAndEq;
226
227begin
228  CheckToken(tjsAndEq,'&=');
229end;
230
231procedure TTestJSScanner.TestBraceOpen;
232
233begin
234  CheckToken(tjsBraceOpen,'(');
235end;
236
237procedure TTestJSScanner.TestBraceClose;
238
239begin
240  CheckToken(tjsBraceClose,')');
241end;
242
243procedure TTestJSScanner.TestSquaredBraceClose;
244
245begin
246  CheckToken(tjsSquaredBraceClose,']');
247end;
248
249procedure TTestJSScanner.TestSquaredBraceOpen;
250
251begin
252  CheckToken(tjssQuaredBraceOpen,'[');
253end;
254
255procedure TTestJSScanner.TestCurlyBraceOpen;
256
257begin
258  CheckToken(tjsCurlyBraceOpen,'{');
259end;
260
261procedure TTestJSScanner.TestCurlyBraceClose;
262
263begin
264  CheckToken(tjsCurlyBraceClose,'}');
265end;
266
267procedure TTestJSScanner.TestComma;
268
269begin
270  CheckToken(tjsComma,',');
271end;
272
273procedure TTestJSScanner.TestColon;
274
275begin
276  CheckToken(tjsColon,':');
277end;
278
279procedure TTestJSScanner.TestDot;
280
281begin
282  CheckToken(tjsDot,'.');
283end;
284
285procedure TTestJSScanner.TestSemicolon;
286
287begin
288  CheckToken(tjsSemicolon,';');
289end;
290
291procedure TTestJSScanner.TestAssign;
292
293begin
294  CheckToken(tjsAssign,'=');
295end;
296
297procedure TTestJSScanner.TestGreaterThan;
298
299begin
300  CheckToken(tjsGT,'>');
301end;
302
303procedure TTestJSScanner.TestLessThan;
304
305begin
306  CheckToken(tjsLT,'<');
307end;
308
309procedure TTestJSScanner.TestPlus;
310
311begin
312  CheckToken(tjsPlus,'+');
313end;
314
315procedure TTestJSScanner.TestMinus;
316
317begin
318  CheckToken(tjsMinus,'-');
319end;
320
321procedure TTestJSScanner.TestMul;
322
323begin
324  CheckToken(tjsMul,'*');
325end;
326
327procedure TTestJSScanner.TestDiv;
328
329begin
330  CheckToken(tjsDiv,'/');
331end;
332
333procedure TTestJSScanner.TestEq;
334
335begin
336  CheckToken(tjsEq,'==');
337end;
338
339procedure TTestJSScanner.TestGE;
340
341begin
342  CheckToken(tjsGE,'>=');
343end;
344
345procedure TTestJSScanner.TestLE;
346
347begin
348  CheckToken(tjsLE,'<=');
349end;
350
351procedure TTestJSScanner.TestLSHIFT;
352
353begin
354  CheckToken(tjsLShift,'<<');
355end;
356
357procedure TTestJSScanner.TestLSHIFTEQ;
358
359begin
360  CheckToken(tjsLShiftEq,'<<=');
361end;
362
363procedure TTestJSScanner.TestMinusEQ;
364
365begin
366  CheckToken(tjsMinusEq,'-=');
367end;
368
369procedure TTestJSScanner.TestMinusMinus;
370
371begin
372  CheckToken(tjsMinusMinus,'--');
373end;
374
375procedure TTestJSScanner.TestModeq;
376
377begin
378  CheckToken(tjsModeq,'%=');
379end;
380
381
382procedure TTestJSScanner.TestDiveq;
383
384begin
385  CheckToken(tjsDiveq,'/=');
386end;
387
388procedure TTestJSScanner.TestXor;
389begin
390  CheckToken(tjsXOR,'^');
391end;
392
393procedure TTestJSScanner.TestXoreq;
394begin
395  CheckToken(tjsXOREQ,'^=');
396end;
397
398procedure TTestJSScanner.TestNE;
399
400begin
401  CheckToken(tjsNE,'!=');
402end;
403
404procedure TTestJSScanner.TestInv;
405
406begin
407  CheckToken(tjsInv,'~');
408end;
409
410procedure TTestJSScanner.TestNot;
411
412begin
413  CheckToken(tjsNot,'!');
414end;
415
416procedure TTestJSScanner.TestTrue;
417
418begin
419  CheckToken(tjsTrue,'true');
420end;
421
422procedure TTestJSScanner.TestFalse;
423
424begin
425  CheckToken(tjsFalse,'false');
426end;
427
428procedure TTestJSScanner.TestOREQ;
429
430begin
431  CheckToken(tjsOREQ,'|=');
432end;
433
434procedure TTestJSScanner.TestOROR;
435
436begin
437  CheckToken(tjsOROR,'||');
438end;
439
440procedure TTestJSScanner.TestPlusEq;
441
442begin
443  CheckToken(tjsPlusEq,'+=');
444end;
445
446procedure TTestJSScanner.TestPlusPlus;
447
448begin
449  CheckToken(tjsPlusPlus,'++');
450end;
451
452procedure TTestJSScanner.TestURShift;
453
454begin
455  CheckToken(tjsURSHIFT,'>>>');
456end;
457
458procedure TTestJSScanner.TestURShiftEq;
459
460begin
461  CheckToken(tjsURSHIFTEQ,'>>>=');
462end;
463
464procedure TTestJSScanner.TestRShift;
465
466begin
467  CheckToken(tjsRSHIFT,'>>');
468end;
469
470procedure TTestJSScanner.TestRShiftEq;
471
472begin
473  CheckToken(tjsRSHIFTEQ,'>>=');
474end;
475
476procedure TTestJSScanner.TestSEq;
477
478begin
479  CheckToken(tjsSEQ,'===');
480end;
481
482procedure TTestJSScanner.TestNSE;
483
484begin
485  CheckToken(tjsSNE,'!==');
486end;
487
488procedure TTestJSScanner.TestStarEq;
489
490begin
491  CheckToken(tjsMulEq,'*=');
492end;
493
494procedure TTestJSScanner.TestBreak;
495
496begin
497  CheckToken(tjsBreak,'break');
498end;
499
500procedure TTestJSScanner.TestCase;
501
502begin
503  CheckToken(tjscase,'case');
504end;
505
506procedure TTestJSScanner.TestCatch;
507
508begin
509  CheckToken(tjscatch,'catch');
510end;
511
512procedure TTestJSScanner.TestContinue;
513
514begin
515  CheckToken(tjscontinue,'continue');
516end;
517
518procedure TTestJSScanner.TestDefault;
519
520begin
521  CheckToken(tjsdefault,'default');
522end;
523
524procedure TTestJSScanner.TestDelete;
525
526begin
527  CheckToken(tjsdelete,'delete');
528end;
529
530procedure TTestJSScanner.TestDO;
531
532begin
533  CheckToken(tjsdo,'do');
534end;
535
536procedure TTestJSScanner.TestElse;
537
538begin
539  CheckToken(tjselse,'else');
540end;
541
542procedure TTestJSScanner.TestFinally;
543
544begin
545  CheckToken(tjsfinally,'finally');
546end;
547
548procedure TTestJSScanner.TestFor;
549
550begin
551  CheckToken(tjsfor,'for');
552end;
553
554procedure TTestJSScanner.TestFunction;
555
556begin
557  CheckToken(tjsfunction,'function');
558end;
559
560procedure TTestJSScanner.TestIf;
561
562begin
563  CheckToken(tjsif,'if');
564end;
565
566procedure TTestJSScanner.TestIn;
567
568begin
569  CheckToken(tjsin,'in');
570end;
571
572procedure TTestJSScanner.TestInstanceOf;
573
574begin
575  CheckToken(tjsinstanceof,'instanceof');
576end;
577
578procedure TTestJSScanner.TestNew;
579
580begin
581  CheckToken(tjsnew,'new');
582end;
583
584procedure TTestJSScanner.TestReturn;
585
586begin
587  CheckToken(tjsreturn,'return');
588end;
589
590procedure TTestJSScanner.TestSwitch;
591
592begin
593  CheckToken(tjsswitch,'switch');
594end;
595
596procedure TTestJSScanner.TestThis;
597
598begin
599  CheckToken(tjsThis,'this');
600end;
601
602procedure TTestJSScanner.TestThrow;
603
604begin
605  CheckToken(tjsThrow,'throw');
606end;
607
608procedure TTestJSScanner.TestTry;
609
610begin
611  CheckToken(tjsTry,'try');
612end;
613
614procedure TTestJSScanner.TestTypeOf;
615
616begin
617  CheckToken(tjstypeof,'typeof');
618end;
619
620procedure TTestJSScanner.TestVar;
621
622begin
623  CheckToken(tjsvar,'var');
624end;
625
626procedure TTestJSScanner.TestVoid;
627
628begin
629  CheckToken(tjsvoid,'void');
630end;
631
632procedure TTestJSScanner.TestWhile;
633
634begin
635  CheckToken(tjswhile,'while');
636end;
637
638procedure TTestJSScanner.TestWith;
639
640begin
641  CheckToken(tjswith,'with');
642end;
643
644procedure TTestJSScanner.CheckTokens(ASource : String; ATokens : Array of TJSToken);
645
646Var
647  I : Integer;
648  J : TJSToken;
649  S : String;
650
651begin
652  CreateScanner(ASource);
653  For I:=Low(ATokens) to High(ATokens) do
654    begin
655    J:=FScanner.FetchToken;
656    S:=GetEnumName(TypeINfo(TJSToken),Ord(ATokens[i]));
657    S:=Format('Source "%s", token %d (%s): expected %s',[ASource,I,FScanner.CurTokenString,S]);
658    AssertEquals(S,ATokens[i],J);
659    end;
660end;
661
662procedure TTestJSScanner.Test2Words;
663begin
664  CheckTokens('with do',[tjsWith,tjsDo]);
665end;
666
667procedure TTestJSScanner.Test3Words;
668begin
669  CheckTokens('with do for',[tjsWith,tjsDo,tjsFor]);
670end;
671
672procedure TTestJSScanner.TestIdentifier;
673begin
674  CheckToken(tjsIdentifier,'something');
675  AssertEquals('Correct identifier','something',FScanner.CurTokenString);
676end;
677
678procedure TTestJSScanner.TestIdentifier2;
679begin
680  CheckToken(tjsIdentifier,'_something');
681  AssertEquals('Correct identifier','_something',FScanner.CurTokenString);
682end;
683
684procedure TTestJSScanner.TestIdentifier3;
685begin
686  CheckToken(tjsIdentifier,'$');
687  AssertEquals('Correct identifier','$',FScanner.CurTokenString);
688end;
689
690procedure TTestJSScanner.TestIdentifier4;
691begin
692  CheckToken(tjsIdentifier,'_0');
693  AssertEquals('Correct identifier','_0',FScanner.CurTokenString);
694end;
695
696procedure TTestJSScanner.TestIdentifier5;
697begin
698  CheckToken(tjsIdentifier,'$0');
699  AssertEquals('Correct identifier','$0',FScanner.CurTokenString);
700end;
701
702procedure TTestJSScanner.TestIdentifierDotIdentifier;
703begin
704  CheckTokens('something.different',[tjsIdentifier,tjsdot,tjsIdentifier]);
705//  AssertEquals('Correct identifier','something',FScanner.CurTokenString);
706end;
707
708procedure TTestJSScanner.TestEOLN;
709begin
710  CreateScanner('something');
711  FScanner.FetchToken;
712  AssertEquals('Got to end of line after reading single token at EOF',True,FScanner.IsEndOfLine);
713//  AssertEquals('Correct identifier','something',FScanner.CurTokenString);
714end;
715
716procedure TTestJSScanner.TestEOLN2;
717begin
718  CreateScanner('something different');
719  FScanner.FetchToken;
720  AssertEquals('Not yet end of line after reading single token at EOF',False,FScanner.IsEndOfLine);
721end;
722
723procedure TTestJSScanner.TestEOLN3;
724begin
725  CreateScanner('something'#13#10'different');
726  FScanner.FetchToken;
727  AssertEquals('End of line after reading single token',True,FScanner.IsEndOfLine);
728end;
729
730procedure TTestJSScanner.TestEOLN4;
731begin
732  CreateScanner('something'#10'different');
733  FScanner.FetchToken;
734  AssertEquals('End of line after reading first token',True,FScanner.IsEndOfLine);
735  FScanner.FetchToken;
736  AssertEquals('End of line after reading second token',True,FScanner.IsEndOfLine);
737end;
738
739procedure TTestJSScanner.TestComment1;
740begin
741  CreateScanner('// some comment string');
742  AssertEquals('Comment line is skipped',tjsEOF,FScanner.FetchToken);
743end;
744
745procedure TTestJSScanner.TestComment2;
746begin
747  CreateScanner('// some comment string');
748  FScanner.ReturnComments:=True;
749  AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
750  AssertEquals('Comment contents is returned',' some comment string',FScanner.CurTokenString);
751end;
752
753procedure TTestJSScanner.TestComment3;
754begin
755  CreateScanner('/* some comment string */');
756  AssertEquals('Comment line is skipped',tjsEOF,FScanner.FetchToken);
757end;
758
759procedure TTestJSScanner.TestComment4;
760begin
761  CreateScanner('/* some comment string */');
762  FScanner.ReturnComments:=True;
763  AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
764  AssertEquals('Comment contents is returned',' some comment string ',FScanner.CurTokenString);
765end;
766
767procedure TTestJSScanner.TestComment5;
768begin
769  CreateScanner('/* some nested comment // string */');
770  FScanner.ReturnComments:=True;
771  AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
772  AssertEquals('Comment contents is returned',' some nested comment // string ',FScanner.CurTokenString);
773end;
774
775procedure TTestJSScanner.TestComment6;
776begin
777  CreateScanner('// /* some nested comment string */');
778  FScanner.ReturnComments:=True;
779  AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
780  AssertEquals('Comment contents is returned',' /* some nested comment string */',FScanner.CurTokenString);
781end;
782
783procedure TTestJSScanner.TearDown;
784begin
785  FreeScanner;
786  Inherited;
787end;
788
789procedure TTestJSScanner.DoTestFloat(F : Double);
790
791Var
792  S : String;
793
794begin
795  Str(F,S);
796  DoTestFloat(F,S);
797end;
798
799procedure TTestJSScanner.DoTestFloat(F : Double; S : String);
800
801Var
802  J : TJSToken;
803  C : Double;
804  I : integer;
805  V : String;
806
807begin
808  CreateScanner(S);
809  try
810    J:=FScanner.FetchToken;
811    AssertEquals(S+' is a number',tjsNumber,J);
812    V:=FScanner.CurTokenString;
813    If (Copy(V,1,2)='0x') then
814      begin
815      Flush(output);
816      V:='$'+Copy(V,3,Length(V)-2);
817      C:=StrToInt(V);
818      end
819    else
820      begin
821      Val(V,C,I);
822      If (I<>0) then
823        Fail(FScanner.CurTokenString+' does not contain a float value');
824      end;
825    AssertEquals('Parsed float equals original float',F,C);
826  finally
827    FreeScanner;
828  end;
829end;
830
831procedure TTestJSScanner.TestFloat;
832
833
834begin
835  DoTestFloat(1.2);
836  DoTestFloat(-1.2);
837  DoTestFloat(0);
838  DoTestFloat(1.2e1);
839  DoTestFloat(-1.2e1);
840  DoTestFloat(0);
841  DoTestFloat(1.2,'1.2');
842  DoTestFloat(-1.2,'-1.2');
843  DoTestFloat(0,'0.0');
844  DoTestFloat(255,'0xff')
845end;
846
847procedure TTestJSScanner.TestFloatError;
848
849begin
850  FErrorSource:='1xz';
851  AssertException('Wrong float',EJSScannerError,@TestErrorSource);
852end;
853
854
855procedure TTestJSScanner.DoTestString(S: String);
856
857Var
858  J : TJSToken;
859begin
860  CreateScanner(S);
861  try
862    J:=FScanner.FetchToken;
863    AssertEquals(S+' is a string',tjsString,J);
864    If (Length(S)>0) and (S[1] in ['"','''']) then
865      S:=Copy(S,2,Length(S)-2);
866    AssertEquals('Correct string is returned',S,FScanner.CurTokenString);
867  finally
868    FreeScanner;
869  end;
870end;
871
872procedure TTestJSScanner.TestString;
873
874begin
875  DoTestString('"A string"');
876  DoTestString('""');
877  DoTestString('''''');
878  DoTestString('''A string''');
879end;
880
881procedure TTestJSScanner.TestErrorSource;
882
883begin
884  CreateScanner(FErrorSource);
885  try
886    While (FScanner.FetchToken<>tjsEOF) do ;
887  finally
888    FreeScanner;
889  end;
890end;
891
892procedure TTestJSScanner.TestStringError;
893
894begin
895  FErrorSource:='"A string';
896  AssertException('Unterminated string',EJSScannerError,@TestErrorSource);
897  FErrorSource:='''A string';
898  AssertException('Unterminated string',EJSScannerError,@TestErrorSource);
899end;
900
901
902{ TTestLineReader }
903
904procedure TTestLineReader.CreateReader(AInput: String);
905begin
906  FData:=TStringStream.Create(AInput);
907  FReader:=TStreamLineReader.Create(FData);
908end;
909
910
911procedure TTestLineReader.TearDown;
912begin
913  FreeAndNil(FReader);
914  FreeAndNil(FData);
915end;
916
917procedure TTestLineReader.TestEmpty;
918begin
919  CreateReader('');
920  AssertEquals('Empty reader returns EOF',True,FReader.IsEOF);
921  AssertEquals('Empty reader returns empty string','',FReader.ReadLine);
922end;
923
924procedure TTestLineReader.TestReadLine;
925begin
926  CreateReader('Something');
927  AssertEquals('Reader with 1 line returns 1 line','Something',FReader.ReadLine);
928  AssertEquals('EOF true after reading line',True,FReader.IsEOF);
929end;
930
931procedure TTestLineReader.TestReadLines13;
932begin
933  CreateReader('Something'#13'else');
934  AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
935  AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
936  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
937end;
938
939procedure TTestLineReader.TestReadLines10;
940begin
941  CreateReader('Something'#10'else');
942  AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
943  AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
944  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
945end;
946
947procedure TTestLineReader.TestReadLines1310;
948begin
949  CreateReader('Something'#13#10'else');
950  AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
951  AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
952  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
953end;
954
955procedure TTestLineReader.TestReadLinesEOF13;
956begin
957  CreateReader('Something'#13);
958  AssertEquals('Reader with 2 lines + CR returns 1st line','Something',FReader.ReadLine);
959  AssertEquals('Reader with 1 lines + CR returns empty 2nd line','',FReader.ReadLine);
960  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
961end;
962
963procedure TTestLineReader.TestReadLinesEOF10;
964begin
965  CreateReader('Something'#10);
966  AssertEquals('Reader with 2 lines + LF returns 1st line','Something',FReader.ReadLine);
967  AssertEquals('Reader with 1 lines + LF returns empty 2nd line','',FReader.ReadLine);
968  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
969end;
970
971procedure TTestLineReader.TestReadLinesEOF1310;
972begin
973  CreateReader('Something'#13#10);
974  AssertEquals('Reader with 2 lines + CRLF returns 1st line','Something',FReader.ReadLine);
975  AssertEquals('Reader with 1 lines + CRLF returns empty 2nd line','',FReader.ReadLine);
976  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
977end;
978
979procedure TTestLineReader.TestReadEmptyLines101010;
980
981begin
982  CreateReader('Something'#10#10#10);
983  AssertEquals('Reader with 1 line + LFLFLF returns 1st line','Something',FReader.ReadLine);
984  AssertEquals('EOF false after reading line 1',False,FReader.IsEOF);
985  AssertEquals('Reader with 1 line + LFLFLF returns empty 2nd line','',FReader.ReadLine);
986  AssertEquals('EOF false after reading line 2',False,FReader.IsEOF);
987  AssertEquals('Reader with 1 line + LFLFLF returns empty 3nd line','',FReader.ReadLine);
988  AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
989end;
990
991initialization
992
993  RegisterTests([TTestLineReader,TTestJSScanner]);
994end.
995
996