123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- {
- This file is part of the Free Pascal Run time library.
- Copyright (c) 2022- by Michael Van Canneyt ([email protected])
- This file contains the tests for the CSS Scanner
- See the File COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit tcCSSScanner;
- {$mode objfpc}{$H+}
- interface
- uses
- TypInfo, Classes, SysUtils, fpcunit, testregistry, fpcssscanner;
- type
- TTestLineReader = Class(TTestCase)
- Private
- FData: TStringStream;
- FReader : TStreamLineReader;
- protected
- Procedure CreateReader(AInput : String);
- procedure TearDown; override;
- published
- Procedure TestEmpty;
- Procedure TestReadLine;
- Procedure TestReadLines13;
- Procedure TestReadLines10;
- Procedure TestReadLines1310;
- procedure TestReadLinesEOF13;
- procedure TestReadLinesEOF10;
- procedure TestReadLinesEOF1310;
- procedure TestReadEmptyLines101010;
- end;
- { TTestCSSScanner }
- TTestCSSScanner = class(TTestCase)
- Private
- FPSeudoDisabled,
- FNeedWhiteSpace : Boolean;
- FStream : TStream;
- FLineReader : TLineReader;
- FScanner : TCSSScanner;
- FErrorSource : String;
- procedure AssertEquals(AMessage: String; AExpected, AActual : TCSSToken); overload;
- procedure CheckToken(AToken: TCSSToken; ASource: String);
- procedure CheckTokens(ASource: String; ATokens: array of TCSSToken);
- procedure DoTestFloat(F: Double);
- procedure DoTestFloat(F: Double; S: String);
- procedure DoTestString(S: String);
- procedure TestErrorSource;
- protected
- Function CreateScanner(AInput : String) : TCSSScanner;
- procedure FreeScanner;
- procedure SetUp; override;
- procedure TearDown; override;
- Property Scanner : TCSSScanner Read FScanner;
- published
- procedure TestEmpty;
- Procedure TestEOF;
- Procedure TestWhiteSpace;
- Procedure TestComment1;
- Procedure TestComment2;
- Procedure TestComment3;
- Procedure TestID1;
- Procedure TestIDUnderscore;
- Procedure TestIDMinus;
- Procedure TestIDMinusMinus;
- Procedure TestIDEscape;
- Procedure TestIDEscapeStart;
- procedure TestPSEUDO;
- procedure TestPSEUDO2;
- procedure TestPSEUDOMinus;
- procedure TestPSEUDO2Minus;
- procedure TestPSEUDODisabled;
- procedure TestUNICODERANGE;
- procedure TestUNICODERANGE2;
- procedure TestFUNCTION;
- procedure TestPSEUDOFUNCTION;
- procedure TestPSEUDOFUNCTION2;
- Procedure TestSEMI;
- Procedure TestLPAREN;
- Procedure TestRPAREN;
- Procedure TestLBRACE;
- Procedure TestRBRACE;
- Procedure TestLBRACKET;
- Procedure TestRBRACKET;
- Procedure TestSTR;
- Procedure TestStrEscapeUnicode;
- procedure TestStrEscapeUnicode2;
- Procedure TestCOMMA;
- Procedure TestEQUALS;
- Procedure TestAND;
- Procedure TestTILDE;
- Procedure TestPLUS;
- Procedure TestCOLON;
- Procedure TestDOUBLECOLON;
- Procedure TestDOT;
- Procedure TestINT;
- Procedure TestFLOAT;
- Procedure TestDOUBLE;
- Procedure TestHASH1;
- Procedure TestHASH2;
- Procedure TestDIV;
- Procedure TestSTATEMENT;
- Procedure TestGT;
- Procedure TestLT;
- Procedure TestPERCENTAGE;
- Procedure TestMINUS;
- Procedure TestIMPORTANT;
- Procedure TestCLASSNAME;
- Procedure TestSTAR;
- Procedure TestURL;
- Procedure TestURLAltQuote;
- Procedure TestURL2;
- Procedure TestBADURL;
- Procedure TestBADEOF;
- Procedure TestJUNK;
- Procedure TestSQUARED;
- end;
- implementation
- function TTestCSSScanner.CreateScanner(AInput: String): TCSSScanner;
- begin
- FreeScanner;
- FStream:=TStringStream.Create(AInput);
- FLineReader:=TStreamLineReader.Create(Fstream);
- FScanner:=TCSSScanner.Create(FLineReader);
- FScanner.DisablePseudo:=FPSeudoDisabled;
- Result:=FScanner;
- if FNeedWhiteSpace then
- FScanner.ReturnWhiteSpace:=True;
- end;
- procedure TTestCSSScanner.FreeScanner;
- begin
- FreeAndNil(FScanner);
- FreeAndNil(FLineReader);
- FreeAndNil(FStream);
- end;
- procedure TTestCSSScanner.SetUp;
- begin
- inherited SetUp;
- FNeedWhiteSpace:=False;
- FPSeudoDisabled:=False;
- end;
- procedure TTestCSSScanner.TearDown;
- begin
- FreeScanner;
- Inherited;
- end;
- procedure TTestCSSScanner.DoTestFloat(F : Double);
- Var
- S : String;
- begin
- Str(F,S);
- DoTestFloat(F,S);
- end;
- procedure TTestCSSScanner.DoTestFloat(F : Double; S : String);
- Var
- J : TCSSToken;
- C : Double;
- I : integer;
- V : String;
- begin
- CreateScanner(S);
- try
- J:=FScanner.FetchToken;
- AssertEquals(S+' is a number',ctkFloat,J);
- V:=FScanner.CurTokenString;
- If (Copy(V,1,2)='0x') then
- begin
- Flush(output);
- V:='$'+Copy(V,3,Length(V)-2);
- C:=StrToInt(V);
- end
- else
- begin
- Val(V,C,I);
- If (I<>0) then
- Fail(FScanner.CurTokenString+' does not contain a float value');
- end;
- AssertEquals('Parsed float equals original float',F,C);
- finally
- FreeScanner;
- end;
- end;
- procedure TTestCSSScanner.DoTestString(S: String);
- Var
- J : TCSSToken;
- begin
- CreateScanner(S);
- try
- J:=FScanner.FetchToken;
- AssertEquals(S+' is a string',ctkSTRING,J);
- If (Length(S)>0) and (S[1] in ['"','''','`']) then
- S:=Copy(S,2,Length(S)-2);
- AssertEquals('Correct string is returned',S,FScanner.CurTokenString);
- finally
- FreeScanner;
- end;
- end;
- procedure TTestCSSScanner.TestErrorSource;
- begin
- CreateScanner(FErrorSource);
- try
- While (FScanner.FetchToken<>ctkEOF) do ;
- finally
- FreeScanner;
- end;
- end;
- procedure TTestCSSScanner.TestEmpty;
- Var
- J : TCSSToken;
- begin
- CreateScanner('');
- J:=Scanner.FetchToken;
- If (J<>ctkEOF) then
- Fail('Empty returns EOF');
- end;
- procedure TTestCSSScanner.TestEOF;
- Var
- C : TCSSToken;
- begin
- CreateScanner('');
- C:=Scanner.FetchToken;
- If (C<>ctkEOF) then
- Fail('Empty returns EOF');
- end;
- procedure TTestCSSScanner.TestWhiteSpace;
- Var
- C : TCSSToken;
- begin
- FNeedWhiteSpace:=True;
- CreateScanner(' ');
- C:=Scanner.FetchToken;
- If (C<>ctkWHITESPACE) then
- Fail('Empty returns EOF');
- end;
- procedure TTestCSSScanner.TestComment1;
- begin
- CreateScanner('/* some comment string */');
- AssertEquals('Comment line is skipped',ctkEOF,FScanner.FetchToken);
- end;
- procedure TTestCSSScanner.TestComment2;
- begin
- CreateScanner('/* some comment string */');
- FScanner.ReturnComments:=True;
- AssertEquals('Comment line is returned',ctkComment,FScanner.FetchToken);
- AssertEquals('Comment contents is returned',' some comment string ',FScanner.CurTokenString);
- end;
- procedure TTestCSSScanner.TestComment3;
- begin
- CreateScanner('/* some multiline comment '#10' string */');
- FScanner.ReturnComments:=True;
- AssertEquals('Comment line is returned',ctkComment,FScanner.FetchToken);
- AssertEquals('Comment contents is returned',' some multiline comment '#10' string ',FScanner.CurTokenString);
- end;
- procedure TTestCSSScanner.TestID1;
- begin
- CheckToken(ctkIDENTIFIER,'anid');
- end;
- procedure TTestCSSScanner.TestIDUnderscore;
- begin
- CheckToken(ctkIDENTIFIER,'_anid');
- end;
- procedure TTestCSSScanner.TestIDMinus;
- begin
- CheckToken(ctkIDENTIFIER,'-anid');
- end;
- procedure TTestCSSScanner.TestIDMinusMinus;
- begin
- CheckToken(ctkIDENTIFIER,'--anid');
- end;
- procedure TTestCSSScanner.TestIDEscape;
- begin
- CheckToken(ctkIDENTIFIER,'an\(id');
- end;
- procedure TTestCSSScanner.TestIDEscapeStart;
- begin
- CheckToken(ctkIDENTIFIER,'\(anid');
- end;
- procedure TTestCSSScanner.TestSEMI;
- begin
- CheckToken(ctkSEMICOLON,';');
- end;
- procedure TTestCSSScanner.TestLPAREN;
- begin
- CheckToken(ctkLPARENTHESIS,'(');
- end;
- procedure TTestCSSScanner.TestRPAREN;
- begin
- CheckToken(ctkRPARENTHESIS,')');
- end;
- procedure TTestCSSScanner.TestLBRACE;
- begin
- CheckToken(ctkLBRACE,'{');
- end;
- procedure TTestCSSScanner.TestRBRACE;
- begin
- CheckToken(ctkRBRACE,'}');
- end;
- procedure TTestCSSScanner.TestLBRACKET;
- begin
- CheckToken(ctkLBRACKET,'[');
- end;
- procedure TTestCSSScanner.TestRBRACKET;
- begin
- CheckToken(ctkRBRACKET,']');
- end;
- procedure TTestCSSScanner.TestSTR;
- begin
- CheckToken(ctkSTRING,'"abc"');
- end;
- procedure TTestCSSScanner.TestStrEscapeUnicode;
- begin
- CheckToken(ctkSTRING,'"\00a0\00a0\00a0\00a0"');
- CheckToken(ctkSTRING,'"\2a"');
- end;
- procedure TTestCSSScanner.TestStrEscapeUnicode2;
- begin
- CheckToken(ctkSTRING,'"\2a"');
- end;
- procedure TTestCSSScanner.TestCOMMA;
- begin
- CheckToken(ctkCOMMA,',');
- end;
- procedure TTestCSSScanner.TestEQUALS;
- begin
- CheckToken(ctkEQUALS,'=');
- end;
- procedure TTestCSSScanner.TestAND;
- begin
- CheckToken(ctkAND,'&');
- end;
- procedure TTestCSSScanner.TestTILDE;
- begin
- CheckToken(ctkTILDE,'~');
- end;
- procedure TTestCSSScanner.TestPLUS;
- begin
- CheckToken(ctkPLUS,'+');
- end;
- procedure TTestCSSScanner.TestCOLON;
- begin
- CheckToken(ctkCOLON,':');
- end;
- procedure TTestCSSScanner.TestDOUBLECOLON;
- begin
- CheckToken(ctkDOUBLECOLON,'::');
- end;
- procedure TTestCSSScanner.TestDOT;
- begin
- CheckToken(ctkDOT,'.');
- end;
- procedure TTestCSSScanner.TestINT;
- begin
- CheckToken(ctkINTEGER,'123');
- end;
- procedure TTestCSSScanner.TestFLOAT;
- begin
- DoTestFloat(123.3,'123.3');
- end;
- procedure TTestCSSScanner.TestDOUBLE;
- begin
- DoTestFloat(123.3,'123.3');
- end;
- procedure TTestCSSScanner.TestHASH1;
- begin
- CheckToken(ctkHASH,'#1231');
- end;
- procedure TTestCSSScanner.TestHASH2;
- begin
- CheckToken(ctkHASH,'#AFAFAF');
- end;
- procedure TTestCSSScanner.TestDIV;
- begin
- CheckToken(ctkDIV,'/');
- end;
- procedure TTestCSSScanner.TestSTATEMENT;
- begin
- CheckToken(ctkATKEYWORD,'@media');
- end;
- procedure TTestCSSScanner.TestGT;
- begin
- CheckToken(ctkGT,'>');
- end;
- procedure TTestCSSScanner.TestLT;
- begin
- CheckToken(ctkLT,'<');
- end;
- procedure TTestCSSScanner.TestPERCENTAGE;
- begin
- CheckToken(ctkPERCENTAGE,'%');
- end;
- procedure TTestCSSScanner.TestMINUS;
- begin
- CheckToken(ctkMinus,'-');
- end;
- procedure TTestCSSScanner.TestIMPORTANT;
- begin
- CheckToken(ctkIMPORTANT,'!important');
- end;
- procedure TTestCSSScanner.TestCLASSNAME;
- begin
- CheckToken(ctkCLASSNAME,'.classname');
- end;
- procedure TTestCSSScanner.TestSTAR;
- begin
- CheckToken(ctkSTAR,'*');
- end;
- procedure TTestCSSScanner.TestURL;
- begin
- CheckToken(ctkURL,'url("abc")');
- end;
- procedure TTestCSSScanner.TestURLAltQuote;
- begin
- CheckToken(ctkURL,'url(''abc'')');
- end;
- procedure TTestCSSScanner.TestURL2;
- begin
- CheckToken(ctkURL,'url(abc)');
- end;
- procedure TTestCSSScanner.TestBADURL;
- begin
- CheckToken(ctkBADURL,'url(de f)');
- end;
- procedure TTestCSSScanner.TestBADEOF;
- begin
- CheckToken(ctkEOF,'url(def');
- end;
- procedure TTestCSSScanner.TestPSEUDO;
- begin
- CheckToken(ctkPSEUDO,':name');
- end;
- procedure TTestCSSScanner.TestPSEUDO2;
- begin
- CheckToken(ctkPSEUDO,'::name');
- end;
- procedure TTestCSSScanner.TestPSEUDOMinus;
- begin
- CheckToken(ctkPSEUDO,':-name');
- end;
- procedure TTestCSSScanner.TestPSEUDO2Minus;
- begin
- CheckToken(ctkPSEUDO,'::-name');
- end;
- procedure TTestCSSScanner.TestPSEUDODisabled;
- begin
- FPseudoDisabled:=True;
- CheckTokens(':me',[ctkColon,ctkIDENTIFIER]);
- end;
- procedure TTestCSSScanner.TestUNICODERANGE;
- begin
- CheckToken(ctkUNICODERANGE,'U+124');
- end;
- procedure TTestCSSScanner.TestUNICODERANGE2;
- begin
- CheckToken(ctkUNICODERANGE,'U+124-128');
- end;
- procedure TTestCSSScanner.TestFUNCTION;
- begin
- CheckToken(ctkFUNCTION,'name(');
- end;
- procedure TTestCSSScanner.TestPSEUDOFUNCTION;
- begin
- CheckToken(ctkPSEUDOFUNCTION,':name(');
- end;
- procedure TTestCSSScanner.TestPSEUDOFUNCTION2;
- begin
- CheckToken(ctkPSEUDOFUNCTION,'::name(');
- end;
- procedure TTestCSSScanner.TestJUNK;
- begin
- FErrorSource:='?';
- AssertException('Exception',ECSSScanner, @TestErrorSource);
- end;
- procedure TTestCSSScanner.TestSQUARED;
- begin
- CheckToken(ctkSQUARED,'^');
- end;
- procedure TTestCSSScanner.AssertEquals(AMessage : String; AExpected, AActual: TCSSToken);
- Var
- S,EN1,EN2 : String;
- begin
- If (AActual<>AExpected) then
- begin
- EN1:=GetEnumName(TypeINfo(TCSSToken),Ord(AExpected));
- EN2:=GetEnumName(TypeINfo(TCSSToken),Ord(AActual));
- S:=Format('%s : %s <> %s',[AMessage,EN1,EN2]);
- Fail(S);
- end;
- end;
- procedure TTestCSSScanner.CheckToken(AToken: TCSSToken; ASource: String);
- Var
- J : TCSSToken;
- EN2 : String;
- begin
- CreateScanner(ASource);
- J:=Scanner.FetchToken;
- EN2:=GetEnumName(TypeINfo(TCSSToken),Ord(AToken));
- AssertEquals(Format('Source %s should result in %s.',[ASource,EN2]),AToken,J);
- end;
- procedure TTestCSSScanner.CheckTokens(ASource: String;
- ATokens: array of TCSSToken);
- Var
- I : Integer;
- J : TCSSToken;
- S : String;
- begin
- CreateScanner(ASource);
- For I:=Low(ATokens) to High(ATokens) do
- begin
- J:=FScanner.FetchToken;
- S:=GetEnumName(TypeINfo(TCSSToken),Ord(ATokens[i]));
- S:=Format('Source "%s", token %d (%s): expected %s',[ASource,I,FScanner.CurTokenString,S]);
- AssertEquals(S,ATokens[i],J);
- end;
- end;
- { TTestLineReader }
- procedure TTestLineReader.CreateReader(AInput: String);
- begin
- FData:=TStringStream.Create(AInput);
- FReader:=TStreamLineReader.Create(FData);
- end;
- procedure TTestLineReader.TearDown;
- begin
- FreeAndNil(FReader);
- FreeAndNil(FData);
- end;
- procedure TTestLineReader.TestEmpty;
- begin
- CreateReader('');
- AssertEquals('Empty reader returns EOF',True,FReader.IsEOF);
- AssertEquals('Empty reader returns empty string','',FReader.ReadLine);
- end;
- procedure TTestLineReader.TestReadLine;
- begin
- CreateReader('Something');
- AssertEquals('Reader with 1 line returns 1 line','Something',FReader.ReadLine);
- AssertEquals('EOF true after reading line',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadLines13;
- begin
- CreateReader('Something'#13'else');
- AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
- AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadLines10;
- begin
- CreateReader('Something'#10'else');
- AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
- AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadLines1310;
- begin
- CreateReader('Something'#13#10'else');
- AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
- AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadLinesEOF13;
- begin
- CreateReader('Something'#13);
- AssertEquals('Reader with 2 lines + CR returns 1st line','Something',FReader.ReadLine);
- AssertEquals('Reader with 1 lines + CR returns empty 2nd line','',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadLinesEOF10;
- begin
- CreateReader('Something'#10);
- AssertEquals('Reader with 2 lines + LF returns 1st line','Something',FReader.ReadLine);
- AssertEquals('Reader with 1 lines + LF returns empty 2nd line','',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadLinesEOF1310;
- begin
- CreateReader('Something'#13#10);
- AssertEquals('Reader with 2 lines + CRLF returns 1st line','Something',FReader.ReadLine);
- AssertEquals('Reader with 1 lines + CRLF returns empty 2nd line','',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- procedure TTestLineReader.TestReadEmptyLines101010;
- begin
- CreateReader('Something'#10#10#10);
- AssertEquals('Reader with 1 line + LFLFLF returns 1st line','Something',FReader.ReadLine);
- AssertEquals('EOF false after reading line 1',False,FReader.IsEOF);
- AssertEquals('Reader with 1 line + LFLFLF returns empty 2nd line','',FReader.ReadLine);
- AssertEquals('EOF false after reading line 2',False,FReader.IsEOF);
- AssertEquals('Reader with 1 line + LFLFLF returns empty 3nd line','',FReader.ReadLine);
- AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
- end;
- initialization
- RegisterTests([TTestLineReader,TTestCSSScanner]);
- end.
|