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