fpc/packages/fcl-passrc/tests/tcvarparser.pas
2015-01-26 13:46:21 +00:00

316 lines
8.3 KiB
ObjectPascal

unit tcvarparser;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, fpcunit, pastree, pscanner,
tcbaseparser, testregistry;
Type
{ TTestVarParser }
TTestVarParser = Class(TTestParser)
private
FHint: string;
FVar: TPasVariable;
Protected
Function ParseVar(ASource : String; Const AHint : String = '') : TPasVariable; virtual; overload;
Procedure AssertVariableType(Const ATypeName : String);
Procedure AssertVariableType(Const AClass : TClass);
Procedure AssertParseVarError(ASource : String);
Property TheVar : TPasVariable Read FVar;
Property Hint : string Read FHint Write FHint;
procedure SetUp; override;
Procedure TearDown; override;
Published
Procedure TestSimpleVar;
Procedure TestSimpleVarDeprecated;
Procedure TestSimpleVarPlatform;
Procedure TestSimpleVarInitialized;
procedure TestSimpleVarInitializedDeprecated;
procedure TestSimpleVarInitializedPlatform;
Procedure TestVarProcedure;
Procedure TestVarProcedureDeprecated;
Procedure TestVarRecord;
Procedure TestVarRecordDeprecated;
Procedure TestVarRecordPlatform;
Procedure TestVarArray;
Procedure TestVarArrayDeprecated;
Procedure TestVarDynArray;
Procedure TestVarExternal;
Procedure TestVarExternalLib;
Procedure TestVarExternalLibName;
Procedure TestVarCVar;
Procedure TestVarCVarExternal;
Procedure TestVarPublic;
Procedure TestVarPublicName;
Procedure TestVarDeprecatedExternalName;
Procedure TestVarHintPriorToInit;
end;
implementation
uses typinfo;
{ TTestVarParser }
function TTestVarParser.ParseVar(ASource: String; const AHint: String
): TPasVariable;
Var
D : String;
begin
Hint:=AHint;
Add('Var');
D:='A : '+ASource;
If Hint<>'' then
D:=D+' '+Hint;
Add(' '+D+';');
// Writeln(source.text);
ParseDeclarations;
AssertEquals('One variable definition',1,Declarations.Variables.Count);
AssertEquals('First declaration is type definition.',TPasVariable,TObject(Declarations.Variables[0]).ClassType);
Result:=TPasVariable(Declarations.Variables[0]);
AssertEquals('First declaration has correct name.','A',Result.Name);
FVar:=Result;
Definition:=Result;
if (Hint<>'') then
CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'h'+Hint)));
end;
procedure TTestVarParser.AssertVariableType(const ATypeName: String);
begin
AssertVariableType(TPasUnresolvedTypeRef);
AssertEquals('Correct unresolved type name',ATypeName,theVar.VarType.Name);
end;
procedure TTestVarParser.AssertVariableType(const AClass: TClass);
begin
AssertNotNull('Have variable type',theVar.VarType);
AssertEquals('Correct type class',AClass,theVar.VarType.ClassType);
end;
procedure TTestVarParser.AssertParseVarError(ASource: String);
begin
try
ParseVar(ASource,'');
Fail('Expected parser error');
except
// all OK.
end;
end;
procedure TTestVarParser.SetUp;
begin
inherited SetUp;
FHint:='';
FVar:=Nil;
end;
procedure TTestVarParser.TearDown;
begin
FVar:=Nil;
inherited TearDown;
end;
procedure TTestVarParser.TestSimpleVar;
begin
ParseVar('b','');
AssertVariableType('b');
end;
procedure TTestVarParser.TestSimpleVarDeprecated;
begin
ParseVar('b','deprecated');
AssertVariableType('b');
end;
procedure TTestVarParser.TestSimpleVarPlatform;
begin
ParseVar('b','platform');
AssertVariableType('b');
end;
procedure TTestVarParser.TestSimpleVarInitialized;
begin
ParseVar('b = 123','');
AssertVariableType('b');
AssertNotNull(TheVar.expr);
AssertExpression('Variable value',TheVar.expr,pekNumber,'123');
end;
procedure TTestVarParser.TestSimpleVarInitializedDeprecated;
begin
ParseVar('b = 123','deprecated');
AssertVariableType('b');
AssertNotNull(TheVar.expr);
AssertExpression('Variable value',TheVar.expr,pekNumber,'123');
end;
procedure TTestVarParser.TestSimpleVarInitializedPlatform;
begin
ParseVar('b = 123','platform');
AssertVariableType('b');
AssertNotNull(TheVar.expr);
AssertExpression('Variable value',TheVar.expr,pekNumber,'123');
end;
procedure TTestVarParser.TestVarProcedure;
begin
ParseVar('procedure','');
AssertVariableType(TPasProcedureType);
end;
procedure TTestVarParser.TestVarProcedureDeprecated;
begin
ParseVar('procedure','deprecated');
AssertVariableType(TPasProcedureType);
end;
procedure TTestVarParser.TestVarRecord;
Var
R : TPasRecordtype;
begin
ParseVar('record x,y : intger; end','');
AssertVariableType(TPasRecordType);
R:=TheVar.VarType as TPasRecordType;
AssertEquals('Correct number of fields',2,R.Members.Count);
end;
procedure TTestVarParser.TestVarRecordDeprecated;
Var
R : TPasRecordtype;
begin
ParseVar('record x,y : integer; end','deprecated');
AssertVariableType(TPasRecordType);
R:=TheVar.VarType as TPasRecordType;
AssertEquals('Correct number of fields',2,R.Members.Count);
end;
procedure TTestVarParser.TestVarRecordPlatform;
Var
R : TPasRecordtype;
begin
ParseVar('record x,y : integer; end','platform');
AssertVariableType(TPasRecordType);
R:=TheVar.VarType as TPasRecordType;
AssertEquals('Correct number of fields',2,R.Members.Count);
end;
procedure TTestVarParser.TestVarArray;
Var
R : TPasArrayType;
begin
ParseVar('Array[1..20] of integer','');
AssertVariableType(TPasArrayType);
R:=TheVar.VarType as TPasArrayType;
AssertNotNull('Correct array type name',R.ElType);
AssertEquals('Correct array type name',TPasunresolvedTypeRef,R.ElType.ClassType);
end;
procedure TTestVarParser.TestVarArrayDeprecated;
Var
R : TPasArrayType;
begin
ParseVar('Array[1..20] of integer','Deprecated');
AssertVariableType(TPasArrayType);
R:=TheVar.VarType as TPasArrayType;
AssertNotNull('Correct array type name',R.ElType);
AssertEquals('Correct array type name',TPasunresolvedTypeRef,R.ElType.ClassType);
end;
procedure TTestVarParser.TestVarDynArray;
Var
R : TPasArrayType;
begin
ParseVar('Array of integer','');
AssertVariableType(TPasArrayType);
R:=TheVar.VarType as TPasArrayType;
AssertEquals('No index','',R.IndexRange);
AssertNotNull('Correct array type name',R.ElType);
AssertEquals('Correct array type name',TPasunresolvedTypeRef,R.ElType.ClassType);
end;
procedure TTestVarParser.TestVarExternal;
begin
ParseVar('integer; external','');
AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
end;
procedure TTestVarParser.TestVarExternalLib;
begin
ParseVar('integer; external name ''mylib''','');
AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
AssertEquals('Library name','',TheVar.LibraryName);
AssertEquals('Library name','''mylib''',TheVar.ExportName);
end;
procedure TTestVarParser.TestVarExternalLibName;
begin
ParseVar('integer; external ''mylib'' name ''d''','');
AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
AssertEquals('Library name','''mylib''',TheVar.LibraryName);
AssertEquals('Library name','''d''',TheVar.ExportName);
end;
procedure TTestVarParser.TestVarCVar;
begin
ParseVar('integer; cvar','');
AssertEquals('Variable modifiers',[vmcvar],TheVar.VarModifiers);
end;
procedure TTestVarParser.TestVarCVarExternal;
begin
ParseVar('integer; cvar;external','');
AssertEquals('Variable modifiers',[vmcvar,vmexternal],TheVar.VarModifiers);
end;
procedure TTestVarParser.TestVarPublic;
begin
ParseVar('integer; public','');
AssertEquals('Variable modifiers',[vmpublic],TheVar.VarModifiers);
end;
procedure TTestVarParser.TestVarPublicName;
begin
ParseVar('integer; public name ''c''','');
AssertEquals('Variable modifiers',[vmpublic],TheVar.VarModifiers);
AssertEquals('Public export name','''c''',TheVar.ExportName);
end;
procedure TTestVarParser.TestVarDeprecatedExternalName;
begin
ParseVar('integer deprecated; external name ''me''','');
CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'hdeprecated')));
AssertEquals('Variable modifiers',[vmexternal],TheVar.VarModifiers);
AssertEquals('Library name','''me''',TheVar.ExportName);
end;
procedure TTestVarParser.TestVarHintPriorToInit;
Var
E : TBoolConstExpr;
begin
ParseVar('boolean platform = false','');
CheckHint(TPasMemberHint(Getenumvalue(typeinfo(TPasMemberHint),'hplatform')));
AssertNotNull('Correctly initialized',Thevar.Expr);
AssertEquals('Correctly initialized',TBoolConstExpr,Thevar.Expr.ClassType);
E:=Thevar.Expr as TBoolConstExpr;
AssertEquals('Correct initialization value',False, E.Value);
end;
initialization
RegisterTests([TTestVarParser]);
end.