mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 17:59:25 +02:00
3474 lines
124 KiB
ObjectPascal
3474 lines
124 KiB
ObjectPascal
unit tcparser;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, fpcunit, testregistry, jstoken, jsParser, jstree, jsbase;
|
|
|
|
type
|
|
|
|
{ TTestJSParser }
|
|
|
|
{ TTestBaseJSParser }
|
|
|
|
TTestBaseJSParser = class(TTestCase)
|
|
Private
|
|
FSource : TStringStream;
|
|
FParser : TJSParser;
|
|
FSE : TJSSourceElements;
|
|
FToFree: TJSElement;
|
|
protected
|
|
procedure SetUp; override;
|
|
procedure TearDown; override;
|
|
Procedure CreateParser(Const ASource : string; aVersion : TECMAVersion = TECMAVersion.ecma5; aIsTypeScript : Boolean = False);
|
|
Function CheckClass(E : TJSElement; C : TJSElementClass; Const aMsg : String = '') : TJSElement;
|
|
Function CheckClass(Const aMsg : String; aExpectedClass : TJSElementClass; aActual : TJSElement) : TJSElement;
|
|
Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSToken); overload;
|
|
Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSType); overload;
|
|
Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSVarType); overload;
|
|
Procedure AssertEquals(Const AMessage : String; Expected, Actual : TKeyOptionality); overload;
|
|
Procedure AssertIdentifier(Msg : String; El : TJSElement; Const AName : TJSString);
|
|
procedure AssertEquals(Const AMessage : String; aExpected : AnsiString; aActual : TJSString); overload;
|
|
Function GetSourceElements : TJSSourceElements;
|
|
Function GetVars : TJSElementNodes;
|
|
Function GetStatements : TJSElementNodes;
|
|
Function GetFunctions : TJSElementNodes;
|
|
Function GetFirstFunction : TJSFunctionDeclarationStatement;
|
|
Function GetClasses : TJSElementNodes;
|
|
Function GetFirstClass(isAmbient : Boolean = false) : TJSClassDeclaration;
|
|
Function GetFirstStatement : TJSElement;
|
|
Function GetFirstVar : TJSElement;
|
|
Function GetModules : TJSElementNodes;
|
|
Function GetFirstModule : TJSModuleDeclaration;
|
|
Function GetNameSpaces : TJSElementNodes;
|
|
Function GetFirstNameSpace : TJSNamespaceDeclaration;
|
|
Function GetTypes : TJSElementNodes;
|
|
Function GetFirstType : TJSTypeDeclaration;
|
|
Function GetEnums : TJSElementNodes;
|
|
Function GetFirstEnum: TJSEnumDeclaration;
|
|
Function GetExpressionStatement : TJSExpressionStatement;
|
|
Function GetInterfaces : TJSElementNodes;
|
|
Function GetFirstInterface : TJSInterfaceDeclaration;
|
|
end;
|
|
|
|
TTestJSParser= class(TTestBaseJSParser)
|
|
private
|
|
published
|
|
procedure TestEmpty;
|
|
procedure TestSimple;
|
|
procedure TestSimpleExpressionNumericalLiteral;
|
|
procedure TestSimpleExpressionStringLiteral;
|
|
procedure TestSimpleExpressionBooleanLiteralFalse;
|
|
procedure TestSimpleExpressionBooleanLiteralTrue;
|
|
procedure TestSimpleExpressionIdentifier;
|
|
procedure TestSimpleExpressionNull;
|
|
procedure TestAssignExpressionNumerical;
|
|
procedure TestAssignExpressionNull;
|
|
procedure TestAssignExpressionString;
|
|
procedure TestAssignExpressionBooleanFalse;
|
|
procedure TestAssignExpressionBooleanTrue;
|
|
procedure TestAssignExpressionIdent;
|
|
procedure TestAssignExpressionPlus;
|
|
procedure TestAssignExpressionMinus;
|
|
procedure TestAssignExpressionDiv;
|
|
procedure TestAssignExpressionMul;
|
|
procedure TestAssignExpressionMod;
|
|
procedure TestAssignExpressionAnd;
|
|
procedure TestAssignExpressionOr;
|
|
procedure TestAssignExpressionXOr;
|
|
procedure TestAssignExpressionLShift;
|
|
procedure TestAssignExpressionRShift;
|
|
procedure TestAssignExpressionURShift;
|
|
procedure TestExpressionPlus;
|
|
procedure TestExpressionSub;
|
|
procedure TestExpressionMul;
|
|
procedure TestExpressionDiv;
|
|
procedure TestExpressionMod;
|
|
procedure TestExpressionLShift;
|
|
procedure TestExpressionRShift;
|
|
procedure TestExpressionURShift;
|
|
procedure TestExpressionPostPlusPlus;
|
|
procedure TestExpressionPostMinusMinus;
|
|
procedure TestExpressionPreMinusMinus;
|
|
procedure TestExpressionPrePlusPlus;
|
|
procedure TestExpressionPrecedenceMulPlus;
|
|
procedure TestExpressionPrecedencePlusMul;
|
|
procedure TestExpressionPrecedenceMulMinus;
|
|
procedure TestExpressionPrecedenceMinusMul;
|
|
procedure TestExpressionPrecedenceDivPlus;
|
|
procedure TestExpressionPrecedencePlusDiv;
|
|
procedure TestExpressionPrecedenceModPlus;
|
|
procedure TestExpressionPrecedencePlusMod;
|
|
procedure TestExpressionPrecedencePlusPostPlusPlus;
|
|
procedure TestExpressionPrecedencePlusPostMinusMinus;
|
|
procedure TestExpressionPrecedenceMulPostMinusMinus;
|
|
procedure TestExpressionPrecedenceMulPostPlusPlus;
|
|
procedure TestExpressionPrecedenceMulPreMinusMinus;
|
|
procedure TestExpressionPrecedenceMulPrePlusPlus;
|
|
procedure TestExpressionPrecedencePlusPreMinusMinus;
|
|
procedure TestExpressionPrecedencePlusPrePlusPlus;
|
|
procedure TestExpressionPrecedencePlusInv;
|
|
procedure TestExpressionPrecedenceMulInv;
|
|
procedure TestExpressionPrecedenceMulNot;
|
|
procedure TestExpressionPrecedencePlusNot;
|
|
procedure TestExpressionPrecedenceBraceMulPlus;
|
|
procedure TestExpressionPrecedenceBracePlusMul;
|
|
procedure TestExpressionFunction;
|
|
procedure TestFunctionCallNoArgs;
|
|
procedure TestAwaitFunctionCallNoArgs;
|
|
procedure TestFunctionCallOneArg;
|
|
procedure TestFunctionCallTwoArgs;
|
|
procedure TestObjectGeneratorFunction;
|
|
procedure TestArrayExpressionNumericalArgs;
|
|
procedure TestArrayExpressionStringArgs;
|
|
procedure TestArrayExpressionIdentArgs;
|
|
Procedure TestVarDeclarationSimple;
|
|
Procedure TestVarDeclarationInit;
|
|
Procedure TestLetDeclarationSimple;
|
|
procedure TestVarDeclarationDouble;
|
|
procedure TestVarDeclarationSimpleInit;
|
|
procedure TestConstDeclarationSimpleInit;
|
|
procedure TestVarDeclarationDoubleInit;
|
|
procedure TestDebuggerStatement;
|
|
procedure TestBlockEmpty;
|
|
procedure TestBlockEmptyStatement;
|
|
procedure TestBlockSimpleStatement;
|
|
procedure TestFunctionDeclarationEmpty;
|
|
procedure TestFunctionDeclarationAsync;
|
|
procedure TestFunctionDeclarationWithArgs;
|
|
procedure TestFunctionDeclarationWithSpreadArgs;
|
|
procedure TestFunctionDeclarationWithBody;
|
|
procedure TestIfSimple;
|
|
procedure TestIfElseSimple;
|
|
procedure TestIfEmptyBlock;
|
|
procedure TestIfEmptyBlockElse;
|
|
procedure TestWhileSimple;
|
|
procedure TestWhileBlock;
|
|
procedure TestDoWhileSimple;
|
|
procedure TestDoWhileBlock;
|
|
procedure TestForEmpty;
|
|
procedure TestForEmptyBody;
|
|
procedure TestForSimpleBody;
|
|
procedure TestTryCatch;
|
|
procedure TestTryCatchFinally;
|
|
procedure TestTryFinally;
|
|
procedure TestThrow;
|
|
procedure TestReturn;
|
|
procedure TestAssignment;
|
|
procedure TestNew;
|
|
procedure TestLabeledStatement;
|
|
procedure TestContinue;
|
|
procedure TestContinueTarget;
|
|
procedure TestBreak;
|
|
procedure TestBreakTarget;
|
|
procedure TestSwitchEmpty;
|
|
procedure TestSwitchOne;
|
|
procedure TestSwitchTwo;
|
|
procedure TestSwitchTwoDefault;
|
|
Procedure TestImportModule;
|
|
Procedure TestImportImportedDefault;
|
|
Procedure TestImportNamespaceImport;
|
|
Procedure TestImportImportedDefaultAndNamespaceImport;
|
|
Procedure TestImportNamedImport;
|
|
Procedure TestImportNamedImportAlias;
|
|
Procedure TestImport2NamedImports;
|
|
Procedure TestImport2NamedImportAlias;
|
|
Procedure TestImport2NamedImportsComma;
|
|
Procedure TestImportDefaultAndNamedImport;
|
|
Procedure TestExportAll;
|
|
Procedure TestExportAllFrom;
|
|
Procedure TestExportExportNameFrom;
|
|
Procedure TestExportExportName;
|
|
Procedure TestExportExportNameAlias;
|
|
Procedure TestExportVar;
|
|
Procedure TestExportLet;
|
|
Procedure TestExportConst;
|
|
Procedure TestExportFunction;
|
|
Procedure TestExportDefaultAssignment;
|
|
Procedure TestExportDefaultFunction;
|
|
Procedure TestExportDefaultAsyncFunction;
|
|
Procedure TestClass;
|
|
Procedure TestClassExtends;
|
|
Procedure TestClassWithMethod;
|
|
procedure TestClassExpression;
|
|
procedure TestLetClassExpression;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses typinfo;
|
|
|
|
{ ----------------------------------------------------------------------
|
|
TTestBaseJSParser
|
|
----------------------------------------------------------------------}
|
|
|
|
procedure TTestBaseJSParser.SetUp;
|
|
begin
|
|
FParser:=Nil;
|
|
FSource:=Nil;
|
|
end;
|
|
|
|
procedure TTestBaseJSParser.TearDown;
|
|
begin
|
|
FreeAndNil(FToFree);
|
|
FreeAndNil(FParser);
|
|
FReeAndNil(FSource);
|
|
end;
|
|
|
|
Procedure TTestBaseJSParser.CreateParser(Const ASource: string; aVersion : TECMAVersion = TECMAVersion.ecma5; aIsTypeScript : Boolean = False);
|
|
begin
|
|
FSource:=TStringStream.Create(ASource);
|
|
FParser:=TJSParser.Create(FSource,aVersion,aIsTypescript);
|
|
end;
|
|
|
|
function TTestBaseJSParser.CheckClass(E: TJSElement; C: TJSElementClass; const aMsg: String): TJSElement;
|
|
begin
|
|
AssertNotNull(aMsg+': Not null element',E);
|
|
AssertNotNull(aMsg+': Not null class',C);
|
|
AssertEquals(aMsg,C,E.ClassType);
|
|
Result:=E;
|
|
end;
|
|
|
|
function TTestBaseJSParser.CheckClass(const aMsg: String; aExpectedClass: TJSElementClass; aActual: TJSElement): TJSElement;
|
|
begin
|
|
Result:=CheckClass(aActual,aExpectedClass,aMsg);
|
|
end;
|
|
|
|
procedure TTestBaseJSParser.AssertEquals(const AMessage: String; Expected, Actual: TJSToken);
|
|
Var
|
|
NE,NA : String;
|
|
|
|
begin
|
|
NE:=GetEnumName(TypeInfo(TJSToken),Ord(Expected));
|
|
NA:=GetEnumName(TypeInfo(TJSToken),Ord(Actual));
|
|
AssertEquals(AMessage,NE,NA);
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetSourceElements: TJSSourceElements;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
FB : TJSFunctionBody;
|
|
|
|
begin
|
|
If Not Assigned(FSE) then
|
|
begin
|
|
AssertNotNull('Parser assigned',FParser);
|
|
E:=FParser.Parse;
|
|
CheckClass(E,TJSFunctionBody);
|
|
FB:=TJSFunctionBody(E);
|
|
AssertNotNull(FB.A);
|
|
CheckClass(FB.A,TJSSourceElements);
|
|
FSE:=TJSSourceElements(FB.A);
|
|
FToFree:=E;
|
|
end;
|
|
Result:=FSE;
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetVars: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Vars;
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetStatements: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Statements;
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetFunctions: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Functions;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstFunction: TJSFunctionDeclarationStatement;
|
|
Var
|
|
aFunctions : TJSElementNodes;
|
|
|
|
begin
|
|
aFunctions:=GetFunctions;
|
|
AssertTrue('Have functions ',aFunctions.Count>0);
|
|
AssertNotNull('have first function node',aFunctions.Nodes[0].Node);
|
|
AssertEquals('First function node is function declaration',TJSFunctionDeclarationStatement,aFunctions.Nodes[0].Node.ClassType);
|
|
Result:=TJSFunctionDeclarationStatement(aFunctions.Nodes[0].Node);
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetClasses: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Classes;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstClass(isAmbient : Boolean = false): TJSClassDeclaration;
|
|
|
|
Var
|
|
aClasses : TJSElementNodes;
|
|
|
|
begin
|
|
aClasses:=GetClasses;
|
|
AssertTrue('Have classes ',aClasses.Count>0);
|
|
AssertNotNull('have first class node',aClasses.Nodes[0].Node);
|
|
if IsAmbient then
|
|
AssertEquals('First class node is ambientclass declaration',TJSAmbientClassDeclaration,aClasses.Nodes[0].Node.ClassType)
|
|
else
|
|
AssertEquals('First class node is class declaration',TJSClassDeclaration,aClasses.Nodes[0].Node.ClassType);
|
|
Result:=TJSClassDeclaration(aClasses.Nodes[0].Node);
|
|
end;
|
|
|
|
Procedure TTestBaseJSParser.AssertEquals(Const AMessage: String; Expected,
|
|
Actual: TJSType);
|
|
|
|
Var
|
|
NE,NA : String;
|
|
|
|
begin
|
|
NE:=GetEnumName(TypeInfo(TJSType),Ord(Expected));
|
|
NA:=GetEnumName(TypeInfo(TJSType),Ord(Actual));
|
|
AssertEquals(AMessage,NE,NA);
|
|
end;
|
|
|
|
procedure TTestBaseJSParser.AssertEquals(const AMessage: String; Expected, Actual: TJSVarType);
|
|
|
|
Var
|
|
NE,NA : String;
|
|
|
|
begin
|
|
NE:=GetEnumName(TypeInfo(TJSVarType),Ord(Expected));
|
|
NA:=GetEnumName(TypeInfo(TJSVarType),Ord(Actual));
|
|
AssertEquals(AMessage,NE,NA);
|
|
end;
|
|
|
|
procedure TTestBaseJSParser.AssertEquals(const AMessage: String; Expected, Actual: TKeyOptionality);
|
|
Var
|
|
NE,NA : String;
|
|
|
|
begin
|
|
NE:=GetEnumName(TypeInfo(TKeyOptionality),Ord(Expected));
|
|
NA:=GetEnumName(TypeInfo(TKeyOptionality),Ord(Actual));
|
|
AssertEquals(AMessage,NE,NA);
|
|
end;
|
|
|
|
Procedure TTestBaseJSParser.AssertIdentifier(Msg: String; El: TJSElement;
|
|
Const AName: TJSString);
|
|
|
|
Var
|
|
L : TJSPrimaryExpressionIdent;
|
|
S1,S2 : TJSString;
|
|
begin
|
|
AssertNotNull(Msg+' have TJSPrimaryExpressionIdent element',El);
|
|
CheckClass(El,TJSPrimaryExpressionIdent);
|
|
L:=TJSPrimaryExpressionIdent(el);
|
|
S1:=L.Name;
|
|
S2:=Aname;
|
|
AssertEquals(Msg+'Identifier has correct name',S2,S1);
|
|
end;
|
|
|
|
procedure TTestBaseJSParser.AssertEquals(const AMessage: String; aExpected: AnsiString; aActual: TJSString);
|
|
begin
|
|
AssertEquals(AMessage,UTF8Decode(aExpected),aActual);
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetFirstStatement: TJSElement;
|
|
|
|
Var
|
|
E : TJSElementNodes;
|
|
begin
|
|
E:=GetStatements;
|
|
AssertNotNull('Have statements',E);
|
|
AssertTrue('1 statement',1<=E.Count);
|
|
Result:=E.Nodes[0].Node;
|
|
AssertNotNull('First statement assigned',Result);
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetFirstVar: TJSElement;
|
|
Var
|
|
E : TJSElementNodes;
|
|
begin
|
|
E:=GetVars;
|
|
AssertNotNull('Have statements',E);
|
|
// Writeln('Count : ',E.Count);
|
|
If (E.Count=0) then
|
|
Fail('Zero variables defined');
|
|
Result:=E.Nodes[0].Node;
|
|
AssertNotNull('First variable declaration',Result);
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetModules: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Modules;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstModule: TJSModuleDeclaration;
|
|
Var
|
|
E : TJSElementNodes;
|
|
|
|
begin
|
|
E:=GetModules;
|
|
AssertNotNull('Have modules',E);
|
|
AssertEquals('1 statement',1,E.Count);
|
|
AssertEquals('First module node is module declaration',TJSModuleDeclaration,E.Nodes[0].Node.ClassType);
|
|
Result:=E.Nodes[0].Node as TJSModuleDeclaration;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetNameSpaces: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.NameSpaces;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstNameSpace: TJSNamespaceDeclaration;
|
|
|
|
Var
|
|
E : TJSElementNodes;
|
|
|
|
begin
|
|
E:=GetNameSpaces;
|
|
AssertNotNull('Have namespaces',E);
|
|
AssertEquals('1 namespace',1,E.Count);
|
|
AssertEquals('First module node is namespace declaration',TJSNamespaceDeclaration,E.Nodes[0].Node.ClassType);
|
|
Result:=E.Nodes[0].Node as TJSNamespaceDeclaration;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetTypes: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Types;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstType: TJSTypeDeclaration;
|
|
Var
|
|
E : TJSElementNodes;
|
|
|
|
begin
|
|
E:=GetTypes;
|
|
AssertNotNull('Have types',E);
|
|
AssertEquals('1 type',1,E.Count);
|
|
AssertEquals('First type node is type declaration',TJSTypeDeclaration,E.Nodes[0].Node.ClassType);
|
|
Result:=(E.Nodes[0].Node as TJSTypeDeclaration);
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetEnums: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Enums;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstEnum: TJSEnumDeclaration;
|
|
Var
|
|
E : TJSElementNodes;
|
|
|
|
begin
|
|
E:=GetEnums;
|
|
AssertNotNull('Have enums',E);
|
|
AssertEquals('1 type',1,E.Count);
|
|
AssertEquals('First type node is enum declaration',TJSEnumDeclaration,E.Nodes[0].Node.ClassType);
|
|
Result:=(E.Nodes[0].Node as TJSEnumDeclaration);
|
|
end;
|
|
|
|
Function TTestBaseJSParser.GetExpressionStatement: TJSExpressionStatement;
|
|
|
|
Var
|
|
N : TJSElement;
|
|
begin
|
|
N:=GetFirstStatement;
|
|
CheckClass(N,TJSExpressionStatement);
|
|
Result:=TJSExpressionStatement(N);
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetInterfaces: TJSElementNodes;
|
|
begin
|
|
Result:=GetSourceElements.Interfaces;
|
|
end;
|
|
|
|
function TTestBaseJSParser.GetFirstInterface: TJSInterfaceDeclaration;
|
|
Var
|
|
E : TJSElementNodes;
|
|
|
|
begin
|
|
E:=GetInterfaces;
|
|
AssertNotNull('Have interfaces',E);
|
|
AssertEquals('1 interfaces',1,E.Count);
|
|
AssertEquals('First interface node is interface declaration',TJSInterfaceDeclaration,E.Nodes[0].Node.ClassType);
|
|
Result:=(E.Nodes[0].Node as TJSInterfaceDeclaration);
|
|
end;
|
|
|
|
|
|
|
|
{ ----------------------------------------------------------------------
|
|
TTestJSParser
|
|
----------------------------------------------------------------------}
|
|
|
|
|
|
|
|
|
|
|
|
procedure TTestJSParser.TestSimple;
|
|
|
|
Var
|
|
E : TJSElementNodes;
|
|
N : TJSElement;
|
|
X : TJSExpressionStatement;
|
|
|
|
begin
|
|
CreateParser('1;');
|
|
E:=GetStatements;
|
|
AssertNotNull('Have statements',E);
|
|
AssertEquals('1 statement',1,E.Count);
|
|
N:=E.Nodes[0].Node;
|
|
AssertNotNull('First statement assigned',N);
|
|
AssertNotNull('First statement assigned',N);
|
|
CheckClass(N,TJSExpressionStatement);
|
|
X:=TJSExpressionStatement(N);
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLiteral);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSimpleExpressionNumericalLiteral;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
|
|
begin
|
|
CreateParser('1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLiteral);
|
|
AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(X.A).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0,TJSLiteral(X.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSimpleExpressionStringLiteral;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
|
|
begin
|
|
CreateParser('"string";');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLiteral);
|
|
AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
|
|
AssertEquals('Expression value type correct', jstString,TJSLiteral(X.A).Value.ValueType);
|
|
AssertEquals('Expression value correct', 'string',TJSLiteral(X.A).Value.AsString);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSimpleExpressionBooleanLiteralFalse;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
|
|
begin
|
|
CreateParser('false;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLiteral);
|
|
AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
|
|
AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(X.A).Value.ValueType);
|
|
AssertEquals('Expression value correct', False, TJSLiteral(X.A).Value.AsBoolean);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSimpleExpressionIdentifier;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
|
|
begin
|
|
CreateParser('Something;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression value assigned','Something',TJSPrimaryExpressionIdent(X.A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSimpleExpressionNull;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
begin
|
|
CreateParser('null;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLiteral);
|
|
AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
|
|
AssertEquals('Expression value type correct', jstNull,TJSLiteral(X.A).Value.ValueType);
|
|
AssertEquals('Expression value correct', True, TJSLiteral(X.A).Value.IsNull);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionNumerical;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionString;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a="string";');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstString,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 'string', TJSLiteral(SA.Expr).Value.AsString);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionBooleanFalse;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a=false;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', False, TJSLiteral(SA.Expr).Value.AsBoolean);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionBooleanTrue;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a=true;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', True, TJSLiteral(SA.Expr).Value.AsBoolean);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionNull;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a=null;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNull,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', True, TJSLiteral(SA.Expr).Value.IsNull);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionIdent;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a=b;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression value type correct', 'b',TJSPrimaryExpressionIdent(SA.Expr).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSAddEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a+=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAddEqAssignStatement);
|
|
SA:=TJSAddEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionMinus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSubEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a-=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSubEqAssignStatement);
|
|
SA:=TJSSubEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionMul;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSMulEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a*=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMulEqAssignStatement);
|
|
SA:=TJSMulEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionDiv;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSDivEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a/=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSDivEqAssignStatement);
|
|
SA:=TJSDivEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionMod;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSModEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a%=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSModEqAssignStatement);
|
|
SA:=TJSModEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionAnd;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSAndEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a&=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAndEqAssignStatement);
|
|
SA:=TJSAndEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionOr;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSOrEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a|=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSOrEqAssignStatement);
|
|
SA:=TJSOrEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionXOr;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSXOrEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a^=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSXOrEqAssignStatement);
|
|
SA:=TJSXOrEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionLShift;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSLShiftEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a<<=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLShiftEqAssignStatement);
|
|
SA:=TJSLShiftEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionRShift;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSRShiftEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a>>=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSRShiftEqAssignStatement);
|
|
SA:=TJSRShiftEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignExpressionURShift;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSURShiftEqAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a>>>=1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSURShiftEqAssignStatement);
|
|
SA:=TJSURShiftEqAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
CheckClass(SA.EXPR,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('1+2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionSub;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionMinus;
|
|
|
|
begin
|
|
CreateParser('1 - 2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionMinus);
|
|
E:=TJSAdditiveExpressionMinus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionMul;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('1*2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionDiv;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSMultiplicativeExpressionDiv;
|
|
|
|
begin
|
|
CreateParser('1/2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionDiv);
|
|
E:=TJSMultiplicativeExpressionDiv(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionMod;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSMultiplicativeExpressionMod;
|
|
|
|
begin
|
|
CreateParser('1%2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMod);
|
|
E:=TJSMultiplicativeExpressionMod(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionLShift;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSLShiftExpression;
|
|
|
|
begin
|
|
CreateParser('1 << 2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLShiftExpression);
|
|
E:=TJSLShiftExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionRShift;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSRShiftExpression;
|
|
|
|
begin
|
|
CreateParser('1 >> 2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSRShiftExpression);
|
|
E:=TJSRShiftExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionURShift;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSURShiftExpression;
|
|
|
|
begin
|
|
CreateParser('1 >>> 2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSURShiftExpression);
|
|
E:=TJSURShiftExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPostPlusPlus;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSUnaryPostPlusPlusExpression;
|
|
|
|
begin
|
|
CreateParser('1++;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSUnaryPostPlusPlusExpression);
|
|
E:=TJSUnaryPostPlusPlusExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Expression operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPostMinusMinus;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSUnaryPostMinusMinusExpression;
|
|
|
|
begin
|
|
CreateParser('1--;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSUnaryPostMinusMinusExpression);
|
|
E:=TJSUnaryPostMinusMinusExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Expression operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrePlusPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSUnaryPrePlusPlusExpression;
|
|
|
|
begin
|
|
CreateParser('++1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSUnaryPrePlusPlusExpression);
|
|
E:=TJSUnaryPrePlusPlusExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Expression operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
|
|
procedure TTestJSParser.TestExpressionPreMinusMinus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSUnaryPreMinusMinusExpression;
|
|
|
|
begin
|
|
CreateParser('--1;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSUnaryPreMinusMinusExpression);
|
|
E:=TJSUnaryPreMinusMinusExpression(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Expression operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
R : TJSMultiplicativeExpressionMul;
|
|
begin
|
|
CreateParser('2 * 3 + 4;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSMultiplicativeExpressionMul);
|
|
R:=TJSMultiplicativeExpressionMul(E.A);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
AssertNotNull('Multiplication right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceBraceMulPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
R : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('2 * (3 + 4);');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSAdditiveExpressionPlus);
|
|
R:=TJSAdditiveExpressionPlus(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
AssertNotNull('Multiplication right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(E.A).Value.AsNumber);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(R.B).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(R.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceBracePlusMul;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
R : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('(3 + 4)*2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSAdditiveExpressionPlus);
|
|
R:=TJSAdditiveExpressionPlus(E.A);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
AssertNotNull('Multiplication right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(E.B).Value.AsNumber);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(R.B).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(R.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionFunction;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
A : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a = function () {};');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
A:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Have left operand',A.LHS);
|
|
CheckClass(A.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Correct name for assignment LHS ','a',TJSPrimaryExpressionIdent(A.LHS).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusMul;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
R : TJSMultiplicativeExpressionMul;
|
|
begin
|
|
CreateParser('4 + 2 * 3;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSMultiplicativeExpressionMul);
|
|
R:=TJSMultiplicativeExpressionMul(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
AssertNotNull('Multiplication right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulMinus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionMinus;
|
|
R : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('2 * 3 - 4;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionMinus);
|
|
E:=TJSAdditiveExpressionMinus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSMultiplicativeExpressionMul);
|
|
R:=TJSMultiplicativeExpressionMul(E.A);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
AssertNotNull('Multiplication right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('subtraction right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('subtraction right operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('subtraction right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMinusMul;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionMinus;
|
|
R : TJSMultiplicativeExpressionMul;
|
|
begin
|
|
CreateParser('4 - 2 * 3;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionMinus);
|
|
E:=TJSAdditiveExpressionMinus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSMultiplicativeExpressionMul);
|
|
R:=TJSMultiplicativeExpressionMul(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
AssertNotNull('Multiplication right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Subtraction left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Subtraction left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Subtraction left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceDivPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
R : TJSMultiplicativeExpressionDiv;
|
|
begin
|
|
CreateParser('2 / 3 + 4;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSMultiplicativeExpressionDiv);
|
|
R:=TJSMultiplicativeExpressionDiv(E.A);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('Div left operand assigned',R.A);
|
|
AssertNotNull('Div right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Div left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Div left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Div right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Div right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Addition right operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusDiv;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
R : TJSMultiplicativeExpressionDiv;
|
|
|
|
begin
|
|
CreateParser('4 + 2 / 3;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSMultiplicativeExpressionDiv);
|
|
R:=TJSMultiplicativeExpressionDiv(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Div left operand assigned',R.A);
|
|
AssertNotNull('Div right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Div left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Div left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Div right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Div right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceModPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
R : TJSMultiplicativeExpressionMod;
|
|
begin
|
|
CreateParser('2 % 3 + 4;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.A,TJSMultiplicativeExpressionMod);
|
|
R:=TJSMultiplicativeExpressionMod(E.A);
|
|
CheckClass(E.B,TJSLiteral);
|
|
AssertNotNull('mod left operand assigned',R.A);
|
|
AssertNotNull('mod right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('mod left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('mod left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('mod right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('mod right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.B).Value);
|
|
AssertEquals('Addition right operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
|
|
AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusMod;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
E : TJSAdditiveExpressionPlus;
|
|
R : TJSMultiplicativeExpressionMod;
|
|
|
|
begin
|
|
CreateParser('4 + 2 % 3;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSMultiplicativeExpressionMod);
|
|
R:=TJSMultiplicativeExpressionMod(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Mod left operand assigned',R.A);
|
|
AssertNotNull('Mod right operand assigned',R.B);
|
|
CheckClass(R.A,TJSLiteral);
|
|
CheckClass(R.B,TJSLiteral);
|
|
AssertEquals('Mod left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Mod left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertEquals('Mod right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
|
|
AssertEquals('Mod right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusPostPlusPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPostPlusPlusExpression;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('4 + 2++;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPostPlusPlusExpression);
|
|
R:=TJSUnaryPostPlusPlusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('++ operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('++ operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('++ operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusPostMinusMinus;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPostMinusMinusExpression;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('4 + 2--;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPostMinusMinusExpression);
|
|
R:=TJSUnaryPostMinusMinusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('-- operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('-- operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('-- operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulPostPlusPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPostPlusPlusExpression;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('4 * 2++;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPostPlusPlusExpression);
|
|
R:=TJSUnaryPostPlusPlusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('++operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('++ operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('++ operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulPostMinusMinus;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPostMinusMinusExpression;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('4 * 2--;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPostMinusMinusExpression);
|
|
R:=TJSUnaryPostMinusMinusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('-- operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('-- operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('-- operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusPrePlusPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPrePlusPlusExpression;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('4 + ++2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPrePlusPlusExpression);
|
|
R:=TJSUnaryPrePlusPlusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('++ operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('++ operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusInv;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryInvExpression;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('4 + ~2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryInvExpression);
|
|
R:=TJSUnaryInvExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('inv operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('inv operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulInv;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryInvExpression;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('4 * ~2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryInvExpression);
|
|
R:=TJSUnaryInvExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('Inv operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Inv operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusNot;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryNotExpression;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('4 + !2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryNotExpression);
|
|
R:=TJSUnaryNotExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('Not operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Not operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionCallNoArgs;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
C : TJSCallExpression;
|
|
|
|
begin
|
|
CreateParser('abc();');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSCallExpression);
|
|
C:=TJSCallExpression(X.A);
|
|
AssertEquals('No arguments',0,C.Args.Elements.Count);
|
|
AssertNotNull('Call function expression',C.Expr);
|
|
CheckClass(C.Expr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAwaitFunctionCallNoArgs;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
W : TJSAwaitExpression;
|
|
C : TJSCallExpression;
|
|
|
|
begin
|
|
CreateParser('await abc();',MinAwaitVersion);
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSAwaitExpression);
|
|
W:=TJSAwaitExpression(X.A);
|
|
CheckClass(W.A,TJSCallExpression);
|
|
C:=TJSCallExpression(W.A);
|
|
AssertEquals('No arguments',0,C.Args.Elements.Count);
|
|
AssertNotNull('Call function expression',C.Expr);
|
|
CheckClass(C.Expr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
|
|
end;
|
|
|
|
|
|
procedure TTestJSParser.TestFunctionCallOneArg;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
C : TJSCallExpression;
|
|
E : TJSelement;
|
|
|
|
begin
|
|
CreateParser('abc(d);');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSCallExpression);
|
|
C:=TJSCallExpression(X.A);
|
|
AssertNotNull('Call function expression',C.Expr);
|
|
CheckClass(C.Expr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
|
|
AssertEquals('1 argument',1,C.Args.Elements.Count);
|
|
E:=C.Args.Elements[0].Expr;
|
|
AssertNotNull('First argument expression',E);
|
|
CheckClass(E,TJSPrimaryExpressionIdent);
|
|
AssertEquals('First argument name correct','d',TJSPrimaryExpressionIdent(E).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionCallTwoArgs;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
C : TJSCallExpression;
|
|
E : TJSelement;
|
|
|
|
begin
|
|
CreateParser('abc(d,e);');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSCallExpression);
|
|
C:=TJSCallExpression(X.A);
|
|
AssertNotNull('Call function expression',C.Expr);
|
|
CheckClass(C.Expr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
|
|
AssertEquals('2 arguments',2,C.Args.Elements.Count);
|
|
E:=C.Args.Elements[0].Expr;
|
|
AssertNotNull('First argument expression',E);
|
|
CheckClass(E,TJSPrimaryExpressionIdent);
|
|
AssertEquals('First argument name correct','d',TJSPrimaryExpressionIdent(E).Name);
|
|
E:=C.Args.Elements[1].Expr;
|
|
AssertNotNull('Second argument expression',E);
|
|
CheckClass(E,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Second argument name correct','e',TJSPrimaryExpressionIdent(E).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestObjectGeneratorFunction;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
SA : TJSSimpleAssignStatement;
|
|
Obj : TJSObjectLiteral;
|
|
|
|
begin
|
|
CreateParser('a = {* g() { } };',MinGeneratorVersion);
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
SA:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Assignment LHS assigned',SA.LHS);
|
|
CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
|
|
AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
AssertEquals('Assignment Expression assigned',TJSObjectLiteral,SA.Expr.ClassType);
|
|
Obj:=TJSObjectLiteral(SA.Expr);
|
|
AssertEquals('Object element count',1,Obj.Elements.Count);
|
|
AssertEquals('Object element name','g',Obj.Elements[0].Name);
|
|
AssertEquals('Object element expression',TJSFunctionDeclarationStatement,Obj.Elements[0].Expr.ClassType);
|
|
AssertTrue('Generator',TJSFunctionDeclarationStatement(Obj.Elements[0].Expr).IsGenerator);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestArrayExpressionNumericalArgs;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
B : TJSBracketMemberExpression;
|
|
|
|
begin
|
|
CreateParser('A[1];');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSBracketMemberExpression);
|
|
B:=TJSBracketMemberExpression(X.A);
|
|
CheckClass(B.Name,TJSLiteral);
|
|
AssertEquals('Member name operand type correct', jstNumber, TJSLiteral(B.Name).Value.ValueType);
|
|
AssertEquals('Member name operand value correct', 1.0, TJSLiteral(B.Name).Value.AsNumber);
|
|
CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestArrayExpressionStringArgs;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
B : TJSBracketMemberExpression;
|
|
|
|
begin
|
|
CreateParser('A["propname"];');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSBracketMemberExpression);
|
|
B:=TJSBracketMemberExpression(X.A);
|
|
CheckClass(B.Name,TJSLiteral);
|
|
AssertEquals('Member name operand type correct', jstString, TJSLiteral(B.Name).Value.ValueType);
|
|
AssertEquals('Member name operand value correct', 'propname', TJSLiteral(B.Name).Value.AsString);
|
|
CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestArrayExpressionIdentArgs;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
B : TJSBracketMemberExpression;
|
|
|
|
begin
|
|
CreateParser('A[B];');
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSBracketMemberExpression);
|
|
B:=TJSBracketMemberExpression(X.A);
|
|
CheckClass(B.Name,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Member name identifier correct', 'B', TJSPrimaryExpressionIdent(B.Name).Name);
|
|
CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
|
|
end;
|
|
|
|
Procedure TTestJSParser.TestVarDeclarationSimple;
|
|
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
begin
|
|
CreateParser('var a;');
|
|
X:=GetFirstVar;
|
|
AssertNotNull('Variable statement assigned',(X));
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
AssertEquals('correct variable type', vtVar, V.VarType);
|
|
AssertEquals('variable name correct registered', 'a', V.Name);
|
|
AssertNull('No initialization expression', V.Init);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestVarDeclarationInit;
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
begin
|
|
CreateParser('var a = 0;');
|
|
X:=GetFirstVar;
|
|
AssertNotNull('Variable statement assigned',(X));
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
AssertEquals('correct variable type', vtVar, V.VarType);
|
|
AssertEquals('variable name correct registered', 'a', V.Name);
|
|
AssertNotNull('initialization expression', V.Init);
|
|
CheckClass(V.Init,TJSLiteral);
|
|
AssertEquals('Init value correct', 0, TJSLiteral(V.init).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestLetDeclarationSimple;
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
begin
|
|
CreateParser('let a;',minLetVersion);
|
|
X:=GetFirstVar;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
AssertEquals('correct variable type', vtLet, V.VarType);
|
|
// AssertNotNull('Variable statement assigned',(X));
|
|
AssertEquals('variable name correct registered', 'a', V.Name);
|
|
AssertNull('No initialization expression', V.Init);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestVarDeclarationDouble;
|
|
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
|
|
begin
|
|
CreateParser('var a, b ;');
|
|
AssertEquals('2 variables declared',2,GetVars.Count);
|
|
X:=GetFirstVar;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
AssertEquals('correct variable type', vtVar, V.VarType);
|
|
// AssertNotNull('Variable statement assigned',(X));
|
|
AssertEquals('variable name correct registered', 'a', V.name);
|
|
X:=GetVars.Nodes[1].Node;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
AssertEquals('correct variable type', vtVar, V.VarType);
|
|
AssertEquals('variable name correct registered', 'b', V.Name);
|
|
AssertNull('No initialization expression', V.Init);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestVarDeclarationSimpleInit;
|
|
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
begin
|
|
CreateParser('var a = b;');
|
|
X:=GetFirstVar;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
// AssertNotNull('Variable statement assigned',(X));
|
|
AssertEquals('variable name correct registered', 'a', V.Name);
|
|
AssertNotNull('Initialization expression present', V.Init);
|
|
CheckClass(V.Init,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Member name identifier correct', 'b', TJSPrimaryExpressionIdent(V.init).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestConstDeclarationSimpleInit;
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
begin
|
|
CreateParser('const a = 1;',MinLetVersion);
|
|
X:=GetFirstVar;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
// AssertNotNull('Variable statement assigned',(X));
|
|
AssertEquals('variable name correct registered', 'a', V.Name);
|
|
AssertNotNull('Initialization expression present', V.Init);
|
|
CheckClass(V.Init,TJSLiteral);
|
|
AssertEquals('Expression value type correct', jstNumber,TJSLiteral(V.Init).Value.ValueType);
|
|
AssertEquals('Expression value correct', 1.0, TJSLiteral(V.Init).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestVarDeclarationDoubleInit;
|
|
|
|
Var
|
|
X : TJSELement;
|
|
V : TJSVarDeclaration;
|
|
begin
|
|
CreateParser('var a, c = b;');
|
|
AssertEquals('2 variables declared',2,GetVars.Count);
|
|
X:=GetFirstVar;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
// AssertNotNull('Variable statement assigned',(X));
|
|
AssertEquals('variable name correct registered', 'a', V.Name);
|
|
AssertNull('No initialization expression', V.Init);
|
|
X:=GetVars.Nodes[1].Node;
|
|
CheckClass(X,TJSVarDeclaration);
|
|
V:=TJSVarDeclaration(X);
|
|
AssertEquals('variable name correct registered', 'c', V.Name);
|
|
AssertNotNull('No initialization expression', V.Init);
|
|
CheckClass(V.Init,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Member name identifier correct', 'b', TJSPrimaryExpressionIdent(V.init).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestDebuggerStatement;
|
|
Var
|
|
E : TJSSourceElements;
|
|
X : TJSElement;
|
|
|
|
begin
|
|
CreateParser('debugger',MinDebuggerVersion);
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 statement in block',1,E.Statements.Count);
|
|
X:=E.Statements.Nodes[0].Node;
|
|
CheckClass(X,TJSDebuggerStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestBlockEmpty;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
X : TJSElement;
|
|
|
|
begin
|
|
CreateParser('{}');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 statement in block',1,E.Statements.Count);
|
|
X:=E.Statements.Nodes[0].Node;
|
|
CheckClass(X,TJSEmptyBlockStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestBlockEmptyStatement;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
X : TJSElement;
|
|
|
|
begin
|
|
CreateParser('{;}');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 statement in block',1,E.Statements.Count);
|
|
X:=E.Statements.Nodes[0].Node;
|
|
CheckClass(X,TJSEmptyStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestBlockSimpleStatement;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
X : TJSElement;
|
|
|
|
begin
|
|
CreateParser('{a;}');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 statement in block',1,E.Statements.Count);
|
|
X:=E.Statements.Nodes[0].Node;
|
|
CheckClass(X,TJSExpressionStatement);
|
|
CheckNotNull(TJSExpressionStatement(X).A);
|
|
CheckClass(TJSExpressionStatement(X).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name','a',TJSPrimaryExpressionIdent(TJSExpressionStatement(X).A).Name)
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionDeclarationEmpty;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
N : TJSElement;
|
|
FD : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('function a () {}');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 function defined',1,E.functions.Count);
|
|
N:=E.Functions.Nodes[0].Node;
|
|
AssertNotNull('Function element defined ',N);
|
|
CheckClass(N,TJSFunctionDeclarationStatement);
|
|
FD:=TJSFunctionDeclarationStatement(N);
|
|
AssertNotNull('Function definition assigned',FD.AFunction);
|
|
AssertFalse('Async function ',FD.AFunction.IsAsync);
|
|
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
AssertEquals('No parameters',0,FD.AFunction.TypedParams.Count);
|
|
N:=FD.AFunction.Body;
|
|
CheckClass(N,TJSFunctionBody);
|
|
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
|
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
|
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
|
AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
|
|
// TJSEmptyBlockStatement
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionDeclarationAsync;
|
|
Var
|
|
E : TJSSourceElements;
|
|
N : TJSElement;
|
|
FD : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('async function a () {}',MinAsyncVersion);
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 function defined',1,E.functions.Count);
|
|
N:=E.Functions.Nodes[0].Node;
|
|
AssertNotNull('Function element defined ',N);
|
|
CheckClass(N,TJSFunctionDeclarationStatement);
|
|
FD:=TJSFunctionDeclarationStatement(N);
|
|
AssertNotNull('Function definition assigned',FD.AFunction);
|
|
AssertTrue('Async function ',FD.AFunction.IsAsync);
|
|
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
AssertEquals('No parameters',0,FD.AFunction.TypedParams.Count);
|
|
N:=FD.AFunction.Body;
|
|
CheckClass(N,TJSFunctionBody);
|
|
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
|
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
|
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
|
AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionDeclarationWithArgs;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
N : TJSElement;
|
|
FD : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('function a (b,c) {}');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 function defined',1,E.functions.Count);
|
|
N:=E.Functions.Nodes[0].Node;
|
|
AssertNotNull('Function element defined ',N);
|
|
CheckClass(N,TJSFunctionDeclarationStatement);
|
|
FD:=TJSFunctionDeclarationStatement(N);
|
|
AssertNotNull('Function definition assigned',FD.AFunction);
|
|
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
AssertEquals('2 parameters',2,FD.AFunction.TypedParams.Count);
|
|
AssertEquals('1st parameter','b',FD.AFunction.TypedParams[0].Name);
|
|
AssertEquals('2nd parameter','c',FD.AFunction.TypedParams[1].Name);
|
|
N:=FD.AFunction.Body;
|
|
CheckClass(N,TJSFunctionBody);
|
|
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
|
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
|
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
|
AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
|
|
// TJSEmptyBlockStatement
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionDeclarationWithSpreadArgs;
|
|
Var
|
|
E : TJSSourceElements;
|
|
N : TJSElement;
|
|
FD : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('function a (...b,c) {}');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 function defined',1,E.functions.Count);
|
|
N:=E.Functions.Nodes[0].Node;
|
|
AssertNotNull('Function element defined ',N);
|
|
CheckClass(N,TJSFunctionDeclarationStatement);
|
|
FD:=TJSFunctionDeclarationStatement(N);
|
|
AssertNotNull('Function definition assigned',FD.AFunction);
|
|
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
AssertEquals('2 parameters',2,FD.AFunction.TypedParams.Count);
|
|
AssertEquals('1st parameter','b',FD.AFunction.TypedParams[0].Name);
|
|
AssertEquals('1st parameter','b',FD.AFunction.TypedParams.Names[0]);
|
|
AssertTrue('1st parameter spread',FD.AFunction.TypedParams.Params[0].IsSpread);
|
|
AssertEquals('2nd parameter','c',FD.AFunction.TypedParams[1].Name);
|
|
N:=FD.AFunction.Body;
|
|
CheckClass(N,TJSFunctionBody);
|
|
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
|
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
|
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
|
AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
|
|
// TJSEmptyBlockStatement
|
|
end;
|
|
|
|
procedure TTestJSParser.TestFunctionDeclarationWithBody;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
N : TJSElement;
|
|
FD : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('function a () { b; }');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 function defined',1,E.functions.Count);
|
|
N:=E.Functions.Nodes[0].Node;
|
|
AssertNotNull('Function element defined ',N);
|
|
CheckClass(N,TJSFunctionDeclarationStatement);
|
|
FD:=TJSFunctionDeclarationStatement(N);
|
|
AssertNotNull('Function definition assigned',FD.AFunction);
|
|
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
AssertEquals('2 parameters',0,FD.AFunction.TypedParams.Count);
|
|
N:=FD.AFunction.Body;
|
|
CheckClass(N,TJSFunctionBody);
|
|
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
|
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
|
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
|
AssertEquals('1 statement in functionbody elements',1,E.Statements.Count);
|
|
N:=E.Statements.Nodes[0].Node;
|
|
CheckClass(N,TJSExpressionStatement);
|
|
CheckNotNull(TJSExpressionStatement(N).A);
|
|
CheckClass(TJSExpressionStatement(N).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(N).A).Name);
|
|
// TJSEmptyBlockStatement
|
|
end;
|
|
|
|
procedure TTestJSParser.TestIfSimple;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
I : TJSIfStatement;
|
|
|
|
begin
|
|
CreateParser('if (a) b;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSIfStatement);
|
|
I:=TJSIfStatement(E);
|
|
AssertNotNull('Statement condition assigned',I.Cond);
|
|
CheckClass(I.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(I.Cond).Name);
|
|
AssertNull('Statement false branch assigned',I.BFalse);
|
|
AssertNotNull('Statement true branch assigned',I.Btrue);
|
|
CheckClass(I.Btrue,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(I.BTrue).A);
|
|
CheckClass(TJSExpressionStatement(I.BTrue).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 2','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.Btrue).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestIfEmptyBlock;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
I : TJSIfStatement;
|
|
|
|
begin
|
|
CreateParser('if (a) {}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSIfStatement);
|
|
I:=TJSIfStatement(E);
|
|
AssertNotNull('Statement condition assigned',I.Cond);
|
|
CheckClass(I.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(I.Cond).Name);
|
|
AssertNull('Statement false branch assigned',I.BFalse);
|
|
AssertNotNull('Statement true branch assigned',I.Btrue);
|
|
CheckClass(I.Btrue,TJSEmptyBlockStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestIfEmptyBlockElse;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
I : TJSIfStatement;
|
|
|
|
begin
|
|
CreateParser('if (a) {} else b;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSIfStatement);
|
|
I:=TJSIfStatement(E);
|
|
AssertNotNull('Statement condition assigned',I.Cond);
|
|
CheckClass(I.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(I.Cond).Name);
|
|
AssertNotNull('Statement false branch assigned',I.BFalse);
|
|
AssertNotNull('Statement true branch assigned',I.Btrue);
|
|
CheckClass(I.Btrue,TJSEmptyBlockStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestWhileSimple;
|
|
Var
|
|
E : TJSElement;
|
|
W : TJSWhileStatement;
|
|
|
|
begin
|
|
CreateParser('while (a) b;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSWhileStatement);
|
|
W:=TJSWhileStatement(E);
|
|
AssertNotNull('Statement condition assigned',W.Cond);
|
|
CheckClass(W.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(W.Cond).Name);
|
|
AssertNotNull('Statement condition assigned',W.body);
|
|
CheckClass(W.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
|
|
CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestWhileBlock;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
W : TJSWhileStatement;
|
|
// B : TJSBlockStatement;
|
|
|
|
begin
|
|
CreateParser('while (a) {b;}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSWhileStatement);
|
|
W:=TJSWhileStatement(E);
|
|
AssertNotNull('Statement condition assigned',W.Cond);
|
|
CheckClass(W.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(W.Cond).Name);
|
|
AssertNotNull('Statement condition assigned',W.body);
|
|
CheckClass(W.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
|
|
CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestDoWhileSimple;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
W : TJSDoWhileStatement;
|
|
// B : TJSBlockStatement;
|
|
|
|
begin
|
|
CreateParser('do b; while (a);');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSDoWhileStatement);
|
|
W:=TJSDoWhileStatement(E);
|
|
AssertNotNull('Statement condition assigned',W.Cond);
|
|
CheckClass(W.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(W.Cond).Name);
|
|
AssertNotNull('Statement condition assigned',W.body);
|
|
CheckClass(W.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
|
|
CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestDoWhileBlock;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
W : TJSDoWhileStatement;
|
|
// B : TJSBlockStatement;
|
|
|
|
begin
|
|
CreateParser('do {b;} while (a);');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSDoWhileStatement);
|
|
W:=TJSDoWhileStatement(E);
|
|
AssertNotNull('Statement condition assigned',W.Cond);
|
|
CheckClass(W.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(W.Cond).Name);
|
|
AssertNotNull('Statement condition assigned',W.body);
|
|
CheckClass(W.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
|
|
CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestForEmpty;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
F : TJSForStatement;
|
|
|
|
begin
|
|
CreateParser('for (;;) a;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSForStatement);
|
|
F:=TJSForStatement(E);
|
|
AssertNull('Statement condition not assigned',F.Cond);
|
|
AssertNull('Statement init not assigned',F.Init);
|
|
AssertNull('Statement step not assigned',F.Incr);
|
|
CheckClass(F.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
|
|
CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestForEmptyBody;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
F : TJSForStatement;
|
|
|
|
begin
|
|
CreateParser('for (;;) {a;}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSForStatement);
|
|
F:=TJSForStatement(E);
|
|
AssertNull('Statement condition not assigned',F.Cond);
|
|
AssertNull('Statement init not assigned',F.Init);
|
|
AssertNull('Statement step not assigned',F.Incr);
|
|
CheckClass(F.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
|
|
CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestForSimpleBody;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
F : TJSForStatement;
|
|
|
|
begin
|
|
CreateParser('for (a;b;c) {d;}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSForStatement);
|
|
F:=TJSForStatement(E);
|
|
AssertNotNull('Statement condition not assigned',F.Cond);
|
|
AssertNotNull('Statement init not assigned',F.Init);
|
|
AssertNotNull('Statement step not assigned',F.Incr);
|
|
CheckClass(F.Init,TJSPrimaryExpressionIdent);
|
|
AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Init));
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(F.Init).Name);
|
|
CheckClass(F.Incr,TJSPrimaryExpressionIdent);
|
|
AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Incr));
|
|
AssertEquals('Name 2','c',TJSPrimaryExpressionIdent(F.Incr).Name);
|
|
CheckClass(F.Cond,TJSPrimaryExpressionIdent);
|
|
AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Cond));
|
|
AssertEquals('Name 3','b',TJSPrimaryExpressionIdent(F.cond).Name);
|
|
CheckClass(F.Body,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
|
|
CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 4','d',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestTryCatch;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
T : TJSTryCatchStatement;
|
|
|
|
begin
|
|
CreateParser('try {a;} catch (e) {b;}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSTryCatchStatement);
|
|
T:=TJSTryCatchStatement(E);
|
|
CheckClass(T.Block,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(T.Block).A);
|
|
CheckClass(TJSExpressionStatement(T.Block).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).Name);
|
|
CheckClass(T.BCatch,TJSExpressionStatement);
|
|
AssertEquals('Except object identifier name','e',T.Ident);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BCatch).A);
|
|
CheckClass(TJSExpressionStatement(T.BCatch).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 2','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BCatch).A).Name);
|
|
AssertNull('No Finally expression',T.BFinally);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestTryCatchFinally;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
T : TJSTryCatchFinallyStatement;
|
|
|
|
begin
|
|
CreateParser('try {a;} catch (e) {b;} finally {c;}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSTryCatchFinallyStatement);
|
|
T:=TJSTryCatchFinallyStatement(E);
|
|
CheckClass(T.Block,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(T.Block).A);
|
|
CheckClass(TJSExpressionStatement(T.Block).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).Name);
|
|
AssertEquals('Except object identifier name','e',T.Ident);
|
|
CheckClass(T.BCatch,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BCatch).A);
|
|
CheckClass(TJSExpressionStatement(T.BCatch).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 2','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BCatch).A).Name);
|
|
AssertNotNull('Finally expression',T.BFinally);
|
|
CheckClass(T.BFinally,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BFinally).A);
|
|
CheckClass(TJSExpressionStatement(T.BFinally).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 3','c',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BFinally).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestTryFinally;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
T : TJSTryFinallyStatement;
|
|
|
|
begin
|
|
CreateParser('try {a;} finally {c;}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSTryFinallyStatement);
|
|
T:=TJSTryFinallyStatement(E);
|
|
CheckClass(T.Block,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(T.Block).A);
|
|
CheckClass(TJSExpressionStatement(T.Block).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).Name);
|
|
AssertNull('No catch',T.BCatch);
|
|
AssertNotNull('Finally expression',T.BFinally);
|
|
AssertNotNull('Finally expression',TJSExpressionStatement(T.BFinally).A);
|
|
CheckClass(TJSExpressionStatement(T.BFinally).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 2','c',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BFinally).A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestThrow;
|
|
Var
|
|
E : TJSElement;
|
|
T : TJSThrowStatement;
|
|
|
|
begin
|
|
CreateParser('throw a;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSThrowStatement);
|
|
T:=TJSThrowStatement(E);
|
|
AssertNotNull('Have throw object',T.A);
|
|
CheckClass(T.A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Correct identifier','a',TJSPrimaryExpressionIdent(T.A).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestReturn;
|
|
|
|
Var
|
|
E : TJSSourceElements;
|
|
N : TJSElement;
|
|
FD : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('function a () { return b; }');
|
|
E:=GetSourceElements;
|
|
AssertEquals('1 function defined',1,E.functions.Count);
|
|
N:=E.Functions.Nodes[0].Node;
|
|
AssertNotNull('Function element defined ',N);
|
|
CheckClass(N,TJSFunctionDeclarationStatement);
|
|
FD:=TJSFunctionDeclarationStatement(N);
|
|
AssertNotNull('Function definition assigned',FD.AFunction);
|
|
AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
AssertEquals('No parameters',0,FD.AFunction.TypedParams.Count);
|
|
N:=FD.AFunction.Body;
|
|
CheckClass(N,TJSFunctionBody);
|
|
AssertNotNull('Function body has element',TJSFunctionBody(N).A);
|
|
CheckClass(TJSFunctionBody(N).A, TJSSourceElements);
|
|
E:=TJSSourceElements(TJSFunctionBody(N).A);
|
|
AssertEquals('1 statement in functionbody elements',1,E.Statements.Count);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestAssignment;
|
|
Var
|
|
E : TJSElement;
|
|
ES : TJSExpressionStatement;
|
|
A : TJSSimpleAssignStatement;
|
|
|
|
begin
|
|
CreateParser('a=b;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExpressionStatement);
|
|
ES:=TJSExpressionStatement(E);
|
|
CheckClass(ES.A,TJSSimpleAssignStatement);
|
|
A:=TJSSimpleAssignStatement(ES.A);
|
|
AssertNotNull('Have LHS',A.LHS);
|
|
CheckClass(A.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
|
|
CheckClass(A.Expr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Have RHS name','b',TJSPrimaryExpressionIdent(A.Expr).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestNew;
|
|
Var
|
|
E : TJSElement;
|
|
ES : TJSExpressionStatement;
|
|
A : TJSSimpleAssignStatement;
|
|
N : TJSNewMemberExpression;
|
|
L : TJSLiteral;
|
|
|
|
begin
|
|
CreateParser('a = new b(123)');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExpressionStatement);
|
|
ES:=TJSExpressionStatement(E);
|
|
CheckClass(ES.A,TJSSimpleAssignStatement);
|
|
A:=TJSSimpleAssignStatement(ES.A);
|
|
CheckClass(A.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
|
|
CheckClass(A.Expr,TJSNewMemberExpression);
|
|
N:=TJSNewMemberExpression(A.Expr);
|
|
AssertNotNull('Have LHS name',N.Mexpr);
|
|
CheckClass(N.Mexpr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Have LHS name','b',TJSPrimaryExpressionIdent(N.Mexpr).Name);
|
|
AssertNotNull('Have arguments',N.Args);
|
|
AssertEquals('One argument',1,N.Args.Elements.Count);
|
|
AssertNotNull('Have argument 0',N.Args.Elements[0].Expr);
|
|
CheckClass(N.Args.Elements[0].Expr,TJSLiteral);
|
|
L:=TJSLiteral(N.Args.Elements[0].Expr);
|
|
AssertNotNull('Expression value assigned',L.Value);
|
|
AssertEquals('Expression value type correct', jstNumber,L.Value.ValueType);
|
|
AssertEquals('Expression value correct', 123,L.Value.AsNumber);
|
|
|
|
end;
|
|
|
|
procedure TTestJSParser.TestLabeledStatement;
|
|
Var
|
|
E : TJSElement;
|
|
ES : TJSExpressionStatement;
|
|
A : TJSSimpleAssignStatement;
|
|
N : TJSNewMemberExpression;
|
|
L : TJSLiteral;
|
|
LS : TJSLabeledStatement;
|
|
|
|
begin
|
|
CreateParser('loc: a = new b(123)');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSLabeledStatement);
|
|
LS:=TJSLabeledStatement(E);
|
|
AssertNotNull('Have label',LS.TheLabel);
|
|
AssertEquals('Have correct label','loc',LS.TheLabel.Name);
|
|
CheckClass(LS.A,TJSExpressionStatement);
|
|
ES:=TJSExpressionStatement(LS.A);
|
|
CheckClass(ES.A,TJSSimpleAssignStatement);
|
|
A:=TJSSimpleAssignStatement(ES.A);
|
|
CheckClass(A.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
|
|
CheckClass(A.Expr,TJSNewMemberExpression);
|
|
N:=TJSNewMemberExpression(A.Expr);
|
|
AssertNotNull('Have LHS name',N.Mexpr);
|
|
CheckClass(N.Mexpr,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Have LHS name','b',TJSPrimaryExpressionIdent(N.Mexpr).Name);
|
|
AssertNotNull('Have arguments',N.Args);
|
|
AssertEquals('One argument',1,N.Args.Elements.Count);
|
|
AssertNotNull('Have argument 0',N.Args.Elements[0].Expr);
|
|
CheckClass(N.Args.Elements[0].Expr,TJSLiteral);
|
|
L:=TJSLiteral(N.Args.Elements[0].Expr);
|
|
AssertNotNull('Expression value assigned',L.Value);
|
|
AssertEquals('Expression value type correct', jstNumber,L.Value.ValueType);
|
|
AssertEquals('Expression value correct', 123,L.Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestContinue;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
C : TJSContinueStatement;
|
|
|
|
begin
|
|
CreateParser('while (true) continue;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSWhileStatement);
|
|
E:=TJSWhileStatement(E).Body;
|
|
CheckClass(E,TJSContinueStatement);
|
|
C:=TJSContinueStatement(E);
|
|
AssertEquals('Have correct (empty) label','',C.TargetName);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestContinueTarget;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
C : TJSContinueStatement;
|
|
|
|
begin
|
|
CreateParser('a: while (true) continue a;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSLabeledStatement);
|
|
E:=TJSLabeledStatement(E).A;
|
|
CheckClass(E,TJSWhileStatement);
|
|
E:=TJSWhileStatement(E).Body;
|
|
CheckClass(E,TJSContinueStatement);
|
|
C:=TJSContinueStatement(E);
|
|
AssertEquals('Have correct label','a',C.TargetName);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestBreakTarget;
|
|
Var
|
|
E : TJSElement;
|
|
C : TJSBreakStatement;
|
|
|
|
begin
|
|
CreateParser('a: while (true) break a;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSLabeledStatement);
|
|
E:=TJSLabeledStatement(E).A;
|
|
CheckClass(E,TJSWhileStatement);
|
|
E:=TJSWhileStatement(E).Body;
|
|
CheckClass(E,TJSBreakStatement);
|
|
C:=TJSBreakStatement(E);
|
|
AssertEquals('Have correct label','a',C.TargetName);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSwitchEmpty;
|
|
Var
|
|
E : TJSElement;
|
|
S : TJSSwitchStatement;
|
|
begin
|
|
CreateParser('switch (a) {}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSSwitchStatement);
|
|
S:=TJSSwitchStatement(E);
|
|
AssertNotNull('Have condition',S.Cond);
|
|
AssertNull('Have no default',S.TheDefault);
|
|
AssertIdentifier('Case condition',S.Cond,'a');
|
|
S:=TJSSwitchStatement(E);
|
|
AssertEquals('No cases',0,S.Cases.Count)
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSwitchOne;
|
|
Var
|
|
E : TJSElement;
|
|
S : TJSSwitchStatement;
|
|
C : TJSCaseElement;
|
|
begin
|
|
CreateParser('switch (a) { case c : {}}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSSwitchStatement);
|
|
S:=TJSSwitchStatement(E);
|
|
AssertNotNull('Have condition',S.Cond);
|
|
AssertNull('Have no default',S.TheDefault);
|
|
AssertIdentifier('Case condition',S.Cond,'a');
|
|
S:=TJSSwitchStatement(E);
|
|
AssertEquals('1 case',1,S.Cases.Count);
|
|
C:=TJSCaseElement(S.Cases[0]);
|
|
AssertIdentifier('Case expression',C.Expr,'c');
|
|
CheckClass(C.Body,TJSEmptyBlockStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSwitchTwo;
|
|
Var
|
|
E : TJSElement;
|
|
S : TJSSwitchStatement;
|
|
C : TJSCaseElement;
|
|
begin
|
|
CreateParser('switch (a) { case c: {}'+sLineBreak+' case d: {}}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSSwitchStatement);
|
|
S:=TJSSwitchStatement(E);
|
|
AssertNotNull('Have condition',S.Cond);
|
|
AssertNull('Have no default',S.TheDefault);
|
|
AssertIdentifier('Case condition',S.Cond,'a');
|
|
S:=TJSSwitchStatement(E);
|
|
AssertEquals('2 cases',2,S.Cases.Count);
|
|
C:=TJSCaseElement(S.Cases[0]);
|
|
AssertIdentifier('Case expression',C.Expr,'c');
|
|
CheckClass(C.Body,TJSEmptyBlockStatement);
|
|
C:=TJSCaseElement(S.Cases[1]);
|
|
AssertIdentifier('Case expression',C.Expr,'d');
|
|
CheckClass(C.Body,TJSEmptyBlockStatement);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSwitchTwoDefault;
|
|
Var
|
|
E : TJSElement;
|
|
S : TJSSwitchStatement;
|
|
C : TJSCaseElement;
|
|
begin
|
|
CreateParser('switch (a) { case c: {} case d: {} default: {}}');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSSwitchStatement);
|
|
S:=TJSSwitchStatement(E);
|
|
AssertNotNull('Have condition',S.Cond);
|
|
AssertNotNull('Have default',S.TheDefault);
|
|
AssertIdentifier('Case condition',S.Cond,'a');
|
|
S:=TJSSwitchStatement(E);
|
|
AssertEquals('2 cases',3,S.Cases.Count);
|
|
C:=TJSCaseElement(S.Cases[0]);
|
|
AssertIdentifier('Case expression',C.Expr,'c');
|
|
CheckClass(C.Body,TJSEmptyBlockStatement);
|
|
C:=TJSCaseElement(S.Cases[1]);
|
|
AssertIdentifier('Case expression',C.Expr,'d');
|
|
CheckClass(C.Body,TJSEmptyBlockStatement);
|
|
C:=TJSCaseElement(S.Cases[2]);
|
|
CheckClass(C.Body,TJSEmptyBlockStatement);
|
|
AssertSame('Default',C,S.TheDefault);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportModule;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
|
|
begin
|
|
CreateParser('import "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertFalse('Named imports',Imp.HaveNamedImports);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportImportedDefault;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
|
|
begin
|
|
CreateParser('import A from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','A',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertFalse('Named imports',Imp.HaveNamedImports);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportNamespaceImport;
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
|
|
begin
|
|
CreateParser('import * as A from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','A',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertFalse('Named imports',Imp.HaveNamedImports);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportImportedDefaultAndNamespaceImport;
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
|
|
begin
|
|
CreateParser('import A, * as B from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','A',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','B',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertFalse('Named imports',Imp.HaveNamedImports);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportNamedImport;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
NamedImp : TJSNamedImportElement;
|
|
|
|
begin
|
|
CreateParser('import {A} from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertTrue('Named imports',Imp.HaveNamedImports);
|
|
AssertEquals('Named import count',1,Imp.NamedImports.Count);
|
|
NamedImp:=Imp.NamedImports[0];
|
|
AssertEquals('Named import name','A',NamedImp.Name);
|
|
AssertEquals('Named import alias','',NamedImp.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportNamedImportAlias;
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
NamedImp : TJSNamedImportElement;
|
|
|
|
begin
|
|
CreateParser('import {A as C} from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertTrue('Named imports',Imp.HaveNamedImports);
|
|
AssertEquals('Named import count',1,Imp.NamedImports.Count);
|
|
NamedImp:=Imp.NamedImports[0];
|
|
AssertEquals('Named import name','A',NamedImp.Name);
|
|
AssertEquals('Named import alias','C',NamedImp.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImport2NamedImports;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
NamedImp : TJSNamedImportElement;
|
|
|
|
begin
|
|
CreateParser('import {A, B} from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertTrue('Named imports',Imp.HaveNamedImports);
|
|
AssertEquals('Named import count',2,Imp.NamedImports.Count);
|
|
NamedImp:=Imp.NamedImports[0];
|
|
AssertEquals('Named import name 1','A',NamedImp.Name);
|
|
AssertEquals('Named import alias 1','',NamedImp.Alias);
|
|
NamedImp:=Imp.NamedImports[1];
|
|
AssertEquals('Named import name 2','B',NamedImp.Name);
|
|
AssertEquals('Named import alias 2','',NamedImp.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImport2NamedImportAlias;
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
NamedImp : TJSNamedImportElement;
|
|
|
|
begin
|
|
CreateParser('import {A as C, B as D} from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertTrue('Named imports',Imp.HaveNamedImports);
|
|
AssertEquals('Named import count',2,Imp.NamedImports.Count);
|
|
NamedImp:=Imp.NamedImports[0];
|
|
AssertEquals('Named import name 1','A',NamedImp.Name);
|
|
AssertEquals('Named import alias 1','C',NamedImp.Alias);
|
|
NamedImp:=Imp.NamedImports[1];
|
|
AssertEquals('Named import name 2','B',NamedImp.Name);
|
|
AssertEquals('Named import alias 2','D',NamedImp.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImport2NamedImportsComma;
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
NamedImp : TJSNamedImportElement;
|
|
|
|
begin
|
|
CreateParser('import {A, B, } from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertTrue('Named imports',Imp.HaveNamedImports);
|
|
AssertEquals('Named import count',2,Imp.NamedImports.Count);
|
|
NamedImp:=Imp.NamedImports[0];
|
|
AssertEquals('Named import name 1','A',NamedImp.Name);
|
|
AssertEquals('Named import alias 1','',NamedImp.Alias);
|
|
NamedImp:=Imp.NamedImports[1];
|
|
AssertEquals('Named import name 2','B',NamedImp.Name);
|
|
AssertEquals('Named import alias 2','',NamedImp.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestImportDefaultAndNamedImport;
|
|
Var
|
|
E : TJSElement;
|
|
Imp : TJSImportStatement absolute E;
|
|
NamedImp : TJSNamedImportElement;
|
|
|
|
begin
|
|
CreateParser('import D, {A} from "a.js"',MinImportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSImportStatement);
|
|
AssertEquals('DefaultImportedName','D',Imp.DefaultBinding);
|
|
AssertEquals('NamespaceImport','',Imp.NameSpaceImport);
|
|
AssertEquals('Modulename','a.js',Imp.ModuleName);
|
|
AssertTrue('Named imports',Imp.HaveNamedImports);
|
|
AssertEquals('Named import count',1,Imp.NamedImports.Count);
|
|
NamedImp:=Imp.NamedImports[0];
|
|
AssertEquals('Named import name','A',NamedImp.Name);
|
|
AssertEquals('Named import alias','',NamedImp.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportAll;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
|
|
begin
|
|
CreateParser('export *',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','*',Exp.NameSpaceExport);
|
|
AssertNull('Declaration',Exp.Declaration);
|
|
AssertEquals('ModuleName','',Exp.ModuleName);
|
|
AssertFalse('ExportNames',Exp.HaveExportNames);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportAllFrom;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
|
|
begin
|
|
CreateParser('export * from "a.js"',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','*',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNull('Declaration',Exp.Declaration);
|
|
AssertEquals('ModuleName','a.js',Exp.ModuleName);
|
|
AssertFalse('ExportNames',Exp.HaveExportNames);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportExportName;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
El : TJSExportNameElement;
|
|
|
|
begin
|
|
CreateParser('export { a }',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNull('Declaration',Exp.Declaration);
|
|
AssertEquals('ModuleName','',Exp.ModuleName);
|
|
AssertTrue('ExportNames',Exp.HaveExportNames);
|
|
AssertEquals('ExportNames count',1,Exp.ExportNames.Count);
|
|
El:=Exp.ExportNames[0];
|
|
AssertEquals('ExportNames[0].Name','a',El.Name);
|
|
AssertEquals('ExportNames[0].Name','',El.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportExportNameAlias;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
El : TJSExportNameElement;
|
|
|
|
begin
|
|
CreateParser('export { a as b }',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNull('Declaration',Exp.Declaration);
|
|
AssertEquals('ModuleName','',Exp.ModuleName);
|
|
AssertTrue('ExportNames',Exp.HaveExportNames);
|
|
AssertEquals('ExportNames count',1,Exp.ExportNames.Count);
|
|
El:=Exp.ExportNames[0];
|
|
AssertEquals('ExportNames[0].Name','a',El.Name);
|
|
AssertEquals('ExportNames[0].Name','b',El.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportVar;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
V : TJSVariableStatement;
|
|
|
|
begin
|
|
CreateParser('export var a = 1',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSVariableStatement);
|
|
V:=TJSVariableStatement(Exp.Declaration);
|
|
AssertEquals('var type',vtVar,V.varType);
|
|
CheckClass(V.VarDecl,TJSVarDeclaration);
|
|
AssertEquals('Variable name','a',TJSVarDeclaration(V.VarDecl).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportLet;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
V : TJSVariableStatement;
|
|
|
|
begin
|
|
CreateParser('export let a = 1',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSVariableStatement);
|
|
V:=TJSVariableStatement(Exp.Declaration);
|
|
AssertEquals('var type',vtLet,V.varType);
|
|
CheckClass(V.VarDecl,TJSVarDeclaration);
|
|
AssertEquals('Variable name','a',TJSVarDeclaration(V.VarDecl).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportConst;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
V : TJSVariableStatement;
|
|
|
|
begin
|
|
CreateParser('export const a = 1',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSVariableStatement);
|
|
V:=TJSVariableStatement(Exp.Declaration);
|
|
AssertEquals('var type',vtConst,V.varType);
|
|
CheckClass(V.VarDecl,TJSVarDeclaration);
|
|
AssertEquals('Variable name','a',TJSVarDeclaration(V.VarDecl).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportFunction;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
F : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('export function a () { return 1; } ',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertFalse('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSFunctionDeclarationStatement);
|
|
F:=TJSFunctionDeclarationStatement(Exp.Declaration);
|
|
AssertNotNull('Have function', F.AFunction);
|
|
AssertEquals('Variable name','a',F.AFunction.Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportDefaultAssignment;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
A : TJSAssignStatement;
|
|
|
|
begin
|
|
CreateParser('export default a = 1',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertTrue('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSSimpleAssignStatement);
|
|
A:=TJSSimpleAssignStatement(Exp.Declaration);
|
|
CheckClass(A.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Operator token',jstoken.tjsASSIGN,A.OperatorToken);
|
|
AssertEquals('Variable name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportDefaultFunction;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
F : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('export default function a () { return 1; } ',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertTrue('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSFunctionDeclarationStatement);
|
|
F:=TJSFunctionDeclarationStatement(Exp.Declaration);
|
|
AssertNotNull('Have function', F.AFunction);
|
|
AssertEquals('Variable name','a',F.AFunction.Name);
|
|
AssertFalse('Async',F.AFunction.IsAsync);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExportDefaultAsyncFunction;
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
F : TJSFunctionDeclarationStatement;
|
|
|
|
begin
|
|
CreateParser('export default async function a () { return 1; } ',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertTrue('Default',Exp.IsDefault);
|
|
AssertNotNull('Declaration',Exp.Declaration);
|
|
CheckClass(Exp.Declaration,TJSFunctionDeclarationStatement);
|
|
F:=TJSFunctionDeclarationStatement(Exp.Declaration);
|
|
AssertNotNull('Have function', F.AFunction);
|
|
AssertEquals('Variable name','a',F.AFunction.Name);
|
|
AssertTrue('Async',F.AFunction.IsAsync);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestClass;
|
|
begin
|
|
CreateParser('class Rectangle { } ',MinClassVersion);
|
|
AssertEquals('class name correct','Rectangle',GetFirstClass.Name);
|
|
AssertNull('class extends name correct',GetFirstClass.Extends);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestClassExtends;
|
|
|
|
Var
|
|
Ext: TJSTypeReference;
|
|
|
|
begin
|
|
CreateParser('class Rectangle extends Shape { function myMethod () { return null; } } ',MinClassVersion);
|
|
AssertEquals('class name correct','Rectangle',GetFirstClass.Name);
|
|
Ext:=TJSTypeReference(CheckClass('Extends is type ref',TJSTypeReference,GetFirstClass.Extends));
|
|
AssertEquals('class extends name correct','Shape',Ext.Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestClassWithMethod;
|
|
begin
|
|
CreateParser('class Rectangle { function myMethod () { return null; } } ',MinClassVersion);
|
|
AssertEquals('class name correct','Rectangle',GetFirstClass.Name);
|
|
AssertNull('class extends name correct',GetFirstClass.Extends);
|
|
AssertNotNull('Have members',GetFirstClass.Members);
|
|
AssertEquals('Have functions',1,GetFirstClass.Members.Functions.Count);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestClassExpression;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
A : TJSSimpleAssignStatement;
|
|
begin
|
|
CreateParser('a = class Rectangle { } ',MinClassVersion);
|
|
X:=GetExpressionStatement;
|
|
CheckClass(X.A,TJSSimpleAssignStatement);
|
|
A:=TJSSimpleAssignStatement(X.A);
|
|
AssertNotNull('Have left operand',A.LHS);
|
|
CheckClass(A.LHS,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Correct name for assignment LHS ','a',TJSPrimaryExpressionIdent(A.LHS).Name);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestLetClassExpression;
|
|
Var
|
|
aVars : TJSVariableStatement;
|
|
aVarDecl : TJSVarDeclaration;
|
|
aClass : TJSClassDeclaration;
|
|
begin
|
|
CreateParser('let a = class Rectangle { } ',MinClassVersion);
|
|
AssertEquals('class name correct',TJSVariableStatement, GetFirstStatement.ClassType);
|
|
aVars:=TJSVariableStatement(GetFirstStatement);
|
|
AssertEquals('First class node is var declaration',TJSVarDeclaration,aVars.VarDecl.ClassType);
|
|
aVarDecl:=TJSVarDeclaration(aVars.VarDecl);
|
|
AssertNotNull('Var declaration has init',aVarDecl.Init);
|
|
AssertEquals('Init is class declaration',TJSClassDeclaration,aVarDecl.Init.ClassType);
|
|
aClass:=TJSClassDeclaration(aVarDecl.Init);
|
|
AssertEquals('class name correct','Rectangle',aClass.Name);
|
|
end;
|
|
|
|
|
|
procedure TTestJSParser.TestExportExportNameFrom;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
Exp : TJSExportStatement absolute E;
|
|
El : TJSExportNameElement;
|
|
|
|
begin
|
|
CreateParser('export { a } from "a.js"',MinExportVersion);
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSExportStatement);
|
|
AssertEquals('NameSpaceExport','',Exp.NameSpaceExport);
|
|
AssertNull('Declaration',Exp.Declaration);
|
|
AssertEquals('ModuleName','a.js',Exp.ModuleName);
|
|
AssertTrue('ExportNames',Exp.HaveExportNames);
|
|
AssertEquals('ExportNames count',1,Exp.ExportNames.Count);
|
|
El:=Exp.ExportNames[0];
|
|
AssertEquals('ExportNames[0].Name','a',El.Name);
|
|
AssertEquals('ExportNames[0].Name','',El.Alias);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestBreak;
|
|
Var
|
|
E : TJSElement;
|
|
C : TJSBreakStatement;
|
|
|
|
begin
|
|
CreateParser('while (true) break;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSWhileStatement);
|
|
E:=TJSWhileStatement(E).Body;
|
|
CheckClass(E,TJSBreakStatement);
|
|
C:=TJSBreakStatement(E);
|
|
AssertEquals('Have correct (empty) label','',C.TargetName);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestIfElseSimple;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
I : TJSIfStatement;
|
|
|
|
begin
|
|
CreateParser('if (a) b; else c;');
|
|
E:=GetFirstStatement;
|
|
CheckClass(E,TJSIfStatement);
|
|
I:=TJSIfStatement(E);
|
|
AssertNotNull('Statement condition assigned',I.Cond);
|
|
CheckClass(I.Cond,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','a',TJSPrimaryExpressionIdent(I.Cond).Name);
|
|
AssertNotNull('Statement condition assigned',I.Btrue);
|
|
CheckClass(I.Btrue,TJSExpressionStatement);
|
|
AssertNotNull('Expression statement expression',TJSExpressionStatement(I.BTrue).A);
|
|
CheckClass(TJSExpressionStatement(I.BTrue).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','b',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.Btrue).A).Name);
|
|
AssertNotNull('Else Statement condition assigned',I.BFalse);
|
|
CheckClass(I.BFalse,TJSExpressionStatement);
|
|
AssertNotNull('Else statement expression',TJSExpressionStatement(I.BFalse).A);
|
|
CheckClass(TJSExpressionStatement(I.BFalse).A,TJSPrimaryExpressionIdent);
|
|
AssertEquals('Name 1','c',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.BFalse).A).Name);
|
|
end;
|
|
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulNot;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryNotExpression;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('4 * !2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryNotExpression);
|
|
R:=TJSUnaryNotExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('Not operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Not operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedencePlusPreMinusMinus;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPreMinusMinusExpression;
|
|
E : TJSAdditiveExpressionPlus;
|
|
|
|
begin
|
|
CreateParser('4 + --2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSAdditiveExpressionPlus);
|
|
E:=TJSAdditiveExpressionPlus(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPreMinusMinusExpression);
|
|
R:=TJSUnaryPreMinusMinusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulPrePlusPlus;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPrePlusPlusExpression;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('4 * ++2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPrePlusPlusExpression);
|
|
R:=TJSUnaryPrePlusPlusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestExpressionPrecedenceMulPreMinusMinus;
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
R : TJSUnaryPreMinusMinusExpression;
|
|
E : TJSMultiplicativeExpressionMul;
|
|
|
|
begin
|
|
CreateParser('4 * --2;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSMultiplicativeExpressionMul);
|
|
E:=TJSMultiplicativeExpressionMul(X.A);
|
|
AssertNotNull('Expression left operand assigned',E.A);
|
|
AssertNotNull('Expression right operand assigned',E.B);
|
|
CheckClass(E.B,TJSUnaryPreMinusMinusExpression);
|
|
R:=TJSUnaryPreMinusMinusExpression(E.B);
|
|
CheckClass(E.A,TJSLiteral);
|
|
AssertNotNull('Multiplication left operand assigned',R.A);
|
|
CheckClass(R.A,TJSLiteral);
|
|
AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
|
|
AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
|
|
AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
|
|
AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
|
|
AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
|
|
end;
|
|
|
|
procedure TTestJSParser.TestSimpleExpressionBooleanLiteralTrue;
|
|
|
|
Var
|
|
X : TJSExpressionStatement;
|
|
|
|
begin
|
|
CreateParser('true;');
|
|
X:=GetExpressionStatement;
|
|
AssertNotNull('Expression statement assigned',X.A);
|
|
CheckClass(X.A,TJSLiteral);
|
|
AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
|
|
AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(X.A).Value.ValueType);
|
|
AssertEquals('Expression value correct', True, TJSLiteral(X.A).Value.AsBoolean);
|
|
end;
|
|
|
|
|
|
procedure TTestJSParser.TestEmpty;
|
|
|
|
Var
|
|
E : TJSElement;
|
|
FB : TJSFunctionBody;
|
|
SE : TJSSourceElements;
|
|
|
|
begin
|
|
CreateParser('var a;');
|
|
E:=FParser.Parse;
|
|
try
|
|
CheckClass(E,TJSFunctionBody);
|
|
FB:=TJSFunctionBody(E);
|
|
AssertNotNull(FB.A);
|
|
CheckClass(FB.A,TJSSourceElements);
|
|
SE:=TJSSourceElements(FB.A);
|
|
AssertEquals('1 variable declaration ',1,SE.Vars.Count);
|
|
CheckClass(FB.A,TJSSourceElements);
|
|
finally
|
|
E.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
initialization
|
|
|
|
RegisterTest(TTestJSParser);
|
|
end.
|
|
|