Kaynağa Gözat

* Tests for switch parsing

git-svn-id: trunk@27032 -
michael 11 yıl önce
ebeveyn
işleme
a748d37f9b
1 değiştirilmiş dosya ile 290 ekleme ve 17 silme
  1. 290 17
      packages/fcl-js/tests/tcparser.pp

+ 290 - 17
packages/fcl-js/tests/tcparser.pp

@@ -23,6 +23,7 @@ type
     Procedure CreateParser(Const ASource : string);
     Procedure CheckClass(E : TJSElement; C : TJSElementClass);
     Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSType); overload;
+    Procedure AssertIdentifier(Msg : String; El : TJSElement; Const AName : TJSString);
     Function  GetSourceElements : TJSSourceElements;
     Function  GetVars : TJSElementNodes;
     Function  GetStatements : TJSElementNodes;
@@ -123,13 +124,24 @@ type
     procedure TestTryFinally;
     procedure TestThrow;
     procedure TestReturn;
+    procedure TestAssignment;
+    procedure TestNew;
+    procedure TestLabeledStatement;
+    procedure TestContinue;
+    procedure TestContinueTarget;
+    procedure TestBreak;
+    procedure TestBreakTarget;
+    procedure TestSwitchEmpty;
+    procedure TestSwitchOne;
+    procedure TestSwitchTwo;
+    procedure TestSwitchTwoDefault;
   end;
 
 implementation
 
 uses typinfo;
 
-procedure TTestJSParser.AssertEquals(const AMessage: String; Expected,
+Procedure TTestJSParser.AssertEquals(Const AMessage: String; Expected,
   Actual: TJSType);
 
 Var
@@ -141,7 +153,22 @@ begin
   AssertEquals(AMessage,NE,NA);
 end;
 
-function TTestJSParser.GetFirstStatement: TJSElement;
+Procedure TTestJSParser.AssertIdentifier(Msg: String; El: TJSElement;
+  Const AName: TJSString);
+
+Var
+  L : TJSPrimaryExpressionIdent;
+  S1,S2 : String;
+begin
+  AssertNotNull(Msg+' have TJSPrimaryExpressionIdent element',El);
+  CheckClass(El,TJSPrimaryExpressionIdent);
+  L:=TJSPrimaryExpressionIdent(el);
+  S1:=L.Name;
+  S2:=Aname;
+  AssertEquals(Msg+'Identifier has correct name',S2,S1);
+end;
+
+Function TTestJSParser.GetFirstStatement: TJSElement;
 
 Var
   E : TJSElementNodes;
@@ -156,7 +183,7 @@ begin
   AssertNotNull('First statement assigned',Result);
 end;
 
-function TTestJSParser.GetFirstVar: TJSElement;
+Function TTestJSParser.GetFirstVar: TJSElement;
 Var
   E : TJSElementNodes;
   N : TJSElement;
@@ -171,7 +198,7 @@ begin
   AssertNotNull('First variable declaration',Result);
 end;
 
-function TTestJSParser.GetExpressionStatement: TJSExpressionStatement;
+Function TTestJSParser.GetExpressionStatement: TJSExpressionStatement;
 
 Var
   N : TJSElement;
@@ -1534,7 +1561,7 @@ begin
   AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
 end;
 
-procedure TTestJSParser.TestVarDeclarationSimple;
+Procedure TTestJSParser.TestVarDeclarationSimple;
 
 Var
   X : TJSELement;
@@ -1852,14 +1879,14 @@ procedure TTestJSParser.TestDoWhileSimple;
 
 Var
   E : TJSElement;
-  W : TJSWhileStatement;
+  W : TJSDoWhileStatement;
 //  B : TJSBlockStatement;
 
 begin
   CreateParser('do b; while (a);');
   E:=GetFirstStatement;
-  CheckClass(E,TJSWhileStatement);
-  W:=TJSWhileStatement(E);
+  CheckClass(E,TJSDoWhileStatement);
+  W:=TJSDoWhileStatement(E);
   AssertNotNull('Statement condition assigned',W.Cond);
   CheckClass(W.Cond,TJSPrimaryExpressionIdent);
   AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).Name);
