fpc/packages/fcl-passrc/tests/tcmoduleparser.pas
Mattias Gaertner d7163d3854 fcl-passrc: parser: create usesclause
git-svn-id: trunk@36006 -
2017-04-29 10:50:00 +00:00

409 lines
12 KiB
ObjectPascal

unit tcmoduleparser;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
tcbaseparser, testregistry;
Type
{ TTestModuleParser }
TTestModuleParser = class(TTestParser)
private
function GetIf: TInterfaceSection;
function GetIm: TImplementationSection;
function CheckUnit(AIndex: Integer; const AName: String; Section: TPasSection): TPasUnresolvedUnitRef;
Protected
Procedure ParseUnit;
Procedure ParseProgram;
Procedure ParseLibrary;
Procedure AssertProgramError;
Property ImplSection : TImplementationSection Read GetIm;
Property IntfSection : TInterfaceSection Read GetIf;
Published
Procedure TestEmptyUnit;
Procedure TestUnitOneUses;
Procedure TestUnitTwoUses;
Procedure TestUnitOneImplUses;
Procedure TestUnitTwoImplUses;
Procedure TestEmptyUnitInitialization;
Procedure TestEmptyUnitFinalization;
Procedure TestEmptyUnitInitializationFinalization;
Procedure TestEmptyUnitBegin;
Procedure TestEmptyProgram;
Procedure TestEmptyProgramInputOUtput;
Procedure TestEmptyProgramNoInitialization;
Procedure TestEmptyProgramNoFinalization;
Procedure TestEmptyProgramMissingBegin;
Procedure TestEmptyProgramNoheader;
Procedure TestEmptyProgramUses;
Procedure TestEmptyProgramUsesTwoUnits;
Procedure TestEmptyProgramUsesUnitIn;
Procedure TestEmptyLibrary;
Procedure TestEmptyLibraryUses;
Procedure TestEmptyLibraryExports;
Procedure TestEmptyLibraryExportsAlias;
Procedure TestEmptyLibraryExportsIndex;
Procedure TestEmptyLibraryExportsTwo;
Procedure TestEmptyLibraryExportsTwoAlias;
Procedure TestEmptyLibraryExportsTwoIndex;
end;
implementation
{ TTestModuleParser }
function TTestModuleParser.GetIf: TInterfaceSection;
begin
Result:=Module.InterfaceSection;
end;
function TTestModuleParser.GetIm: TImplementationSection;
begin
Result:=Module.ImplementationSection;
end;
procedure TTestModuleParser.ParseUnit;
begin
EndSource;
ParseModule;
AssertNotNull('Have interface',Module.InterfaceSection);
Declarations:=Module.InterfaceSection;
AssertEquals('Interface section',TInterfaceSection,Declarations.ClassType);
AssertNotNull('Have implmeentation',Module.ImplementationSection);
AssertEquals('implementation section',TImplementationSection,Module.ImplementationSection.ClassType);
AssertNotNull('Have interface units',IntfSection.UsesList);
AssertNotNull('Have implementation units',ImplSection.UsesList);
end;
procedure TTestModuleParser.ParseProgram;
begin
EndSource;
ParseModule;
AssertEquals('Is program',TPasProgram,Module.ClassType);
end;
procedure TTestModuleParser.ParseLibrary;
begin
EndSource;
ParseModule;
AssertEquals('Is library',TPasLibrary,Module.ClassType);
end;
procedure TTestModuleParser.AssertProgramError;
begin
AssertException(EParserError,@ParseProgram)
end;
function TTestModuleParser.CheckUnit(AIndex: Integer; const AName: String;
Section: TPasSection): TPasUnresolvedUnitRef;
Var
C : string;
AList: TFPList;
Clause: TPasUsesClause;
begin
Result:=nil;
C:='Unit '+IntTostr(AIndex)+' ';
AList:=Section.UsesList;
AssertNotNull('Have useslist',AList);
if (AIndex>=AList.Count) then
Fail(Format('Index %d larger than unit list count %d',[AIndex,AList.Count ]));
AssertNotNull('Have pascal element',AList[AIndex]);
AssertEquals(C+'Correct class',TPasUnresolvedUnitRef,TObject(AList[AIndex]).CLassType);
Clause:=Section.UsesClause;
if AIndex>=length(Clause) then
Fail(Format('Index %d larger than unit list count %d',[AIndex,length(Clause) ]));
AssertNotNull('Have pascal element',Clause[AIndex]);
AssertEquals(C+'Correct class',TPasUsesUnit,Clause[AIndex].ClassType);
AssertNotNull(C+'Has Module',Clause[AIndex].Module);
AssertEquals(C+'Correct module class',TPasUnresolvedUnitRef,Clause[AIndex].Module.ClassType);
Result:=TPasUnresolvedUnitRef(Clause[AIndex].Module);
AssertEquals(C+'Unit name correct',AName,Result.Name);
end;
procedure TTestModuleParser.TestEmptyUnit;
begin
StartUnit('unit1');
StartImplementation;
ParseUnit;
AssertEquals('Only system in interface units',1,IntfSection.UsesList.Count);
AssertEquals('Only system in interface units',1,length(IntfSection.UsesClause));
CheckUnit(0,'System',IntfSection);
AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
AssertEquals('No implementation units',0,length(ImplSection.UsesClause));
end;
procedure TTestModuleParser.TestUnitOneUses;
begin
StartUnit('unit1');
UsesClause(['a']);
StartImplementation;
ParseUnit;
AssertEquals('Two interface units',2,IntfSection.UsesList.Count);
AssertEquals('Two interface units',2,length(IntfSection.UsesClause));
CheckUnit(0,'System',IntfSection);
CheckUnit(1,'a',IntfSection);
AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
AssertEquals('No implementation units',0,length(ImplSection.UsesClause));
end;
procedure TTestModuleParser.TestUnitTwoUses;
begin
StartUnit('unit1');
UsesClause(['a','b']);
StartImplementation;
ParseUnit;
AssertEquals('Three interface units',3,IntfSection.UsesList.Count);
AssertEquals('Three interface units',3,length(IntfSection.UsesClause));
CheckUnit(0,'System',IntfSection);
CheckUnit(1,'a',IntfSection);
CheckUnit(2,'b',IntfSection);
AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
AssertEquals('No implementation units',0,length(ImplSection.UsesClause));
end;
procedure TTestModuleParser.TestUnitOneImplUses;
begin
StartUnit('unit1');
StartImplementation;
UsesClause(['a']);
ParseUnit;
AssertEquals('One implementation units',1,ImplSection.UsesList.Count);
AssertEquals('One implementation units',1,length(ImplSection.UsesClause));
CheckUnit(0,'a',ImplSection);
AssertEquals('Only system in interface units',1,IntfSection.UsesList.Count);
AssertEquals('Only system in interface units',1,length(IntfSection.UsesClause));
CheckUnit(0,'System',IntfSection);
end;
procedure TTestModuleParser.TestUnitTwoImplUses;
begin
StartUnit('unit1');
StartImplementation;
UsesClause(['a','b']);
ParseUnit;
AssertEquals('One interface unit',1,IntfSection.UsesList.Count);
AssertEquals('One interface unit',1,length(IntfSection.UsesClause));
CheckUnit(0,'System',IntfSection);
AssertEquals('Two implementation units',2,ImplSection.UsesList.Count);
AssertEquals('Two implementation units',2,length(ImplSection.UsesClause));
CheckUnit(0,'a',ImplSection);
CheckUnit(1,'b',ImplSection);
end;
procedure TTestModuleParser.TestEmptyUnitInitialization;
begin
StartUnit('unit1');
StartImplementation;
Add('initialization');
ParseUnit;
AssertNotNull('Have initialization section',Module.InitializationSection);
AssertNull('Have no finalization section',Module.FinalizationSection)
end;
procedure TTestModuleParser.TestEmptyUnitFinalization;
begin
StartUnit('unit1');
StartImplementation;
Add('finalization');
ParseUnit;
AssertNull('Have no initalization section',Module.InitializationSection);
AssertNotNull('Have finalization section',Module.FinalizationSection)
end;
procedure TTestModuleParser.TestEmptyUnitInitializationFinalization;
begin
StartUnit('unit1');
StartImplementation;
Add('initialization');
Add('finalization');
ParseUnit;
AssertNotNull('Have finalization section',Module.InitializationSection);
AssertNotNull('Have finalization section',Module.FinalizationSection);
end;
procedure TTestModuleParser.TestEmptyUnitBegin;
begin
StartUnit('unit1');
StartImplementation;
Add('begin');
ParseUnit;
AssertNotNull('Have initialization section',Module.InitializationSection);
AssertNull('Have no finalization section',Module.FinalizationSection)
end;
procedure TTestModuleParser.TestEmptyProgram;
begin
StartProgram('something');
Add('begin');
ParseProgram;
end;
procedure TTestModuleParser.TestEmptyProgramInputOUtput;
begin
StartProgram('something','input','output');
Add('begin');
ParseProgram;
end;
procedure TTestModuleParser.TestEmptyProgramNoInitialization;
begin
StartProgram('something','input','output');
Add('initialization');
AssertProgramError;
end;
procedure TTestModuleParser.TestEmptyProgramNoFinalization;
begin
StartProgram('something','input','output');
Add('finalization');
AssertProgramError;
end;
procedure TTestModuleParser.TestEmptyProgramMissingBegin;
begin
StartProgram('something','input','output');
AssertProgramError;
end;
procedure TTestModuleParser.TestEmptyProgramNoheader;
begin
Add('begin');
ParseProgram;
end;
procedure TTestModuleParser.TestEmptyProgramUses;
begin
UsesClause(['a']);
Add('begin');
ParseProgram;
AssertEquals('Two interface units',2, PasProgram.ProgramSection.UsesList.Count);
AssertEquals('Two interface units',2, length(PasProgram.ProgramSection.UsesClause));
CheckUnit(0,'System',PasProgram.ProgramSection);
CheckUnit(1,'a',PasProgram.ProgramSection);
end;
procedure TTestModuleParser.TestEmptyProgramUsesTwoUnits;
begin
UsesClause(['a','b']);
Add('begin');
ParseProgram;
AssertEquals('Three interface units',3, PasProgram.ProgramSection.UsesList.Count);
AssertEquals('Three interface unit',3, length(PasProgram.ProgramSection.UsesClause));
CheckUnit(0,'System',PasProgram.ProgramSection);
CheckUnit(1,'a',PasProgram.ProgramSection);
CheckUnit(2,'b',PasProgram.ProgramSection);
end;
procedure TTestModuleParser.TestEmptyProgramUsesUnitIn;
Var
U : TPasUnresolvedUnitRef;
begin
UsesClause(['a in ''../a.pas''','b']);
Add('begin');
ParseProgram;
AssertEquals('Three interface unit',3, PasProgram.ProgramSection.UsesList.Count);
AssertEquals('Three interface unit',3, length(PasProgram.ProgramSection.UsesClause));
CheckUnit(0,'System',PasProgram.ProgramSection);
U:=CheckUnit(1,'a',PasProgram.ProgramSection);
AssertEquals('Filename','''../a.pas''',U.FileName);
CheckUnit(2,'b',PasProgram.ProgramSection);
end;
procedure TTestModuleParser.TestEmptyLibrary;
begin
StartLibrary('');
ParseLibrary;
AssertEquals('Correct class',TPasLibrary,Module.ClassType);
end;
procedure TTestModuleParser.TestEmptyLibraryUses;
begin
StartLibrary('');
UsesClause(['a']);
ParseLibrary;
AssertEquals('Correct class',TPasLibrary,Module.ClassType);
AssertEquals('Two interface units',2, PasLibrary.LibrarySection.UsesList.Count);
AssertEquals('Two interface units',2, length(PasLibrary.LibrarySection.UsesClause));
CheckUnit(0,'System',PasLibrary.LibrarySection);
CheckUnit(1,'a',PasLibrary.LibrarySection);
end;
procedure TTestModuleParser.TestEmptyLibraryExports;
begin
StartLibrary('');
UsesClause(['b']);
Add('exports A;');
ParseLibrary;
AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
AssertExportSymbol('Export symbol a',0,'A','',-1);
end;
procedure TTestModuleParser.TestEmptyLibraryExportsAlias;
begin
StartLibrary('');
UsesClause(['b']);
Add('exports A name ''c'';');
ParseLibrary;
AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
AssertExportSymbol('Export symbol a',0,'A','c',-1);
end;
procedure TTestModuleParser.TestEmptyLibraryExportsIndex;
begin
StartLibrary('');
UsesClause(['b']);
Add('exports A index 23;');
ParseLibrary;
AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
AssertExportSymbol('Export symbol a',0,'A','',23);
end;
procedure TTestModuleParser.TestEmptyLibraryExportsTwo;
begin
StartLibrary('');
UsesClause(['b']);
Add('exports A , C;');
ParseLibrary;
AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
AssertExportSymbol('Export symbol a',0,'A','',-1);
AssertExportSymbol('Export symbol C',1,'C','',-1);
end;
procedure TTestModuleParser.TestEmptyLibraryExportsTwoAlias;
begin
StartLibrary('');
UsesClause(['b']);
Add('exports A name ''de'', C;');
ParseLibrary;
AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
AssertExportSymbol('Export symbol a',0,'A','de',-1);
AssertExportSymbol('Export symbol C',1,'C','',-1);
end;
procedure TTestModuleParser.TestEmptyLibraryExportsTwoIndex;
begin
StartLibrary('');
UsesClause(['b']);
Add('exports A index 23, C;');
ParseLibrary;
AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
AssertExportSymbol('Export symbol a',0,'A','',23);
AssertExportSymbol('Export symbol C',1,'C','',-1);
end;
initialization
RegisterTests([TTestModuleParser]);
end.