tcconverter.pp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2014 by Michael Van Canneyt
  4. Unit tests for Pascal-to-Javascript converter class.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit tcconverter;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, fpcunit, testutils, testregistry, fppas2js, jsbase, jstree, pastree;
  16. type
  17. { TTestConverter }
  18. TTestConverter = class(TTestCase)
  19. private
  20. FAC: TPasElement;
  21. FConverter: TPasToJSConverter;
  22. FRes: TJSElement;
  23. FSource: TPasElement;
  24. protected
  25. procedure SetUp; override;
  26. procedure TearDown; override;
  27. Property AttemptConvert : TPasElement Read FAC Write FAC;
  28. Procedure TryConvert;
  29. Function Convert(AElement : TPasElement; AClass : TJSElementClass) : TJSElement;
  30. Property Converter : TPasToJSConverter Read FConverter;
  31. Property TheSource : TPasElement Read FSource Write FSource;
  32. Property TheResult : TJSElement Read FRes Write FRes;
  33. Public
  34. Class procedure AssertEquals(Const Msg : String; AExpected, AActual : TJSType); overload;
  35. Class procedure AssertLiteral(Const Msg : String; Lit : TJSElement; AType : TJSType);
  36. Class procedure AssertLiteral(Const Msg : String; Lit : TJSElement; AValue : Boolean);
  37. Class procedure AssertLiteral(Const Msg : String; Lit : TJSElement; AValue : TJSString);
  38. Class procedure AssertLiteral(Const Msg : String; Lit : TJSElement; AValue : TJSNumber);
  39. Class procedure AssertIdentifier(Const Msg : String; Ident : TJSElement; AName : String);
  40. Class Procedure AssertAssignStatement(Const Msg: String; El: TJSElement; LHS: String='a'; RHS: String='b');
  41. Class Procedure AssertEmptyBlockStatement(Const Msg: String; El: TJSElement);
  42. class Function AssertListStatement(Const Msg: String; El: TJSElement) : TJSStatementList;
  43. class Function AssertElement(Const Msg: String; AClass : TJSElementClass; El: TJSElement) : TJSElement;
  44. Class Function CreateLiteral(AValue : String) : TPasExpr;
  45. Class Function CreateLiteral(AValue : Double) : TPasExpr;
  46. Class Function CreateIdent(AName : String) : TPrimitiveExpr;
  47. Class Function CreateAssignStatement(LHS: String = 'a';RHS : String = 'b'): TPasImplAssign;
  48. Class Function CreateFunctionCall(AName : String; Params : Array of String) : TParamsExpr;
  49. Class Function CreateCondition: TPasExpr;
  50. end;
  51. TTestTestConverter = class(TTestConverter)
  52. published
  53. procedure TestEmpty;
  54. end;
  55. { TTestExpressionConverter }
  56. TTestExpressionConverter = Class(TTestConverter)
  57. Protected
  58. Function TestLiteralExpression(AElement : TPasElement; AClass : TJSElementClass) : TJSLIteral;
  59. Function TestUnaryExpression(AElement : TPasElement; AClass : TJSElementClass) : TJSUnary;
  60. Function TestBinaryExpression(AElement : TPasElement; AClass : TJSElementClass) : TJSBinary;
  61. Published
  62. Procedure TestPrimitiveString;
  63. Procedure TestPrimitiveNumber;
  64. Procedure TestPrimitiveNil;
  65. Procedure TestPrimitiveBoolTrue;
  66. Procedure TestPrimitiveBoolFalse;
  67. Procedure TestPrimitiveIdent;
  68. Procedure TestUnaryMinus;
  69. Procedure TestUnaryPlus;
  70. Procedure TestBinaryPlus;
  71. Procedure TestBinaryMinus;
  72. Procedure TestBinaryMultiply;
  73. Procedure TestBinaryDivision;
  74. Procedure TestBinaryDiv;
  75. Procedure TestBinaryMod;
  76. Procedure TestBinarySHL;
  77. Procedure TestBinarySHR;
  78. Procedure TestBinaryEqual;
  79. Procedure TestBinaryNotEqual;
  80. Procedure TestBinaryLessThan;
  81. Procedure TestBinaryLessThanEqual;
  82. Procedure TestBinaryGreater;
  83. Procedure TestBinaryGreaterThanEqual;
  84. Procedure TestBinaryIs;
  85. Procedure TestCallExpressionNone;
  86. Procedure TestCallExpressionOne;
  87. Procedure TestCallExpressionTwo;
  88. Procedure TestMemberExpressionArrayOneDim;
  89. Procedure TestMemberExpressionArrayTwoDim;
  90. Procedure TestVariable;
  91. Procedure TestArrayVariable;
  92. end;
  93. { TTestStatementConverter }
  94. TTestStatementConverter = Class(TTestConverter)
  95. private
  96. Published
  97. Procedure TestRaiseStatement;
  98. Procedure TestAssignStatement;
  99. Procedure TestIfStatement;
  100. Procedure TestIfStatementFull;
  101. Procedure TestIfStatementElse;
  102. Procedure TestWhileStatementEmpty;
  103. Procedure TestWhileStatement;
  104. Procedure TestSimpleStatement;
  105. Procedure TestRepeatUntilStatementEmpty;
  106. Procedure TestRepeatUntilStatementOne;
  107. Procedure TestRepeatUntilStatementTwo;
  108. Procedure TestRepeatUntilStatementThree;
  109. Procedure TestForLoopUp;
  110. Procedure TestForLoopDown;
  111. Procedure TestBeginEndBlockEmpty;
  112. Procedure TestBeginEndBlockStatementOne;
  113. Procedure TestBeginEndBlockStatementTwo;
  114. Procedure TestBeginEndBlockStatementThree;
  115. Procedure TestWithStatementEmpty;
  116. Procedure TestWithStatementOne;
  117. Procedure TestWithStatementTwo;
  118. Procedure TestTryFinallyStatement;
  119. Procedure TestTryExceptStatement;
  120. Procedure TestTryExceptStatementOnE;
  121. Procedure TestReRaise;
  122. Procedure TestVariableStatement;
  123. end;
  124. implementation
  125. uses typinfo;
  126. { TTestStatementConverter }
  127. Procedure TTestStatementConverter.TestRaiseStatement;
  128. Var
  129. R : TPasImplRaise;
  130. E : TJSThrowStatement;
  131. begin
  132. R:=TPasImplRaise.Create('',Nil);
  133. R.ExceptObject:=CreateIdent('e');
  134. E:=TJSThrowStatement(Convert(R,TJSThrowStatement));
  135. AssertIdentifier('Raise exception object',E.A,'e');
  136. end;
  137. Procedure TTestStatementConverter.TestAssignStatement;
  138. Var
  139. R : TPasImplAssign;
  140. E : TJSSimpleAssignStatement;
  141. begin
  142. R:=CreateAssignStatement('a','b');
  143. E:=TJSSimpleAssignStatement(Convert(R,TJSSimpleAssignStatement));
  144. AssertAssignStatement('a = b assignment',E);
  145. end;
  146. Procedure TTestStatementConverter.TestIfStatement;
  147. Var
  148. R : TPasImplIfElse;
  149. E : TJSIfStatement;
  150. begin
  151. // If a then ;
  152. R:=TPasImplIfElse.Create('',Nil);
  153. R.ConditionExpr:=CreateCondition;
  154. E:=TJSIfStatement(Convert(R,TJSIfStatement));
  155. AssertEquals('If branch is empty block statement',TJSEmptyBlockStatement,E.btrue.ClassType);
  156. AssertNull('No else branch',E.bfalse);
  157. AssertIdentifier('Left hand side OK',E.Cond,'a');
  158. end;
  159. Procedure TTestStatementConverter.TestIfStatementFull;
  160. Var
  161. R : TPasImplIfElse;
  162. E : TJSIfStatement;
  163. begin
  164. // If a then a:=b;
  165. R:=TPasImplIfElse.Create('',Nil);
  166. R.ConditionExpr:=CreateCondition;
  167. R.IfBranch:=CreateAssignStatement;
  168. E:=TJSIfStatement(Convert(R,TJSIfStatement));
  169. AssertIdentifier('Conditional expression',E.Cond,'a');
  170. AssertAssignStatement('If branch',E.btrue);
  171. AssertNull('No else branch',E.bfalse);
  172. end;
  173. Procedure TTestStatementConverter.TestIfStatementElse;
  174. Var
  175. R : TPasImplIfElse;
  176. E : TJSIfStatement;
  177. begin
  178. // If a then a:=b else a:=e;
  179. R:=TPasImplIfElse.Create('',Nil);
  180. R.ConditionExpr:=CreateCondition;
  181. R.IfBranch:=CreateAssignStatement;
  182. R.ElseBranch:=CreateAssignStatement('a','e');
  183. E:=TJSIfStatement(Convert(R,TJSIfStatement));
  184. AssertIdentifier('Conditional expression',E.Cond,'a');
  185. AssertAssignStatement('If branch',E.btrue);
  186. AssertAssignStatement('else branch',E.bfalse,'a','e');
  187. end;
  188. Procedure TTestStatementConverter.TestWhileStatementEmpty;
  189. Var
  190. R : TPasImplWhileDo;
  191. E : TJSWhileStatement;
  192. begin
  193. // While a do ;
  194. R:=TPasImplWhileDo.Create('',Nil);
  195. R.ConditionExpr:=CreateCondition;
  196. E:=TJSWhileStatement(Convert(R,TJSWhileStatement));
  197. AssertIdentifier('Conditional expression',E.Cond,'a');
  198. AssertEquals('No statement, empty block statement',TJSEmptyBlockStatement,E.body.ClassType);
  199. end;
  200. Procedure TTestStatementConverter.TestWhileStatement;
  201. Var
  202. R : TPasImplWhileDo;
  203. E : TJSWhileStatement;
  204. begin
  205. // While a do b:=c;
  206. R:=TPasImplWhileDo.Create('',Nil);
  207. R.Body:=CreateAssignStatement('b','c');
  208. R.ConditionExpr:=CreateCondition;
  209. E:=TJSWhileStatement(Convert(R,TJSWhileStatement));
  210. AssertIdentifier('Conditional expression',E.Cond,'a');
  211. AssertAssignStatement('While Block is assignment',E.body,'b','c');
  212. end;
  213. Procedure TTestStatementConverter.TestSimpleStatement;
  214. Var
  215. R : TPasImplSimple;
  216. E : TJSExpressionStatement;
  217. C : TJSCallExpression;
  218. begin
  219. R:=TPasImplSimple.Create('',Nil);
  220. R.Expr:=CreateFunctionCall('a',['b']);
  221. E:=TJSExpressionStatement(Convert(R,TJSExpressionStatement));
  222. AssertNotNull('Have call node',E.A);
  223. AssertEquals('Have call expression',TJSCallExpression,E.A.ClassType);
  224. AssertEquals('Have call expression',TJSCallExpression,E.A.ClassType);
  225. C:=TJSCallExpression(E.A);
  226. AssertIdentifier('Call expression',C.Expr,'a');
  227. end;
  228. Procedure TTestStatementConverter.TestRepeatUntilStatementEmpty;
  229. Var
  230. R : TPasImplRepeatUntil;
  231. E : TJSWhileStatement;
  232. begin
  233. // Repeat until a;
  234. R:=TPasImplRepeatUntil.Create('',Nil);
  235. R.ConditionExpr:=CreateCondition;
  236. E:=TJSDoWhileStatement(Convert(R,TJSDoWhileStatement));
  237. AssertNotNull('Have condition',E.Cond);
  238. AssertEquals('Correct condition class',TJSUnaryNotExpression,E.Cond.ClassType);
  239. AssertIdentifier('Conditional expression',TJSUnaryNotExpression(E.Cond).A,'a');
  240. AssertNotNull('Have body',E.Body);
  241. AssertEquals('No statement, empty block statement',TJSEmptyBlockStatement,E.body.ClassType);
  242. end;
  243. Procedure TTestStatementConverter.TestRepeatUntilStatementOne;
  244. Var
  245. R : TPasImplRepeatUntil;
  246. E : TJSWhileStatement;
  247. L : TJSStatementList;
  248. begin
  249. // Repeat b:=c; until a;
  250. R:=TPasImplRepeatUntil.Create('',Nil);
  251. R.ConditionExpr:=CreateCondition;
  252. R.AddAssign(CreateIdent('b'),CreateIdent('c'));
  253. E:=TJSDoWhileStatement(Convert(R,TJSDoWhileStatement));
  254. AssertNotNull('Have condition',E.Cond);
  255. AssertEquals('Correct condition class',TJSUnaryNotExpression,E.Cond.ClassType);
  256. AssertIdentifier('Conditional expression',TJSUnaryNotExpression(E.Cond).A,'a');
  257. AssertNotNull('Have body',E.Body);
  258. AssertEquals('List statement, List statement',TJSStatementList,E.body.ClassType);
  259. L:=TJSStatementList(E.Body);
  260. AssertAssignStatement('First List statement is assignment',L.A,'b','c');
  261. AssertNull('No second statement',L.B);
  262. end;
  263. Procedure TTestStatementConverter.TestRepeatUntilStatementTwo;
  264. Var
  265. R : TPasImplRepeatUntil;
  266. E : TJSWhileStatement;
  267. L : TJSStatementList;
  268. begin
  269. // Repeat b:=c; d:=e; until a;
  270. R:=TPasImplRepeatUntil.Create('',Nil);
  271. R.ConditionExpr:=CreateCondition;
  272. R.AddAssign(CreateIdent('b'),CreateIdent('c'));
  273. R.AddAssign(CreateIdent('d'),CreateIdent('e'));
  274. E:=TJSDoWhileStatement(Convert(R,TJSDoWhileStatement));
  275. AssertNotNull('Have condition',E.Cond);
  276. AssertEquals('Correct condition class',TJSUnaryNotExpression,E.Cond.ClassType);
  277. AssertIdentifier('Conditional expression',TJSUnaryNotExpression(E.Cond).A,'a');
  278. L:=AssertListStatement('Multiple statements',E.Body);
  279. AssertAssignStatement('First List statement is assignment',L.A,'b','c');
  280. AssertAssignStatement('Second List statement is assignment',L.b,'d','e');
  281. end;
  282. Procedure TTestStatementConverter.TestRepeatUntilStatementThree;
  283. Var
  284. R : TPasImplRepeatUntil;
  285. E : TJSWhileStatement;
  286. L : TJSStatementList;
  287. begin
  288. // Repeat b:=c; d:=e; f:=g; until a;
  289. R:=TPasImplRepeatUntil.Create('',Nil);
  290. R.ConditionExpr:=CreateCondition;
  291. R.AddAssign(CreateIdent('b'),CreateIdent('c'));
  292. R.AddAssign(CreateIdent('d'),CreateIdent('e'));
  293. R.AddAssign(CreateIdent('f'),CreateIdent('g'));
  294. E:=TJSDoWhileStatement(Convert(R,TJSDoWhileStatement));
  295. AssertNotNull('Have condition',E.Cond);
  296. AssertEquals('Correct condition class',TJSUnaryNotExpression,E.Cond.ClassType);
  297. AssertIdentifier('Conditional expression',TJSUnaryNotExpression(E.Cond).A,'a');
  298. AssertNotNull('Have body',E.Body);
  299. L:=AssertListStatement('Multiple statements',E.Body);
  300. AssertAssignStatement('First List statement is assignment',L.A,'b','c');
  301. L:=AssertListStatement('Second statement is again list',L.B);
  302. AssertAssignStatement('Second List statement is assignment',L.A,'d','e');
  303. AssertAssignStatement('third List statement is assignment',L.B,'f','g');
  304. end;
  305. Procedure TTestStatementConverter.TestForLoopUp;
  306. Var
  307. F : TPasImplForLoop;
  308. E : TJSForStatement;
  309. L : TJSStatementList;
  310. VS : TJSVariableStatement;
  311. VD : TJSVarDeclaration;
  312. A : TJSSimpleAssignStatement;
  313. I : TJSUnaryPostPlusPlusExpression;
  314. C : TJSRelationalExpressionLE;
  315. begin
  316. // For I:=0 to 100 do a:=b;
  317. F:=TPasImplForLoop.Create('',Nil);
  318. F.Variable:=TPasVariable.Create('I',F);
  319. F.VariableName:='I';
  320. F.StartExpr:=CreateLiteral(1);
  321. F.EndExpr:=CreateLiteral(100);
  322. F.Body:=CreateAssignStatement();
  323. L:=TJSStatementList(Convert(F,TJSStatementList));
  324. VS:=TJSVariableStatement(AssertElement('Start with upper limit temp var',TJSVariableStatement,L.A));
  325. VD:=TJSVarDeclaration(AssertElement('Have variable',TJSVarDeclaration,VS.A));
  326. AssertEquals('Correct name for end value','i$endloopvalue',VD.Name);
  327. AssertLiteral('Correct end value',VD.Init,100);
  328. E:=TJSForStatement(AssertElement('Second in list is for statement',TJSForStatement,L.B));
  329. A:=TJSSimpleAssignStatement(AssertElement('Init statement is assign statement',TJSSimpleAssignStatement,E.Init));
  330. AssertLiteral('Init statement RHS is start value',A.Expr,1);
  331. AssertIdentifier('Init statement LHS is loop variable',A.LHS,'i');
  332. I:=TJSUnaryPostPlusPlusExpression(AssertElement('Increment is ++ statement',TJSUnaryPostPlusPlusExpression,E.Incr));
  333. AssertIdentifier('++ on correct variable name',I.A,'i');
  334. AssertAssignStatement('Correct body',E.Body);
  335. C:=TJSRelationalExpressionLE(AssertElement('Condition is <= expression',TJSRelationalExpressionLE,E.Cond));
  336. AssertIdentifier('Cond LHS is loop variable',C.A,'i');
  337. AssertIdentifier('Cond RHS is end loop value variable',C.B,'i$endloopvalue');
  338. end;
  339. Procedure TTestStatementConverter.TestForLoopDown;
  340. Var
  341. F : TPasImplForLoop;
  342. E : TJSForStatement;
  343. L : TJSStatementList;
  344. VS : TJSVariableStatement;
  345. VD : TJSVarDeclaration;
  346. A : TJSSimpleAssignStatement;
  347. I : TJSUnaryPostMinusMinusExpression;
  348. C : TJSRelationalExpressionGE;
  349. begin
  350. // For I:=0 to 100 do a:=b;
  351. F:=TPasImplForLoop.Create('',Nil);
  352. F.Variable:=TPasVariable.Create('I',F);
  353. F.VariableName:='I';
  354. F.StartExpr:=CreateLiteral(100);
  355. F.EndExpr:=CreateLiteral(1);
  356. F.LoopType:=ltDown;
  357. F.Body:=CreateAssignStatement();
  358. L:=TJSStatementList(Convert(F,TJSStatementList));
  359. VS:=TJSVariableStatement(AssertElement('Start with upper limit temp var',TJSVariableStatement,L.A));
  360. VD:=TJSVarDeclaration(AssertElement('Have variable',TJSVarDeclaration,VS.A));
  361. AssertEquals('Correct name for end value','i$endloopvalue',VD.Name);
  362. AssertLiteral('Correct end value',VD.Init,1);
  363. E:=TJSForStatement(AssertElement('Second in list is for statement',TJSForStatement,L.B));
  364. A:=TJSSimpleAssignStatement(AssertElement('Init statement is assign statement',TJSSimpleAssignStatement,E.Init));
  365. AssertLiteral('Init statement RHS is start value',A.Expr,100);
  366. AssertIdentifier('Init statement LHS is loop variable',A.LHS,'i');
  367. I:=TJSUnaryPostMinusMinusExpression(AssertElement('Increment is -- statement',TJSUnaryPostMinusMinusExpression,E.Incr));
  368. AssertIdentifier('++ on correct variable name',I.A,'i');
  369. AssertAssignStatement('Correct body',E.Body);
  370. C:=TJSRelationalExpressionGE(AssertElement('Condition is <= expression',TJSRelationalExpressionGE,E.Cond));
  371. AssertIdentifier('Cond LHS is loop variable',C.A,'i');
  372. AssertIdentifier('Cond RHS is end loop value variable',C.B,'i$endloopvalue');
  373. end;
  374. Procedure TTestStatementConverter.TestBeginEndBlockEmpty;
  375. Var
  376. R : TPasImplBeginBlock;
  377. begin
  378. // begin end;
  379. R:=TPasImplBeginBlock.Create('',Nil);
  380. Convert(R,TJSEmptyBlockStatement);
  381. end;
  382. Procedure TTestStatementConverter.TestBeginEndBlockStatementOne;
  383. Var
  384. R : TPasImplBeginBlock;
  385. L : TJSStatementList;
  386. begin
  387. // begin a:=bend;
  388. R:=TPasImplBeginBlock.Create('',Nil);
  389. R.AddAssign(CreateIdent('a'),CreateIdent('b'));
  390. L:=TJSStatementList(Convert(R,TJSStatementList));
  391. AssertNull('No second statement',L.B);
  392. AssertAssignStatement('First List statement is assignment',L.A,'a','b');
  393. end;
  394. Procedure TTestStatementConverter.TestBeginEndBlockStatementTwo;
  395. Var
  396. R : TPasImplBeginBlock;
  397. L : TJSStatementList;
  398. begin
  399. // begin a:=b; c:=d; end;
  400. R:=TPasImplBeginBlock.Create('',Nil);
  401. R.AddAssign(CreateIdent('a'),CreateIdent('b'));
  402. R.AddAssign(CreateIdent('c'),CreateIdent('d'));
  403. L:=TJSStatementList(Convert(R,TJSStatementList));
  404. AssertAssignStatement('First List statement is assignment',L.A,'a','b');
  405. AssertAssignStatement('Second List statement is assignment',L.B,'c','d');
  406. end;
  407. Procedure TTestStatementConverter.TestBeginEndBlockStatementThree;
  408. Var
  409. R : TPasImplBeginBlock;
  410. L : TJSStatementList;
  411. begin
  412. // begin a:=b; c:=d; end;
  413. R:=TPasImplBeginBlock.Create('',Nil);
  414. R.AddAssign(CreateIdent('a'),CreateIdent('b'));
  415. R.AddAssign(CreateIdent('c'),CreateIdent('d'));
  416. R.AddAssign(CreateIdent('e'),CreateIdent('f'));
  417. L:=TJSStatementList(Convert(R,TJSStatementList));
  418. AssertAssignStatement('First List statement is assignment',L.A,'a','b');
  419. L:=AssertListStatement('Second statement is again list',L.B);
  420. AssertAssignStatement('Second List statement is assignment',L.A,'c','d');
  421. AssertAssignStatement('third List statement is assignment',L.B,'e','f');
  422. end;
  423. Procedure TTestStatementConverter.TestWithStatementEmpty;
  424. Var
  425. W : TPasImplWithDo;
  426. El : TJSWithStatement;
  427. begin
  428. // With A do ;
  429. W:=TPasImplWithDo.Create('',NIl);
  430. W.Expressions.Add(CreateIdent('a'));
  431. El:=TJSWithStatement(Convert(W,TJSWithStatement));
  432. AssertIdentifier('Correct with expression',EL.A,'a');
  433. AssertEmptyBlockStatement('Empty with',El.B);
  434. end;
  435. Procedure TTestStatementConverter.TestWithStatementOne;
  436. Var
  437. W : TPasImplWithDo;
  438. El : TJSWithStatement;
  439. begin
  440. // With A do b:=c;
  441. W:=TPasImplWithDo.Create('',NIl);
  442. W.Expressions.Add(CreateIdent('a'));
  443. W.Body:=CreateAssignStatement('b','c');
  444. El:=TJSWithStatement(Convert(W,TJSWithStatement));
  445. AssertIdentifier('Correct with expression',EL.A,'a');
  446. AssertAssignStatement('Correct assignment',EL.B,'b','c');
  447. end;
  448. Procedure TTestStatementConverter.TestWithStatementTwo;
  449. Var
  450. W : TPasImplWithDo;
  451. El : TJSWithStatement;
  452. begin
  453. // With A,D do b:=c;
  454. W:=TPasImplWithDo.Create('',NIl);
  455. W.Expressions.Add(CreateIdent('a'));
  456. W.Expressions.Add(CreateIdent('d'));
  457. W.Body:=CreateAssignStatement('b','c');
  458. El:=TJSWithStatement(Convert(W,TJSWithStatement));
  459. AssertIdentifier('Correct with expression',EL.A,'a');
  460. El:=TJSWithStatement(AssertElement('Have second with statement',TJSWithStatement,EL.B));
  461. AssertIdentifier('Correct with expression',EL.A,'d');
  462. AssertAssignStatement('Correct assignment',El.B,'b','c');
  463. end;
  464. Procedure TTestStatementConverter.TestTryFinallyStatement;
  465. Var
  466. T : TPasImplTry;
  467. F : TPasImplTryFinally;
  468. El : TJSTryFinallyStatement;
  469. L : TJSStatementList;
  470. begin
  471. // Try a:=B finally b:=c end;
  472. T:=TPasImplTry.Create('',Nil);
  473. T.AddElement(CreateAssignStatement('a','b'));
  474. F:=T.AddFinally;
  475. F.AddElement(CreateAssignStatement('b','c'));
  476. El:=TJSTryFinallyStatement(Convert(T,TJSTryFinallyStatement));
  477. L:=AssertListStatement('try..finally block is statement list',EL.Block);
  478. AssertAssignStatement('Correct assignment in try..finally block',L.A,'a','b');
  479. AssertNull('No second statement',L.B);
  480. L:=AssertListStatement('try..finally block is statement list',El.BFinally);
  481. AssertAssignStatement('Correct assignment in finally..end block',L.A,'b','c');
  482. AssertNull('No second statement',L.B);
  483. end;
  484. Procedure TTestStatementConverter.TestTryExceptStatement;
  485. Var
  486. T : TPasImplTry;
  487. F : TPasImplTryExcept;
  488. El : TJSTryFinallyStatement;
  489. L : TJSStatementList;
  490. begin
  491. // Try a:=B except b:=c end;
  492. T:=TPasImplTry.Create('',Nil);
  493. T.AddElement(CreateAssignStatement('a','b'));
  494. F:=T.AddExcept;
  495. F.AddElement(CreateAssignStatement('b','c'));
  496. El:=TJSTryFinallyStatement(Convert(T,TJSTryCatchStatement));
  497. L:=AssertListStatement('try..except block is statement list',EL.Block);
  498. AssertAssignStatement('Correct assignment in try..except block',L.A,'a','b');
  499. AssertNull('No second statement',L.B);
  500. L:=AssertListStatement('try..except block is statement list',El.BCatch);
  501. AssertAssignStatement('Correct assignment in except..end block',L.A,'b','c');
  502. AssertEquals('Correct exception object name','jsexception',EL.Ident);
  503. AssertNull('No second statement',L.B);
  504. end;
  505. Procedure TTestStatementConverter.TestTryExceptStatementOnE;
  506. Var
  507. T : TPasImplTry;
  508. F : TPasImplTryExcept;
  509. O : TPasImplExceptOn;
  510. El : TJSTryFinallyStatement;
  511. L : TJSStatementList;
  512. I : TJSIfStatement;
  513. IC : TJSRelationalExpressionInstanceOf;
  514. V : TJSVarDeclaration;
  515. begin
  516. // Try a:=B except on E : exception do b:=c end;
  517. // Try a:=B except on E : exception do b:=c end;
  518. {
  519. Becomes:
  520. try {
  521. a=b;
  522. } catch (jsexception) {
  523. if jsexception instanceof exception {
  524. var e = jsexception;
  525. b = c;
  526. }
  527. }
  528. }
  529. T:=TPasImplTry.Create('',Nil);
  530. T.AddElement(CreateAssignStatement('a','b'));
  531. F:=T.AddExcept;
  532. O:=F.AddExceptOn(CreateIdent('E'),CreateIdent('Exception'));
  533. O.Body:=CreateAssignStatement('b','c');
  534. // Convert
  535. El:=TJSTryFinallyStatement(Convert(T,TJSTryCatchStatement));
  536. AssertEquals('Correct exception object name','jsexception',EL.Ident);
  537. L:=AssertListStatement('try..except block is statement list',El.BCatch);
  538. AssertNull('No second statement',L.B);
  539. I:=TJSIfStatement(AssertElement('On block is if',TJSIfStatement,L.A));
  540. Ic:=TJSRelationalExpressionInstanceOf(AssertElement('If condition is InstanceOf expression',TJSRelationalExpressionInstanceOf,I.Cond));
  541. Assertidentifier('InstanceOf left is exception object',Ic.A,'jsexception');
  542. // Lowercased exception - May need checking
  543. Assertidentifier('InstanceOf right is original exception type',Ic.B,'exception');
  544. L:=AssertListStatement('On block is always a list',i.btrue);
  545. V:=TJSVarDeclaration(AssertElement('First statement in list is a var declaration',TJSVarDeclaration,L.A));
  546. AssertEquals('Variable name is identifier in On A : Ex do','e',V.Name);
  547. Assertidentifier('Variable init is exception object',v.init,'jsexception');
  548. L:=AssertListStatement('Second statement is again list',L.B);
  549. AssertAssignStatement('Original assignment in second statement',L.A,'b','c');
  550. end;
  551. Procedure TTestStatementConverter.TestReRaise;
  552. Var
  553. T : TPasImplTry;
  554. F : TPasImplTryExcept;
  555. O : TPasImplExceptOn;
  556. El : TJSTryFinallyStatement;
  557. L : TJSStatementList;
  558. I : TJSIfStatement;
  559. IC : TJSRelationalExpressionInstanceOf;
  560. R : TJSThrowStatement;
  561. V : TJSVarDeclaration;
  562. begin
  563. // Try a:=B except on E : exception do b:=c end;
  564. {
  565. Becomes:
  566. try {
  567. a=b;
  568. } catch (jsexception) {
  569. if jsexception instanceof exception {
  570. var e = jsexception;
  571. throw jsexception;
  572. }
  573. }
  574. }
  575. T:=TPasImplTry.Create('',Nil);
  576. T.AddElement(CreateAssignStatement('a','b'));
  577. F:=T.AddExcept;
  578. O:=F.AddExceptOn(CreateIdent('E'),CreateIdent('Exception'));
  579. O.Body:=TPasImplRaise.Create('',Nil);
  580. // Convert
  581. El:=TJSTryFinallyStatement(Convert(T,TJSTryCatchStatement));
  582. AssertEquals('Correct exception object name','jsexception',EL.Ident);
  583. L:=AssertListStatement('try..except block is statement list',El.BCatch);
  584. AssertNull('No second statement',L.B);
  585. I:=TJSIfStatement(AssertElement('On block is if',TJSIfStatement,L.A));
  586. Ic:=TJSRelationalExpressionInstanceOf(AssertElement('If condition is InstanceOf expression',TJSRelationalExpressionInstanceOf,I.Cond));
  587. Assertidentifier('InstanceOf left is exception object',Ic.A,'jsexception');
  588. // Lowercased exception - May need checking
  589. L:=AssertListStatement('On block is always a list',i.btrue);
  590. V:=TJSVarDeclaration(AssertElement('First statement in list is a var declaration',TJSVarDeclaration,L.A));
  591. AssertEquals('Variable name is identifier in On A : Ex do','e',V.Name);
  592. Assertidentifier('Variable init is exception object',v.init,'jsexception');
  593. L:=AssertListStatement('Second statement is again list',L.B);
  594. R:=TJSThrowStatement(AssertElement('On block is throw statement',TJSThrowStatement,L.A));
  595. Assertidentifier('R expression is original exception ',R.A,'jsexception');
  596. end;
  597. Procedure TTestStatementConverter.TestVariableStatement;
  598. Var
  599. S : TPasSection;
  600. V : TPasVariable;
  601. L : TJSStatementList;
  602. JV : TJSVariableStatement;
  603. JVD : TJSVarDeclaration;
  604. begin
  605. S:=TPasSection.Create('',Nil);
  606. V:=TPasVariable.Create('A',Nil);
  607. S.Declarations.Add(V);
  608. S.Variables.Add(V);
  609. L:=TJSStatementList(Convert(S,TJSStatementList));
  610. JV:=TJSVariableStatement(AssertElement('Variable statement',TJSVariableStatement,L.A));
  611. JVD:=TJSVarDeclaration(AssertElement('Variable declaration',TJSVarDeclaration,JV.A));
  612. AssertEquals('Correct variable name','a',JVD.Name);
  613. end;
  614. { TTestExpressionConverter }
  615. Function TTestExpressionConverter.TestLiteralExpression(AElement: TPasElement;
  616. AClass: TJSElementClass): TJSLIteral;
  617. Var
  618. E : TJSElement;
  619. begin
  620. E:=Convert(AElement,AClass);
  621. if not (E is TJSLiteral) then
  622. Fail('Do not have literal class, but: '+E.ClassName);
  623. Result:=TJSLIteral(E);
  624. end;
  625. Function TTestExpressionConverter.TestUnaryExpression(AElement: TPasElement; AClass: TJSElementClass): TJSUnary;
  626. Var
  627. E : TJSElement;
  628. begin
  629. E:=Convert(AElement,AClass);
  630. AssertNotNull('Convert returned a result',E);
  631. if not (E is TJSUnary) then
  632. Fail('Do not have unary class, but: '+E.ClassName);
  633. Result:=TJSUnary(E);
  634. end;
  635. Function TTestExpressionConverter.TestBinaryExpression(AElement: TPasElement;
  636. AClass: TJSElementClass): TJSBinary;
  637. Var
  638. E : TJSElement;
  639. begin
  640. E:=Convert(AElement,AClass);
  641. if not (E is TJSBinary) then
  642. Fail('Do not have literal class, but: '+E.ClassName);
  643. Result:=TJSBinary(E);
  644. end;
  645. Procedure TTestExpressionConverter.TestPrimitiveString;
  646. Var
  647. S : TPrimitiveExpr;
  648. E : TJSLiteral;
  649. begin
  650. S:=TPrimitiveExpr.Create(Nil,pekString,'''me''');
  651. E:=TestLiteralExpression(S,TJSLiteral);
  652. AssertEquals('Correct literal type',jstString,E.Value.ValueType);
  653. AssertEquals('Correct literal value','me',E.Value.AsString);
  654. end;
  655. Procedure TTestExpressionConverter.TestPrimitiveNumber;
  656. Var
  657. S : TPrimitiveExpr;
  658. E : TJSLiteral;
  659. begin
  660. S:=TPrimitiveExpr.Create(Nil,pekNumber,'1.23');
  661. E:=TestLiteralExpression(S,TJSLiteral);
  662. AssertEquals('Correct literal type',jstNumber,E.Value.ValueType);
  663. AssertEquals('Correct literal value',1.23,E.Value.AsNumber);
  664. end;
  665. Procedure TTestExpressionConverter.TestPrimitiveNil;
  666. Var
  667. S : TNilExpr;
  668. E : TJSLiteral;
  669. begin
  670. S:=TNilExpr.Create(Nil);
  671. E:=TestLiteralExpression(S,TJSLiteral);
  672. AssertEquals('Correct literal type',jstNull,E.Value.ValueType);
  673. AssertEquals('Correct literal value',True,E.Value.IsNull);
  674. end;
  675. Procedure TTestExpressionConverter.TestPrimitiveBoolTrue;
  676. Var
  677. S : TBoolConstExpr;
  678. E : TJSLiteral;
  679. begin
  680. S:=TBoolConstExpr.Create(Nil,pekBoolConst,True);
  681. E:=TestLiteralExpression(S,TJSLiteral);
  682. AssertEquals('Correct literal type',jstBoolean,E.Value.ValueType);
  683. AssertEquals('Correct literal value',True,E.Value.AsBoolean);
  684. end;
  685. Procedure TTestExpressionConverter.TestPrimitiveBoolFalse;
  686. Var
  687. S : TBoolConstExpr;
  688. E : TJSLiteral;
  689. begin
  690. S:=TBoolConstExpr.Create(Nil,pekBoolConst,False);
  691. E:=TestLiteralExpression(S,TJSLiteral);
  692. AssertEquals('Correct literal type',jstBoolean,E.Value.ValueType);
  693. AssertEquals('Correct literal value',False,E.Value.AsBoolean);
  694. end;
  695. Procedure TTestExpressionConverter.TestPrimitiveIdent;
  696. Var
  697. Id : TPrimitiveExpr;
  698. Res : TJSPrimaryExpressionIdent;
  699. begin
  700. Id:=TPrimitiveExpr.Create(Nil,pekIdent,'a');
  701. Res:=TJSPrimaryExpressionIdent(Convert(Id,TJSPrimaryExpressionIdent));
  702. AssertEquals('Correct identifier name','a',Res.Name);
  703. end;
  704. Procedure TTestExpressionConverter.TestUnaryMinus;
  705. Var
  706. U : TUnaryExpr;
  707. E : TJSUnaryMinusExpression;
  708. begin
  709. U:=TUnaryExpr.Create(Nil,pekUnary,eopSubtract);
  710. U.Operand:=CreateLiteral(1.23);
  711. E:=TJSUnaryMinusExpression(TestUnaryExpression(U,TJSUnaryMinusExpression));
  712. AssertLiteral('Correct literal for minus',E.A,1.23)
  713. end;
  714. Procedure TTestExpressionConverter.TestUnaryPlus;
  715. Var
  716. U : TUnaryExpr;
  717. E : TJSUnaryPlusExpression;
  718. begin
  719. U:=TUnaryExpr.Create(Nil,pekUnary,eopAdd);
  720. U.Operand:=CreateLiteral(1.23);
  721. E:=TJSUnaryPlusExpression(TestUnaryExpression(U,TJSUnaryPlusExpression));
  722. AssertLiteral('Correct literal for plus',E.A,1.23)
  723. end;
  724. Procedure TTestExpressionConverter.TestBinaryPlus;
  725. Var
  726. B : TBinaryExpr;
  727. E : TJSAdditiveExpressionPlus;
  728. begin
  729. B:=TBinaryExpr.Create(Nil,pekBinary,eopAdd);
  730. B.left:=CreateLiteral(1.23);
  731. B.Right:=CreateLiteral(3.45);
  732. E:=TJSAdditiveExpressionPlus(TestBinaryExpression(B,TJSAdditiveExpressionPlus));
  733. AssertLiteral('Correct left literal for addition',E.A,1.23);
  734. AssertLiteral('Correct right literal for addition',E.B,3.45);
  735. end;
  736. Procedure TTestExpressionConverter.TestBinaryMinus;
  737. Var
  738. B : TBinaryExpr;
  739. E : TJSAdditiveExpressionMinus;
  740. begin
  741. B:=TBinaryExpr.Create(Nil,pekBinary,eopSubtract);
  742. B.left:=CreateLiteral(1.23);
  743. B.Right:=CreateLiteral(3.45);
  744. E:=TJSAdditiveExpressionMinus(TestBinaryExpression(B,TJSAdditiveExpressionMinus));
  745. AssertLiteral('Correct left literal for subtract',E.A,1.23);
  746. AssertLiteral('Correct right literal for subtract',E.B,3.45);
  747. end;
  748. Procedure TTestExpressionConverter.TestBinaryMultiply;
  749. Var
  750. B : TBinaryExpr;
  751. E : TJSMultiplicativeExpressionMul;
  752. begin
  753. B:=TBinaryExpr.Create(Nil,pekBinary,eopMultiply);
  754. B.left:=CreateLiteral(1.23);
  755. B.Right:=CreateLiteral(3.45);
  756. E:=TJSMultiplicativeExpressionMul(TestBinaryExpression(B,TJSMultiplicativeExpressionMul));
  757. AssertLiteral('Correct left literal for multiplication',E.A,1.23);
  758. AssertLiteral('Correct right literal for multiplication',E.B,3.45);
  759. end;
  760. Procedure TTestExpressionConverter.TestBinaryDivision;
  761. Var
  762. B : TBinaryExpr;
  763. E : TJSMultiplicativeExpressionDiv;
  764. begin
  765. B:=TBinaryExpr.Create(Nil,pekBinary,eopDivide);
  766. B.left:=CreateLiteral(1.23);
  767. B.Right:=CreateLiteral(3.45);
  768. E:=TJSMultiplicativeExpressionDiv(TestBinaryExpression(B,TJSMultiplicativeExpressionDiv));
  769. AssertLiteral('Correct left literal for division',E.A,1.23);
  770. AssertLiteral('Correct right literal for division',E.B,3.45);
  771. end;
  772. Procedure TTestExpressionConverter.TestBinaryDiv;
  773. Var
  774. B : TBinaryExpr;
  775. E : TJSMultiplicativeExpressionDiv;
  776. begin
  777. B:=TBinaryExpr.Create(Nil,pekBinary,eopDiv);
  778. B.left:=CreateLiteral(1.23);
  779. B.Right:=CreateLiteral(3.45);
  780. E:=TJSMultiplicativeExpressionDiv(TestBinaryExpression(B,TJSMultiplicativeExpressionDiv));
  781. AssertLiteral('Correct left literal for div',E.A,1.23);
  782. AssertLiteral('Correct right literal for div',E.B,3.45);
  783. end;
  784. Procedure TTestExpressionConverter.TestBinaryMod;
  785. Var
  786. B : TBinaryExpr;
  787. E : TJSMultiplicativeExpressionMod;
  788. begin
  789. B:=TBinaryExpr.Create(Nil,pekBinary,eopMod);
  790. B.left:=CreateLiteral(1.23);
  791. B.Right:=CreateLiteral(3.45);
  792. E:=TJSMultiplicativeExpressionMod(TestBinaryExpression(B,TJSMultiplicativeExpressionMod));
  793. AssertLiteral('Correct left literal for mod',E.A,1.23);
  794. AssertLiteral('Correct right literal for mod',E.B,3.45);
  795. end;
  796. Procedure TTestExpressionConverter.TestBinarySHL;
  797. Var
  798. B : TBinaryExpr;
  799. E : TJSLShiftExpression;
  800. begin
  801. B:=TBinaryExpr.Create(Nil,pekBinary,eopSHL);
  802. B.left:=CreateLiteral(13);
  803. B.Right:=CreateLiteral(3);
  804. E:=TJSLShiftExpression(TestBinaryExpression(B,TJSLShiftExpression));
  805. AssertLiteral('Correct left literal for shl',E.A,13);
  806. AssertLiteral('Correct right literal for shl',E.B,3);
  807. end;
  808. Procedure TTestExpressionConverter.TestBinarySHR;
  809. Var
  810. B : TBinaryExpr;
  811. E : TJSRShiftExpression;
  812. begin
  813. B:=TBinaryExpr.Create(Nil,pekBinary,eopSHR);
  814. B.left:=CreateLiteral(13);
  815. B.Right:=CreateLiteral(3);
  816. E:=TJSRShiftExpression(TestBinaryExpression(B,TJSRShiftExpression));
  817. AssertLiteral('Correct left literal for shr',E.A,13);
  818. AssertLiteral('Correct right literal for shr',E.B,3);
  819. end;
  820. Procedure TTestExpressionConverter.TestBinaryEqual;
  821. Var
  822. B : TBinaryExpr;
  823. E : TJSEqualityExpressionEq;
  824. begin
  825. B:=TBinaryExpr.Create(Nil,pekBinary,eopEqual);
  826. B.left:=CreateLiteral(13);
  827. B.Right:=CreateLiteral(3);
  828. E:=TJSEqualityExpressionEq(TestBinaryExpression(B,TJSEqualityExpressionEq));
  829. AssertLiteral('Correct left literal for equal',E.A,13);
  830. AssertLiteral('Correct right literal for equal',E.B,3);
  831. end;
  832. Procedure TTestExpressionConverter.TestBinaryNotEqual;
  833. Var
  834. B : TBinaryExpr;
  835. E : TJSEqualityExpressionNE;
  836. begin
  837. B:=TBinaryExpr.Create(Nil,pekBinary,eopNotEqual);
  838. B.left:=CreateLiteral(13);
  839. B.Right:=CreateLiteral(3);
  840. E:=TJSEqualityExpressionNE(TestBinaryExpression(B,TJSEqualityExpressionNE));
  841. AssertLiteral('Correct left literal for not equal',E.A,13);
  842. AssertLiteral('Correct right literal for not equal',E.B,3);
  843. end;
  844. Procedure TTestExpressionConverter.TestBinaryLessThan;
  845. Var
  846. B : TBinaryExpr;
  847. E : TJSRelationalExpressionLT;
  848. begin
  849. B:=TBinaryExpr.Create(Nil,pekBinary,eopLessThan);
  850. B.left:=CreateLiteral(13);
  851. B.Right:=CreateLiteral(3);
  852. E:=TJSRelationalExpressionLT(TestBinaryExpression(B,TJSRelationalExpressionLT));
  853. AssertLiteral('Correct left literal for less than',E.A,13);
  854. AssertLiteral('Correct right literal for less than',E.B,3);
  855. end;
  856. Procedure TTestExpressionConverter.TestBinaryLessThanEqual;
  857. Var
  858. B : TBinaryExpr;
  859. E : TJSRelationalExpressionLE;
  860. begin
  861. B:=TBinaryExpr.Create(Nil,pekBinary,eopLessThanEqual);
  862. B.left:=CreateLiteral(13);
  863. B.Right:=CreateLiteral(3);
  864. E:=TJSRelationalExpressionLE(TestBinaryExpression(B,TJSRelationalExpressionLE));
  865. AssertLiteral('Correct left literal for less than or equal',E.A,13);
  866. AssertLiteral('Correct right literal for less than or equal',E.B,3);
  867. end;
  868. Procedure TTestExpressionConverter.TestBinaryGreater;
  869. Var
  870. B : TBinaryExpr;
  871. E : TJSRelationalExpressionGT;
  872. begin
  873. B:=TBinaryExpr.Create(Nil,pekBinary,eopGreaterThan);
  874. B.left:=CreateLiteral(13);
  875. B.Right:=CreateLiteral(3);
  876. E:=TJSRelationalExpressionGT(TestBinaryExpression(B,TJSRelationalExpressionGT));
  877. AssertLiteral('Correct left literal for greater than',E.A,13);
  878. AssertLiteral('Correct right literal for greater than',E.B,3);
  879. end;
  880. Procedure TTestExpressionConverter.TestBinaryGreaterThanEqual;
  881. Var
  882. B : TBinaryExpr;
  883. E : TJSRelationalExpressionGE;
  884. begin
  885. B:=TBinaryExpr.Create(Nil,pekBinary,eopGreaterThanEqual);
  886. B.left:=CreateLiteral(13);
  887. B.Right:=CreateLiteral(3);
  888. E:=TJSRelationalExpressionGE(TestBinaryExpression(B,TJSRelationalExpressionGE));
  889. AssertLiteral('Correct left literal for greater than or equal',E.A,13);
  890. AssertLiteral('Correct right literal for greater than or equal',E.B,3);
  891. end;
  892. Procedure TTestExpressionConverter.TestBinaryIs;
  893. Var
  894. B : TBinaryExpr;
  895. E : TJSRelationalExpressionInstanceOf;
  896. begin
  897. B:=TBinaryExpr.Create(Nil,pekBinary,eopIs);
  898. B.left:=CreateIdent('a');
  899. B.Right:=CreateIdent('b');
  900. E:=TJSRelationalExpressionInstanceOf(TestBinaryExpression(B,TJSRelationalExpressionInstanceOf));
  901. AssertIdentifier('Correct left literal for is',E.A,'a');
  902. AssertIdentifier('Correct right literal for is',E.B,'b');
  903. end;
  904. Procedure TTestExpressionConverter.TestCallExpressionNone;
  905. Var
  906. B : TParamsExpr;
  907. E : TJSCallExpression;
  908. begin
  909. // a();
  910. B:=CreateFunctionCall('a',[]);
  911. E:=TJSCallExpression(Convert(B,TJSCallExpression));
  912. AssertIdentifier('Correct left literal for is',E.Expr,'a');
  913. AssertNull('No arguments',E.Args);
  914. // AssertEquals('No arguments',0,E.Args.Elements.Count);
  915. end;
  916. Procedure TTestExpressionConverter.TestCallExpressionOne;
  917. Var
  918. B : TParamsExpr;
  919. E : TJSCallExpression;
  920. begin
  921. // a(b);
  922. B:=CreateFunctionCall('a',['b']);
  923. E:=TJSCallExpression(Convert(B,TJSCallExpression));
  924. AssertIdentifier('Correct left literal for is',E.Expr,'a');
  925. AssertNotNull('have arguments',E.Args);
  926. AssertEquals('Argument count',1,E.Args.Elements.Count);
  927. AssertIdentifier('Argument 1 identifier',E.Args.Elements[0].Expr,'b');
  928. end;
  929. Procedure TTestExpressionConverter.TestCallExpressionTwo;
  930. Var
  931. B : TParamsExpr;
  932. E : TJSCallExpression;
  933. begin
  934. // a(b,c);
  935. B:=CreateFunctionCall('a',['b','c']);
  936. E:=TJSCallExpression(Convert(B,TJSCallExpression));
  937. AssertIdentifier('Correct left literal for is',E.Expr,'a');
  938. AssertNotNull('have arguments',E.Args);
  939. AssertEquals('Argument count',2,E.Args.Elements.Count);
  940. AssertIdentifier('Argument 1 identifier',E.Args.Elements[0].Expr,'b');
  941. AssertIdentifier('Argument 2 identifier',E.Args.Elements[1].Expr,'c');
  942. end;
  943. Procedure TTestExpressionConverter.TestMemberExpressionArrayOneDim;
  944. Var
  945. B : TParamsExpr;
  946. E : TJSBracketMemberExpression;
  947. begin
  948. // a[b];
  949. B:=TParamsExpr.Create(Nil,pekArrayParams,eopNone);
  950. B.Value:=CreateIdent('a');
  951. B.AddParam(CreateIdent('b'));
  952. E:=TJSBracketMemberExpression(Convert(B,TJSBracketMemberExpression));
  953. AssertIdentifier('Correct array name',E.MExpr,'a');
  954. AssertIdentifier('Correct array member name',E.Name,'b');
  955. end;
  956. Procedure TTestExpressionConverter.TestMemberExpressionArrayTwoDim;
  957. Var
  958. B : TParamsExpr;
  959. E : TJSBracketMemberExpression;
  960. begin
  961. // a[b,c];
  962. B:=TParamsExpr.Create(Nil,pekArrayParams,eopNone);
  963. B.Value:=CreateIdent('a');
  964. B.AddParam(CreateIdent('b'));
  965. B.AddParam(CreateIdent('c'));
  966. AttemptConvert:=B;
  967. AssertException('Cannot yet convert 2-dim arrays',EPasToJS,@TryConvert);
  968. end;
  969. Procedure TTestExpressionConverter.TestVariable;
  970. Var
  971. VD : TJSVarDeclaration;
  972. R :TPasVariable;
  973. begin
  974. R:=TPasVariable.Create('A',Nil);
  975. VD:=TJSVarDeclaration(Convert(R,TJSVarDeclaration));
  976. AssertEquals('Correct name, lowercased','a',VD.Name);
  977. AssertNull('No init',VD.Init);
  978. end;
  979. Procedure TTestExpressionConverter.TestArrayVariable;
  980. Var
  981. VD : TJSVarDeclaration;
  982. R :TPasVariable;
  983. A : TJSArrayLiteral;
  984. begin
  985. R:=TPasVariable.Create('A',Nil);
  986. R.VarType:=TPasArrayType.Create('myarray',Nil);
  987. VD:=TJSVarDeclaration(Convert(R,TJSVarDeclaration));
  988. AssertEquals('Correct name, lowercased','a',VD.Name);
  989. A:=TJSArrayLiteral(AssertElement('Init is array literal',TJSArrayLiteral,VD.Init));
  990. AssertEquals('No elements',0,A.Elements.Count);
  991. end;
  992. procedure TTestTestConverter.TestEmpty;
  993. begin
  994. AssertNotNull('Have converter',Converter);
  995. end;
  996. procedure TTestConverter.SetUp;
  997. begin
  998. FConverter:=TPasToJSConverter.Create;
  999. end;
  1000. procedure TTestConverter.TearDown;
  1001. begin
  1002. FreeAndNil(FRes);
  1003. FreeAndNil(FSource);
  1004. FreeAndNil(FConverter);
  1005. end;
  1006. Procedure TTestConverter.TryConvert;
  1007. begin
  1008. Convert(FAC,TJSElement);
  1009. end;
  1010. Function TTestConverter.Convert(AElement: TPasElement; AClass: TJSElementClass
  1011. ): TJSElement;
  1012. begin
  1013. FSource:=AElement;
  1014. Result:=FConverter.ConvertElement(AElement);
  1015. FRes:=Result;
  1016. if (AClass<>Nil) then
  1017. begin
  1018. AssertNotNull('Have conversion result',Result);
  1019. AssertEquals('Conversion result has correct class',AClass,Result.ClassType);
  1020. end;
  1021. end;
  1022. Class procedure TTestConverter.AssertEquals(Const Msg: String; AExpected, AActual: TJSType);
  1023. begin
  1024. AssertEquals(Msg,GetEnumName(TypeInfo(TJSType),Ord(AExpected)),
  1025. GetEnumName(TypeInfo(TJSType),Ord(AActual)));
  1026. end;
  1027. Class procedure TTestConverter.AssertLiteral(Const Msg : String; Lit: TJSElement; AType: TJSType);
  1028. begin
  1029. AssertNotNull(Msg+': Have instance',Lit);
  1030. AssertEquals(Msg+': Correct class',TJSLIteral,Lit.ClassType);
  1031. AssertEquals(Msg+': Correct value type',AType,TJSLIteral(Lit).Value.ValueType);
  1032. end;
  1033. Class procedure TTestConverter.AssertLiteral(Const Msg : String; Lit: TJSElement; AValue: Boolean);
  1034. begin
  1035. AssertLiteral(Msg,Lit,jstBoolean);
  1036. AssertEquals(Msg+': Correct value',AValue,TJSLiteral(Lit).Value.AsBoolean);
  1037. end;
  1038. Class procedure TTestConverter.AssertLiteral(Const Msg : String; Lit: TJSElement; AValue: TJSString);
  1039. begin
  1040. AssertLiteral(Msg,Lit,jstString);
  1041. AssertEquals(Msg+': Correct value',AValue,TJSLiteral(Lit).Value.AsString);
  1042. end;
  1043. Class procedure TTestConverter.AssertLiteral(Const Msg : String; Lit: TJSElement; AValue: TJSNumber);
  1044. begin
  1045. AssertLiteral(Msg,Lit,jstNumber);
  1046. AssertEquals(Msg+': Correct value',AValue,TJSLiteral(Lit).Value.AsNumber);
  1047. end;
  1048. Class procedure TTestConverter.AssertIdentifier(Const Msg: String;
  1049. Ident: TJSElement; AName: String);
  1050. begin
  1051. AssertNotNull(Msg+': Have instance',Ident);
  1052. AssertEquals(Msg+': Correct class',TJSPrimaryExpressionIdent,Ident.ClassType);
  1053. AssertEquals(Msg+': Correct name',AName,TJSPrimaryExpressionIdent(Ident).Name);
  1054. end;
  1055. Class Function TTestConverter.CreateLiteral(AValue: String): TPasExpr;
  1056. begin
  1057. Result:=TPrimitiveExpr.Create(Nil,pekString,'me');
  1058. end;
  1059. Class Function TTestConverter.CreateLiteral(AValue: Double): TPasExpr;
  1060. Var
  1061. S : String;
  1062. begin
  1063. Str(AValue,S);
  1064. Result:=TPrimitiveExpr.Create(Nil,pekNumber,S);
  1065. end;
  1066. Class Function TTestConverter.CreateIdent(AName: String): TPrimitiveExpr;
  1067. begin
  1068. Result:=TPrimitiveExpr.Create(Nil,pekIdent,AName);
  1069. end;
  1070. Class Function TTestConverter.CreateCondition : TPasExpr;
  1071. begin
  1072. Result:=CreateIdent('a');
  1073. end;
  1074. Class Function TTestConverter.CreateAssignStatement(LHS: String = 'a';RHS : String = 'b'): TPasImplAssign;
  1075. begin
  1076. Result:=TPasImplAssign.Create('',Nil);
  1077. Result.left:=CreateIdent(LHS);
  1078. Result.right:=CreateIdent(RHS);
  1079. end;
  1080. Class Function TTestConverter.CreateFunctionCall(AName: String;
  1081. Params: Array of String): TParamsExpr;
  1082. Var
  1083. I : Integer;
  1084. begin
  1085. Result:=TParamsExpr.Create(Nil,pekFuncParams,eopNone);
  1086. Result.Value:=CreateIdent(AName);
  1087. For I:=Low(Params) to High(Params) do
  1088. Result.AddParam(TPasExpr(CreateIdent(Params[I])));
  1089. end;
  1090. Class Procedure TTestConverter.AssertAssignStatement(Const Msg : String; El : TJSElement;LHS: String = 'a';RHS : String = 'b');
  1091. begin
  1092. AssertNotNull(Msg+': have statement',EL);
  1093. If not (El is TJSSimpleAssignStatement) then
  1094. Fail(Msg+': statement is not assign statement but is'+El.ClassName);
  1095. AssertIdentifier(Msg+': left hand side ('+LHS+')',TJSAssignStatement(EL).LHS,LHS);
  1096. AssertIdentifier(Msg+': left hand side ('+LHS+')',TJSAssignStatement(EL).Expr,RHS);
  1097. end;
  1098. Class Procedure TTestConverter.AssertEmptyBlockStatement(Const Msg: String;
  1099. El: TJSElement);
  1100. begin
  1101. AssertNotNull(Msg+': have statement',EL);
  1102. If not (El is TJSEmptyBlockStatement) then
  1103. Fail(Msg+': statement is not empty block statement but is'+El.ClassName);
  1104. end;
  1105. class Function TTestConverter.AssertListStatement(Const Msg: String;
  1106. El: TJSElement): TJSStatementList;
  1107. begin
  1108. AssertNotNull(Msg+': have statement',EL);
  1109. If not (El is TJSStatementList) then
  1110. Fail(Msg+': statement is not a list statement but is'+El.ClassName);
  1111. Result:=TJSStatementList(El);
  1112. end;
  1113. class Function TTestConverter.AssertElement(Const Msg: String;
  1114. AClass: TJSElementClass; El: TJSElement): TJSElement;
  1115. begin
  1116. AssertNotNull(Msg+': have element',El);
  1117. if not (El is ACLass) then
  1118. Fail(Msg+': is not of class '+AClass.ClassName+' but is '+EL.ClassName);
  1119. Result:=El;
  1120. end;
  1121. Initialization
  1122. RegisterTests([TTestTestConverter,TTestExpressionConverter,TTestStatementConverter]);
  1123. end.