|
@@ -0,0 +1,2311 @@
|
|
|
+unit tcparser;
|
|
|
+
|
|
|
+{$mode objfpc}{$H+}
|
|
|
+
|
|
|
+interface
|
|
|
+
|
|
|
+uses
|
|
|
+ Classes, SysUtils, fpcunit, testutils, testregistry, jsParser, jstree, jsbase;
|
|
|
+
|
|
|
+type
|
|
|
+
|
|
|
+ { TTestJSParser }
|
|
|
+
|
|
|
+ TTestJSParser= class(TTestCase)
|
|
|
+ Private
|
|
|
+ FSource : TStringStream;
|
|
|
+ FParser : TJSParser;
|
|
|
+ FSE : TJSSourceElements;
|
|
|
+ FToFree: TJSElement;
|
|
|
+ protected
|
|
|
+ procedure SetUp; override;
|
|
|
+ procedure TearDown; override;
|
|
|
+ Procedure CreateParser(Const ASource : string);
|
|
|
+ Procedure CheckClass(E : TJSElement; C : TJSElementClass);
|
|
|
+ Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSType); overload;
|
|
|
+ Function GetSourceElements : TJSSourceElements;
|
|
|
+ Function GetVars : TJSElementNodes;
|
|
|
+ Function GetStatements : TJSElementNodes;
|
|
|
+ Function GetFunctions : TJSElementNodes;
|
|
|
+ Function GetFirstStatement : TJSElement;
|
|
|
+ Function GetFirstVar : TJSElement;
|
|
|
+ Function GetExpressionStatement : TJSExpressionStatement;
|
|
|
+ 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 TestFunctionCallOneArg;
|
|
|
+ procedure TestFunctionCallTwoArgs;
|
|
|
+ procedure TestArrayExpressionNumericalArgs;
|
|
|
+ procedure TestArrayExpressionStringArgs;
|
|
|
+ procedure TestArrayExpressionIdentArgs;
|
|
|
+ Procedure TestVarDeclarationSimple;
|
|
|
+ procedure TestVarDeclarationDouble;
|
|
|
+ procedure TestVarDeclarationSimpleInit;
|
|
|
+ procedure TestVarDeclarationDoubleInit;
|
|
|
+ procedure TestBlockEmpty;
|
|
|
+ procedure TestBlockEmptyStatement;
|
|
|
+ procedure TestBlockSimpleStatement;
|
|
|
+ procedure TestFunctionDeclarationEmpty;
|
|
|
+ procedure TestFunctionDeclarationWithArgs;
|
|
|
+ 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;
|
|
|
+ end;
|
|
|
+
|
|
|
+implementation
|
|
|
+
|
|
|
+uses typinfo;
|
|
|
+
|
|
|
+procedure TTestJSParser.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;
|
|
|
+
|
|
|
+function TTestJSParser.GetFirstStatement: TJSElement;
|
|
|
+
|
|
|
+Var
|
|
|
+ E : TJSElementNodes;
|
|
|
+ N : TJSElement;
|
|
|
+ X : TJSExpressionStatement;
|
|
|
+
|
|
|
+begin
|
|
|
+ E:=GetStatements;
|
|
|
+ AssertNotNull('Have statements',E);
|
|
|
+ AssertEquals('1 statement',1,E.Count);
|
|
|
+ Result:=E.Nodes[0].Node;
|
|
|
+ AssertNotNull('First statement assigned',Result);
|
|
|
+end;
|
|
|
+
|
|
|
+function TTestJSParser.GetFirstVar: TJSElement;
|
|
|
+Var
|
|
|
+ E : TJSElementNodes;
|
|
|
+ N : TJSElement;
|
|
|
+ X : TJSExpressionStatement;
|
|
|
+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 TTestJSParser.GetExpressionStatement: TJSExpressionStatement;
|
|
|
+
|
|
|
+Var
|
|
|
+ N : TJSElement;
|
|
|
+ X : TJSExpressionStatement;
|
|
|
+
|
|
|
+begin
|
|
|
+ N:=GetFirstStatement;
|
|
|
+ CheckClass(N,TJSExpressionStatement);
|
|
|
+ Result:=TJSExpressionStatement(N);
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+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).AString);
|
|
|
+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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ AssertNotNull('Assignment Expression assigned',SA.Expr);
|
|
|
+ CheckClass(SA.EXPR,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('Expression value type correct', 'b',TJSPrimaryExpressionIdent(SA.Expr).AString);
|
|
|
+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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+ 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).AString);
|
|
|
+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).AString);
|
|
|
+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).AString);
|
|
|
+ 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).AString);
|
|
|
+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).AString);
|
|
|
+ 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).AString);
|
|
|
+ E:=C.Args.Elements[1].Expr;
|
|
|
+ AssertNotNull('Second argument expression',E);
|
|
|
+ CheckClass(E,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('Second argument name correct','e',TJSPrimaryExpressionIdent(E).AString);
|
|
|
+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).AString);
|
|
|
+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).AString);
|
|
|
+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).AString);
|
|
|
+ CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).AString);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.TestVarDeclarationSimple;
|
|
|
+
|
|
|
+Var
|
|
|
+ X : TJSELement;
|
|
|
+ V : TJSVarDeclaration;
|
|
|
+begin
|
|
|
+ CreateParser('var a;');
|
|
|
+ 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);
|
|
|
+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);
|
|
|
+// 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('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).AString);
|
|
|
+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).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(X).A).AString)
|
|
|
+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);
|
|
|
+ AssertEquals('Function name OK','a',FD.AFunction.Name);
|
|
|
+ AssertNotNull('Function body assigned', FD.AFunction.Body);
|
|
|
+ AssertEquals('No parameters',0,FD.AFunction.Params.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.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.Params.Count);
|
|
|
+ AssertEquals('1st parameter','b',FD.AFunction.Params[0]);
|
|
|
+ AssertEquals('2nd parameter','c',FD.AFunction.Params[1]);
|
|
|
+ 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.Params.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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(N).A).AString);
|
|
|
+// 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('a',TJSPrimaryExpressionIdent(I.Cond).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.Btrue).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(I.Cond).AString);
|
|
|
+ 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('a',TJSPrimaryExpressionIdent(I.Cond).AString);
|
|
|
+ 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('a',TJSPrimaryExpressionIdent(W.Cond).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(W.Cond).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).AString);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.TestDoWhileSimple;
|
|
|
+
|
|
|
+Var
|
|
|
+ E : TJSElement;
|
|
|
+ W : TJSWhileStatement;
|
|
|
+// B : TJSBlockStatement;
|
|
|
+
|
|
|
+begin
|
|
|
+ CreateParser('do b; while (a);');
|
|
|
+ E:=GetFirstStatement;
|
|
|
+ CheckClass(E,TJSWhileStatement);
|
|
|
+ W:=TJSWhileStatement(E);
|
|
|
+ AssertNotNull('Statement condition assigned',W.Cond);
|
|
|
+ CheckClass(W.Cond,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).AString);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.TestDoWhileBlock;
|
|
|
+
|
|
|
+Var
|
|
|
+ E : TJSElement;
|
|
|
+ W : TJSWhileStatement;
|
|
|
+// B : TJSBlockStatement;
|
|
|
+
|
|
|
+begin
|
|
|
+ CreateParser('do {b;} while (a);');
|
|
|
+ E:=GetFirstStatement;
|
|
|
+ CheckClass(E,TJSWhileStatement);
|
|
|
+ W:=TJSWhileStatement(E);
|
|
|
+ AssertNotNull('Statement condition assigned',W.Cond);
|
|
|
+ CheckClass(W.Cond,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(F.Init).AString);
|
|
|
+ CheckClass(F.Incr,TJSPrimaryExpressionIdent);
|
|
|
+ AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Incr));
|
|
|
+ AssertEquals('c',TJSPrimaryExpressionIdent(F.Incr).AString);
|
|
|
+ CheckClass(F.Cond,TJSPrimaryExpressionIdent);
|
|
|
+ AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Cond));
|
|
|
+ AssertEquals('b',TJSPrimaryExpressionIdent(F.cond).AString);
|
|
|
+ CheckClass(F.Body,TJSExpressionStatement);
|
|
|
+ AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
|
|
|
+ CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('d',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BCatch).A).AString);
|
|
|
+ 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('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BCatch).A).AString);
|
|
|
+ AssertNotNull('Finally expression',T.BFinally);
|
|
|
+ CheckClass(T.BFinally,TJSExpressionStatement);
|
|
|
+ AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BFinally).A);
|
|
|
+ CheckClass(TJSExpressionStatement(T.BFinally).A,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('c',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BFinally).A).AString);
|
|
|
+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('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).AString);
|
|
|
+ AssertNull('No catch',T.BCatch);
|
|
|
+ AssertNotNull('Finally expression',T.BFinally);
|
|
|
+ AssertNotNull('Finally expression',TJSExpressionStatement(T.BFinally).A);
|
|
|
+ CheckClass(TJSExpressionStatement(T.BFinally).A,TJSPrimaryExpressionIdent);
|
|
|
+ AssertEquals('c',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BFinally).A).AString);
|
|
|
+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).AsTring);
|
|
|
+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.Params.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.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('a',TJSPrimaryExpressionIdent(I.Cond).AString);
|
|
|
+ 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('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.Btrue).A).AString);
|
|
|
+ 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('c',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.BFalse).A).AString);
|
|
|
+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;
|
|
|
+ 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);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.SetUp;
|
|
|
+begin
|
|
|
+ FParser:=Nil;
|
|
|
+ FSource:=Nil;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.TearDown;
|
|
|
+begin
|
|
|
+// FreeAndNil(FToFree);
|
|
|
+ FreeAndNil(FParser);
|
|
|
+ FReeAndNil(FSource);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.CreateParser(const ASource: string);
|
|
|
+begin
|
|
|
+ FSource:=TStringStream.Create(ASource);
|
|
|
+ FParser:=TJSParser.Create(FSource);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TTestJSParser.CheckClass(E: TJSElement; C: TJSElementClass);
|
|
|
+begin
|
|
|
+ AssertEquals(C,E.ClassType);
|
|
|
+end;
|
|
|
+
|
|
|
+function TTestJSParser.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);
|
|
|
+ end;
|
|
|
+ Result:=FSE;
|
|
|
+ FToFree:=E;
|
|
|
+end;
|
|
|
+
|
|
|
+function TTestJSParser.GetVars: TJSElementNodes;
|
|
|
+begin
|
|
|
+ Result:=GetSourceElements.Vars;
|
|
|
+end;
|
|
|
+
|
|
|
+function TTestJSParser.GetStatements: TJSElementNodes;
|
|
|
+begin
|
|
|
+ Result:=GetSourceElements.Statements;
|
|
|
+end;
|
|
|
+
|
|
|
+function TTestJSParser.GetFunctions: TJSElementNodes;
|
|
|
+begin
|
|
|
+ Result:=GetSourceElements.Functions;
|
|
|
+end;
|
|
|
+
|
|
|
+
|
|
|
+initialization
|
|
|
+
|
|
|
+ RegisterTest(TTestJSParser);
|
|
|
+end.
|
|
|
+
|