tcconverter.pp 44 KB

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