@@ -1874,14 +1901,14 @@ procedure TTestJSParser.TestDoWhileBlock;
 
 Var
   E : TJSElement;
-  W : TJSWhileStatement;
+  W : TJSDoWhileStatement;
 //  B : TJSBlockStatement;
 
 begin
   CreateParser('do {b;} while (a);');
   E:=GetFirstStatement;
-  CheckClass(E,TJSWhileStatement);
-  W:=TJSWhileStatement(E);
+  CheckClass(E,TJSDoWhileStatement);
+  W:=TJSDoWhileStatement(E);
   AssertNotNull('Statement condition assigned',W.Cond);
   CheckClass(W.Cond,TJSPrimaryExpressionIdent);
   AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).Name);
@@ -2075,6 +2102,252 @@ begin
   AssertEquals('1 statement in functionbody elements',1,E.Statements.Count);
 end;
 
+procedure TTestJSParser.TestAssignment;
+Var
+  E : TJSElement;
+  ES : TJSExpressionStatement;
+  A : TJSSimpleAssignStatement;
+
+begin
+  CreateParser('a=b;');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSExpressionStatement);
+  ES:=TJSExpressionStatement(E);
+  CheckClass(ES.A,TJSSimpleAssignStatement);
+  A:=TJSSimpleAssignStatement(ES.A);
+  AssertNotNull('Have LHS',A.LHS);
+  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
+  AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
+  CheckClass(A.Expr,TJSPrimaryExpressionIdent);
+  AssertEquals('Have RHS name','b',TJSPrimaryExpressionIdent(A.Expr).Name);
+end;
+
+procedure TTestJSParser.TestNew;
+Var
+  E : TJSElement;
+  ES : TJSExpressionStatement;
+  A : TJSSimpleAssignStatement;
+  N : TJSNewMemberExpression;
+  L : TJSLiteral;
+
+begin
+  CreateParser('a = new b(123)');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSExpressionStatement);
+  ES:=TJSExpressionStatement(E);
+  CheckClass(ES.A,TJSSimpleAssignStatement);
+  A:=TJSSimpleAssignStatement(ES.A);
+  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
+  AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
+  CheckClass(A.Expr,TJSNewMemberExpression);
+  N:=TJSNewMemberExpression(A.Expr);
+  AssertNotNull('Have LHS name',N.Mexpr);
+  CheckClass(N.Mexpr,TJSPrimaryExpressionIdent);
+  AssertEquals('Have LHS name','b',TJSPrimaryExpressionIdent(N.Mexpr).Name);
+  AssertNotNull('Have arguments',N.Args);
+  AssertEquals('One argument',1,N.Args.Elements.Count);
+  AssertNotNull('Have argument 0',N.Args.Elements[0].Expr);
+  CheckClass(N.Args.Elements[0].Expr,TJSLiteral);
+  L:=TJSLiteral(N.Args.Elements[0].Expr);
+  AssertNotNull('Expression value assigned',L.Value);
+  AssertEquals('Expression value type correct', jstNumber,L.Value.ValueType);
+  AssertEquals('Expression value correct', 123,L.Value.AsNumber);
+
+end;
+
+procedure TTestJSParser.TestLabeledStatement;
+Var
+  E : TJSElement;
+  ES : TJSExpressionStatement;
+  A : TJSSimpleAssignStatement;
+  N : TJSNewMemberExpression;
+  L : TJSLiteral;
+  LS : TJSLabeledStatement;
+
+begin
+  CreateParser('loc: a = new b(123)');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSLabeledStatement);
+  LS:=TJSLabeledStatement(E);
+  AssertNotNull('Have label',LS.TheLabel);
+  AssertEquals('Have correct label','loc',LS.TheLabel.Name);
+  CheckClass(LS.A,TJSExpressionStatement);
+  ES:=TJSExpressionStatement(LS.A);
+  CheckClass(ES.A,TJSSimpleAssignStatement);
+  A:=TJSSimpleAssignStatement(ES.A);
+  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
+  AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
+  CheckClass(A.Expr,TJSNewMemberExpression);
+  N:=TJSNewMemberExpression(A.Expr);
+  AssertNotNull('Have LHS name',N.Mexpr);
+  CheckClass(N.Mexpr,TJSPrimaryExpressionIdent);
+  AssertEquals('Have LHS name','b',TJSPrimaryExpressionIdent(N.Mexpr).Name);
+  AssertNotNull('Have arguments',N.Args);
+  AssertEquals('One argument',1,N.Args.Elements.Count);
+  AssertNotNull('Have argument 0',N.Args.Elements[0].Expr);
+  CheckClass(N.Args.Elements[0].Expr,TJSLiteral);
+  L:=TJSLiteral(N.Args.Elements[0].Expr);
+  AssertNotNull('Expression value assigned',L.Value);
+  AssertEquals('Expression value type correct', jstNumber,L.Value.ValueType);
+  AssertEquals('Expression value correct', 123,L.Value.AsNumber);
+end;
+
+procedure TTestJSParser.TestContinue;
+
+Var
+  E : TJSElement;
+  C : TJSContinueStatement;
+
+begin
+  CreateParser('while (true) continue;');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSWhileStatement);
+  E:=TJSWhileStatement(E).Body;
+  CheckClass(E,TJSContinueStatement);
+  C:=TJSContinueStatement(E);
+  AssertEquals('Have correct (empty) label','',C.TargetName);
+end;
+
+procedure TTestJSParser.TestContinueTarget;
+
+Var
+  E : TJSElement;
+  C : TJSContinueStatement;
+
+begin
+  CreateParser('a: while (true) continue a;');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSLabeledStatement);
+  E:=TJSLabeledStatement(E).A;
+  CheckClass(E,TJSWhileStatement);
+  E:=TJSWhileStatement(E).Body;
+  CheckClass(E,TJSContinueStatement);
+  C:=TJSContinueStatement(E);
+  AssertEquals('Have correct  label','a',C.TargetName);
+end;
+
+procedure TTestJSParser.TestBreakTarget;
+Var
+  E : TJSElement;
+  C : TJSBreakStatement;
+
+begin
+  CreateParser('a: while (true) break a;');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSLabeledStatement);
+  E:=TJSLabeledStatement(E).A;
+  CheckClass(E,TJSWhileStatement);
+  E:=TJSWhileStatement(E).Body;
+  CheckClass(E,TJSBreakStatement);
+  C:=TJSBreakStatement(E);
+  AssertEquals('Have correct  label','a',C.TargetName);
+end;
+
+procedure TTestJSParser.TestSwitchEmpty;
+Var
+  E : TJSElement;
+  S : TJSSwitchStatement;
+  P : TJSPrimaryExpressionIdent;
+
+begin
+  CreateParser('switch (a) {}');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSSwitchStatement);
+  S:=TJSSwitchStatement(E);
+  AssertNotNull('Have condition',S.Cond);
+  AssertNull('Have no default',S.TheDefault);
+  AssertIdentifier('Case condition',S.Cond,'a');
+  S:=TJSSwitchStatement(E);
+  AssertEquals('No cases',0,S.Cases.Count)
+end;
+
+procedure TTestJSParser.TestSwitchOne;
+Var
+  E : TJSElement;
+  S : TJSSwitchStatement;
+  P : TJSPrimaryExpressionIdent;
+  C : TJSCaseElement;
+begin
+  CreateParser('switch (a) { case c : {}}');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSSwitchStatement);
+  S:=TJSSwitchStatement(E);
+  AssertNotNull('Have condition',S.Cond);
+  AssertNull('Have no default',S.TheDefault);
+  AssertIdentifier('Case condition',S.Cond,'a');
+  S:=TJSSwitchStatement(E);
+  AssertEquals('1 case',1,S.Cases.Count);
+  C:=TJSCaseElement(S.Cases[0]);
+  AssertIdentifier('Case expression',C.Expr,'c');
+  CheckClass(C.Body,TJSEmptyBlockStatement);
+end;
+
+procedure TTestJSParser.TestSwitchTwo;
+Var
+  E : TJSElement;
+  S : TJSSwitchStatement;
+  P : TJSPrimaryExpressionIdent;
+  C : TJSCaseElement;
+begin
+  CreateParser('switch (a) { case c: {}'+sLineBreak+' case d: {}}');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSSwitchStatement);
+  S:=TJSSwitchStatement(E);
+  AssertNotNull('Have condition',S.Cond);
+  AssertNull('Have no default',S.TheDefault);
+  AssertIdentifier('Case condition',S.Cond,'a');
+  S:=TJSSwitchStatement(E);
+  AssertEquals('2 cases',2,S.Cases.Count);
+  C:=TJSCaseElement(S.Cases[0]);
+  AssertIdentifier('Case expression',C.Expr,'c');
+  CheckClass(C.Body,TJSEmptyBlockStatement);
+  C:=TJSCaseElement(S.Cases[1]);
+  AssertIdentifier('Case expression',C.Expr,'d');
+  CheckClass(C.Body,TJSEmptyBlockStatement);
+end;
+
+procedure TTestJSParser.TestSwitchTwoDefault;
+Var
+  E : TJSElement;
+  S : TJSSwitchStatement;
+  P : TJSPrimaryExpressionIdent;
+  C : TJSCaseElement;
+begin
+  CreateParser('switch (a) { case c: {} case d: {} default: {}}');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSSwitchStatement);
+  S:=TJSSwitchStatement(E);
+  AssertNotNull('Have condition',S.Cond);
+  AssertNotNull('Have default',S.TheDefault);
+  AssertIdentifier('Case condition',S.Cond,'a');
+  S:=TJSSwitchStatement(E);
+  AssertEquals('2 cases',3,S.Cases.Count);
+  C:=TJSCaseElement(S.Cases[0]);
+  AssertIdentifier('Case expression',C.Expr,'c');
+  CheckClass(C.Body,TJSEmptyBlockStatement);
+  C:=TJSCaseElement(S.Cases[1]);
+  AssertIdentifier('Case expression',C.Expr,'d');
+  CheckClass(C.Body,TJSEmptyBlockStatement);
+  C:=TJSCaseElement(S.Cases[2]);
+  CheckClass(C.Body,TJSEmptyBlockStatement);
+  AssertSame('Default',C,S.TheDefault);
+end;
+
+procedure TTestJSParser.TestBreak;
+Var
+  E : TJSElement;
+  C : TJSBreakStatement;
+
+begin
+  CreateParser('while (true) break;');
+  E:=GetFirstStatement;
+  CheckClass(E,TJSWhileStatement);
+  E:=TJSWhileStatement(E).Body;
+  CheckClass(E,TJSBreakStatement);
+  C:=TJSBreakStatement(E);
+  AssertEquals('Have correct (empty) label','',C.TargetName);
+end;
+
 procedure TTestJSParser.TestIfElseSimple;
 
 Var
