tcconverter.pp 44 KB

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