1unit tcparser;
2
3{$mode objfpc}{$H+}
4
5interface
6
7uses
8  Classes, SysUtils, fpcunit, testregistry, jsParser, jstree, jsbase;
9
10type
11
12  { TTestJSParser }
13
14  TTestJSParser= class(TTestCase)
15  Private
16    FSource : TStringStream;
17    FParser : TJSParser;
18    FSE : TJSSourceElements;
19    FToFree: TJSElement;
20  protected
21    procedure SetUp; override;
22    procedure TearDown; override;
23    Procedure CreateParser(Const ASource : string);
24    Procedure CheckClass(E : TJSElement; C : TJSElementClass);
25    Procedure AssertEquals(Const AMessage : String; Expected, Actual : TJSType); overload;
26    Procedure AssertIdentifier(Msg : String; El : TJSElement; Const AName : TJSString);
27    Function  GetSourceElements : TJSSourceElements;
28    Function  GetVars : TJSElementNodes;
29    Function  GetStatements : TJSElementNodes;
30    Function  GetFunctions : TJSElementNodes;
31    Function  GetFirstStatement : TJSElement;
32    Function  GetFirstVar : TJSElement;
33    Function  GetExpressionStatement : TJSExpressionStatement;
34  published
35    procedure TestEmpty;
36    procedure TestSimple;
37    procedure TestSimpleExpressionNumericalLiteral;
38    procedure TestSimpleExpressionStringLiteral;
39    procedure TestSimpleExpressionBooleanLiteralFalse;
40    procedure TestSimpleExpressionBooleanLiteralTrue;
41    procedure TestSimpleExpressionIdentifier;
42    procedure TestSimpleExpressionNull;
43    procedure TestAssignExpressionNumerical;
44    procedure TestAssignExpressionNull;
45    procedure TestAssignExpressionString;
46    procedure TestAssignExpressionBooleanFalse;
47    procedure TestAssignExpressionBooleanTrue;
48    procedure TestAssignExpressionIdent;
49    procedure TestAssignExpressionPlus;
50    procedure TestAssignExpressionMinus;
51    procedure TestAssignExpressionDiv;
52    procedure TestAssignExpressionMul;
53    procedure TestAssignExpressionMod;
54    procedure TestAssignExpressionAnd;
55    procedure TestAssignExpressionOr;
56    procedure TestAssignExpressionXOr;
57    procedure TestAssignExpressionLShift;
58    procedure TestAssignExpressionRShift;
59    procedure TestAssignExpressionURShift;
60    procedure TestExpressionPlus;
61    procedure TestExpressionSub;
62    procedure TestExpressionMul;
63    procedure TestExpressionDiv;
64    procedure TestExpressionMod;
65    procedure TestExpressionLShift;
66    procedure TestExpressionRShift;
67    procedure TestExpressionURShift;
68    procedure TestExpressionPostPlusPlus;
69    procedure TestExpressionPostMinusMinus;
70    procedure TestExpressionPreMinusMinus;
71    procedure TestExpressionPrePlusPlus;
72    procedure TestExpressionPrecedenceMulPlus;
73    procedure TestExpressionPrecedencePlusMul;
74    procedure TestExpressionPrecedenceMulMinus;
75    procedure TestExpressionPrecedenceMinusMul;
76    procedure TestExpressionPrecedenceDivPlus;
77    procedure TestExpressionPrecedencePlusDiv;
78    procedure TestExpressionPrecedenceModPlus;
79    procedure TestExpressionPrecedencePlusMod;
80    procedure TestExpressionPrecedencePlusPostPlusPlus;
81    procedure TestExpressionPrecedencePlusPostMinusMinus;
82    procedure TestExpressionPrecedenceMulPostMinusMinus;
83    procedure TestExpressionPrecedenceMulPostPlusPlus;
84    procedure TestExpressionPrecedenceMulPreMinusMinus;
85    procedure TestExpressionPrecedenceMulPrePlusPlus;
86    procedure TestExpressionPrecedencePlusPreMinusMinus;
87    procedure TestExpressionPrecedencePlusPrePlusPlus;
88    procedure TestExpressionPrecedencePlusInv;
89    procedure TestExpressionPrecedenceMulInv;
90    procedure TestExpressionPrecedenceMulNot;
91    procedure TestExpressionPrecedencePlusNot;
92    procedure TestExpressionPrecedenceBraceMulPlus;
93    procedure TestExpressionPrecedenceBracePlusMul;
94    procedure TestExpressionFunction;
95    procedure TestFunctionCallNoArgs;
96    procedure TestFunctionCallOneArg;
97    procedure TestFunctionCallTwoArgs;
98    procedure TestArrayExpressionNumericalArgs;
99    procedure TestArrayExpressionStringArgs;
100    procedure TestArrayExpressionIdentArgs;
101    Procedure TestVarDeclarationSimple;
102    procedure TestVarDeclarationDouble;
103    procedure TestVarDeclarationSimpleInit;
104    procedure TestVarDeclarationDoubleInit;
105    procedure TestBlockEmpty;
106    procedure TestBlockEmptyStatement;
107    procedure TestBlockSimpleStatement;
108    procedure TestFunctionDeclarationEmpty;
109    procedure TestFunctionDeclarationWithArgs;
110    procedure TestFunctionDeclarationWithBody;
111    procedure TestIfSimple;
112    procedure TestIfElseSimple;
113    procedure TestIfEmptyBlock;
114    procedure TestIfEmptyBlockElse;
115    procedure TestWhileSimple;
116    procedure TestWhileBlock;
117    procedure TestDoWhileSimple;
118    procedure TestDoWhileBlock;
119    procedure TestForEmpty;
120    procedure TestForEmptyBody;
121    procedure TestForSimpleBody;
122    procedure TestTryCatch;
123    procedure TestTryCatchFinally;
124    procedure TestTryFinally;
125    procedure TestThrow;
126    procedure TestReturn;
127    procedure TestAssignment;
128    procedure TestNew;
129    procedure TestLabeledStatement;
130    procedure TestContinue;
131    procedure TestContinueTarget;
132    procedure TestBreak;
133    procedure TestBreakTarget;
134    procedure TestSwitchEmpty;
135    procedure TestSwitchOne;
136    procedure TestSwitchTwo;
137    procedure TestSwitchTwoDefault;
138  end;
139
140implementation
141
142uses typinfo;
143
144Procedure TTestJSParser.AssertEquals(Const AMessage: String; Expected,
145  Actual: TJSType);
146
147Var
148  NE,NA : String;
149
150begin
151  NE:=GetEnumName(TypeInfo(TJSType),Ord(Expected));
152  NA:=GetEnumName(TypeInfo(TJSType),Ord(Actual));
153  AssertEquals(AMessage,NE,NA);
154end;
155
156Procedure TTestJSParser.AssertIdentifier(Msg: String; El: TJSElement;
157  Const AName: TJSString);
158
159Var
160  L : TJSPrimaryExpressionIdent;
161  S1,S2 : String;
162begin
163  AssertNotNull(Msg+' have TJSPrimaryExpressionIdent element',El);
164  CheckClass(El,TJSPrimaryExpressionIdent);
165  L:=TJSPrimaryExpressionIdent(el);
166  S1:=L.Name;
167  S2:=Aname;
168  AssertEquals(Msg+'Identifier has correct name',S2,S1);
169end;
170
171Function TTestJSParser.GetFirstStatement: TJSElement;
172
173Var
174  E : TJSElementNodes;
175begin
176  E:=GetStatements;
177  AssertNotNull('Have statements',E);
178  AssertEquals('1 statement',1,E.Count);
179  Result:=E.Nodes[0].Node;
180  AssertNotNull('First statement assigned',Result);
181end;
182
183Function TTestJSParser.GetFirstVar: TJSElement;
184Var
185  E : TJSElementNodes;
186begin
187  E:=GetVars;
188  AssertNotNull('Have statements',E);
189  Writeln('Count : ',E.Count);
190  If (E.Count=0) then
191    Fail('Zero variables defined');
192  Result:=E.Nodes[0].Node;
193  AssertNotNull('First variable declaration',Result);
194end;
195
196Function TTestJSParser.GetExpressionStatement: TJSExpressionStatement;
197
198Var
199  N : TJSElement;
200begin
201  N:=GetFirstStatement;
202  CheckClass(N,TJSExpressionStatement);
203  Result:=TJSExpressionStatement(N);
204end;
205
206
207procedure TTestJSParser.TestSimple;
208
209Var
210  E : TJSElementNodes;
211  N : TJSElement;
212  X : TJSExpressionStatement;
213
214begin
215  CreateParser('1;');
216  E:=GetStatements;
217  AssertNotNull('Have statements',E);
218  AssertEquals('1 statement',1,E.Count);
219  N:=E.Nodes[0].Node;
220  AssertNotNull('First statement assigned',N);
221  AssertNotNull('First statement assigned',N);
222  CheckClass(N,TJSExpressionStatement);
223  X:=TJSExpressionStatement(N);
224  AssertNotNull('Expression statement assigned',X.A);
225  CheckClass(X.A,TJSLiteral);
226end;
227
228procedure TTestJSParser.TestSimpleExpressionNumericalLiteral;
229Var
230  X : TJSExpressionStatement;
231
232begin
233  CreateParser('1;');
234  X:=GetExpressionStatement;
235  AssertNotNull('Expression statement assigned',X.A);
236  CheckClass(X.A,TJSLiteral);
237  AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
238  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(X.A).Value.ValueType);
239  AssertEquals('Expression value correct', 1.0,TJSLiteral(X.A).Value.AsNumber);
240end;
241
242procedure TTestJSParser.TestSimpleExpressionStringLiteral;
243
244Var
245  X : TJSExpressionStatement;
246
247begin
248  CreateParser('"string";');
249  X:=GetExpressionStatement;
250  AssertNotNull('Expression statement assigned',X.A);
251  CheckClass(X.A,TJSLiteral);
252  AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
253  AssertEquals('Expression value type correct', jstString,TJSLiteral(X.A).Value.ValueType);
254  AssertEquals('Expression value correct', 'string',TJSLiteral(X.A).Value.AsString);
255end;
256
257procedure TTestJSParser.TestSimpleExpressionBooleanLiteralFalse;
258
259Var
260  X : TJSExpressionStatement;
261
262begin
263  CreateParser('false;');
264  X:=GetExpressionStatement;
265  AssertNotNull('Expression statement assigned',X.A);
266  CheckClass(X.A,TJSLiteral);
267  AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
268  AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(X.A).Value.ValueType);
269  AssertEquals('Expression value correct', False, TJSLiteral(X.A).Value.AsBoolean);
270end;
271
272procedure TTestJSParser.TestSimpleExpressionIdentifier;
273
274Var
275  X : TJSExpressionStatement;
276
277begin
278  CreateParser('Something;');
279  X:=GetExpressionStatement;
280  AssertNotNull('Expression statement assigned',X.A);
281  CheckClass(X.A,TJSPrimaryExpressionIdent);
282  AssertEquals('Expression value assigned','Something',TJSPrimaryExpressionIdent(X.A).Name);
283end;
284
285procedure TTestJSParser.TestSimpleExpressionNull;
286
287Var
288  X : TJSExpressionStatement;
289begin
290    CreateParser('null;');
291    X:=GetExpressionStatement;
292    AssertNotNull('Expression statement assigned',X.A);
293    CheckClass(X.A,TJSLiteral);
294    AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
295    AssertEquals('Expression value type correct', jstNull,TJSLiteral(X.A).Value.ValueType);
296    AssertEquals('Expression value correct', True, TJSLiteral(X.A).Value.IsNull);
297end;
298
299procedure TTestJSParser.TestAssignExpressionNumerical;
300
301Var
302  X : TJSExpressionStatement;
303  SA : TJSSimpleAssignStatement;
304begin
305  CreateParser('a=1;');
306  X:=GetExpressionStatement;
307  AssertNotNull('Expression statement assigned',X.A);
308  CheckClass(X.A,TJSSimpleAssignStatement);
309  SA:=TJSSimpleAssignStatement(X.A);
310  AssertNotNull('Assignment LHS assigned',SA.LHS);
311  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
312  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
313  AssertNotNull('Assignment Expression assigned',SA.Expr);
314  CheckClass(SA.EXPR,TJSLiteral);
315  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
316  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
317end;
318
319procedure TTestJSParser.TestAssignExpressionString;
320
321Var
322  X : TJSExpressionStatement;
323  SA : TJSSimpleAssignStatement;
324begin
325  CreateParser('a="string";');
326  X:=GetExpressionStatement;
327  AssertNotNull('Expression statement assigned',X.A);
328  CheckClass(X.A,TJSSimpleAssignStatement);
329  SA:=TJSSimpleAssignStatement(X.A);
330  AssertNotNull('Assignment LHS assigned',SA.LHS);
331  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
332  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
333  AssertNotNull('Assignment Expression assigned',SA.Expr);
334  CheckClass(SA.EXPR,TJSLiteral);
335  AssertEquals('Expression value type correct', jstString,TJSLiteral(SA.Expr).Value.ValueType);
336  AssertEquals('Expression value correct', 'string', TJSLiteral(SA.Expr).Value.AsString);
337end;
338
339procedure TTestJSParser.TestAssignExpressionBooleanFalse;
340
341Var
342  X : TJSExpressionStatement;
343  SA : TJSSimpleAssignStatement;
344begin
345  CreateParser('a=false;');
346  X:=GetExpressionStatement;
347  AssertNotNull('Expression statement assigned',X.A);
348  CheckClass(X.A,TJSSimpleAssignStatement);
349  SA:=TJSSimpleAssignStatement(X.A);
350  AssertNotNull('Assignment LHS assigned',SA.LHS);
351  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
352  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
353  AssertNotNull('Assignment Expression assigned',SA.Expr);
354  CheckClass(SA.EXPR,TJSLiteral);
355  AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(SA.Expr).Value.ValueType);
356  AssertEquals('Expression value correct', False, TJSLiteral(SA.Expr).Value.AsBoolean);
357end;
358
359procedure TTestJSParser.TestAssignExpressionBooleanTrue;
360Var
361  X : TJSExpressionStatement;
362  SA : TJSSimpleAssignStatement;
363begin
364  CreateParser('a=true;');
365  X:=GetExpressionStatement;
366  AssertNotNull('Expression statement assigned',X.A);
367  CheckClass(X.A,TJSSimpleAssignStatement);
368  SA:=TJSSimpleAssignStatement(X.A);
369  AssertNotNull('Assignment LHS assigned',SA.LHS);
370  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
371  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
372  AssertNotNull('Assignment Expression assigned',SA.Expr);
373  CheckClass(SA.EXPR,TJSLiteral);
374  AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(SA.Expr).Value.ValueType);
375  AssertEquals('Expression value correct', True, TJSLiteral(SA.Expr).Value.AsBoolean);
376end;
377
378procedure TTestJSParser.TestAssignExpressionNull;
379
380Var
381  X : TJSExpressionStatement;
382  SA : TJSSimpleAssignStatement;
383begin
384  CreateParser('a=null;');
385  X:=GetExpressionStatement;
386  AssertNotNull('Expression statement assigned',X.A);
387  CheckClass(X.A,TJSSimpleAssignStatement);
388  SA:=TJSSimpleAssignStatement(X.A);
389  AssertNotNull('Assignment LHS assigned',SA.LHS);
390  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
391  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
392  AssertNotNull('Assignment Expression assigned',SA.Expr);
393  CheckClass(SA.EXPR,TJSLiteral);
394  AssertEquals('Expression value type correct', jstNull,TJSLiteral(SA.Expr).Value.ValueType);
395  AssertEquals('Expression value correct', True, TJSLiteral(SA.Expr).Value.IsNull);
396end;
397
398procedure TTestJSParser.TestAssignExpressionIdent;
399Var
400  X : TJSExpressionStatement;
401  SA : TJSSimpleAssignStatement;
402begin
403  CreateParser('a=b;');
404  X:=GetExpressionStatement;
405  AssertNotNull('Expression statement assigned',X.A);
406  CheckClass(X.A,TJSSimpleAssignStatement);
407  SA:=TJSSimpleAssignStatement(X.A);
408  AssertNotNull('Assignment LHS assigned',SA.LHS);
409  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
410  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
411  AssertNotNull('Assignment Expression assigned',SA.Expr);
412  CheckClass(SA.EXPR,TJSPrimaryExpressionIdent);
413  AssertEquals('Expression value type correct', 'b',TJSPrimaryExpressionIdent(SA.Expr).Name);
414end;
415
416procedure TTestJSParser.TestAssignExpressionPlus;
417
418Var
419  X : TJSExpressionStatement;
420  SA : TJSAddEqAssignStatement;
421
422begin
423  CreateParser('a+=1;');
424  X:=GetExpressionStatement;
425  AssertNotNull('Expression statement assigned',X.A);
426  CheckClass(X.A,TJSAddEqAssignStatement);
427  SA:=TJSAddEqAssignStatement(X.A);
428  AssertNotNull('Assignment LHS assigned',SA.LHS);
429  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
430  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
431  AssertNotNull('Assignment Expression assigned',SA.Expr);
432  CheckClass(SA.EXPR,TJSLiteral);
433  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
434  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
435end;
436
437procedure TTestJSParser.TestAssignExpressionMinus;
438
439Var
440  X : TJSExpressionStatement;
441  SA : TJSSubEqAssignStatement;
442
443begin
444  CreateParser('a-=1;');
445  X:=GetExpressionStatement;
446  AssertNotNull('Expression statement assigned',X.A);
447  CheckClass(X.A,TJSSubEqAssignStatement);
448  SA:=TJSSubEqAssignStatement(X.A);
449  AssertNotNull('Assignment LHS assigned',SA.LHS);
450  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
451  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
452  AssertNotNull('Assignment Expression assigned',SA.Expr);
453  CheckClass(SA.EXPR,TJSLiteral);
454  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
455  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
456end;
457
458procedure TTestJSParser.TestAssignExpressionMul;
459
460Var
461  X : TJSExpressionStatement;
462  SA : TJSMulEqAssignStatement;
463
464begin
465  CreateParser('a*=1;');
466  X:=GetExpressionStatement;
467  AssertNotNull('Expression statement assigned',X.A);
468  CheckClass(X.A,TJSMulEqAssignStatement);
469  SA:=TJSMulEqAssignStatement(X.A);
470  AssertNotNull('Assignment LHS assigned',SA.LHS);
471  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
472  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
473  AssertNotNull('Assignment Expression assigned',SA.Expr);
474  CheckClass(SA.EXPR,TJSLiteral);
475  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
476  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
477end;
478
479procedure TTestJSParser.TestAssignExpressionDiv;
480
481Var
482  X : TJSExpressionStatement;
483  SA : TJSDivEqAssignStatement;
484
485begin
486  CreateParser('a/=1;');
487  X:=GetExpressionStatement;
488  AssertNotNull('Expression statement assigned',X.A);
489  CheckClass(X.A,TJSDivEqAssignStatement);
490  SA:=TJSDivEqAssignStatement(X.A);
491  AssertNotNull('Assignment LHS assigned',SA.LHS);
492  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
493  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
494  AssertNotNull('Assignment Expression assigned',SA.Expr);
495  CheckClass(SA.EXPR,TJSLiteral);
496  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
497  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
498end;
499
500procedure TTestJSParser.TestAssignExpressionMod;
501
502Var
503  X : TJSExpressionStatement;
504  SA : TJSModEqAssignStatement;
505
506begin
507  CreateParser('a%=1;');
508  X:=GetExpressionStatement;
509  AssertNotNull('Expression statement assigned',X.A);
510  CheckClass(X.A,TJSModEqAssignStatement);
511  SA:=TJSModEqAssignStatement(X.A);
512  AssertNotNull('Assignment LHS assigned',SA.LHS);
513  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
514  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
515  AssertNotNull('Assignment Expression assigned',SA.Expr);
516  CheckClass(SA.EXPR,TJSLiteral);
517  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
518  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
519end;
520
521procedure TTestJSParser.TestAssignExpressionAnd;
522
523Var
524  X : TJSExpressionStatement;
525  SA : TJSAndEqAssignStatement;
526
527begin
528  CreateParser('a&=1;');
529  X:=GetExpressionStatement;
530  AssertNotNull('Expression statement assigned',X.A);
531  CheckClass(X.A,TJSAndEqAssignStatement);
532  SA:=TJSAndEqAssignStatement(X.A);
533  AssertNotNull('Assignment LHS assigned',SA.LHS);
534  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
535  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
536  AssertNotNull('Assignment Expression assigned',SA.Expr);
537  CheckClass(SA.EXPR,TJSLiteral);
538  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
539  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
540end;
541
542procedure TTestJSParser.TestAssignExpressionOr;
543
544Var
545  X : TJSExpressionStatement;
546  SA : TJSOrEqAssignStatement;
547
548begin
549  CreateParser('a|=1;');
550  X:=GetExpressionStatement;
551  AssertNotNull('Expression statement assigned',X.A);
552  CheckClass(X.A,TJSOrEqAssignStatement);
553  SA:=TJSOrEqAssignStatement(X.A);
554  AssertNotNull('Assignment LHS assigned',SA.LHS);
555  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
556  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
557  AssertNotNull('Assignment Expression assigned',SA.Expr);
558  CheckClass(SA.EXPR,TJSLiteral);
559  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
560  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
561end;
562
563procedure TTestJSParser.TestAssignExpressionXOr;
564
565Var
566  X : TJSExpressionStatement;
567  SA : TJSXOrEqAssignStatement;
568
569begin
570  CreateParser('a^=1;');
571  X:=GetExpressionStatement;
572  AssertNotNull('Expression statement assigned',X.A);
573  CheckClass(X.A,TJSXOrEqAssignStatement);
574  SA:=TJSXOrEqAssignStatement(X.A);
575  AssertNotNull('Assignment LHS assigned',SA.LHS);
576  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
577  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
578  AssertNotNull('Assignment Expression assigned',SA.Expr);
579  CheckClass(SA.EXPR,TJSLiteral);
580  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
581  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
582end;
583
584procedure TTestJSParser.TestAssignExpressionLShift;
585
586Var
587  X : TJSExpressionStatement;
588  SA : TJSLShiftEqAssignStatement;
589
590begin
591  CreateParser('a<<=1;');
592  X:=GetExpressionStatement;
593  AssertNotNull('Expression statement assigned',X.A);
594  CheckClass(X.A,TJSLShiftEqAssignStatement);
595  SA:=TJSLShiftEqAssignStatement(X.A);
596  AssertNotNull('Assignment LHS assigned',SA.LHS);
597  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
598  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
599  AssertNotNull('Assignment Expression assigned',SA.Expr);
600  CheckClass(SA.EXPR,TJSLiteral);
601  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
602  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
603end;
604
605procedure TTestJSParser.TestAssignExpressionRShift;
606
607Var
608  X : TJSExpressionStatement;
609  SA : TJSRShiftEqAssignStatement;
610
611begin
612  CreateParser('a>>=1;');
613  X:=GetExpressionStatement;
614  AssertNotNull('Expression statement assigned',X.A);
615  CheckClass(X.A,TJSRShiftEqAssignStatement);
616  SA:=TJSRShiftEqAssignStatement(X.A);
617  AssertNotNull('Assignment LHS assigned',SA.LHS);
618  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
619  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
620  AssertNotNull('Assignment Expression assigned',SA.Expr);
621  CheckClass(SA.EXPR,TJSLiteral);
622  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
623  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
624end;
625
626procedure TTestJSParser.TestAssignExpressionURShift;
627
628Var
629  X : TJSExpressionStatement;
630  SA : TJSURShiftEqAssignStatement;
631
632begin
633  CreateParser('a>>>=1;');
634  X:=GetExpressionStatement;
635  AssertNotNull('Expression statement assigned',X.A);
636  CheckClass(X.A,TJSURShiftEqAssignStatement);
637  SA:=TJSURShiftEqAssignStatement(X.A);
638  AssertNotNull('Assignment LHS assigned',SA.LHS);
639  CheckClass(SA.LHS,TJSPrimaryExpressionIdent);
640  AssertEquals('Expression LHS name correct', 'a',TJSPrimaryExpressionIdent(SA.LHS).Name);
641  AssertNotNull('Assignment Expression assigned',SA.Expr);
642  CheckClass(SA.EXPR,TJSLiteral);
643  AssertEquals('Expression value type correct', jstNumber,TJSLiteral(SA.Expr).Value.ValueType);
644  AssertEquals('Expression value correct', 1.0, TJSLiteral(SA.Expr).Value.AsNumber);
645end;
646
647procedure TTestJSParser.TestExpressionPlus;
648
649Var
650  X : TJSExpressionStatement;
651  E : TJSAdditiveExpressionPlus;
652
653begin
654  CreateParser('1+2;');
655  X:=GetExpressionStatement;
656  AssertNotNull('Expression statement assigned',X.A);
657  CheckClass(X.A,TJSAdditiveExpressionPlus);
658  E:=TJSAdditiveExpressionPlus(X.A);
659  AssertNotNull('Expression left operand assigned',E.A);
660  AssertNotNull('Expression right operand assigned',E.B);
661  CheckClass(E.A,TJSLiteral);
662  CheckClass(E.B,TJSLiteral);
663  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
664  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
665  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
666  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
667  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
668  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
669end;
670
671procedure TTestJSParser.TestExpressionSub;
672Var
673  X : TJSExpressionStatement;
674  E : TJSAdditiveExpressionMinus;
675
676begin
677  CreateParser('1 - 2;');
678  X:=GetExpressionStatement;
679  AssertNotNull('Expression statement assigned',X.A);
680  CheckClass(X.A,TJSAdditiveExpressionMinus);
681  E:=TJSAdditiveExpressionMinus(X.A);
682  AssertNotNull('Expression left operand assigned',E.A);
683  AssertNotNull('Expression right operand assigned',E.B);
684  CheckClass(E.A,TJSLiteral);
685  CheckClass(E.B,TJSLiteral);
686  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
687  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
688  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
689  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
690  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
691  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
692end;
693
694procedure TTestJSParser.TestExpressionMul;
695
696Var
697  X : TJSExpressionStatement;
698  E : TJSMultiplicativeExpressionMul;
699
700begin
701  CreateParser('1*2;');
702  X:=GetExpressionStatement;
703  AssertNotNull('Expression statement assigned',X.A);
704  CheckClass(X.A,TJSMultiplicativeExpressionMul);
705  E:=TJSMultiplicativeExpressionMul(X.A);
706  AssertNotNull('Expression left operand assigned',E.A);
707  AssertNotNull('Expression right operand assigned',E.B);
708  CheckClass(E.A,TJSLiteral);
709  CheckClass(E.B,TJSLiteral);
710  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
711  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
712  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
713  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
714  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
715  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
716end;
717
718procedure TTestJSParser.TestExpressionDiv;
719Var
720  X : TJSExpressionStatement;
721  E : TJSMultiplicativeExpressionDiv;
722
723begin
724  CreateParser('1/2;');
725  X:=GetExpressionStatement;
726  AssertNotNull('Expression statement assigned',X.A);
727  CheckClass(X.A,TJSMultiplicativeExpressionDiv);
728  E:=TJSMultiplicativeExpressionDiv(X.A);
729  AssertNotNull('Expression left operand assigned',E.A);
730  AssertNotNull('Expression right operand assigned',E.B);
731  CheckClass(E.A,TJSLiteral);
732  CheckClass(E.B,TJSLiteral);
733  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
734  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
735  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
736  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
737  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
738  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
739end;
740
741procedure TTestJSParser.TestExpressionMod;
742Var
743  X : TJSExpressionStatement;
744  E : TJSMultiplicativeExpressionMod;
745
746begin
747  CreateParser('1%2;');
748  X:=GetExpressionStatement;
749  AssertNotNull('Expression statement assigned',X.A);
750  CheckClass(X.A,TJSMultiplicativeExpressionMod);
751  E:=TJSMultiplicativeExpressionMod(X.A);
752  AssertNotNull('Expression left operand assigned',E.A);
753  AssertNotNull('Expression right operand assigned',E.B);
754  CheckClass(E.A,TJSLiteral);
755  CheckClass(E.B,TJSLiteral);
756  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
757  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
758  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
759  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
760  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
761  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
762end;
763
764procedure TTestJSParser.TestExpressionLShift;
765Var
766  X : TJSExpressionStatement;
767  E : TJSLShiftExpression;
768
769begin
770  CreateParser('1 << 2;');
771  X:=GetExpressionStatement;
772  AssertNotNull('Expression statement assigned',X.A);
773  CheckClass(X.A,TJSLShiftExpression);
774  E:=TJSLShiftExpression(X.A);
775  AssertNotNull('Expression left operand assigned',E.A);
776  AssertNotNull('Expression right operand assigned',E.B);
777  CheckClass(E.A,TJSLiteral);
778  CheckClass(E.B,TJSLiteral);
779  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
780  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
781  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
782  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
783  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
784  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
785end;
786
787procedure TTestJSParser.TestExpressionRShift;
788Var
789  X : TJSExpressionStatement;
790  E : TJSRShiftExpression;
791
792begin
793  CreateParser('1 >> 2;');
794  X:=GetExpressionStatement;
795  AssertNotNull('Expression statement assigned',X.A);
796  CheckClass(X.A,TJSRShiftExpression);
797  E:=TJSRShiftExpression(X.A);
798  AssertNotNull('Expression left operand assigned',E.A);
799  AssertNotNull('Expression right operand assigned',E.B);
800  CheckClass(E.A,TJSLiteral);
801  CheckClass(E.B,TJSLiteral);
802  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
803  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
804  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
805  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
806  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
807  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
808end;
809
810procedure TTestJSParser.TestExpressionURShift;
811Var
812  X : TJSExpressionStatement;
813  E : TJSURShiftExpression;
814
815begin
816  CreateParser('1 >>> 2;');
817  X:=GetExpressionStatement;
818  AssertNotNull('Expression statement assigned',X.A);
819  CheckClass(X.A,TJSURShiftExpression);
820  E:=TJSURShiftExpression(X.A);
821  AssertNotNull('Expression left operand assigned',E.A);
822  AssertNotNull('Expression right operand assigned',E.B);
823  CheckClass(E.A,TJSLiteral);
824  CheckClass(E.B,TJSLiteral);
825  AssertNotNull('Expression left operand value assigned',TJSLiteral(E.A).Value);
826  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
827  AssertEquals('Expression left operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
828  AssertNotNull('Expression right operand value assigned',TJSLiteral(E.B).Value);
829  AssertEquals('Expression left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
830  AssertEquals('Expression right operand value correct', 2.0,TJSLiteral(E.B).Value.AsNumber);
831end;
832
833procedure TTestJSParser.TestExpressionPostPlusPlus;
834Var
835  X : TJSExpressionStatement;
836  E : TJSUnaryPostPlusPlusExpression;
837
838begin
839  CreateParser('1++;');
840  X:=GetExpressionStatement;
841  AssertNotNull('Expression statement assigned',X.A);
842  CheckClass(X.A,TJSUnaryPostPlusPlusExpression);
843  E:=TJSUnaryPostPlusPlusExpression(X.A);
844  AssertNotNull('Expression left operand assigned',E.A);
845  CheckClass(E.A,TJSLiteral);
846  AssertNotNull('Expression  operand value assigned',TJSLiteral(E.A).Value);
847  AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
848  AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
849end;
850
851procedure TTestJSParser.TestExpressionPostMinusMinus;
852Var
853  X : TJSExpressionStatement;
854  E : TJSUnaryPostMinusMinusExpression;
855
856begin
857  CreateParser('1--;');
858  X:=GetExpressionStatement;
859  AssertNotNull('Expression statement assigned',X.A);
860  CheckClass(X.A,TJSUnaryPostMinusMinusExpression);
861  E:=TJSUnaryPostMinusMinusExpression(X.A);
862  AssertNotNull('Expression left operand assigned',E.A);
863  CheckClass(E.A,TJSLiteral);
864  AssertNotNull('Expression  operand value assigned',TJSLiteral(E.A).Value);
865  AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
866  AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
867end;
868
869procedure TTestJSParser.TestExpressionPrePlusPlus;
870
871Var
872  X : TJSExpressionStatement;
873  E : TJSUnaryPrePlusPlusExpression;
874
875begin
876  CreateParser('++1;');
877  X:=GetExpressionStatement;
878  AssertNotNull('Expression statement assigned',X.A);
879  CheckClass(X.A,TJSUnaryPrePlusPlusExpression);
880  E:=TJSUnaryPrePlusPlusExpression(X.A);
881  AssertNotNull('Expression left operand assigned',E.A);
882  CheckClass(E.A,TJSLiteral);
883  AssertNotNull('Expression  operand value assigned',TJSLiteral(E.A).Value);
884  AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
885  AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
886end;
887
888
889procedure TTestJSParser.TestExpressionPreMinusMinus;
890
891Var
892  X : TJSExpressionStatement;
893  E : TJSUnaryPreMinusMinusExpression;
894
895begin
896  CreateParser('--1;');
897  X:=GetExpressionStatement;
898  AssertNotNull('Expression statement assigned',X.A);
899  CheckClass(X.A,TJSUnaryPreMinusMinusExpression);
900  E:=TJSUnaryPreMinusMinusExpression(X.A);
901  AssertNotNull('Expression left operand assigned',E.A);
902  CheckClass(E.A,TJSLiteral);
903  AssertNotNull('Expression  operand value assigned',TJSLiteral(E.A).Value);
904  AssertEquals('Expression operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
905  AssertEquals('Expression operand value correct', 1.0, TJSLiteral(E.A).Value.AsNumber);
906end;
907
908procedure TTestJSParser.TestExpressionPrecedenceMulPlus;
909
910Var
911  X : TJSExpressionStatement;
912  E : TJSAdditiveExpressionPlus;
913  R : TJSMultiplicativeExpressionMul;
914begin
915  CreateParser('2 * 3 + 4;');
916  X:=GetExpressionStatement;
917  AssertNotNull('Expression statement assigned',X.A);
918  CheckClass(X.A,TJSAdditiveExpressionPlus);
919  E:=TJSAdditiveExpressionPlus(X.A);
920  AssertNotNull('Expression left operand assigned',E.A);
921  AssertNotNull('Expression right operand assigned',E.B);
922  CheckClass(E.A,TJSMultiplicativeExpressionMul);
923  R:=TJSMultiplicativeExpressionMul(E.A);
924  CheckClass(E.B,TJSLiteral);
925  AssertNotNull('Multiplication left operand assigned',R.A);
926  AssertNotNull('Multiplication right operand assigned',R.B);
927  CheckClass(R.A,TJSLiteral);
928  CheckClass(R.B,TJSLiteral);
929  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
930  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
931  AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
932  AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
933  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.B).Value);
934  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
935  AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
936end;
937
938procedure TTestJSParser.TestExpressionPrecedenceBraceMulPlus;
939
940Var
941  X : TJSExpressionStatement;
942  E : TJSMultiplicativeExpressionMul;
943  R : TJSAdditiveExpressionPlus;
944
945begin
946  CreateParser('2 * (3 + 4);');
947  X:=GetExpressionStatement;
948  AssertNotNull('Expression statement assigned',X.A);
949  CheckClass(X.A,TJSMultiplicativeExpressionMul);
950  E:=TJSMultiplicativeExpressionMul(X.A);
951  AssertNotNull('Expression left operand assigned',E.A);
952  AssertNotNull('Expression right operand assigned',E.B);
953  CheckClass(E.B,TJSAdditiveExpressionPlus);
954  R:=TJSAdditiveExpressionPlus(E.B);
955  CheckClass(E.A,TJSLiteral);
956  AssertNotNull('Multiplication left operand assigned',R.A);
957  AssertNotNull('Multiplication right operand assigned',R.B);
958  CheckClass(R.A,TJSLiteral);
959  CheckClass(R.B,TJSLiteral);
960  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
961  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(E.A).Value.AsNumber);
962  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
963  AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.A).Value.AsNumber);
964  AssertNotNull('Addition right operand value assigned',TJSLiteral(R.B).Value);
965  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
966  AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(R.B).Value.AsNumber);
967end;
968
969procedure TTestJSParser.TestExpressionPrecedenceBracePlusMul;
970
971Var
972  X : TJSExpressionStatement;
973  E : TJSMultiplicativeExpressionMul;
974  R : TJSAdditiveExpressionPlus;
975
976begin
977  CreateParser('(3 + 4)*2;');
978  X:=GetExpressionStatement;
979  AssertNotNull('Expression statement assigned',X.A);
980  CheckClass(X.A,TJSMultiplicativeExpressionMul);
981  E:=TJSMultiplicativeExpressionMul(X.A);
982  AssertNotNull('Expression left operand assigned',E.A);
983  AssertNotNull('Expression right operand assigned',E.B);
984  CheckClass(E.A,TJSAdditiveExpressionPlus);
985  R:=TJSAdditiveExpressionPlus(E.A);
986  CheckClass(E.B,TJSLiteral);
987  AssertNotNull('Multiplication left operand assigned',R.A);
988  AssertNotNull('Multiplication right operand assigned',R.B);
989  CheckClass(R.A,TJSLiteral);
990  CheckClass(R.B,TJSLiteral);
991  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
992  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(E.B).Value.AsNumber);
993  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
994  AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.A).Value.AsNumber);
995  AssertNotNull('Addition right operand value assigned',TJSLiteral(R.B).Value);
996  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
997  AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(R.B).Value.AsNumber);
998end;
999
1000procedure TTestJSParser.TestExpressionFunction;
1001Var
1002  X : TJSExpressionStatement;
1003  A  : TJSSimpleAssignStatement;
1004begin
1005  CreateParser('a = function () {};');
1006  X:=GetExpressionStatement;
1007  CheckClass(X.A,TJSSimpleAssignStatement);
1008  A:=TJSSimpleAssignStatement(X.A);
1009  AssertNotNull('Have left operand',A.LHS);
1010  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
1011  AssertEquals('Correct name for assignment LHS ','a',TJSPrimaryExpressionIdent(A.LHS).Name);
1012end;
1013
1014procedure TTestJSParser.TestExpressionPrecedencePlusMul;
1015
1016Var
1017  X : TJSExpressionStatement;
1018  E : TJSAdditiveExpressionPlus;
1019  R : TJSMultiplicativeExpressionMul;
1020begin
1021  CreateParser('4 + 2 * 3;');
1022  X:=GetExpressionStatement;
1023  AssertNotNull('Expression statement assigned',X.A);
1024  CheckClass(X.A,TJSAdditiveExpressionPlus);
1025  E:=TJSAdditiveExpressionPlus(X.A);
1026  AssertNotNull('Expression left operand assigned',E.A);
1027  AssertNotNull('Expression right operand assigned',E.B);
1028  CheckClass(E.B,TJSMultiplicativeExpressionMul);
1029  R:=TJSMultiplicativeExpressionMul(E.B);
1030  CheckClass(E.A,TJSLiteral);
1031  AssertNotNull('Multiplication left operand assigned',R.A);
1032  AssertNotNull('Multiplication right operand assigned',R.B);
1033  CheckClass(R.A,TJSLiteral);
1034  CheckClass(R.B,TJSLiteral);
1035  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1036  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1037  AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1038  AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1039  AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1040  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1041  AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1042end;
1043
1044procedure TTestJSParser.TestExpressionPrecedenceMulMinus;
1045
1046Var
1047  X : TJSExpressionStatement;
1048  E : TJSAdditiveExpressionMinus;
1049  R : TJSMultiplicativeExpressionMul;
1050
1051begin
1052  CreateParser('2 * 3 - 4;');
1053  X:=GetExpressionStatement;
1054  AssertNotNull('Expression statement assigned',X.A);
1055  CheckClass(X.A,TJSAdditiveExpressionMinus);
1056  E:=TJSAdditiveExpressionMinus(X.A);
1057  AssertNotNull('Expression left operand assigned',E.A);
1058  AssertNotNull('Expression right operand assigned',E.B);
1059  CheckClass(E.A,TJSMultiplicativeExpressionMul);
1060  R:=TJSMultiplicativeExpressionMul(E.A);
1061  CheckClass(E.B,TJSLiteral);
1062  AssertNotNull('Multiplication left operand assigned',R.A);
1063  AssertNotNull('Multiplication right operand assigned',R.B);
1064  CheckClass(R.A,TJSLiteral);
1065  CheckClass(R.B,TJSLiteral);
1066  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1067  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1068  AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1069  AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1070  AssertNotNull('subtraction right operand value assigned',TJSLiteral(E.B).Value);
1071  AssertEquals('subtraction right operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
1072  AssertEquals('subtraction right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
1073end;
1074
1075procedure TTestJSParser.TestExpressionPrecedenceMinusMul;
1076
1077Var
1078  X : TJSExpressionStatement;
1079  E : TJSAdditiveExpressionMinus;
1080  R : TJSMultiplicativeExpressionMul;
1081begin
1082  CreateParser('4 - 2 * 3;');
1083  X:=GetExpressionStatement;
1084  AssertNotNull('Expression statement assigned',X.A);
1085  CheckClass(X.A,TJSAdditiveExpressionMinus);
1086  E:=TJSAdditiveExpressionMinus(X.A);
1087  AssertNotNull('Expression left operand assigned',E.A);
1088  AssertNotNull('Expression right operand assigned',E.B);
1089  CheckClass(E.B,TJSMultiplicativeExpressionMul);
1090  R:=TJSMultiplicativeExpressionMul(E.B);
1091  CheckClass(E.A,TJSLiteral);
1092  AssertNotNull('Multiplication left operand assigned',R.A);
1093  AssertNotNull('Multiplication right operand assigned',R.B);
1094  CheckClass(R.A,TJSLiteral);
1095  CheckClass(R.B,TJSLiteral);
1096  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1097  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1098  AssertEquals('Multiplication right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1099  AssertEquals('Multiplication right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1100  AssertNotNull('Subtraction left operand value assigned',TJSLiteral(E.A).Value);
1101  AssertEquals('Subtraction left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1102  AssertEquals('Subtraction left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1103end;
1104
1105procedure TTestJSParser.TestExpressionPrecedenceDivPlus;
1106
1107Var
1108  X : TJSExpressionStatement;
1109  E : TJSAdditiveExpressionPlus;
1110  R : TJSMultiplicativeExpressionDiv;
1111begin
1112  CreateParser('2 / 3 + 4;');
1113  X:=GetExpressionStatement;
1114  AssertNotNull('Expression statement assigned',X.A);
1115  CheckClass(X.A,TJSAdditiveExpressionPlus);
1116  E:=TJSAdditiveExpressionPlus(X.A);
1117  AssertNotNull('Expression left operand assigned',E.A);
1118  AssertNotNull('Expression right operand assigned',E.B);
1119  CheckClass(E.A,TJSMultiplicativeExpressionDiv);
1120  R:=TJSMultiplicativeExpressionDiv(E.A);
1121  CheckClass(E.B,TJSLiteral);
1122  AssertNotNull('Div left operand assigned',R.A);
1123  AssertNotNull('Div right operand assigned',R.B);
1124  CheckClass(R.A,TJSLiteral);
1125  CheckClass(R.B,TJSLiteral);
1126  AssertEquals('Div left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1127  AssertEquals('Div left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1128  AssertEquals('Div right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1129  AssertEquals('Div right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1130  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.B).Value);
1131  AssertEquals('Addition right operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
1132  AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
1133end;
1134
1135procedure TTestJSParser.TestExpressionPrecedencePlusDiv;
1136
1137Var
1138  X : TJSExpressionStatement;
1139  E : TJSAdditiveExpressionPlus;
1140  R : TJSMultiplicativeExpressionDiv;
1141
1142begin
1143  CreateParser('4 + 2 / 3;');
1144  X:=GetExpressionStatement;
1145  AssertNotNull('Expression statement assigned',X.A);
1146  CheckClass(X.A,TJSAdditiveExpressionPlus);
1147  E:=TJSAdditiveExpressionPlus(X.A);
1148  AssertNotNull('Expression left operand assigned',E.A);
1149  AssertNotNull('Expression right operand assigned',E.B);
1150  CheckClass(E.B,TJSMultiplicativeExpressionDiv);
1151  R:=TJSMultiplicativeExpressionDiv(E.B);
1152  CheckClass(E.A,TJSLiteral);
1153  AssertNotNull('Div left operand assigned',R.A);
1154  AssertNotNull('Div right operand assigned',R.B);
1155  CheckClass(R.A,TJSLiteral);
1156  CheckClass(R.B,TJSLiteral);
1157  AssertEquals('Div left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1158  AssertEquals('Div left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1159  AssertEquals('Div right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1160  AssertEquals('Div right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1161  AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1162  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1163  AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1164end;
1165
1166procedure TTestJSParser.TestExpressionPrecedenceModPlus;
1167
1168Var
1169  X : TJSExpressionStatement;
1170  E : TJSAdditiveExpressionPlus;
1171  R : TJSMultiplicativeExpressionMod;
1172begin
1173  CreateParser('2 % 3 + 4;');
1174  X:=GetExpressionStatement;
1175  AssertNotNull('Expression statement assigned',X.A);
1176  CheckClass(X.A,TJSAdditiveExpressionPlus);
1177  E:=TJSAdditiveExpressionPlus(X.A);
1178  AssertNotNull('Expression left operand assigned',E.A);
1179  AssertNotNull('Expression right operand assigned',E.B);
1180  CheckClass(E.A,TJSMultiplicativeExpressionMod);
1181  R:=TJSMultiplicativeExpressionMod(E.A);
1182  CheckClass(E.B,TJSLiteral);
1183  AssertNotNull('mod left operand assigned',R.A);
1184  AssertNotNull('mod right operand assigned',R.B);
1185  CheckClass(R.A,TJSLiteral);
1186  CheckClass(R.B,TJSLiteral);
1187  AssertEquals('mod left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1188  AssertEquals('mod left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1189  AssertEquals('mod right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1190  AssertEquals('mod right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1191  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.B).Value);
1192  AssertEquals('Addition right operand type correct', jstNumber, TJSLiteral(E.B).Value.ValueType);
1193  AssertEquals('Addition right operand value correct', 4.0,TJSLiteral(E.B).Value.AsNumber);
1194end;
1195
1196procedure TTestJSParser.TestExpressionPrecedencePlusMod;
1197
1198Var
1199  X : TJSExpressionStatement;
1200  E : TJSAdditiveExpressionPlus;
1201  R : TJSMultiplicativeExpressionMod;
1202
1203begin
1204  CreateParser('4 + 2 % 3;');
1205  X:=GetExpressionStatement;
1206  AssertNotNull('Expression statement assigned',X.A);
1207  CheckClass(X.A,TJSAdditiveExpressionPlus);
1208  E:=TJSAdditiveExpressionPlus(X.A);
1209  AssertNotNull('Expression left operand assigned',E.A);
1210  AssertNotNull('Expression right operand assigned',E.B);
1211  CheckClass(E.B,TJSMultiplicativeExpressionMod);
1212  R:=TJSMultiplicativeExpressionMod(E.B);
1213  CheckClass(E.A,TJSLiteral);
1214  AssertNotNull('Mod left operand assigned',R.A);
1215  AssertNotNull('Mod right operand assigned',R.B);
1216  CheckClass(R.A,TJSLiteral);
1217  CheckClass(R.B,TJSLiteral);
1218  AssertEquals('Mod left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1219  AssertEquals('Mod left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1220  AssertEquals('Mod right operand type correct', jstNumber, TJSLiteral(R.B).Value.ValueType);
1221  AssertEquals('Mod right operand value correct', 3.0, TJSLiteral(R.B).Value.AsNumber);
1222  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
1223  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1224  AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1225end;
1226
1227procedure TTestJSParser.TestExpressionPrecedencePlusPostPlusPlus;
1228
1229Var
1230  X : TJSExpressionStatement;
1231  R : TJSUnaryPostPlusPlusExpression;
1232  E : TJSAdditiveExpressionPlus;
1233
1234begin
1235  CreateParser('4 + 2++;');
1236  X:=GetExpressionStatement;
1237  AssertNotNull('Expression statement assigned',X.A);
1238  CheckClass(X.A,TJSAdditiveExpressionPlus);
1239  E:=TJSAdditiveExpressionPlus(X.A);
1240  AssertNotNull('Expression left operand assigned',E.A);
1241  AssertNotNull('Expression right operand assigned',E.B);
1242  CheckClass(E.B,TJSUnaryPostPlusPlusExpression);
1243  R:=TJSUnaryPostPlusPlusExpression(E.B);
1244  CheckClass(E.A,TJSLiteral);
1245  AssertNotNull('++ operand assigned',R.A);
1246  CheckClass(R.A,TJSLiteral);
1247  AssertEquals('++ operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1248  AssertEquals('++ operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1249  AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1250  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1251  AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1252end;
1253
1254procedure TTestJSParser.TestExpressionPrecedencePlusPostMinusMinus;
1255Var
1256  X : TJSExpressionStatement;
1257  R : TJSUnaryPostMinusMinusExpression;
1258  E : TJSAdditiveExpressionPlus;
1259
1260begin
1261  CreateParser('4 + 2--;');
1262  X:=GetExpressionStatement;
1263  AssertNotNull('Expression statement assigned',X.A);
1264  CheckClass(X.A,TJSAdditiveExpressionPlus);
1265  E:=TJSAdditiveExpressionPlus(X.A);
1266  AssertNotNull('Expression left operand assigned',E.A);
1267  AssertNotNull('Expression right operand assigned',E.B);
1268  CheckClass(E.B,TJSUnaryPostMinusMinusExpression);
1269  R:=TJSUnaryPostMinusMinusExpression(E.B);
1270  CheckClass(E.A,TJSLiteral);
1271  AssertNotNull('-- operand assigned',R.A);
1272  CheckClass(R.A,TJSLiteral);
1273  AssertEquals('-- operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1274  AssertEquals('-- operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1275  AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1276  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1277  AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1278end;
1279
1280procedure TTestJSParser.TestExpressionPrecedenceMulPostPlusPlus;
1281
1282Var
1283  X : TJSExpressionStatement;
1284  R : TJSUnaryPostPlusPlusExpression;
1285  E : TJSMultiplicativeExpressionMul;
1286
1287begin
1288  CreateParser('4 * 2++;');
1289  X:=GetExpressionStatement;
1290  AssertNotNull('Expression statement assigned',X.A);
1291  CheckClass(X.A,TJSMultiplicativeExpressionMul);
1292  E:=TJSMultiplicativeExpressionMul(X.A);
1293  AssertNotNull('Expression left operand assigned',E.A);
1294  AssertNotNull('Expression right operand assigned',E.B);
1295  CheckClass(E.B,TJSUnaryPostPlusPlusExpression);
1296  R:=TJSUnaryPostPlusPlusExpression(E.B);
1297  CheckClass(E.A,TJSLiteral);
1298  AssertNotNull('++operand assigned',R.A);
1299  CheckClass(R.A,TJSLiteral);
1300  AssertEquals('++ operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1301  AssertEquals('++ operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1302  AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
1303  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1304  AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1305end;
1306
1307procedure TTestJSParser.TestExpressionPrecedenceMulPostMinusMinus;
1308Var
1309  X : TJSExpressionStatement;
1310  R : TJSUnaryPostMinusMinusExpression;
1311  E : TJSMultiplicativeExpressionMul;
1312
1313begin
1314  CreateParser('4 * 2--;');
1315  X:=GetExpressionStatement;
1316  AssertNotNull('Expression statement assigned',X.A);
1317  CheckClass(X.A,TJSMultiplicativeExpressionMul);
1318  E:=TJSMultiplicativeExpressionMul(X.A);
1319  AssertNotNull('Expression left operand assigned',E.A);
1320  AssertNotNull('Expression right operand assigned',E.B);
1321  CheckClass(E.B,TJSUnaryPostMinusMinusExpression);
1322  R:=TJSUnaryPostMinusMinusExpression(E.B);
1323  CheckClass(E.A,TJSLiteral);
1324  AssertNotNull('-- operand assigned',R.A);
1325  CheckClass(R.A,TJSLiteral);
1326  AssertEquals('-- operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1327  AssertEquals('-- operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1328  AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
1329  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1330  AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1331end;
1332
1333procedure TTestJSParser.TestExpressionPrecedencePlusPrePlusPlus;
1334
1335Var
1336  X : TJSExpressionStatement;
1337  R : TJSUnaryPrePlusPlusExpression;
1338  E : TJSAdditiveExpressionPlus;
1339
1340begin
1341  CreateParser('4 + ++2;');
1342  X:=GetExpressionStatement;
1343  AssertNotNull('Expression statement assigned',X.A);
1344  CheckClass(X.A,TJSAdditiveExpressionPlus);
1345  E:=TJSAdditiveExpressionPlus(X.A);
1346  AssertNotNull('Expression left operand assigned',E.A);
1347  AssertNotNull('Expression right operand assigned',E.B);
1348  CheckClass(E.B,TJSUnaryPrePlusPlusExpression);
1349  R:=TJSUnaryPrePlusPlusExpression(E.B);
1350  CheckClass(E.A,TJSLiteral);
1351  AssertNotNull('Multiplication left operand assigned',R.A);
1352  CheckClass(R.A,TJSLiteral);
1353  AssertEquals('++ operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1354  AssertEquals('++ operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1355  AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1356  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1357  AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1358end;
1359
1360procedure TTestJSParser.TestExpressionPrecedencePlusInv;
1361
1362Var
1363  X : TJSExpressionStatement;
1364  R : TJSUnaryInvExpression;
1365  E : TJSAdditiveExpressionPlus;
1366
1367begin
1368    CreateParser('4 + ~2;');
1369    X:=GetExpressionStatement;
1370    AssertNotNull('Expression statement assigned',X.A);
1371    CheckClass(X.A,TJSAdditiveExpressionPlus);
1372    E:=TJSAdditiveExpressionPlus(X.A);
1373    AssertNotNull('Expression left operand assigned',E.A);
1374    AssertNotNull('Expression right operand assigned',E.B);
1375    CheckClass(E.B,TJSUnaryInvExpression);
1376    R:=TJSUnaryInvExpression(E.B);
1377    CheckClass(E.A,TJSLiteral);
1378    AssertNotNull('Multiplication left operand assigned',R.A);
1379    CheckClass(R.A,TJSLiteral);
1380    AssertEquals('inv operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1381    AssertEquals('inv operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1382    AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1383    AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1384    AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1385end;
1386
1387procedure TTestJSParser.TestExpressionPrecedenceMulInv;
1388
1389Var
1390  X : TJSExpressionStatement;
1391  R : TJSUnaryInvExpression;
1392  E : TJSMultiplicativeExpressionMul;
1393
1394begin
1395  CreateParser('4 * ~2;');
1396  X:=GetExpressionStatement;
1397  AssertNotNull('Expression statement assigned',X.A);
1398  CheckClass(X.A,TJSMultiplicativeExpressionMul);
1399  E:=TJSMultiplicativeExpressionMul(X.A);
1400  AssertNotNull('Expression left operand assigned',E.A);
1401  AssertNotNull('Expression right operand assigned',E.B);
1402  CheckClass(E.B,TJSUnaryInvExpression);
1403  R:=TJSUnaryInvExpression(E.B);
1404  CheckClass(E.A,TJSLiteral);
1405  AssertNotNull('Multiplication left operand assigned',R.A);
1406  CheckClass(R.A,TJSLiteral);
1407  AssertEquals('Inv operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1408  AssertEquals('Inv operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1409  AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
1410  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1411  AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1412end;
1413
1414procedure TTestJSParser.TestExpressionPrecedencePlusNot;
1415
1416Var
1417  X : TJSExpressionStatement;
1418  R : TJSUnaryNotExpression;
1419  E : TJSAdditiveExpressionPlus;
1420
1421begin
1422    CreateParser('4 + !2;');
1423    X:=GetExpressionStatement;
1424    AssertNotNull('Expression statement assigned',X.A);
1425    CheckClass(X.A,TJSAdditiveExpressionPlus);
1426    E:=TJSAdditiveExpressionPlus(X.A);
1427    AssertNotNull('Expression left operand assigned',E.A);
1428    AssertNotNull('Expression right operand assigned',E.B);
1429    CheckClass(E.B,TJSUnaryNotExpression);
1430    R:=TJSUnaryNotExpression(E.B);
1431    CheckClass(E.A,TJSLiteral);
1432    AssertNotNull('Multiplication left operand assigned',R.A);
1433    CheckClass(R.A,TJSLiteral);
1434    AssertEquals('Not operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
1435    AssertEquals('Not operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
1436    AssertNotNull('Addition left operand value assigned',TJSLiteral(E.A).Value);
1437    AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
1438    AssertEquals('Addition left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
1439end;
1440
1441procedure TTestJSParser.TestFunctionCallNoArgs;
1442
1443Var
1444  X : TJSExpressionStatement;
1445  C : TJSCallExpression;
1446
1447begin
1448  CreateParser('abc();');
1449  X:=GetExpressionStatement;
1450  CheckClass(X.A,TJSCallExpression);
1451  C:=TJSCallExpression(X.A);
1452  AssertEquals('No arguments',0,C.Args.Elements.Count);
1453  AssertNotNull('Call function expression',C.Expr);
1454  CheckClass(C.Expr,TJSPrimaryExpressionIdent);
1455  AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
1456end;
1457
1458procedure TTestJSParser.TestFunctionCallOneArg;
1459
1460Var
1461  X : TJSExpressionStatement;
1462  C : TJSCallExpression;
1463  E : TJSelement;
1464
1465begin
1466  CreateParser('abc(d);');
1467  X:=GetExpressionStatement;
1468  CheckClass(X.A,TJSCallExpression);
1469  C:=TJSCallExpression(X.A);
1470  AssertNotNull('Call function expression',C.Expr);
1471  CheckClass(C.Expr,TJSPrimaryExpressionIdent);
1472  AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
1473  AssertEquals('1 argument',1,C.Args.Elements.Count);
1474  E:=C.Args.Elements[0].Expr;
1475  AssertNotNull('First argument expression',E);
1476  CheckClass(E,TJSPrimaryExpressionIdent);
1477  AssertEquals('First argument name correct','d',TJSPrimaryExpressionIdent(E).Name);
1478end;
1479
1480procedure TTestJSParser.TestFunctionCallTwoArgs;
1481
1482Var
1483  X : TJSExpressionStatement;
1484  C : TJSCallExpression;
1485  E : TJSelement;
1486
1487begin
1488  CreateParser('abc(d,e);');
1489  X:=GetExpressionStatement;
1490  CheckClass(X.A,TJSCallExpression);
1491  C:=TJSCallExpression(X.A);
1492  AssertNotNull('Call function expression',C.Expr);
1493  CheckClass(C.Expr,TJSPrimaryExpressionIdent);
1494  AssertEquals('Function name correct','abc',TJSPrimaryExpressionIdent(C.Expr).Name);
1495  AssertEquals('2 arguments',2,C.Args.Elements.Count);
1496  E:=C.Args.Elements[0].Expr;
1497  AssertNotNull('First argument expression',E);
1498  CheckClass(E,TJSPrimaryExpressionIdent);
1499  AssertEquals('First argument name correct','d',TJSPrimaryExpressionIdent(E).Name);
1500  E:=C.Args.Elements[1].Expr;
1501  AssertNotNull('Second argument expression',E);
1502  CheckClass(E,TJSPrimaryExpressionIdent);
1503  AssertEquals('Second argument name correct','e',TJSPrimaryExpressionIdent(E).Name);
1504end;
1505
1506procedure TTestJSParser.TestArrayExpressionNumericalArgs;
1507Var
1508  X : TJSExpressionStatement;
1509  B : TJSBracketMemberExpression;
1510
1511begin
1512  CreateParser('A[1];');
1513  X:=GetExpressionStatement;
1514  CheckClass(X.A,TJSBracketMemberExpression);
1515  B:=TJSBracketMemberExpression(X.A);
1516  CheckClass(B.Name,TJSLiteral);
1517  AssertEquals('Member name operand type correct', jstNumber, TJSLiteral(B.Name).Value.ValueType);
1518  AssertEquals('Member name operand value correct', 1.0, TJSLiteral(B.Name).Value.AsNumber);
1519  CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
1520  AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
1521end;
1522
1523procedure TTestJSParser.TestArrayExpressionStringArgs;
1524Var
1525  X : TJSExpressionStatement;
1526  B : TJSBracketMemberExpression;
1527
1528begin
1529  CreateParser('A["propname"];');
1530  X:=GetExpressionStatement;
1531  CheckClass(X.A,TJSBracketMemberExpression);
1532  B:=TJSBracketMemberExpression(X.A);
1533  CheckClass(B.Name,TJSLiteral);
1534  AssertEquals('Member name operand type correct', jstString, TJSLiteral(B.Name).Value.ValueType);
1535  AssertEquals('Member name operand value correct', 'propname', TJSLiteral(B.Name).Value.AsString);
1536  CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
1537  AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
1538end;
1539
1540procedure TTestJSParser.TestArrayExpressionIdentArgs;
1541
1542Var
1543  X : TJSExpressionStatement;
1544  B : TJSBracketMemberExpression;
1545
1546begin
1547  CreateParser('A[B];');
1548  X:=GetExpressionStatement;
1549  CheckClass(X.A,TJSBracketMemberExpression);
1550  B:=TJSBracketMemberExpression(X.A);
1551  CheckClass(B.Name,TJSPrimaryExpressionIdent);
1552  AssertEquals('Member name identifier correct', 'B', TJSPrimaryExpressionIdent(B.Name).Name);
1553  CheckClass(B.Mexpr,TJSPrimaryExpressionIdent);
1554  AssertEquals('Array name correct','A',TJSPrimaryExpressionIdent(B.Mexpr).Name);
1555end;
1556
1557Procedure TTestJSParser.TestVarDeclarationSimple;
1558
1559Var
1560  X : TJSELement;
1561  V : TJSVarDeclaration;
1562begin
1563  CreateParser('var a;');
1564  X:=GetFirstVar;
1565  CheckClass(X,TJSVarDeclaration);
1566  V:=TJSVarDeclaration(X);
1567//  AssertNotNull('Variable statement assigned',(X));
1568  AssertEquals('variable name correct registered', 'a', V.Name);
1569  AssertNull('No initialization expression', V.Init);
1570end;
1571
1572procedure TTestJSParser.TestVarDeclarationDouble;
1573
1574Var
1575  X : TJSELement;
1576  V : TJSVarDeclaration;
1577
1578begin
1579  CreateParser('var a, b ;');
1580  AssertEquals('2 variables declared',2,GetVars.Count);
1581  X:=GetFirstVar;
1582  CheckClass(X,TJSVarDeclaration);
1583  V:=TJSVarDeclaration(X);
1584//  AssertNotNull('Variable statement assigned',(X));
1585  AssertEquals('variable name correct registered', 'a', V.name);
1586  X:=GetVars.Nodes[1].Node;
1587  CheckClass(X,TJSVarDeclaration);
1588  V:=TJSVarDeclaration(X);
1589  AssertEquals('variable name correct registered', 'b', V.Name);
1590  AssertNull('No initialization expression', V.Init);
1591end;
1592
1593procedure TTestJSParser.TestVarDeclarationSimpleInit;
1594
1595Var
1596  X : TJSELement;
1597  V : TJSVarDeclaration;
1598begin
1599  CreateParser('var a = b;');
1600  X:=GetFirstVar;
1601  CheckClass(X,TJSVarDeclaration);
1602  V:=TJSVarDeclaration(X);
1603//  AssertNotNull('Variable statement assigned',(X));
1604  AssertEquals('variable name correct registered', 'a', V.Name);
1605  AssertNotNull('Initialization expression present', V.Init);
1606  CheckClass(V.Init,TJSPrimaryExpressionIdent);
1607  AssertEquals('Member name identifier correct', 'b', TJSPrimaryExpressionIdent(V.init).Name);
1608end;
1609
1610procedure TTestJSParser.TestVarDeclarationDoubleInit;
1611
1612Var
1613  X : TJSELement;
1614  V : TJSVarDeclaration;
1615begin
1616  CreateParser('var a, c = b;');
1617  AssertEquals('2 variables declared',2,GetVars.Count);
1618  X:=GetFirstVar;
1619  CheckClass(X,TJSVarDeclaration);
1620  V:=TJSVarDeclaration(X);
1621//  AssertNotNull('Variable statement assigned',(X));
1622  AssertEquals('variable name correct registered', 'a', V.Name);
1623  AssertNull('No initialization expression', V.Init);
1624  X:=GetVars.Nodes[1].Node;
1625  CheckClass(X,TJSVarDeclaration);
1626  V:=TJSVarDeclaration(X);
1627  AssertEquals('variable name correct registered', 'c', V.Name);
1628  AssertNotNull('No initialization expression', V.Init);
1629  CheckClass(V.Init,TJSPrimaryExpressionIdent);
1630  AssertEquals('Member name identifier correct', 'b', TJSPrimaryExpressionIdent(V.init).Name);
1631end;
1632
1633procedure TTestJSParser.TestBlockEmpty;
1634
1635Var
1636  E : TJSSourceElements;
1637  X : TJSElement;
1638
1639begin
1640  CreateParser('{}');
1641  E:=GetSourceElements;
1642  AssertEquals('1 statement in block',1,E.Statements.Count);
1643  X:=E.Statements.Nodes[0].Node;
1644  CheckClass(X,TJSEmptyBlockStatement);
1645end;
1646
1647procedure TTestJSParser.TestBlockEmptyStatement;
1648
1649Var
1650  E : TJSSourceElements;
1651  X : TJSElement;
1652
1653begin
1654  CreateParser('{;}');
1655  E:=GetSourceElements;
1656  AssertEquals('1 statement in block',1,E.Statements.Count);
1657  X:=E.Statements.Nodes[0].Node;
1658  CheckClass(X,TJSEmptyStatement);
1659end;
1660
1661procedure TTestJSParser.TestBlockSimpleStatement;
1662
1663Var
1664  E : TJSSourceElements;
1665  X : TJSElement;
1666
1667begin
1668  CreateParser('{a;}');
1669  E:=GetSourceElements;
1670  AssertEquals('1 statement in block',1,E.Statements.Count);
1671  X:=E.Statements.Nodes[0].Node;
1672  CheckClass(X,TJSExpressionStatement);
1673  CheckNotNull(TJSExpressionStatement(X).A);
1674  CheckClass(TJSExpressionStatement(X).A,TJSPrimaryExpressionIdent);
1675  AssertEquals('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(X).A).Name)
1676end;
1677
1678procedure TTestJSParser.TestFunctionDeclarationEmpty;
1679
1680Var
1681  E : TJSSourceElements;
1682  N : TJSElement;
1683  FD : TJSFunctionDeclarationStatement;
1684
1685begin
1686  CreateParser('function a () {}');
1687  E:=GetSourceElements;
1688  AssertEquals('1 function defined',1,E.functions.Count);
1689  N:=E.Functions.Nodes[0].Node;
1690  AssertNotNull('Function element defined ',N);
1691  CheckClass(N,TJSFunctionDeclarationStatement);
1692  FD:=TJSFunctionDeclarationStatement(N);
1693  AssertNotNull('Function definition assigned',FD.AFunction);
1694  AssertEquals('Function name OK','a',FD.AFunction.Name);
1695  AssertNotNull('Function body assigned', FD.AFunction.Body);
1696  AssertEquals('No parameters',0,FD.AFunction.Params.Count);
1697  N:=FD.AFunction.Body;
1698  CheckClass(N,TJSFunctionBody);
1699  AssertNotNull('Function body has element',TJSFunctionBody(N).A);
1700  CheckClass(TJSFunctionBody(N).A,  TJSSourceElements);
1701  E:=TJSSourceElements(TJSFunctionBody(N).A);
1702  AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
1703//  TJSEmptyBlockStatement
1704end;
1705
1706procedure TTestJSParser.TestFunctionDeclarationWithArgs;
1707
1708Var
1709  E : TJSSourceElements;
1710  N : TJSElement;
1711  FD : TJSFunctionDeclarationStatement;
1712
1713begin
1714  CreateParser('function a (b,c) {}');
1715  E:=GetSourceElements;
1716  AssertEquals('1 function defined',1,E.functions.Count);
1717  N:=E.Functions.Nodes[0].Node;
1718  AssertNotNull('Function element defined ',N);
1719  CheckClass(N,TJSFunctionDeclarationStatement);
1720  FD:=TJSFunctionDeclarationStatement(N);
1721  AssertNotNull('Function definition assigned',FD.AFunction);
1722  AssertEquals('Function name OK','a',FD.AFunction.Name);
1723  AssertNotNull('Function body assigned', FD.AFunction.Body);
1724  AssertEquals('2 parameters',2,FD.AFunction.Params.Count);
1725  AssertEquals('1st parameter','b',FD.AFunction.Params[0]);
1726  AssertEquals('2nd parameter','c',FD.AFunction.Params[1]);
1727  N:=FD.AFunction.Body;
1728  CheckClass(N,TJSFunctionBody);
1729  AssertNotNull('Function body has element',TJSFunctionBody(N).A);
1730  CheckClass(TJSFunctionBody(N).A,  TJSSourceElements);
1731  E:=TJSSourceElements(TJSFunctionBody(N).A);
1732  AssertEquals('0 statement in functionbody elements',0,E.Statements.Count);
1733//  TJSEmptyBlockStatement
1734end;
1735
1736procedure TTestJSParser.TestFunctionDeclarationWithBody;
1737
1738Var
1739  E : TJSSourceElements;
1740  N : TJSElement;
1741  FD : TJSFunctionDeclarationStatement;
1742
1743begin
1744  CreateParser('function a () { b; }');
1745  E:=GetSourceElements;
1746  AssertEquals('1 function defined',1,E.functions.Count);
1747  N:=E.Functions.Nodes[0].Node;
1748  AssertNotNull('Function element defined ',N);
1749  CheckClass(N,TJSFunctionDeclarationStatement);
1750  FD:=TJSFunctionDeclarationStatement(N);
1751  AssertNotNull('Function definition assigned',FD.AFunction);
1752  AssertEquals('Function name OK','a',FD.AFunction.Name);
1753  AssertNotNull('Function body assigned', FD.AFunction.Body);
1754  AssertEquals('2 parameters',0,FD.AFunction.Params.Count);
1755  N:=FD.AFunction.Body;
1756  CheckClass(N,TJSFunctionBody);
1757  AssertNotNull('Function body has element',TJSFunctionBody(N).A);
1758  CheckClass(TJSFunctionBody(N).A,  TJSSourceElements);
1759  E:=TJSSourceElements(TJSFunctionBody(N).A);
1760  AssertEquals('1 statement in functionbody elements',1,E.Statements.Count);
1761  N:=E.Statements.Nodes[0].Node;
1762  CheckClass(N,TJSExpressionStatement);
1763  CheckNotNull(TJSExpressionStatement(N).A);
1764  CheckClass(TJSExpressionStatement(N).A,TJSPrimaryExpressionIdent);
1765  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(N).A).Name);
1766//  TJSEmptyBlockStatement
1767end;
1768
1769procedure TTestJSParser.TestIfSimple;
1770
1771Var
1772  E : TJSElement;
1773  I : TJSIfStatement;
1774
1775begin
1776  CreateParser('if (a) b;');
1777  E:=GetFirstStatement;
1778  CheckClass(E,TJSIfStatement);
1779  I:=TJSIfStatement(E);
1780  AssertNotNull('Statement condition assigned',I.Cond);
1781  CheckClass(I.Cond,TJSPrimaryExpressionIdent);
1782  AssertEquals('a',TJSPrimaryExpressionIdent(I.Cond).Name);
1783  AssertNull('Statement false branch assigned',I.BFalse);
1784  AssertNotNull('Statement true branch assigned',I.Btrue);
1785  CheckClass(I.Btrue,TJSExpressionStatement);
1786  AssertNotNull('Expression statement expression',TJSExpressionStatement(I.BTrue).A);
1787  CheckClass(TJSExpressionStatement(I.BTrue).A,TJSPrimaryExpressionIdent);
1788  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.Btrue).A).Name);
1789end;
1790
1791procedure TTestJSParser.TestIfEmptyBlock;
1792
1793Var
1794  E : TJSElement;
1795  I : TJSIfStatement;
1796
1797begin
1798  CreateParser('if (a) {}');
1799  E:=GetFirstStatement;
1800  CheckClass(E,TJSIfStatement);
1801  I:=TJSIfStatement(E);
1802  AssertNotNull('Statement condition assigned',I.Cond);
1803  CheckClass(I.Cond,TJSPrimaryExpressionIdent);
1804  AssertEquals('a',TJSPrimaryExpressionIdent(I.Cond).Name);
1805  AssertNull('Statement false branch assigned',I.BFalse);
1806  AssertNotNull('Statement true branch assigned',I.Btrue);
1807  CheckClass(I.Btrue,TJSEmptyBlockStatement);
1808end;
1809
1810procedure TTestJSParser.TestIfEmptyBlockElse;
1811
1812Var
1813  E : TJSElement;
1814  I : TJSIfStatement;
1815
1816begin
1817  CreateParser('if (a) {} else b;');
1818  E:=GetFirstStatement;
1819  CheckClass(E,TJSIfStatement);
1820  I:=TJSIfStatement(E);
1821  AssertNotNull('Statement condition assigned',I.Cond);
1822  CheckClass(I.Cond,TJSPrimaryExpressionIdent);
1823  AssertEquals('a',TJSPrimaryExpressionIdent(I.Cond).Name);
1824  AssertNotNull('Statement false branch assigned',I.BFalse);
1825  AssertNotNull('Statement true branch assigned',I.Btrue);
1826  CheckClass(I.Btrue,TJSEmptyBlockStatement);
1827end;
1828
1829procedure TTestJSParser.TestWhileSimple;
1830Var
1831  E : TJSElement;
1832  W : TJSWhileStatement;
1833
1834begin
1835  CreateParser('while (a) b;');
1836  E:=GetFirstStatement;
1837  CheckClass(E,TJSWhileStatement);
1838  W:=TJSWhileStatement(E);
1839  AssertNotNull('Statement condition assigned',W.Cond);
1840  CheckClass(W.Cond,TJSPrimaryExpressionIdent);
1841  AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).Name);
1842  AssertNotNull('Statement condition assigned',W.body);
1843  CheckClass(W.Body,TJSExpressionStatement);
1844  AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
1845  CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
1846  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
1847end;
1848
1849procedure TTestJSParser.TestWhileBlock;
1850
1851Var
1852  E : TJSElement;
1853  W : TJSWhileStatement;
1854//  B : TJSBlockStatement;
1855
1856begin
1857  CreateParser('while (a) {b;}');
1858  E:=GetFirstStatement;
1859  CheckClass(E,TJSWhileStatement);
1860  W:=TJSWhileStatement(E);
1861  AssertNotNull('Statement condition assigned',W.Cond);
1862  CheckClass(W.Cond,TJSPrimaryExpressionIdent);
1863  AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).Name);
1864  AssertNotNull('Statement condition assigned',W.body);
1865  CheckClass(W.Body,TJSExpressionStatement);
1866  AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
1867  CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
1868  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
1869end;
1870
1871procedure TTestJSParser.TestDoWhileSimple;
1872
1873Var
1874  E : TJSElement;
1875  W : TJSDoWhileStatement;
1876//  B : TJSBlockStatement;
1877
1878begin
1879  CreateParser('do b; while (a);');
1880  E:=GetFirstStatement;
1881  CheckClass(E,TJSDoWhileStatement);
1882  W:=TJSDoWhileStatement(E);
1883  AssertNotNull('Statement condition assigned',W.Cond);
1884  CheckClass(W.Cond,TJSPrimaryExpressionIdent);
1885  AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).Name);
1886  AssertNotNull('Statement condition assigned',W.body);
1887  CheckClass(W.Body,TJSExpressionStatement);
1888  AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
1889  CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
1890  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
1891end;
1892
1893procedure TTestJSParser.TestDoWhileBlock;
1894
1895Var
1896  E : TJSElement;
1897  W : TJSDoWhileStatement;
1898//  B : TJSBlockStatement;
1899
1900begin
1901  CreateParser('do {b;} while (a);');
1902  E:=GetFirstStatement;
1903  CheckClass(E,TJSDoWhileStatement);
1904  W:=TJSDoWhileStatement(E);
1905  AssertNotNull('Statement condition assigned',W.Cond);
1906  CheckClass(W.Cond,TJSPrimaryExpressionIdent);
1907  AssertEquals('a',TJSPrimaryExpressionIdent(W.Cond).Name);
1908  AssertNotNull('Statement condition assigned',W.body);
1909  CheckClass(W.Body,TJSExpressionStatement);
1910  AssertNotNull('Expression statement expression',TJSExpressionStatement(W.Body).A);
1911  CheckClass(TJSExpressionStatement(W.Body).A,TJSPrimaryExpressionIdent);
1912  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(W.Body).A).Name);
1913end;
1914
1915procedure TTestJSParser.TestForEmpty;
1916
1917Var
1918  E : TJSElement;
1919  F : TJSForStatement;
1920
1921begin
1922  CreateParser('for (;;) a;');
1923  E:=GetFirstStatement;
1924  CheckClass(E,TJSForStatement);
1925  F:=TJSForStatement(E);
1926  AssertNull('Statement condition not assigned',F.Cond);
1927  AssertNull('Statement init not assigned',F.Init);
1928  AssertNull('Statement step not assigned',F.Incr);
1929  CheckClass(F.Body,TJSExpressionStatement);
1930  AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
1931  CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
1932  AssertEquals('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).Name);
1933end;
1934
1935procedure TTestJSParser.TestForEmptyBody;
1936
1937Var
1938  E : TJSElement;
1939  F : TJSForStatement;
1940
1941begin
1942  CreateParser('for (;;) {a;}');
1943  E:=GetFirstStatement;
1944  CheckClass(E,TJSForStatement);
1945  F:=TJSForStatement(E);
1946  AssertNull('Statement condition not assigned',F.Cond);
1947  AssertNull('Statement init not assigned',F.Init);
1948  AssertNull('Statement step not assigned',F.Incr);
1949  CheckClass(F.Body,TJSExpressionStatement);
1950  AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
1951  CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
1952  AssertEquals('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).Name);
1953end;
1954
1955procedure TTestJSParser.TestForSimpleBody;
1956
1957Var
1958  E : TJSElement;
1959  F : TJSForStatement;
1960
1961begin
1962  CreateParser('for (a;b;c) {d;}');
1963  E:=GetFirstStatement;
1964  CheckClass(E,TJSForStatement);
1965  F:=TJSForStatement(E);
1966  AssertNotNull('Statement condition not assigned',F.Cond);
1967  AssertNotNull('Statement init not assigned',F.Init);
1968  AssertNotNull('Statement step not assigned',F.Incr);
1969  CheckClass(F.Init,TJSPrimaryExpressionIdent);
1970  AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Init));
1971  AssertEquals('a',TJSPrimaryExpressionIdent(F.Init).Name);
1972  CheckClass(F.Incr,TJSPrimaryExpressionIdent);
1973  AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Incr));
1974  AssertEquals('c',TJSPrimaryExpressionIdent(F.Incr).Name);
1975  CheckClass(F.Cond,TJSPrimaryExpressionIdent);
1976  AssertNotNull('Expression statement expression',TJSPrimaryExpressionIdent(F.Cond));
1977  AssertEquals('b',TJSPrimaryExpressionIdent(F.cond).Name);
1978  CheckClass(F.Body,TJSExpressionStatement);
1979  AssertNotNull('Expression statement expression',TJSExpressionStatement(F.Body).A);
1980  CheckClass(TJSExpressionStatement(F.Body).A,TJSPrimaryExpressionIdent);
1981  AssertEquals('d',TJSPrimaryExpressionIdent(TJSExpressionStatement(F.Body).A).Name);
1982end;
1983
1984procedure TTestJSParser.TestTryCatch;
1985
1986Var
1987  E : TJSElement;
1988  T : TJSTryCatchStatement;
1989
1990begin
1991  CreateParser('try {a;} catch (e) {b;}');
1992  E:=GetFirstStatement;
1993  CheckClass(E,TJSTryCatchStatement);
1994  T:=TJSTryCatchStatement(E);
1995  CheckClass(T.Block,TJSExpressionStatement);
1996  AssertNotNull('Expression statement expression',TJSExpressionStatement(T.Block).A);
1997  CheckClass(TJSExpressionStatement(T.Block).A,TJSPrimaryExpressionIdent);
1998  AssertEquals('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).Name);
1999  CheckClass(T.BCatch,TJSExpressionStatement);
2000  AssertEquals('Except object identifier name','e',T.Ident);
2001  AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BCatch).A);
2002  CheckClass(TJSExpressionStatement(T.BCatch).A,TJSPrimaryExpressionIdent);
2003  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BCatch).A).Name);
2004  AssertNull('No Finally expression',T.BFinally);
2005end;
2006
2007procedure TTestJSParser.TestTryCatchFinally;
2008
2009Var
2010  E : TJSElement;
2011  T : TJSTryCatchFinallyStatement;
2012
2013begin
2014  CreateParser('try {a;} catch (e) {b;} finally {c;}');
2015  E:=GetFirstStatement;
2016  CheckClass(E,TJSTryCatchFinallyStatement);
2017  T:=TJSTryCatchFinallyStatement(E);
2018  CheckClass(T.Block,TJSExpressionStatement);
2019  AssertNotNull('Expression statement expression',TJSExpressionStatement(T.Block).A);
2020  CheckClass(TJSExpressionStatement(T.Block).A,TJSPrimaryExpressionIdent);
2021  AssertEquals('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).Name);
2022  AssertEquals('Except object identifier name','e',T.Ident);
2023  CheckClass(T.BCatch,TJSExpressionStatement);
2024  AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BCatch).A);
2025  CheckClass(TJSExpressionStatement(T.BCatch).A,TJSPrimaryExpressionIdent);
2026  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BCatch).A).Name);
2027  AssertNotNull('Finally expression',T.BFinally);
2028  CheckClass(T.BFinally,TJSExpressionStatement);
2029  AssertNotNull('Expression statement expression',TJSExpressionStatement(T.BFinally).A);
2030  CheckClass(TJSExpressionStatement(T.BFinally).A,TJSPrimaryExpressionIdent);
2031  AssertEquals('c',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BFinally).A).Name);
2032end;
2033
2034procedure TTestJSParser.TestTryFinally;
2035
2036Var
2037  E : TJSElement;
2038  T : TJSTryFinallyStatement;
2039
2040begin
2041  CreateParser('try {a;} finally {c;}');
2042  E:=GetFirstStatement;
2043  CheckClass(E,TJSTryFinallyStatement);
2044  T:=TJSTryFinallyStatement(E);
2045  CheckClass(T.Block,TJSExpressionStatement);
2046  AssertNotNull('Expression statement expression',TJSExpressionStatement(T.Block).A);
2047  CheckClass(TJSExpressionStatement(T.Block).A,TJSPrimaryExpressionIdent);
2048  AssertEquals('a',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.Block).A).Name);
2049  AssertNull('No catch',T.BCatch);
2050  AssertNotNull('Finally expression',T.BFinally);
2051  AssertNotNull('Finally expression',TJSExpressionStatement(T.BFinally).A);
2052  CheckClass(TJSExpressionStatement(T.BFinally).A,TJSPrimaryExpressionIdent);
2053  AssertEquals('c',TJSPrimaryExpressionIdent(TJSExpressionStatement(T.BFinally).A).Name);
2054end;
2055
2056procedure TTestJSParser.TestThrow;
2057Var
2058  E : TJSElement;
2059  T : TJSThrowStatement;
2060
2061begin
2062  CreateParser('throw a;');
2063  E:=GetFirstStatement;
2064  CheckClass(E,TJSThrowStatement);
2065  T:=TJSThrowStatement(E);
2066  AssertNotNull('Have throw object',T.A);
2067  CheckClass(T.A,TJSPrimaryExpressionIdent);
2068  AssertEquals('Correct identifier','a',TJSPrimaryExpressionIdent(T.A).Name);
2069end;
2070
2071procedure TTestJSParser.TestReturn;
2072
2073Var
2074  E : TJSSourceElements;
2075  N : TJSElement;
2076  FD : TJSFunctionDeclarationStatement;
2077
2078begin
2079  CreateParser('function a () { return b; }');
2080  E:=GetSourceElements;
2081  AssertEquals('1 function defined',1,E.functions.Count);
2082  N:=E.Functions.Nodes[0].Node;
2083  AssertNotNull('Function element defined ',N);
2084  CheckClass(N,TJSFunctionDeclarationStatement);
2085  FD:=TJSFunctionDeclarationStatement(N);
2086  AssertNotNull('Function definition assigned',FD.AFunction);
2087  AssertEquals('Function name OK','a',FD.AFunction.Name);
2088  AssertNotNull('Function body assigned', FD.AFunction.Body);
2089  AssertEquals('No parameters',0,FD.AFunction.Params.Count);
2090  N:=FD.AFunction.Body;
2091  CheckClass(N,TJSFunctionBody);
2092  AssertNotNull('Function body has element',TJSFunctionBody(N).A);
2093  CheckClass(TJSFunctionBody(N).A,  TJSSourceElements);
2094  E:=TJSSourceElements(TJSFunctionBody(N).A);
2095  AssertEquals('1 statement in functionbody elements',1,E.Statements.Count);
2096end;
2097
2098procedure TTestJSParser.TestAssignment;
2099Var
2100  E : TJSElement;
2101  ES : TJSExpressionStatement;
2102  A : TJSSimpleAssignStatement;
2103
2104begin
2105  CreateParser('a=b;');
2106  E:=GetFirstStatement;
2107  CheckClass(E,TJSExpressionStatement);
2108  ES:=TJSExpressionStatement(E);
2109  CheckClass(ES.A,TJSSimpleAssignStatement);
2110  A:=TJSSimpleAssignStatement(ES.A);
2111  AssertNotNull('Have LHS',A.LHS);
2112  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
2113  AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
2114  CheckClass(A.Expr,TJSPrimaryExpressionIdent);
2115  AssertEquals('Have RHS name','b',TJSPrimaryExpressionIdent(A.Expr).Name);
2116end;
2117
2118procedure TTestJSParser.TestNew;
2119Var
2120  E : TJSElement;
2121  ES : TJSExpressionStatement;
2122  A : TJSSimpleAssignStatement;
2123  N : TJSNewMemberExpression;
2124  L : TJSLiteral;
2125
2126begin
2127  CreateParser('a = new b(123)');
2128  E:=GetFirstStatement;
2129  CheckClass(E,TJSExpressionStatement);
2130  ES:=TJSExpressionStatement(E);
2131  CheckClass(ES.A,TJSSimpleAssignStatement);
2132  A:=TJSSimpleAssignStatement(ES.A);
2133  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
2134  AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
2135  CheckClass(A.Expr,TJSNewMemberExpression);
2136  N:=TJSNewMemberExpression(A.Expr);
2137  AssertNotNull('Have LHS name',N.Mexpr);
2138  CheckClass(N.Mexpr,TJSPrimaryExpressionIdent);
2139  AssertEquals('Have LHS name','b',TJSPrimaryExpressionIdent(N.Mexpr).Name);
2140  AssertNotNull('Have arguments',N.Args);
2141  AssertEquals('One argument',1,N.Args.Elements.Count);
2142  AssertNotNull('Have argument 0',N.Args.Elements[0].Expr);
2143  CheckClass(N.Args.Elements[0].Expr,TJSLiteral);
2144  L:=TJSLiteral(N.Args.Elements[0].Expr);
2145  AssertNotNull('Expression value assigned',L.Value);
2146  AssertEquals('Expression value type correct', jstNumber,L.Value.ValueType);
2147  AssertEquals('Expression value correct', 123,L.Value.AsNumber);
2148
2149end;
2150
2151procedure TTestJSParser.TestLabeledStatement;
2152Var
2153  E : TJSElement;
2154  ES : TJSExpressionStatement;
2155  A : TJSSimpleAssignStatement;
2156  N : TJSNewMemberExpression;
2157  L : TJSLiteral;
2158  LS : TJSLabeledStatement;
2159
2160begin
2161  CreateParser('loc: a = new b(123)');
2162  E:=GetFirstStatement;
2163  CheckClass(E,TJSLabeledStatement);
2164  LS:=TJSLabeledStatement(E);
2165  AssertNotNull('Have label',LS.TheLabel);
2166  AssertEquals('Have correct label','loc',LS.TheLabel.Name);
2167  CheckClass(LS.A,TJSExpressionStatement);
2168  ES:=TJSExpressionStatement(LS.A);
2169  CheckClass(ES.A,TJSSimpleAssignStatement);
2170  A:=TJSSimpleAssignStatement(ES.A);
2171  CheckClass(A.LHS,TJSPrimaryExpressionIdent);
2172  AssertEquals('Have LHS name','a',TJSPrimaryExpressionIdent(A.LHS).Name);
2173  CheckClass(A.Expr,TJSNewMemberExpression);
2174  N:=TJSNewMemberExpression(A.Expr);
2175  AssertNotNull('Have LHS name',N.Mexpr);
2176  CheckClass(N.Mexpr,TJSPrimaryExpressionIdent);
2177  AssertEquals('Have LHS name','b',TJSPrimaryExpressionIdent(N.Mexpr).Name);
2178  AssertNotNull('Have arguments',N.Args);
2179  AssertEquals('One argument',1,N.Args.Elements.Count);
2180  AssertNotNull('Have argument 0',N.Args.Elements[0].Expr);
2181  CheckClass(N.Args.Elements[0].Expr,TJSLiteral);
2182  L:=TJSLiteral(N.Args.Elements[0].Expr);
2183  AssertNotNull('Expression value assigned',L.Value);
2184  AssertEquals('Expression value type correct', jstNumber,L.Value.ValueType);
2185  AssertEquals('Expression value correct', 123,L.Value.AsNumber);
2186end;
2187
2188procedure TTestJSParser.TestContinue;
2189
2190Var
2191  E : TJSElement;
2192  C : TJSContinueStatement;
2193
2194begin
2195  CreateParser('while (true) continue;');
2196  E:=GetFirstStatement;
2197  CheckClass(E,TJSWhileStatement);
2198  E:=TJSWhileStatement(E).Body;
2199  CheckClass(E,TJSContinueStatement);
2200  C:=TJSContinueStatement(E);
2201  AssertEquals('Have correct (empty) label','',C.TargetName);
2202end;
2203
2204procedure TTestJSParser.TestContinueTarget;
2205
2206Var
2207  E : TJSElement;
2208  C : TJSContinueStatement;
2209
2210begin
2211  CreateParser('a: while (true) continue a;');
2212  E:=GetFirstStatement;
2213  CheckClass(E,TJSLabeledStatement);
2214  E:=TJSLabeledStatement(E).A;
2215  CheckClass(E,TJSWhileStatement);
2216  E:=TJSWhileStatement(E).Body;
2217  CheckClass(E,TJSContinueStatement);
2218  C:=TJSContinueStatement(E);
2219  AssertEquals('Have correct  label','a',C.TargetName);
2220end;
2221
2222procedure TTestJSParser.TestBreakTarget;
2223Var
2224  E : TJSElement;
2225  C : TJSBreakStatement;
2226
2227begin
2228  CreateParser('a: while (true) break a;');
2229  E:=GetFirstStatement;
2230  CheckClass(E,TJSLabeledStatement);
2231  E:=TJSLabeledStatement(E).A;
2232  CheckClass(E,TJSWhileStatement);
2233  E:=TJSWhileStatement(E).Body;
2234  CheckClass(E,TJSBreakStatement);
2235  C:=TJSBreakStatement(E);
2236  AssertEquals('Have correct  label','a',C.TargetName);
2237end;
2238
2239procedure TTestJSParser.TestSwitchEmpty;
2240Var
2241  E : TJSElement;
2242  S : TJSSwitchStatement;
2243begin
2244  CreateParser('switch (a) {}');
2245  E:=GetFirstStatement;
2246  CheckClass(E,TJSSwitchStatement);
2247  S:=TJSSwitchStatement(E);
2248  AssertNotNull('Have condition',S.Cond);
2249  AssertNull('Have no default',S.TheDefault);
2250  AssertIdentifier('Case condition',S.Cond,'a');
2251  S:=TJSSwitchStatement(E);
2252  AssertEquals('No cases',0,S.Cases.Count)
2253end;
2254
2255procedure TTestJSParser.TestSwitchOne;
2256Var
2257  E : TJSElement;
2258  S : TJSSwitchStatement;
2259  C : TJSCaseElement;
2260begin
2261  CreateParser('switch (a) { case c : {}}');
2262  E:=GetFirstStatement;
2263  CheckClass(E,TJSSwitchStatement);
2264  S:=TJSSwitchStatement(E);
2265  AssertNotNull('Have condition',S.Cond);
2266  AssertNull('Have no default',S.TheDefault);
2267  AssertIdentifier('Case condition',S.Cond,'a');
2268  S:=TJSSwitchStatement(E);
2269  AssertEquals('1 case',1,S.Cases.Count);
2270  C:=TJSCaseElement(S.Cases[0]);
2271  AssertIdentifier('Case expression',C.Expr,'c');
2272  CheckClass(C.Body,TJSEmptyBlockStatement);
2273end;
2274
2275procedure TTestJSParser.TestSwitchTwo;
2276Var
2277  E : TJSElement;
2278  S : TJSSwitchStatement;
2279  C : TJSCaseElement;
2280begin
2281  CreateParser('switch (a) { case c: {}'+sLineBreak+' case d: {}}');
2282  E:=GetFirstStatement;
2283  CheckClass(E,TJSSwitchStatement);
2284  S:=TJSSwitchStatement(E);
2285  AssertNotNull('Have condition',S.Cond);
2286  AssertNull('Have no default',S.TheDefault);
2287  AssertIdentifier('Case condition',S.Cond,'a');
2288  S:=TJSSwitchStatement(E);
2289  AssertEquals('2 cases',2,S.Cases.Count);
2290  C:=TJSCaseElement(S.Cases[0]);
2291  AssertIdentifier('Case expression',C.Expr,'c');
2292  CheckClass(C.Body,TJSEmptyBlockStatement);
2293  C:=TJSCaseElement(S.Cases[1]);
2294  AssertIdentifier('Case expression',C.Expr,'d');
2295  CheckClass(C.Body,TJSEmptyBlockStatement);
2296end;
2297
2298procedure TTestJSParser.TestSwitchTwoDefault;
2299Var
2300  E : TJSElement;
2301  S : TJSSwitchStatement;
2302  C : TJSCaseElement;
2303begin
2304  CreateParser('switch (a) { case c: {} case d: {} default: {}}');
2305  E:=GetFirstStatement;
2306  CheckClass(E,TJSSwitchStatement);
2307  S:=TJSSwitchStatement(E);
2308  AssertNotNull('Have condition',S.Cond);
2309  AssertNotNull('Have default',S.TheDefault);
2310  AssertIdentifier('Case condition',S.Cond,'a');
2311  S:=TJSSwitchStatement(E);
2312  AssertEquals('2 cases',3,S.Cases.Count);
2313  C:=TJSCaseElement(S.Cases[0]);
2314  AssertIdentifier('Case expression',C.Expr,'c');
2315  CheckClass(C.Body,TJSEmptyBlockStatement);
2316  C:=TJSCaseElement(S.Cases[1]);
2317  AssertIdentifier('Case expression',C.Expr,'d');
2318  CheckClass(C.Body,TJSEmptyBlockStatement);
2319  C:=TJSCaseElement(S.Cases[2]);
2320  CheckClass(C.Body,TJSEmptyBlockStatement);
2321  AssertSame('Default',C,S.TheDefault);
2322end;
2323
2324procedure TTestJSParser.TestBreak;
2325Var
2326  E : TJSElement;
2327  C : TJSBreakStatement;
2328
2329begin
2330  CreateParser('while (true) break;');
2331  E:=GetFirstStatement;
2332  CheckClass(E,TJSWhileStatement);
2333  E:=TJSWhileStatement(E).Body;
2334  CheckClass(E,TJSBreakStatement);
2335  C:=TJSBreakStatement(E);
2336  AssertEquals('Have correct (empty) label','',C.TargetName);
2337end;
2338
2339procedure TTestJSParser.TestIfElseSimple;
2340
2341Var
2342  E : TJSElement;
2343  I : TJSIfStatement;
2344
2345begin
2346  CreateParser('if (a) b; else c;');
2347  E:=GetFirstStatement;
2348  CheckClass(E,TJSIfStatement);
2349  I:=TJSIfStatement(E);
2350  AssertNotNull('Statement condition assigned',I.Cond);
2351  CheckClass(I.Cond,TJSPrimaryExpressionIdent);
2352  AssertEquals('a',TJSPrimaryExpressionIdent(I.Cond).Name);
2353  AssertNotNull('Statement condition assigned',I.Btrue);
2354  CheckClass(I.Btrue,TJSExpressionStatement);
2355  AssertNotNull('Expression statement expression',TJSExpressionStatement(I.BTrue).A);
2356  CheckClass(TJSExpressionStatement(I.BTrue).A,TJSPrimaryExpressionIdent);
2357  AssertEquals('b',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.Btrue).A).Name);
2358  AssertNotNull('Else Statement condition assigned',I.BFalse);
2359  CheckClass(I.BFalse,TJSExpressionStatement);
2360  AssertNotNull('Else statement expression',TJSExpressionStatement(I.BFalse).A);
2361  CheckClass(TJSExpressionStatement(I.BFalse).A,TJSPrimaryExpressionIdent);
2362  AssertEquals('c',TJSPrimaryExpressionIdent(TJSExpressionStatement(I.BFalse).A).Name);
2363end;
2364
2365
2366procedure TTestJSParser.TestExpressionPrecedenceMulNot;
2367
2368Var
2369  X : TJSExpressionStatement;
2370  R : TJSUnaryNotExpression;
2371  E : TJSMultiplicativeExpressionMul;
2372
2373begin
2374  CreateParser('4 * !2;');
2375  X:=GetExpressionStatement;
2376  AssertNotNull('Expression statement assigned',X.A);
2377  CheckClass(X.A,TJSMultiplicativeExpressionMul);
2378  E:=TJSMultiplicativeExpressionMul(X.A);
2379  AssertNotNull('Expression left operand assigned',E.A);
2380  AssertNotNull('Expression right operand assigned',E.B);
2381  CheckClass(E.B,TJSUnaryNotExpression);
2382  R:=TJSUnaryNotExpression(E.B);
2383  CheckClass(E.A,TJSLiteral);
2384  AssertNotNull('Multiplication left operand assigned',R.A);
2385  CheckClass(R.A,TJSLiteral);
2386  AssertEquals('Not operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
2387  AssertEquals('Not operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
2388  AssertNotNull('Multiplication left operand value assigned',TJSLiteral(E.A).Value);
2389  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
2390  AssertEquals('Multiplication left operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
2391end;
2392
2393procedure TTestJSParser.TestExpressionPrecedencePlusPreMinusMinus;
2394Var
2395  X : TJSExpressionStatement;
2396  R : TJSUnaryPreMinusMinusExpression;
2397  E : TJSAdditiveExpressionPlus;
2398
2399begin
2400  CreateParser('4 + --2;');
2401  X:=GetExpressionStatement;
2402  AssertNotNull('Expression statement assigned',X.A);
2403  CheckClass(X.A,TJSAdditiveExpressionPlus);
2404  E:=TJSAdditiveExpressionPlus(X.A);
2405  AssertNotNull('Expression left operand assigned',E.A);
2406  AssertNotNull('Expression right operand assigned',E.B);
2407  CheckClass(E.B,TJSUnaryPreMinusMinusExpression);
2408  R:=TJSUnaryPreMinusMinusExpression(E.B);
2409  CheckClass(E.A,TJSLiteral);
2410  AssertNotNull('Multiplication left operand assigned',R.A);
2411  CheckClass(R.A,TJSLiteral);
2412  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
2413  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
2414  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
2415  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
2416  AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
2417end;
2418
2419procedure TTestJSParser.TestExpressionPrecedenceMulPrePlusPlus;
2420
2421Var
2422  X : TJSExpressionStatement;
2423  R : TJSUnaryPrePlusPlusExpression;
2424  E : TJSMultiplicativeExpressionMul;
2425
2426begin
2427  CreateParser('4 * ++2;');
2428  X:=GetExpressionStatement;
2429  AssertNotNull('Expression statement assigned',X.A);
2430  CheckClass(X.A,TJSMultiplicativeExpressionMul);
2431  E:=TJSMultiplicativeExpressionMul(X.A);
2432  AssertNotNull('Expression left operand assigned',E.A);
2433  AssertNotNull('Expression right operand assigned',E.B);
2434  CheckClass(E.B,TJSUnaryPrePlusPlusExpression);
2435  R:=TJSUnaryPrePlusPlusExpression(E.B);
2436  CheckClass(E.A,TJSLiteral);
2437  AssertNotNull('Multiplication left operand assigned',R.A);
2438  CheckClass(R.A,TJSLiteral);
2439  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
2440  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
2441  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
2442  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
2443  AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
2444end;
2445
2446procedure TTestJSParser.TestExpressionPrecedenceMulPreMinusMinus;
2447Var
2448  X : TJSExpressionStatement;
2449  R : TJSUnaryPreMinusMinusExpression;
2450  E : TJSMultiplicativeExpressionMul;
2451
2452begin
2453  CreateParser('4 * --2;');
2454  X:=GetExpressionStatement;
2455  AssertNotNull('Expression statement assigned',X.A);
2456  CheckClass(X.A,TJSMultiplicativeExpressionMul);
2457  E:=TJSMultiplicativeExpressionMul(X.A);
2458  AssertNotNull('Expression left operand assigned',E.A);
2459  AssertNotNull('Expression right operand assigned',E.B);
2460  CheckClass(E.B,TJSUnaryPreMinusMinusExpression);
2461  R:=TJSUnaryPreMinusMinusExpression(E.B);
2462  CheckClass(E.A,TJSLiteral);
2463  AssertNotNull('Multiplication left operand assigned',R.A);
2464  CheckClass(R.A,TJSLiteral);
2465  AssertEquals('Multiplication left operand type correct', jstNumber, TJSLiteral(R.A).Value.ValueType);
2466  AssertEquals('Multiplication left operand value correct', 2.0, TJSLiteral(R.A).Value.AsNumber);
2467  AssertNotNull('Addition right operand value assigned',TJSLiteral(E.A).Value);
2468  AssertEquals('Addition left operand type correct', jstNumber, TJSLiteral(E.A).Value.ValueType);
2469  AssertEquals('Expression right operand value correct', 4.0,TJSLiteral(E.A).Value.AsNumber);
2470end;
2471
2472procedure TTestJSParser.TestSimpleExpressionBooleanLiteralTrue;
2473
2474Var
2475  X : TJSExpressionStatement;
2476
2477begin
2478  CreateParser('true;');
2479  X:=GetExpressionStatement;
2480  AssertNotNull('Expression statement assigned',X.A);
2481  CheckClass(X.A,TJSLiteral);
2482  AssertNotNull('Expression value assigned',TJSLiteral(X.A).Value);
2483  AssertEquals('Expression value type correct', jstBoolean,TJSLiteral(X.A).Value.ValueType);
2484  AssertEquals('Expression value correct', True, TJSLiteral(X.A).Value.AsBoolean);
2485end;
2486
2487
2488procedure TTestJSParser.TestEmpty;
2489
2490Var
2491  E : TJSElement;
2492  FB : TJSFunctionBody;
2493  SE : TJSSourceElements;
2494
2495begin
2496  CreateParser('var a;');
2497  E:=FParser.Parse;
2498  try
2499    CheckClass(E,TJSFunctionBody);
2500    FB:=TJSFunctionBody(E);
2501    AssertNotNull(FB.A);
2502    CheckClass(FB.A,TJSSourceElements);
2503    SE:=TJSSourceElements(FB.A);
2504    AssertEquals('1 variable declaration ',1,SE.Vars.Count);
2505    CheckClass(FB.A,TJSSourceElements);
2506  finally
2507    E.Free;
2508  end;
2509end;
2510
2511procedure TTestJSParser.SetUp;
2512begin
2513  FParser:=Nil;
2514  FSource:=Nil;
2515end;
2516
2517procedure TTestJSParser.TearDown;
2518begin
2519  FreeAndNil(FToFree);
2520  FreeAndNil(FParser);
2521  FReeAndNil(FSource);
2522end;
2523
2524Procedure TTestJSParser.CreateParser(Const ASource: string);
2525begin
2526  FSource:=TStringStream.Create(ASource);
2527  FParser:=TJSParser.Create(FSource);
2528end;
2529
2530Procedure TTestJSParser.CheckClass(E: TJSElement; C: TJSElementClass);
2531begin
2532  AssertEquals(C,E.ClassType);
2533end;
2534
2535Function TTestJSParser.GetSourceElements: TJSSourceElements;
2536
2537Var
2538  E : TJSElement;
2539  FB : TJSFunctionBody;
2540
2541begin
2542  If Not Assigned(FSE) then
2543    begin
2544    AssertNotNull('Parser assigned',FParser);
2545    E:=FParser.Parse;
2546    CheckClass(E,TJSFunctionBody);
2547    FB:=TJSFunctionBody(E);
2548    AssertNotNull(FB.A);
2549    CheckClass(FB.A,TJSSourceElements);
2550    FSE:=TJSSourceElements(FB.A);
2551    FToFree:=E;
2552    end;
2553  Result:=FSE;
2554end;
2555
2556Function TTestJSParser.GetVars: TJSElementNodes;
2557begin
2558  Result:=GetSourceElements.Vars;
2559end;
2560
2561Function TTestJSParser.GetStatements: TJSElementNodes;
2562begin
2563  Result:=GetSourceElements.Statements;
2564end;
2565
2566Function TTestJSParser.GetFunctions: TJSElementNodes;
2567begin
2568  Result:=GetSourceElements.Functions;
2569end;
2570
2571
2572initialization
2573
2574  RegisterTest(TTestJSParser);
2575end.
2576
2577