@@ -2260,18 +2533,18 @@ begin
   FReeAndNil(FSource);
 end;
 
-procedure TTestJSParser.CreateParser(const ASource: string);
+Procedure TTestJSParser.CreateParser(Const ASource: string);
 begin
   FSource:=TStringStream.Create(ASource);
   FParser:=TJSParser.Create(FSource);
 end;
 
-procedure TTestJSParser.CheckClass(E: TJSElement; C: TJSElementClass);
+Procedure TTestJSParser.CheckClass(E: TJSElement; C: TJSElementClass);
 begin
   AssertEquals(C,E.ClassType);
 end;
 
-function TTestJSParser.GetSourceElements: TJSSourceElements;
+Function TTestJSParser.GetSourceElements: TJSSourceElements;
 
 Var
   E : TJSElement;
@@ -2292,17 +2565,17 @@ begin
   Result:=FSE;
 end;
 
-function TTestJSParser.GetVars: TJSElementNodes;
+Function TTestJSParser.GetVars: TJSElementNodes;
 begin
   Result:=GetSourceElements.Vars;
 end;
 
-function TTestJSParser.GetStatements: TJSElementNodes;
+Function TTestJSParser.GetStatements: TJSElementNodes;
 begin
   Result:=GetSourceElements.Statements;
 end;
 
-function TTestJSParser.GetFunctions: TJSElementNodes;
+Function TTestJSParser.GetFunctions: TJSElementNodes;
 begin
   Result:=GetSourceElements.Functions;
 end;