spider-src 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE.txt +74 -0
  5. data/README.md +37 -0
  6. data/Rakefile +25 -0
  7. data/lib/spider-src/support/spider/.eslintrc +17 -0
  8. data/lib/spider-src/support/spider/.npmignore +9 -0
  9. data/lib/spider-src/support/spider/.travis.yml +7 -0
  10. data/lib/spider-src/support/spider/.yo-rc.json +3 -0
  11. data/lib/spider-src/support/spider/CHANGELOG.md +64 -0
  12. data/lib/spider-src/support/spider/Gruntfile.js +97 -0
  13. data/lib/spider-src/support/spider/Gruntfile.spider +93 -0
  14. data/lib/spider-src/support/spider/LICENSE +201 -0
  15. data/lib/spider-src/support/spider/README.md +50 -0
  16. data/lib/spider-src/support/spider/cli.js +119 -0
  17. data/lib/spider-src/support/spider/lib/ast/CaseClause.js +179 -0
  18. data/lib/spider-src/support/spider/lib/ast/CatchClause.js +26 -0
  19. data/lib/spider-src/support/spider/lib/ast/ExportBatchSpecifier.js +19 -0
  20. data/lib/spider-src/support/spider/lib/ast/ExportSpecifier.js +33 -0
  21. data/lib/spider-src/support/spider/lib/ast/ImportDefaultSpecifier.js +23 -0
  22. data/lib/spider-src/support/spider/lib/ast/ImportNamespaceSpecifier.js +23 -0
  23. data/lib/spider-src/support/spider/lib/ast/ImportSpecifier.js +40 -0
  24. data/lib/spider-src/support/spider/lib/ast/Node.js +93 -0
  25. data/lib/spider-src/support/spider/lib/ast/Parameter.js +229 -0
  26. data/lib/spider-src/support/spider/lib/ast/Program.js +58 -0
  27. data/lib/spider-src/support/spider/lib/ast/Property.js +32 -0
  28. data/lib/spider-src/support/spider/lib/ast/Range.js +257 -0
  29. data/lib/spider-src/support/spider/lib/ast/VariableDeclarator.js +29 -0
  30. data/lib/spider-src/support/spider/lib/ast/expressions/ArrayExpression.js +41 -0
  31. data/lib/spider-src/support/spider/lib/ast/expressions/ArrayPattern.js +45 -0
  32. data/lib/spider-src/support/spider/lib/ast/expressions/AssignmentExpression.js +29 -0
  33. data/lib/spider-src/support/spider/lib/ast/expressions/BinaryExpression.js +104 -0
  34. data/lib/spider-src/support/spider/lib/ast/expressions/CallExpression.js +139 -0
  35. data/lib/spider-src/support/spider/lib/ast/expressions/ConditionalExpression.js +31 -0
  36. data/lib/spider-src/support/spider/lib/ast/expressions/CurryCallExpression.js +102 -0
  37. data/lib/spider-src/support/spider/lib/ast/expressions/ExistentialExpression.js +83 -0
  38. data/lib/spider-src/support/spider/lib/ast/expressions/ForInExpression.js +116 -0
  39. data/lib/spider-src/support/spider/lib/ast/expressions/FunctionExpression.js +157 -0
  40. data/lib/spider-src/support/spider/lib/ast/expressions/InExpression.js +99 -0
  41. data/lib/spider-src/support/spider/lib/ast/expressions/LogicalExpression.js +50 -0
  42. data/lib/spider-src/support/spider/lib/ast/expressions/MemberExpression.js +43 -0
  43. data/lib/spider-src/support/spider/lib/ast/expressions/NewExpression.js +46 -0
  44. data/lib/spider-src/support/spider/lib/ast/expressions/NullCheckCallExpression.js +132 -0
  45. data/lib/spider-src/support/spider/lib/ast/expressions/NullCoalescingExpression.js +114 -0
  46. data/lib/spider-src/support/spider/lib/ast/expressions/NullPropagatingExpression.js +161 -0
  47. data/lib/spider-src/support/spider/lib/ast/expressions/ObjectExpression.js +39 -0
  48. data/lib/spider-src/support/spider/lib/ast/expressions/ObjectPattern.js +49 -0
  49. data/lib/spider-src/support/spider/lib/ast/expressions/RangeMemberExpression.js +157 -0
  50. data/lib/spider-src/support/spider/lib/ast/expressions/SplatExpression.js +48 -0
  51. data/lib/spider-src/support/spider/lib/ast/expressions/SuperExpression.js +170 -0
  52. data/lib/spider-src/support/spider/lib/ast/expressions/ThisExpression.js +22 -0
  53. data/lib/spider-src/support/spider/lib/ast/expressions/UnaryExpression.js +147 -0
  54. data/lib/spider-src/support/spider/lib/ast/expressions/UpdateExpression.js +26 -0
  55. data/lib/spider-src/support/spider/lib/ast/literals/BooleanLiteral.js +24 -0
  56. data/lib/spider-src/support/spider/lib/ast/literals/Identifier.js +60 -0
  57. data/lib/spider-src/support/spider/lib/ast/literals/NullLiteral.js +24 -0
  58. data/lib/spider-src/support/spider/lib/ast/literals/NumberLiteral.js +24 -0
  59. data/lib/spider-src/support/spider/lib/ast/literals/RegularExpressionLiteral.js +25 -0
  60. data/lib/spider-src/support/spider/lib/ast/literals/StringLiteral.js +90 -0
  61. data/lib/spider-src/support/spider/lib/ast/literals/UndefinedLiteral.js +30 -0
  62. data/lib/spider-src/support/spider/lib/ast/statements/BlockStatement.js +47 -0
  63. data/lib/spider-src/support/spider/lib/ast/statements/BreakStatement.js +19 -0
  64. data/lib/spider-src/support/spider/lib/ast/statements/ContinueStatement.js +19 -0
  65. data/lib/spider-src/support/spider/lib/ast/statements/DebuggerStatement.js +19 -0
  66. data/lib/spider-src/support/spider/lib/ast/statements/DoWhileStatement.js +25 -0
  67. data/lib/spider-src/support/spider/lib/ast/statements/ExportDeclarationStatement.js +51 -0
  68. data/lib/spider-src/support/spider/lib/ast/statements/ExpressionStatement.js +22 -0
  69. data/lib/spider-src/support/spider/lib/ast/statements/FallthroughStatement.js +74 -0
  70. data/lib/spider-src/support/spider/lib/ast/statements/ForInStatement.js +79 -0
  71. data/lib/spider-src/support/spider/lib/ast/statements/ForOfStatement.js +98 -0
  72. data/lib/spider-src/support/spider/lib/ast/statements/ForStatement.js +43 -0
  73. data/lib/spider-src/support/spider/lib/ast/statements/FunctionDeclarationStatement.js +104 -0
  74. data/lib/spider-src/support/spider/lib/ast/statements/GoStatement.js +41 -0
  75. data/lib/spider-src/support/spider/lib/ast/statements/IfStatement.js +32 -0
  76. data/lib/spider-src/support/spider/lib/ast/statements/ImportDeclarationStatement.js +40 -0
  77. data/lib/spider-src/support/spider/lib/ast/statements/PushStatement.js +37 -0
  78. data/lib/spider-src/support/spider/lib/ast/statements/ReturnStatement.js +26 -0
  79. data/lib/spider-src/support/spider/lib/ast/statements/SwitchStatement.js +159 -0
  80. data/lib/spider-src/support/spider/lib/ast/statements/ThrowStatement.js +22 -0
  81. data/lib/spider-src/support/spider/lib/ast/statements/TryStatement.js +36 -0
  82. data/lib/spider-src/support/spider/lib/ast/statements/UntilStatement.js +31 -0
  83. data/lib/spider-src/support/spider/lib/ast/statements/UseStatement.js +49 -0
  84. data/lib/spider-src/support/spider/lib/ast/statements/VariableDeclarationStatement.js +36 -0
  85. data/lib/spider-src/support/spider/lib/ast/statements/WhileStatement.js +25 -0
  86. data/lib/spider-src/support/spider/lib/ast.js +16 -0
  87. data/lib/spider-src/support/spider/lib/parser.js +14878 -0
  88. data/lib/spider-src/support/spider/lib/spider.js +217 -0
  89. data/lib/spider-src/support/spider/package.json +61 -0
  90. data/lib/spider-src/support/spider/spider-script.js +6 -0
  91. data/lib/spider-src/support/spider/src/ast/CaseClause.spider +179 -0
  92. data/lib/spider-src/support/spider/src/ast/CatchClause.spider +30 -0
  93. data/lib/spider-src/support/spider/src/ast/ExportBatchSpecifier.spider +19 -0
  94. data/lib/spider-src/support/spider/src/ast/ExportSpecifier.spider +37 -0
  95. data/lib/spider-src/support/spider/src/ast/ImportDefaultSpecifier.spider +25 -0
  96. data/lib/spider-src/support/spider/src/ast/ImportNamespaceSpecifier.spider +25 -0
  97. data/lib/spider-src/support/spider/src/ast/ImportSpecifier.spider +44 -0
  98. data/lib/spider-src/support/spider/src/ast/Node.spider +104 -0
  99. data/lib/spider-src/support/spider/src/ast/Parameter.spider +233 -0
  100. data/lib/spider-src/support/spider/src/ast/Program.spider +109 -0
  101. data/lib/spider-src/support/spider/src/ast/Property.spider +36 -0
  102. data/lib/spider-src/support/spider/src/ast/Range.spider +291 -0
  103. data/lib/spider-src/support/spider/src/ast/VariableDeclarator.spider +33 -0
  104. data/lib/spider-src/support/spider/src/ast/expressions/ArrayExpression.spider +32 -0
  105. data/lib/spider-src/support/spider/src/ast/expressions/ArrayPattern.spider +37 -0
  106. data/lib/spider-src/support/spider/src/ast/expressions/AssignmentExpression.spider +34 -0
  107. data/lib/spider-src/support/spider/src/ast/expressions/BinaryExpression.spider +125 -0
  108. data/lib/spider-src/support/spider/src/ast/expressions/CallExpression.spider +149 -0
  109. data/lib/spider-src/support/spider/src/ast/expressions/ConditionalExpression.spider +34 -0
  110. data/lib/spider-src/support/spider/src/ast/expressions/CurryCallExpression.spider +109 -0
  111. data/lib/spider-src/support/spider/src/ast/expressions/ExistentialExpression.spider +102 -0
  112. data/lib/spider-src/support/spider/src/ast/expressions/ForInExpression.spider +140 -0
  113. data/lib/spider-src/support/spider/src/ast/expressions/FunctionExpression.spider +183 -0
  114. data/lib/spider-src/support/spider/src/ast/expressions/InExpression.spider +114 -0
  115. data/lib/spider-src/support/spider/src/ast/expressions/LogicalExpression.spider +62 -0
  116. data/lib/spider-src/support/spider/src/ast/expressions/MemberExpression.spider +57 -0
  117. data/lib/spider-src/support/spider/src/ast/expressions/NewExpression.spider +40 -0
  118. data/lib/spider-src/support/spider/src/ast/expressions/NullCheckCallExpression.spider +151 -0
  119. data/lib/spider-src/support/spider/src/ast/expressions/NullCoalescingExpression.spider +151 -0
  120. data/lib/spider-src/support/spider/src/ast/expressions/NullPropagatingExpression.spider +190 -0
  121. data/lib/spider-src/support/spider/src/ast/expressions/ObjectExpression.spider +30 -0
  122. data/lib/spider-src/support/spider/src/ast/expressions/ObjectPattern.spider +42 -0
  123. data/lib/spider-src/support/spider/src/ast/expressions/RangeMemberExpression.spider +179 -0
  124. data/lib/spider-src/support/spider/src/ast/expressions/SplatExpression.spider +49 -0
  125. data/lib/spider-src/support/spider/src/ast/expressions/SuperExpression.spider +235 -0
  126. data/lib/spider-src/support/spider/src/ast/expressions/ThisExpression.spider +21 -0
  127. data/lib/spider-src/support/spider/src/ast/expressions/UnaryExpression.spider +158 -0
  128. data/lib/spider-src/support/spider/src/ast/expressions/UpdateExpression.spider +28 -0
  129. data/lib/spider-src/support/spider/src/ast/literals/BooleanLiteral.spider +23 -0
  130. data/lib/spider-src/support/spider/src/ast/literals/Identifier.spider +68 -0
  131. data/lib/spider-src/support/spider/src/ast/literals/NullLiteral.spider +23 -0
  132. data/lib/spider-src/support/spider/src/ast/literals/NumberLiteral.spider +23 -0
  133. data/lib/spider-src/support/spider/src/ast/literals/RegularExpressionLiteral.spider +24 -0
  134. data/lib/spider-src/support/spider/src/ast/literals/StringLiteral.spider +91 -0
  135. data/lib/spider-src/support/spider/src/ast/literals/UndefinedLiteral.spider +30 -0
  136. data/lib/spider-src/support/spider/src/ast/statements/BlockStatement.spider +45 -0
  137. data/lib/spider-src/support/spider/src/ast/statements/BreakStatement.spider +19 -0
  138. data/lib/spider-src/support/spider/src/ast/statements/ContinueStatement.spider +19 -0
  139. data/lib/spider-src/support/spider/src/ast/statements/DebuggerStatement.spider +19 -0
  140. data/lib/spider-src/support/spider/src/ast/statements/DoWhileStatement.spider +28 -0
  141. data/lib/spider-src/support/spider/src/ast/statements/ExportDeclarationStatement.spider +46 -0
  142. data/lib/spider-src/support/spider/src/ast/statements/ExpressionStatement.spider +22 -0
  143. data/lib/spider-src/support/spider/src/ast/statements/FallthroughStatement.spider +85 -0
  144. data/lib/spider-src/support/spider/src/ast/statements/ForInStatement.spider +92 -0
  145. data/lib/spider-src/support/spider/src/ast/statements/ForOfStatement.spider +117 -0
  146. data/lib/spider-src/support/spider/src/ast/statements/ForStatement.spider +51 -0
  147. data/lib/spider-src/support/spider/src/ast/statements/FunctionDeclarationStatement.spider +115 -0
  148. data/lib/spider-src/support/spider/src/ast/statements/GoStatement.spider +44 -0
  149. data/lib/spider-src/support/spider/src/ast/statements/IfStatement.spider +38 -0
  150. data/lib/spider-src/support/spider/src/ast/statements/ImportDeclarationStatement.spider +33 -0
  151. data/lib/spider-src/support/spider/src/ast/statements/PushStatement.spider +40 -0
  152. data/lib/spider-src/support/spider/src/ast/statements/ReturnStatement.spider +28 -0
  153. data/lib/spider-src/support/spider/src/ast/statements/SwitchStatement.spider +161 -0
  154. data/lib/spider-src/support/spider/src/ast/statements/ThrowStatement.spider +23 -0
  155. data/lib/spider-src/support/spider/src/ast/statements/TryStatement.spider +42 -0
  156. data/lib/spider-src/support/spider/src/ast/statements/UntilStatement.spider +36 -0
  157. data/lib/spider-src/support/spider/src/ast/statements/UseStatement.spider +62 -0
  158. data/lib/spider-src/support/spider/src/ast/statements/VariableDeclarationStatement.spider +34 -0
  159. data/lib/spider-src/support/spider/src/ast/statements/WhileStatement.spider +28 -0
  160. data/lib/spider-src/support/spider/src/ast.spider +80 -0
  161. data/lib/spider-src/support/spider/src/spider.pegjs +1434 -0
  162. data/lib/spider-src/support/spider/src/spider.spider +276 -0
  163. data/lib/spider-src/support/spider/test/spider_test.js +1787 -0
  164. data/lib/spider-src/version.rb +5 -0
  165. data/lib/spider-src.rb +37 -0
  166. data/spider-src.gemspec +24 -0
  167. data/test/test_spider_src.rb +33 -0
  168. metadata +225 -0
@@ -0,0 +1,1787 @@
1
+ /*global describe,it*/
2
+ 'use strict';
3
+
4
+ require('traceur');
5
+
6
+ var should = require('should'),
7
+ spider = require('../lib/spider');
8
+
9
+ function generateTest(code, expectation) {
10
+ return function () {
11
+ should(spider.compile({ text: code,
12
+ generateSourceMap: false,
13
+ target: "ES6",
14
+ iifi: false,
15
+ useStrict: false
16
+ }).result).be.exactly(expectation);
17
+ };
18
+ }
19
+
20
+ function generateErrorTest(code, expectedErrors) {
21
+ return function () {
22
+ var errors = spider.compile({
23
+ text: code,
24
+ generateSourceMap: false,
25
+ target: "ES6",
26
+ iifi: false,
27
+ useStrict: false
28
+ }).errors;
29
+
30
+ should(errors.map(function (error) {
31
+ delete error.message;
32
+ delete error.loc;
33
+
34
+ return error;
35
+ })).eql(expectedErrors);
36
+ };
37
+ }
38
+
39
+ describe('variable statement:', function () {
40
+ it('syntax error', generateErrorTest('var x = y^', [{ type: "SyntaxError" }]));
41
+
42
+ it('create variable',
43
+ generateTest('var a;', 'let a;'));
44
+
45
+ it('create variable with number literal',
46
+ generateTest('var a = 5;', 'let a = 5;'));
47
+
48
+ it('create variable with string literal',
49
+ generateTest('var a = "test";', 'let a = "test";'));
50
+
51
+ it('create variable with boolean literal',
52
+ generateTest('var a = true;', 'let a = true;'));
53
+
54
+ it('create variable with null literal',
55
+ generateTest('var a = null;', 'let a = null;'));
56
+
57
+ it('create variable with identifier value',
58
+ generateTest('var a = b;', 'let a = b;'));
59
+
60
+ it('create multiple variables in one statement',
61
+ generateTest('var a, b;', 'let a, b;'));
62
+
63
+ it('create multiple variables in one statement with values',
64
+ generateTest('var a = 5, b = false;', 'let a = 5, b = false;'));
65
+
66
+ it('create multiple variables in multiple statements',
67
+ generateTest('var a; var b;', 'let a;\nlet b;'));
68
+ });
69
+
70
+ describe('member expressions:', function () {
71
+ it('member expression with 2 nodes',
72
+ generateTest('var a = b.c;', 'let a = b.c;'));
73
+
74
+ it('member expression with 3 nodes',
75
+ generateTest('var a = b.c.d;', 'let a = b.c.d;'));
76
+
77
+ it('member expression with 4 nodes',
78
+ generateTest('var a = b.c.d.e;', 'let a = b.c.d.e;'));
79
+ });
80
+
81
+ describe('null propagating member expressions:', function () {
82
+ it('null propagating member expression with 2 nodes',
83
+ generateTest('var a = b?.c;', 'let a = typeof b !== "undefined" && b !== null ? b.c : void 0;'));
84
+
85
+ it('null propagating member expression with 3 nodes',
86
+ generateTest('var a = b?.c?.d;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null) ? b.c.d : void 0;'));
87
+
88
+ it('null propagating member expression with 4 nodes',
89
+ generateTest('var a = b?.c?.d?.e;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null && b.c.d !== null) ? b.c.d.e : void 0;'));
90
+ });
91
+
92
+ describe('member and null propagating member expressions:', function () {
93
+ it('1 member expression and 1 null propagating member expression',
94
+ generateTest('var a = b.c?.d;', 'let a = typeof b.c !== "undefined" && b.c !== null ? b.c.d : void 0;'));
95
+
96
+ it('2 member expressions and 1 null propagating member expression',
97
+ generateTest('var a = b.c.d?.e;', 'let a = typeof b.c.d !== "undefined" && b.c.d !== null ? b.c.d.e : void 0;'));
98
+
99
+ it('3 member expressions and 1 null propagating member expression',
100
+ generateTest('var a = b.c.d.e?.f;', 'let a = typeof b.c.d.e !== "undefined" && b.c.d.e !== null ? b.c.d.e.f : void 0;'));
101
+
102
+ it('1 member expression and 2 null propagating member expressions',
103
+ generateTest('var a = b.c?.d?.e;', 'let a = typeof b.c !== "undefined" && (b.c !== null && b.c.d !== null) ? b.c.d.e : void 0;'));
104
+
105
+ it('1 member expression and 3 null propagating member expressions',
106
+ generateTest('var a = b.c?.d?.e?.f;', 'let a = typeof b.c !== "undefined" && (b.c !== null && b.c.d !== null && b.c.d.e !== null) ? b.c.d.e.f : void 0;'));
107
+
108
+ it('2 member expressions and 2 null propagating member expressions',
109
+ generateTest('var a = b.c.d?.e?.f;', 'let a = typeof b.c.d !== "undefined" && (b.c.d !== null && b.c.d.e !== null) ? b.c.d.e.f : void 0;'));
110
+
111
+ it('3 member expressions and 3 null propagating member expressions',
112
+ generateTest('var a = b.c.d.e?.f?.g?.h;', 'let a = typeof b.c.d.e !== \"undefined\" && (b.c.d.e !== null && b.c.d.e.f !== null && b.c.d.e.f.g !== null) ? b.c.d.e.f.g.h : void 0;'));
113
+
114
+ it('1 null propagating member expression and 1 member expression',
115
+ generateTest('var a = b?.c;', 'let a = typeof b !== \"undefined\" && b !== null ? b.c : void 0;'));
116
+
117
+ it('2 null propagating member expressions and 1 member expression',
118
+ generateTest('var a = b?.c?.d.e;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null) ? b.c.d.e : void 0;'));
119
+
120
+ it('3 null propagating member expressions and 1 member expression',
121
+ generateTest('var a = b?.c?.d?.e.f;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null && b.c.d !== null) ? b.c.d.e.f : void 0;'));
122
+
123
+ it('1 null propagating member expression and 2 member expressions',
124
+ generateTest('var a = b?.c.d;', 'let a = typeof b !== "undefined" && b !== null ? b.c.d : void 0;'));
125
+
126
+ it('1 null propagating member expression and 3 member expressions',
127
+ generateTest('var a = b?.c.d.e;', 'let a = typeof b !== "undefined" && b !== null ? b.c.d.e : void 0;'));
128
+
129
+ it('2 null propagating member expressions and 2 member expressions',
130
+ generateTest('var a = b?.c?.d.e.f;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null) ? b.c.d.e.f : void 0;'));
131
+
132
+ it('3 null propagating member expression and 2 member expressions',
133
+ generateTest('var a = b?.c?.d?.e.f.g;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null && b.c.d !== null) ? b.c.d.e.f.g : void 0;'));
134
+
135
+ it('3 null propagating member expression and 3 member expressions',
136
+ generateTest('var a = b?.c?.d?.e.f.g.h;', 'let a = typeof b !== "undefined" && (b !== null && b.c !== null && b.c.d !== null) ? b.c.d.e.f.g.h : void 0;'));
137
+
138
+ it('1 member expression, 1 null propagating member expression, 1 member expression',
139
+ generateTest('var a = b.c?.d.e;', 'let a = typeof b.c !== "undefined" && b.c !== null ? b.c.d.e : void 0;'));
140
+
141
+ it('2 member expressions, 1 null propagating member expression, 1 member expression',
142
+ generateTest('var a = b.c.d?.e.f;', 'let a = typeof b.c.d !== "undefined" && b.c.d !== null ? b.c.d.e.f : void 0;'));
143
+
144
+ it('1 member expression, 2 null propagating member expressions, 1 member expression',
145
+ generateTest('var a = b.c?.d?.e.f;', 'let a = typeof b.c !== \"undefined\" && (b.c !== null && b.c.d !== null) ? b.c.d.e.f : void 0;'));
146
+
147
+ it('1 member expression, 1 null propagating member expression, 2 member expressions',
148
+ generateTest('var a = b.c?.d.e.f;', 'let a = typeof b.c !== "undefined" && b.c !== null ? b.c.d.e.f : void 0;'));
149
+
150
+ it('1 null propagating member expression, 1 member expression, 1 null propagating member expression',
151
+ generateTest('var a = b?.c.d?.e;', 'let nullPropagating0 = typeof b !== \"undefined\" && b !== null ? b.c.d : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.e : void 0;'));
152
+
153
+ it('2 null propagating member expressions, 1 member expression, 1 null propagating member expression',
154
+ generateTest('var a = b?.c?.d.e?.f;', 'let nullPropagating0 = typeof b !== \"undefined\" && (b !== null && b.c !== null) ? b.c.d.e : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.f : void 0;'));
155
+
156
+ it('3 null propagating member expressions, 1 member expression, 1 null propagating member expression',
157
+ generateTest('var a = b?.c?.d?.e.f?.h;', 'let nullPropagating0 = typeof b !== \"undefined\" && (b !== null && b.c !== null && b.c.d !== null) ? b.c.d.e.f : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.h : void 0;'));
158
+
159
+ it('1 null propagating member expression, 2 member expressions, 1 null propagating member expression',
160
+ generateTest('var a = b?.c.d.e?.f;', 'let nullPropagating0 = typeof b !== \"undefined\" && b !== null ? b.c.d.e : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.f : void 0;'));
161
+
162
+ it('1 null propagating member expression, 3 member expressions, 1 null propagating member expression',
163
+ generateTest('var a = b?.c.d.e.f?.h;', 'let nullPropagating0 = typeof b !== \"undefined\" && b !== null ? b.c.d.e.f : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.h : void 0;'));
164
+
165
+ it('1 null propagating member expression, 1 member expression, 2 null propagating member expressions',
166
+ generateTest('var a = b?.c.d?.e?.f;', 'let nullPropagating0 = typeof b !== \"undefined\" && b !== null ? b.c.d : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.e !== null) ? nullPropagating0.e.f : void 0;'));
167
+
168
+ it('1 null propagating member expression, 1 member expression, 3 null propagating member expressions',
169
+ generateTest('var a = b?.c.d?.e?.f?.h;', 'let nullPropagating0 = typeof b !== \"undefined\" && b !== null ? b.c.d : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.e !== null && nullPropagating0.e.f !== null) ? nullPropagating0.e.f.h : void 0;'));
170
+
171
+ it('scramble member and null propagating member expressions (1)',
172
+ generateTest('var a = b?.c.d?.e.f;', 'let nullPropagating0 = typeof b !== \"undefined\" && b !== null ? b.c.d : void 0;\nlet a = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.e.f : void 0;'));
173
+
174
+ it('scramble member and null propagating member expressions (2)',
175
+ generateTest('var a = b?.c?.d.e?.f?.g.h?.i;', 'let nullPropagating0 = typeof b !== \"undefined\" && (b !== null && b.c !== null) ? b.c.d.e : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.f !== null) ? nullPropagating0.f.g.h : void 0;\nlet a = typeof nullPropagating1 !== \"undefined\" && nullPropagating1 !== null ? nullPropagating1.i : void 0;'));
176
+ });
177
+
178
+ describe('call expressions and statements:', function () {
179
+ it('call statement without arguments',
180
+ generateTest('f();', 'f();'));
181
+
182
+ it('call statement with 1 argument',
183
+ generateTest('f(1);', 'f(1);'));
184
+
185
+ it('call statement with 2 arguments',
186
+ generateTest('f(1, true);',
187
+ 'f(1, true);'));
188
+
189
+ it('call statement with 3 arguments',
190
+ generateTest('f(1, true, "test");',
191
+ 'f(1, true, "test");'));
192
+
193
+ it('call statement with 4 arguments',
194
+ generateTest('f(1, true, "test", { a: 1 });',
195
+ 'f(1, true, "test", { a: 1 });'));
196
+
197
+ it('call expression without arguments',
198
+ generateTest('var a = f();', 'let a = f();'));
199
+
200
+ it('call expression with 1 argument',
201
+ generateTest('var a = f(1);', 'let a = f(1);'));
202
+
203
+ it('call expression with 2 arguments',
204
+ generateTest('var a = f(1, true);', 'let a = f(1, true);'));
205
+
206
+ it('call expression with 3 arguments',
207
+ generateTest('var a = f(1, true, "test");', 'let a = f(1, true, "test");'));
208
+
209
+ it('call expression with 4 arguments',
210
+ generateTest('var a = f(1, true, "test", { a: 1 });', 'let a = f(1, true, "test", { a: 1 });'));
211
+ });
212
+
213
+ describe('call statements with member expressions:', function () {
214
+ it('1 member expression and 1 call statement',
215
+ generateTest('a.f();', 'a.f();'));
216
+
217
+ it('2 member expressions and 1 call statement',
218
+ generateTest('a.b.f();', 'a.b.f();'));
219
+
220
+ it('3 member expressions and 1 call statement',
221
+ generateTest('a.b.c.f();', 'a.b.c.f();'));
222
+
223
+ it('1 member expression and 2 call statements',
224
+ generateTest('a.fn1().fn2();', 'a.fn1().fn2();'));
225
+
226
+ it('1 member expression and 3 call statements',
227
+ generateTest('a.fn1().fn2().fn3();', 'a.fn1().fn2().fn3();'));
228
+
229
+ it('1 member expression, 1 call statement, 1 member expression, 1 call statement',
230
+ generateTest('a.fn1().b.fn2();', 'a.fn1().b.fn2();'));
231
+
232
+ it('2 member expression, 2 call statement, 2 member expression, 2 call statement',
233
+ generateTest('a.b.fn1().fn2().c.d.fn3().fn4();', 'a.b.fn1().fn2().c.d.fn3().fn4();'));
234
+ });
235
+
236
+ describe('call statements with null propagating member expressions:', function () {
237
+ it('1 null propagating member expression and 1 call statement',
238
+ generateTest('a?.f();', 'if (typeof a !== \"undefined\" && a !== null) {\n a.f();\n}'));
239
+
240
+ it('2 null propagating member expressions and 1 call statement',
241
+ generateTest('a?.b?.f();',
242
+ 'if (typeof a !== \"undefined\" && (a !== null && a.b !== null)) {\n a.b.f();\n}'));
243
+
244
+ it('3 null propagating member expressions and 1 call statement',
245
+ generateTest('a?.b?.c?.f();',
246
+ 'if (typeof a !== \"undefined\" && (a !== null && a.b !== null && a.b.c !== null)) {\n a.b.c.f();\n}'));
247
+
248
+ it('1 null propagating member expression and 2 call statements',
249
+ generateTest('a?.fn1()?.fn2();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.fn1() : void 0;\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.fn2();\n}'));
250
+
251
+ it('1 null propagating member expression and 3 call statements',
252
+ generateTest('a?.fn1()?.fn2()?.fn3();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.fn1() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.fn2() : void 0;\nif (typeof nullPropagating1 !== \"undefined\" && nullPropagating1 !== null) {\n nullPropagating1.fn3();\n}'));
253
+
254
+ it('1 null propagating member expression, 1 call statement, 1 null propagating member expression, 1 call statement',
255
+ generateTest('a?.fn1()?.b?.fn2();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.fn1() : void 0;\nif (typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.b !== null)) {\n nullPropagating0.b.fn2();\n}'));
256
+
257
+ it('2 null propagating member expression, 2 call statement, 2 null propagating member expression, 2 call statement',
258
+ generateTest('a?.b?.fn1()?.fn2()?.c?.d?.fn3()?.fn4();', 'let nullPropagating0 = typeof a !== \"undefined\" && (a !== null && a.b !== null) ? a.b.fn1() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.fn2() : void 0;\nlet nullPropagating2 = typeof nullPropagating1 !== \"undefined\" && (nullPropagating1 !== null && nullPropagating1.c !== null && nullPropagating1.c.d !== null) ? nullPropagating1.c.d.fn3() : void 0;\nif (typeof nullPropagating2 !== \"undefined\" && nullPropagating2 !== null) {\n nullPropagating2.fn4();\n}'));
259
+ });
260
+
261
+ describe('call statements with member and null propagating member expressions:', function () {
262
+ it('1 member expression, 1 call statement, 1 null propagating member expression, 1 call statement',
263
+ generateTest('a.b()?.c();', 'let nullPropagating0 = a.b();\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.c();\n}'));
264
+
265
+ it('2 member expressions, 1 call statement, 1 null propagating member expression, 1 call statement',
266
+ generateTest('a.b.c()?.d();', 'let nullPropagating0 = a.b.c();\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.d();\n}'));
267
+
268
+ it('1 member expression, 2 call statements, 1 null propagating member expression, 1 call statement',
269
+ generateTest('a.b().c()?.d();', 'let nullPropagating0 = a.b().c();\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.d();\n}'));
270
+
271
+ it('1 member expression, 1 call statement, 2 null propagating member expressions, 1 call statement',
272
+ generateTest('a.b()?.c?.d();', 'let nullPropagating0 = a.b();\nif (typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.c !== null)) {\n nullPropagating0.c.d();\n}'));
273
+
274
+ it('1 member expression, 1 call statement, 1 null propagating member expression, 2 call statement',
275
+ generateTest('a.b()?.c().d();', 'let nullPropagating0 = a.b();\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.c().d();\n}'));
276
+
277
+ it('1 null propagating member expression, 1 call statement, 1 member expression, 1 call statement',
278
+ generateTest('a?.b().c();',
279
+ 'if (typeof a !== \"undefined\" && a !== null) {\n a.b().c();\n}'));
280
+
281
+ it('2 null propagating member expression, 1 call statement, 1 member expression, 1 call statement',
282
+ generateTest('a?.b()?.c().d();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.c().d();\n}'));
283
+
284
+ it('1 null propagating member expression, 2 call statement, 1 member expression, 1 call statement',
285
+ generateTest('a?.b()?.c.d();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null) {\n nullPropagating0.c.d();\n}'));
286
+
287
+ it('scramble call statements with member and null propagating member expressions',
288
+ generateTest('a?.b()?.c.d().e.f.g?.h?.i?.j.k();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c.d().e.f.g : void 0;\nif (typeof nullPropagating1 !== \"undefined\" && (nullPropagating1 !== null && nullPropagating1.h !== null && nullPropagating1.h.i !== null)) {\n nullPropagating1.h.i.j.k();\n}'));
289
+ });
290
+
291
+ describe('call expressions with member expressions:', function () {
292
+ it('1 member expression and 1 call expression',
293
+ generateTest('var x = a.f();', 'let x = a.f();'));
294
+
295
+ it('2 member expressions and 1 call expression',
296
+ generateTest('var x = a.b.f();', 'let x = a.b.f();'));
297
+
298
+ it('3 member expressions and 1 call expression',
299
+ generateTest('var x = a.b.c.f();', 'let x = a.b.c.f();'));
300
+
301
+ it('1 member expression and 2 call expressions',
302
+ generateTest('var x = a.fn1().fn2();', 'let x = a.fn1().fn2();'));
303
+
304
+ it('1 member expression and 3 call expressions',
305
+ generateTest('var x = a.fn1().fn2().fn3();', 'let x = a.fn1().fn2().fn3();'));
306
+
307
+ it('1 member expression, 1 call expression, 1 member expression, 1 call expression',
308
+ generateTest('var x = a.fn1().b.fn2();', 'let x = a.fn1().b.fn2();'));
309
+
310
+ it('2 member expression, 2 call expression, 2 member expression, 2 call expression',
311
+ generateTest('var x = a.b.fn1().fn2().c.d.fn3().fn4();', 'let x = a.b.fn1().fn2().c.d.fn3().fn4();'));
312
+ });
313
+
314
+ describe('call expressions with null propagating member expressions:', function () {
315
+ it('1 null propagating member expression and 1 call expression',
316
+ generateTest('var x = a?.f();', 'let x = typeof a !== \"undefined\" && a !== null ? a.f() : void 0;'));
317
+
318
+ it('2 null propagating member expressions and 1 call expression',
319
+ generateTest('var x = a?.b?.f();', 'let x = typeof a !== \"undefined\" && (a !== null && a.b !== null) ? a.b.f() : void 0;'));
320
+
321
+ it('3 null propagating member expressions and 1 call expression',
322
+ generateTest('var x = a?.b?.c?.f();', 'let x = typeof a !== \"undefined\" && (a !== null && a.b !== null && a.b.c !== null) ? a.b.c.f() : void 0;'));
323
+
324
+ it('1 null propagating member expression and 2 call expressions',
325
+ generateTest('var x = a?.fn1()?.fn2();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.fn1() : void 0;\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.fn2() : void 0;'));
326
+
327
+ it('1 null propagating member expression and 3 call expressions',
328
+ generateTest('var x = a?.fn1()?.fn2()?.fn3();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.fn1() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.fn2() : void 0;\nlet x = typeof nullPropagating1 !== \"undefined\" && nullPropagating1 !== null ? nullPropagating1.fn3() : void 0;'));
329
+
330
+ it('1 null propagating member expression, 1 call expression, 1 null propagating member expression, 1 call expression',
331
+ generateTest('var x = a?.fn1()?.b?.fn2();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.fn1() : void 0;\nlet x = typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.b !== null) ? nullPropagating0.b.fn2() : void 0;'));
332
+
333
+ it('2 null propagating member expression, 2 call expressions, 2 null propagating member expression, 2 call expressions',
334
+ generateTest('var x = a?.b?.fn1()?.fn2()?.c?.d?.fn3()?.fn4();', 'let nullPropagating0 = typeof a !== \"undefined\" && (a !== null && a.b !== null) ? a.b.fn1() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.fn2() : void 0;\nlet nullPropagating2 = typeof nullPropagating1 !== \"undefined\" && (nullPropagating1 !== null && nullPropagating1.c !== null && nullPropagating1.c.d !== null) ? nullPropagating1.c.d.fn3() : void 0;\nlet x = typeof nullPropagating2 !== \"undefined\" && nullPropagating2 !== null ? nullPropagating2.fn4() : void 0;'));
335
+ });
336
+
337
+ describe('call expressions with member and null propagating member expressions:', function () {
338
+ it('1 member expression, 1 call expression, 1 null propagating member expression, 1 call expression',
339
+ generateTest('var x = a.b()?.c();', 'let nullPropagating0 = a.b();\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c() : void 0;'));
340
+
341
+ it('2 member expressions, 1 call expression, 1 null propagating member expression, 1 call expression',
342
+ generateTest('var x = a.b.c()?.d();', 'let nullPropagating0 = a.b.c();\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.d() : void 0;'));
343
+
344
+ it('1 member expression, 2 call expressions, 1 null propagating member expression, 1 call expression',
345
+ generateTest('var x = a.b().c()?.d();', 'let nullPropagating0 = a.b().c();\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.d() : void 0;'));
346
+
347
+ it('1 member expression, 1 call expression, 2 null propagating member expressions, 1 call expression',
348
+ generateTest('var x = a.b()?.c?.d();', 'let nullPropagating0 = a.b();\nlet x = typeof nullPropagating0 !== \"undefined\" && (nullPropagating0 !== null && nullPropagating0.c !== null) ? nullPropagating0.c.d() : void 0;'));
349
+
350
+ it('1 member expression, 1 call expression, 1 null propagating member expression, 2 call expressions',
351
+ generateTest('var x = a.b()?.c().d();', 'let nullPropagating0 = a.b();\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c().d() : void 0;'));
352
+
353
+ it('1 null propagating member expression, 1 call expression, 1 member expression, 1 call expression',
354
+ generateTest('var x = a?.b().c();', 'let x = typeof a !== \"undefined\" && a !== null ? a.b().c() : void 0;'));
355
+
356
+ it('2 null propagating member expression, 1 call expression, 1 member expression, 1 call expression',
357
+ generateTest('var x = a?.b()?.c().d();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c().d() : void 0;'));
358
+
359
+ it('1 null propagating member expression, 2 call expressions, 1 member expression, 1 call expression',
360
+ generateTest('var x = a?.b()?.c.d();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c.d() : void 0;'));
361
+
362
+ it('scramble call expressions with member and null propagating member expressions',
363
+ generateTest('var x = a?.b()?.c.d().e.f.g?.h?.i?.j.k();', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c.d().e.f.g : void 0;\nlet x = typeof nullPropagating1 !== \"undefined\" && (nullPropagating1 !== null && nullPropagating1.h !== null && nullPropagating1.h.i !== null) ? nullPropagating1.h.i.j.k() : void 0;'));
364
+ });
365
+
366
+ describe('null coalescing expressions:', function () {
367
+ it('null coalescing expression with 2 identifiers',
368
+ generateTest('var x = a ?? b;', 'let x = typeof a === \"undefined\" || a == null ? b : a;'));
369
+
370
+ it('null coalescing expression with 2 member expressions',
371
+ generateTest('var x = a.b ?? c.d;', 'let x = a.b == null ? c.d : a.b;'));
372
+
373
+ it('null coalescing expression with 6 member expressions',
374
+ generateTest('var x = a.b.c.d ?? e.f.g.h;', 'let x = a.b.c.d == null ? e.f.g.h : a.b.c.d;'));
375
+
376
+ it('null coalescing expression with 2 null propagating member expressions',
377
+ generateTest('var x = a?.b ?? c?.d;', 'let nullCoalescing0 = typeof a !== \"undefined\" && a !== null ? a.b : void 0;\nlet x = nullCoalescing0 == null ? typeof c !== \"undefined\" && c !== null ? c.d : void 0 : nullCoalescing0;'));
378
+
379
+ it('null coalescing expression with 6 null propagating member expressions',
380
+ generateTest('var x = a?.b?.c?.d ?? e?.f?.g?.h;', 'let nullCoalescing0 = typeof a !== \"undefined\" && (a !== null && a.b !== null && a.b.c !== null) ? a.b.c.d : void 0;\nlet x = nullCoalescing0 == null ? typeof e !== \"undefined\" && (e !== null && e.f !== null && e.f.g !== null) ? e.f.g.h : void 0 : nullCoalescing0;'));
381
+
382
+ it('null coalescing expression with 6 null propagating member expressions combined',
383
+ generateTest('var x = a?.b.c?.d ?? e.f?.g?.h;', 'let nullPropagating0 = typeof a !== \"undefined\" && a !== null ? a.b.c : void 0;\nlet nullCoalescing0 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.d : void 0;\nlet x = nullCoalescing0 == null ? typeof e.f !== \"undefined\" && (e.f !== null && e.f.g !== null) ? e.f.g.h : void 0 : nullCoalescing0;'));
384
+
385
+ it('null coalescing expression with 2 call expressions',
386
+ generateTest('var x = a() ?? b();', 'let nullCoalescing0 = a();\nlet x = nullCoalescing0 == null ? b() : nullCoalescing0;'));
387
+
388
+ it('null coalescing expression with 2 call expressions and null propagating member expressions',
389
+ generateTest('var x = a.b()?.c() ?? d?.e().f();', 'let nullPropagating0 = a.b();\nlet nullCoalescing0 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null ? nullPropagating0.c() : void 0;\nlet x = nullCoalescing0 == null ? typeof d !== \"undefined\" && d !== null ? d.e().f() : void 0 : nullCoalescing0;'));
390
+
391
+ it('null coalescing statement',
392
+ generateTest('a() ?? b();', 'let nullCoalescing0 = a();\nif (nullCoalescing0 == null) {\n b();\n}'));
393
+ });
394
+
395
+ describe('null check call expressions:', function () {
396
+ it('null check call expression',
397
+ generateTest('var x = a?();', 'let x = typeof a === \"function\" ? a() : void 0;'));
398
+
399
+ it('null check call expression with 1 argument',
400
+ generateTest('var a = f?(1);', 'let a = typeof f === \"function\" ? f(1) : void 0;'));
401
+
402
+ it('null check call expression with 2 arguments',
403
+ generateTest('var a = f?(1, true);', 'let a = typeof f === \"function\" ? f(1, true) : void 0;'));
404
+
405
+ it('null check call expression with 3 arguments',
406
+ generateTest('var a = f?(1, true, "test");', 'let a = typeof f === \"function\" ? f(1, true, \"test\") : void 0;'));
407
+
408
+ it('null check call expression with 4 arguments',
409
+ generateTest('var a = f?(1, true, "test", { a: 1 });', 'let a = typeof f === \"function\" ? f(1, true, \"test\", { a: 1 }) : void 0;'));
410
+
411
+ it('call expression with null check call expression',
412
+ generateTest('var x = a?()();', 'let x = (typeof a === \"function\" ? a() : void 0)();'));
413
+
414
+ it('null check call expression with null check call expression',
415
+ generateTest('var x = a?()?();', 'let nullCheck0 = typeof a === \"function\" ? a() : void 0;\nlet x = typeof nullCheck0 === \"function\" ? nullCheck0() : void 0;'));
416
+
417
+ it('null check call expression with member expression',
418
+ generateTest('var x = a?().b;', 'let x = typeof a === \"function\" ? a().b : void 0;'));
419
+
420
+ it('null check call expression with 2 member expressions',
421
+ generateTest('var x = a?().b.c;', 'let x = typeof a === \"function\" ? a().b.c : void 0;'));
422
+
423
+ it('null check call expression with call expression',
424
+ generateTest('var x = a?().b();', 'let x = typeof a === \"function\" ? a().b() : void 0;'));
425
+
426
+ it('null check call expression with 2 call expressions',
427
+ generateTest('var x = a?().b().c();', 'let x = typeof a === \"function\" ? a().b().c() : void 0;'));
428
+
429
+ it('member expression with null check call expression',
430
+ generateTest('var x = a.b?();', 'let x = typeof a.b === \"function\" ? a.b() : void 0;'));
431
+
432
+ it('2 member expressions with null check call expression',
433
+ generateTest('var x = a.b.c?();', 'let x = typeof a.b.c === \"function\" ? a.b.c() : void 0;'));
434
+
435
+ it('call expression with null check call expression',
436
+ generateTest('var x = a().b?();', 'let nullCheck0 = a().b;\nlet x = typeof nullCheck0 === \"function\" ? nullCheck0() : void 0;'));
437
+
438
+ it('2 call expression with null check call expression',
439
+ generateTest('var x = a().b().c?();', 'let nullCheck0 = a().b().c;\nlet x = typeof nullCheck0 === \"function\" ? nullCheck0() : void 0;'));
440
+
441
+ it('2 null check call expressions',
442
+ generateTest('var x = a?().b?();', 'let nullCheck0 = typeof a === \"function\" ? a().b : void 0;\nlet x = typeof nullCheck0 === \"function\" ? nullCheck0() : void 0;'));
443
+
444
+ it('3 null check call expressions',
445
+ generateTest('var x = a?().b?().c?();', 'let nullCheck0 = typeof a === \"function\" ? a().b : void 0;\nlet nullCheck1 = typeof nullCheck0 === \"function\" ? nullCheck0().c : void 0;\nlet x = typeof nullCheck1 === \"function\" ? nullCheck1() : void 0;'));
446
+
447
+ it('2 null check call expressions with null propagating relationship',
448
+ generateTest('var x = a?()?.b?();', 'let nullPropagating0 = typeof a === \"function\" ? a() : void 0;\nlet x = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null && typeof nullPropagating0.b === \"function\" ? nullPropagating0.b() : void 0;'));
449
+
450
+ it('3 null check call expressions with null propagating relationship',
451
+ generateTest('var x = a?()?.b?()?.c();', 'let nullPropagating0 = typeof a === \"function\" ? a() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null && typeof nullPropagating0.b === \"function\" ? nullPropagating0.b() : void 0;\nlet x = typeof nullPropagating1 !== \"undefined\" && nullPropagating1 !== null ? nullPropagating1.c() : void 0;'));
452
+ });
453
+
454
+ describe('null check call statements:', function () {
455
+ it('null check call statement',
456
+ generateTest('a?();',
457
+ 'if (typeof a === \"function\") {\n a();\n}'));
458
+
459
+ it('null check call statement with 1 argument',
460
+ generateTest('f?(1);',
461
+ 'if (typeof f === \"function\") {\n f(1);\n}'));
462
+
463
+ it('null check call statement with 2 arguments',
464
+ generateTest('f?(1, true);',
465
+ 'if (typeof f === \"function\") {\n f(1, true);\n}'));
466
+
467
+ it('null check call statement with 3 arguments',
468
+ generateTest('f?(1, true, "test");',
469
+ 'if (typeof f === \"function\") {\n f(1, true, \"test\");\n}'));
470
+
471
+ it('null check call statement with 4 arguments',
472
+ generateTest('f?(1, true, "test", { a: 1 });',
473
+ 'if (typeof f === \"function\") {\n f(1, true, \"test\", { a: 1 });\n}'));
474
+
475
+ it('call statement with null check call expression',
476
+ generateTest('a?()();',
477
+ '(typeof a === \"function\" ? a() : void 0)();'));
478
+
479
+ it('null check call expression with null check call expression',
480
+ generateTest('a?()?();', 'let nullCheck0 = typeof a === \"function\" ? a() : void 0;\nif (typeof nullCheck0 === \"function\") {\n nullCheck0();\n}'));
481
+
482
+ it('null check call expression with call statement',
483
+ generateTest('a?().b();',
484
+ 'if (typeof a === \"function\") {\n a().b();\n}'));
485
+
486
+ it('null check call expression with 2 call statements',
487
+ generateTest('a?().b().c();',
488
+ 'if (typeof a === \"function\") {\n a().b().c();\n}'));
489
+
490
+ it('member expression with null check call statement',
491
+ generateTest('a.b?();',
492
+ 'if (typeof a.b === \"function\") {\n a.b();\n}'));
493
+
494
+ it('2 member expressions with null check call statement',
495
+ generateTest('a.b.c?();',
496
+ 'if (typeof a.b.c === \"function\") {\n a.b.c();\n}'));
497
+
498
+ it('call expression with null check call statement',
499
+ generateTest('a().b?();', 'let nullCheck0 = a().b;\nif (typeof nullCheck0 === \"function\") {\n nullCheck0();\n}'));
500
+
501
+ it('2 call expression with null check call statement',
502
+ generateTest('a().b().c?();', 'let nullCheck0 = a().b().c;\nif (typeof nullCheck0 === \"function\") {\n nullCheck0();\n}'));
503
+
504
+ it('2 null check call statements',
505
+ generateTest('a?().b?();', 'let nullCheck0 = typeof a === \"function\" ? a().b : void 0;\nif (typeof nullCheck0 === \"function\") {\n nullCheck0();\n}'));
506
+
507
+ it('3 null check call statements',
508
+ generateTest('a?().b?().c?();', 'let nullCheck0 = typeof a === \"function\" ? a().b : void 0;\nlet nullCheck1 = typeof nullCheck0 === \"function\" ? nullCheck0().c : void 0;\nif (typeof nullCheck1 === \"function\") {\n nullCheck1();\n}'));
509
+
510
+ it('2 null check call statements with null propagating relationship',
511
+ generateTest('a?()?.b?();', 'let nullPropagating0 = typeof a === \"function\" ? a() : void 0;\nif (typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null && typeof nullPropagating0.b === \"function\") {\n nullPropagating0.b();\n}'));
512
+
513
+ it('3 null check call statements with null propagating relationship',
514
+ generateTest('a?()?.b?()?.c();', 'let nullPropagating0 = typeof a === \"function\" ? a() : void 0;\nlet nullPropagating1 = typeof nullPropagating0 !== \"undefined\" && nullPropagating0 !== null && typeof nullPropagating0.b === \"function\" ? nullPropagating0.b() : void 0;\nif (typeof nullPropagating1 !== \"undefined\" && nullPropagating1 !== null) {\n nullPropagating1.c();\n}'));
515
+ });
516
+
517
+ describe('existential expressions:', function () {
518
+ it('existential opreator on identifier',
519
+ generateTest('var x = a?;', 'let x = typeof a !== \"undefined\" && a !== null;'));
520
+
521
+ it('existential opreator on call expression',
522
+ generateTest('var x = a()?;', 'let existential0 = a();\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
523
+
524
+ it('existential opreator on null check call expression',
525
+ generateTest('var x = a?()?;', 'let existential0 = typeof a === \"function\" ? a() : void 0;\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
526
+
527
+ it('existential opreator on member expression',
528
+ generateTest('var x = a.b?;', 'let x = typeof a.b !== \"undefined\" && a.b !== null;'));
529
+
530
+ it('existential opreator on member expression with call expression',
531
+ generateTest('var x = a.b()?;', 'let existential0 = a.b();\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
532
+
533
+ it('existential opreator on member expression with null check call expression',
534
+ generateTest('var x = a.b?()?;', 'let existential0 = typeof a.b === \"function\" ? a.b() : void 0;\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
535
+
536
+ it('existential opreator on null propagating member expression',
537
+ generateTest('var x = a?.b?;', 'let existential0 = typeof a !== \"undefined\" && a !== null ? a.b : void 0;\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
538
+
539
+ it('existential opreator on propagating member expression with call expression',
540
+ generateTest('var x = a?.b()?;', 'let existential0 = typeof a !== \"undefined\" && a !== null ? a.b() : void 0;\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
541
+
542
+ it('existential opreator on propagating member expression with null check call expression',
543
+ generateTest('var x = a?.b?()?;', 'let existential0 = typeof a !== \"undefined\" && a !== null && typeof a.b === \"function\" ? a.b() : void 0;\nlet x = typeof existential0 !== \"undefined\" && existential0 !== null;'));
544
+ });
545
+
546
+ describe('object expressions:', function () {
547
+ it('empty object',
548
+ generateTest('var x = {};', 'let x = {};'));
549
+
550
+ it('object with number property',
551
+ generateTest('var x = { a: 1 };', 'let x = { a: 1 };'));
552
+
553
+ it('object with boolean property',
554
+ generateTest('var x = { a: true };', 'let x = { a: true };'));
555
+
556
+ it('object with identifier property',
557
+ generateTest('var x = { a: b };', 'let x = { a: b };'));
558
+
559
+ it('object with string property',
560
+ generateTest('var x = { a: "test" };', 'let x = { a: "test" };'));
561
+
562
+ it('object with object property',
563
+ generateTest('var x = { a: { b: 1 } };', 'let x = { a: { b: 1 } };'));
564
+
565
+ it('object with array property',
566
+ generateTest('var x = { a: [true] };', 'let x = { a: [true] };'));
567
+
568
+ it('object with quoted object property name',
569
+ generateTest('var x = { "a b": { b: 1 } };', 'let x = { \"a b\": { b: 1 } };'));
570
+
571
+ it('object with 2 properties',
572
+ generateTest('var x = { a: 1, b: true };', 'let x = {\n a: 1,\n b: true\n};'));
573
+
574
+ it('object with 3 properties',
575
+ generateTest('var x = { a: 1, b: true, c: b };', 'let x = {\n a: 1,\n b: true,\n c: b\n};'));
576
+
577
+ it('object with 4 properties',
578
+ generateTest('var x = { a: 1, b: true, c: b, d: "test" };', 'let x = {\n a: 1,\n b: true,\n c: b,\n d: "test"\n};'));
579
+ });
580
+
581
+ describe('array expressions:', function () {
582
+ it('empty array',
583
+ generateTest('var x = [];', 'let x = [];'));
584
+
585
+ it('array with 1 number element',
586
+ generateTest('var x = [1];', 'let x = [1];'));
587
+
588
+ it('array with 2 number elements',
589
+ generateTest('var x = [1, 2];', 'let x = [\n 1,\n 2\n];'));
590
+
591
+ it('array with 3 number elements',
592
+ generateTest('var x = [1, 2, 3];', 'let x = [\n 1,\n 2,\n 3\n];'));
593
+
594
+ it('array with 1 boolean element',
595
+ generateTest('var x = [true];', 'let x = [true];'));
596
+
597
+ it('array with 2 boolean elements',
598
+ generateTest('var x = [true, false];', 'let x = [\n true,\n false\n];'));
599
+
600
+ it('array with 3 boolean elements',
601
+ generateTest('var x = [true, false, true];', 'let x = [\n true,\n false,\n true\n];'));
602
+
603
+ it('array with 1 identifier element',
604
+ generateTest('var x = [a];', 'let x = [a];'));
605
+
606
+ it('array with 2 identifier elements',
607
+ generateTest('var x = [a, b];', 'let x = [\n a,\n b\n];'));
608
+
609
+ it('array with 3 identifier elements',
610
+ generateTest('var x = [a, b, c];', 'let x = [\n a,\n b,\n c\n];'));
611
+
612
+ it('array with 1 string element',
613
+ generateTest('var x = ["test"];', 'let x = ["test"];'));
614
+
615
+ it('array with 2 string elements',
616
+ generateTest('var x = ["test", "test2"];', 'let x = [\n "test",\n "test2"\n];'));
617
+
618
+ it('array with 3 string elements',
619
+ generateTest('var x = ["test", "test2", "test3"];', 'let x = [\n "test",\n "test2",\n "test3"\n];'));
620
+
621
+ it('array with 1 array element',
622
+ generateTest('var x = [[true]];', 'let x = [[true]];'));
623
+
624
+ it('array with 2 array elements',
625
+ generateTest('var x = [[true], [false]];', 'let x = [\n [true],\n [false]\n];'));
626
+
627
+ it('array with 3 array elements',
628
+ generateTest('var x = [[true], [false], [true]];', 'let x = [\n [true],\n [false],\n [true]\n];'));
629
+
630
+ it('array with 1 object element',
631
+ generateTest('var x = [{ a: 1 }];', 'let x = [{ a: 1 }];'));
632
+
633
+ it('array with 2 object elements',
634
+ generateTest('var x = [{ a: 1 }, { b: 2 }];', 'let x = [\n { a: 1 },\n { b: 2 }\n];'));
635
+
636
+ it('array with 3 object elements',
637
+ generateTest('var x = [{ a: 1 }, { b: 2 }, { c: 3 }];', 'let x = [\n { a: 1 },\n { b: 2 },\n { c: 3 }\n];'));
638
+ });
639
+
640
+ describe('unary expressions:', function () {
641
+ it('unary not',
642
+ generateTest('var x = !a;', 'let x = !a;'));
643
+
644
+ it('unary plus',
645
+ generateTest('var x = +5;', 'let x = +5;'));
646
+
647
+ it('unary minus',
648
+ generateTest('var x = -5;', 'let x = -5;'));
649
+
650
+ it('typeof identifier',
651
+ generateTest('var x = typeof a;', 'let x = typeof a === \"undefined\" ? \"undefined\" : {}.toString.call(a).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();'));
652
+
653
+ it('typeof call expression',
654
+ generateTest('var x = typeof a();', 'let x = {}.toString.call(a()).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();'));
655
+ });
656
+
657
+ describe('arithmetic expressions:', function () {
658
+ it('plus with 2 elements',
659
+ generateTest('var x = a+b;', 'let x = a + b;'));
660
+
661
+ it('plus with 3 elements',
662
+ generateTest('var x = a+b+c;', 'let x = a + b + c;'));
663
+
664
+ it('minus with 2 elements',
665
+ generateTest('var x = a-b;', 'let x = a - b;'));
666
+
667
+ it('minus with 3 elements',
668
+ generateTest('var x = a-b-c;', 'let x = a - b - c;'));
669
+
670
+ it('multipication with 2 elements',
671
+ generateTest('var x = a*b;', 'let x = a * b;'));
672
+
673
+ it('multipication with 3 elements',
674
+ generateTest('var x = a*b*c;', 'let x = a * b * c;'));
675
+
676
+ it('division with 2 elements',
677
+ generateTest('var x = a/b;', 'let x = a / b;'));
678
+
679
+ it('division with 3 elements',
680
+ generateTest('var x = a/b/c;', 'let x = a / b / c;'));
681
+
682
+ it('order of operators',
683
+ generateTest('var x = 3+4*5-(3+4)*5/(a+b-c*d);', 'let x = 3 + 4 * 5 - (3 + 4) * 5 / (a + b - c * d);'));
684
+
685
+ it('exponentiation with 2 elements',
686
+ generateTest('var x = a**b;', 'let x = Math.pow(a, b);'));
687
+
688
+ it('exponentiation with 3 elements',
689
+ generateTest('var x = a**b**c;', 'let x = Math.pow(Math.pow(a, b), c);'));
690
+
691
+ it('integer division with 2 elements',
692
+ generateTest('var x = a#b;', 'let x = Math.floor(a / b);'));
693
+
694
+ it('integer division with 3 elements',
695
+ generateTest('var x = a#b#c;', 'let x = Math.floor(Math.floor(a / b) / c);'));
696
+
697
+ it('modulo with 2 elements',
698
+ generateTest('var x = a%b;', 'let x = a % b;'));
699
+
700
+ it('modulo with 3 elements',
701
+ generateTest('var x = a%b%c;', 'let x = a % b % c;'));
702
+
703
+ it('math modulo with 2 elements',
704
+ generateTest('var x = a%%b;', 'let x = (a % b + b) % b;'));
705
+
706
+ it('math modulo with 3 elements',
707
+ generateTest('var x = a%%b%%c;', 'let x = ((a % b + b) % b % c + c) % c;'));
708
+ });
709
+
710
+ describe('logical expressions:', function () {
711
+ it('AND expression',
712
+ generateTest('var x = a && b;', 'let x = !!a && !!b;'));
713
+
714
+ it('2 AND expressions',
715
+ generateTest('var x = a && b && c;', 'let x = !!(!!a && !!b) && !!c;'));
716
+
717
+ it('worded AND expression',
718
+ generateTest('var x = a and b;', 'let x = !!a && !!b;'));
719
+
720
+ it('2 worded AND expressions',
721
+ generateTest('var x = a and b and c;', 'let x = !!(!!a && !!b) && !!c;'));
722
+
723
+ it('OR expression',
724
+ generateTest('var x = a || b;', 'let x = !!a || !!b;'));
725
+
726
+ it('2 OR expressions',
727
+ generateTest('var x = a || b || c;', 'let x = !!(!!a || !!b) || !!c;'));
728
+
729
+ it('worded OR expression',
730
+ generateTest('var x = a or b;', 'let x = !!a || !!b;'));
731
+
732
+ it('2 worded OR expressions',
733
+ generateTest('var x = a or b or c;', 'let x = !!(!!a || !!b) || !!c;'));
734
+
735
+ it('order of logical expressions 1',
736
+ generateTest('var x = a && b || c;', 'let x = !!(!!a && !!b) || !!c;'));
737
+
738
+ it('order of logical expressions 2',
739
+ generateTest('var x = a && b || c && d;', 'let x = !!(!!a && !!b) || !!(!!c && !!d);'));
740
+
741
+ it('order of logical expressions 3',
742
+ generateTest('var x = a && b || c && (d || e || f && g);', 'let x = !!(!!a && !!b) || !!(!!c && !!(!!(!!d || !!e) || !!(!!f && !!g)));'));
743
+ });
744
+
745
+ describe('binary expressions:', function () {
746
+ it('equals expression',
747
+ generateTest('var x = a == b;', 'let x = a === b;'));
748
+
749
+ it('not equals expression',
750
+ generateTest('var x = a != b;', 'let x = a !== b;'));
751
+
752
+ it('larger expression',
753
+ generateTest('var x = a > b;', 'let x = a > b;'));
754
+
755
+ it('larger or equals expression',
756
+ generateTest('var x = a >= b;', 'let x = a >= b;'));
757
+
758
+ it('smaller expression',
759
+ generateTest('var x = a < b;', 'let x = a < b;'));
760
+
761
+ it('smaller or equals expression',
762
+ generateTest('var x = a <= b;', 'let x = a <= b;'));
763
+
764
+ it('chained comparisons',
765
+ generateTest('var x = a > x > c;', 'let x = a > x && x > c;'));
766
+
767
+ it('chained comparisons with 2 components',
768
+ generateTest('var x = a > x > c > d;', 'let x = a > x && x > c && c > d;'));
769
+
770
+ it('chained comparisons with 3 components',
771
+ generateTest('var x = a > x > c > d > e;', 'let x = a > x && x > c && c > d && d > e;'));
772
+ });
773
+
774
+ describe('update expressions:', function () {
775
+ it('increment statement',
776
+ generateTest('a++;', 'a++;'));
777
+
778
+ it('decrement statement',
779
+ generateTest('a--;', 'a--;'));
780
+
781
+ it('increment expression',
782
+ generateTest('var x = a++;', 'let x = a++;'));
783
+
784
+ it('decrement expression',
785
+ generateTest('var x = a--;', 'let x = a--;'));
786
+
787
+ it('increment prefix statement',
788
+ generateTest('++a;', '++a;'));
789
+
790
+ it('decrement prefix statement',
791
+ generateTest('--a;', '--a;'));
792
+
793
+ it('increment prefix expression',
794
+ generateTest('var x = ++a;', 'let x = ++a;'));
795
+
796
+ it('decrement prefix expression',
797
+ generateTest('var x = --a;', 'let x = --a;'));
798
+ });
799
+
800
+ describe('assignment expressions:', function () {
801
+ it('assignment statement',
802
+ generateTest('a = 1;', 'a = 1;'));
803
+
804
+ it('assignment statement with 2 variables',
805
+ generateTest('a = b = 1;', 'a = b = 1;'));
806
+
807
+ it('assignment statement with 3 variables',
808
+ generateTest('a = b = c = 1;', 'a = b = c = 1;'));
809
+
810
+ it('assignment expression',
811
+ generateTest('var x = a = 1;', 'let x = a = 1;'));
812
+
813
+ it('assignment expression with 2 variables',
814
+ generateTest('var x = a = b = 1;', 'let x = a = b = 1;'));
815
+
816
+ it('assignment expression with 3 variables',
817
+ generateTest('var x = a = b = c = 1;', 'let x = a = b = c = 1;'));
818
+
819
+ it('addition assignment', generateTest('x += a;', 'x += a;'));
820
+ it('subtraction assignment', generateTest('x -= a;', 'x -= a;'));
821
+ it('multiplication assignment', generateTest('x *= a;', 'x *= a;'));
822
+ it('division assignment', generateTest('x /= a;', 'x /= a;'));
823
+ it('remainder assignment', generateTest('x %= a;', 'x %= a;'));
824
+ it('left shift assignment', generateTest('x <<= a;', 'x <<= a;'));
825
+ it('right shift assignment', generateTest('x >>= a;', 'x >>= a;'));
826
+ it('logical right shift assignment', generateTest('x >>>= a;', 'x >>>= a;'));
827
+ it('bitwise AND assignment', generateTest('x &= a;', 'x &= a;'));
828
+ it('bitwise XOR assignment', generateTest('x ^= a;', 'x ^= a;'));
829
+ it('bitwise OR assignment', generateTest('x |= a;', 'x |= a;'));
830
+ });
831
+
832
+ describe('if statement:', function () {
833
+ it('if statement',
834
+ generateTest('if true { }', 'if (true) {\n}'));
835
+
836
+ it('if statement with else clause',
837
+ generateTest('if true { } else { }', 'if (true) {\n} else {\n}'));
838
+
839
+ it('if statement without block',
840
+ generateTest('if true a();', 'if (true) {\n a();\n}'));
841
+
842
+ it('if statement with else without block',
843
+ generateTest('if true a(); else b();', 'if (true) {\n a();\n} else {\n b();\n}'));
844
+ });
845
+
846
+ describe('for statement:', function () {
847
+ it('for loop with empty arguments',
848
+ generateTest('for ;; { }', 'for (;;) {\n}'));
849
+
850
+ it('for loop with initialiser only',
851
+ generateTest('for var i = 0;; { }', 'for (let i = 0;;) {\n}'));
852
+
853
+ it('for loop with condition only',
854
+ generateTest('for ; i > 0; { }', 'for (; i > 0;) {\n}'));
855
+
856
+ it('for loop with update only',
857
+ generateTest('for ;; i++ { }', 'for (;; i++) {\n}'));
858
+
859
+ it('for loop with initialiser and condition',
860
+ generateTest('for var i = 0; i > 0; { }', 'for (let i = 0; i > 0;) {\n}'));
861
+
862
+ it('for loop with initialiser and update',
863
+ generateTest('for var i = 0;; i++ { }', 'for (let i = 0;; i++) {\n}'));
864
+
865
+ it('for loop with condition and update',
866
+ generateTest('for ; i > 0; i++ { }', 'for (; i > 0; i++) {\n}'));
867
+
868
+ it('for loop with initialiser, condition and update',
869
+ generateTest('for var i = 0; i > 0; i++ { }', 'for (let i = 0; i > 0; i++) {\n}'));
870
+ });
871
+
872
+ describe('function declarations:', function () {
873
+ it('fn decl without arguments',
874
+ generateTest('fn f() { }', 'function f() {\n}'));
875
+
876
+ it('fn decl with 1 argument',
877
+ generateTest('fn f(a) { }', 'function f(a) {\n}'));
878
+
879
+ it('fn decl with 2 arguments',
880
+ generateTest('fn f(a, b) { }', 'function f(a, b) {\n}'));
881
+
882
+ it('fn decl with 3 arguments',
883
+ generateTest('fn f(a, b, c) { }', 'function f(a, b, c) {\n}'));
884
+ });
885
+
886
+ describe('function expressions:', function () {
887
+ it('function expression without arguments',
888
+ generateTest('var a = () -> 1;', 'let a = function () {\n return 1;\n};'));
889
+
890
+ it('function expression with 1 argument',
891
+ generateTest('var a = (a) -> a;', 'let a = function (a) {\n return a;\n};'));
892
+
893
+ it('function expression with 2 arguments',
894
+ generateTest('var a = (a, b) -> a+b;', 'let a = function (a, b) {\n return a + b;\n};'));
895
+
896
+ it('function expression with 3 arguments',
897
+ generateTest('var a = (a, b, c) -> a+b-c;', 'let a = function (a, b, c) {\n return a + b - c;\n};'));
898
+
899
+ it('block function expression without arguments',
900
+ generateTest('var a = () -> { };', 'let a = function () {\n};'));
901
+
902
+ it('block function expression with 1 argument',
903
+ generateTest('var a = (a) -> { };', 'let a = function (a) {\n};'));
904
+
905
+ it('block function expression with 2 arguments',
906
+ generateTest('var a = (a, b) -> { };', 'let a = function (a, b) {\n};'));
907
+
908
+ it('block function expression with 3 arguments',
909
+ generateTest('var a = (a, b, c) -> { };', 'let a = function (a, b, c) {\n};'));
910
+
911
+ it('block function expression (fn syntax) without arguments',
912
+ generateTest('var a = fn () { };', 'let a = function () {\n};'));
913
+
914
+ it('block function expression (fn syntax) with 1 argument',
915
+ generateTest('var a = fn (a) { };', 'let a = function (a) {\n};'));
916
+
917
+ it('block function expression (fn syntax) with 2 arguments',
918
+ generateTest('var a = fn (a, b) { };', 'let a = function (a, b) {\n};'));
919
+
920
+ it('block function expression (fn syntax) with 3 arguments',
921
+ generateTest('var a = fn (a, b, c) { };', 'let a = function (a, b, c) {\n};'));
922
+
923
+ it('block function expression (fn syntax with id) without arguments',
924
+ generateTest('var a = fn f() { };', 'let a = function f() {\n};'));
925
+
926
+ it('block function expression (fn syntax with id) with 1 argument',
927
+ generateTest('var a = fn f(a) { };', 'let a = function f(a) {\n};'));
928
+
929
+ it('block function expression (fn syntax with id) with 2 arguments',
930
+ generateTest('var a = fn f(a, b) { };', 'let a = function f(a, b) {\n};'));
931
+
932
+ it('block function expression (fn syntax with id) with 3 arguments',
933
+ generateTest('var a = fn f(a, b, c) { };', 'let a = function f(a, b, c) {\n};'));
934
+ });
935
+
936
+ describe('return statement:', function () {
937
+ it('function declaration with a return statement',
938
+ generateTest('fn x() { return 1; }',
939
+ 'function x() {\n return 1;\n}'));
940
+
941
+ it('function expression with a return statement',
942
+ generateTest('var a = () -> { return 1; };', 'let a = function () {\n return 1;\n};'));
943
+
944
+ it('function declaration with empty return statement',
945
+ generateTest('fn x() { return; }',
946
+ 'function x() {\n return;\n}'));
947
+
948
+ it('function expression with empty return statement',
949
+ generateTest('var a = () -> { return; };', 'let a = function () {\n return;\n};'));
950
+ });
951
+
952
+ describe('global identifiers and use statements:', function () {
953
+ it('global function call',
954
+ generateErrorTest('x("test");',
955
+ [{ type: 'UndefinedIdentifier', 'identifier': 'x' }]));
956
+
957
+ it('global function call with :: operator',
958
+ generateTest('::x("test");', 'x("test");'));
959
+
960
+ it('global function call with use statement',
961
+ generateTest('use x; x("test");', 'x("test");'));
962
+
963
+ it('global function call with use statement and :: operator',
964
+ generateTest('use x; ::x("test");', 'x("test");'));
965
+
966
+ it('global function call with use statement after the function call',
967
+ generateErrorTest('x("test"); use x;',
968
+ [{ type: 'UndefinedIdentifier', 'identifier': 'x' }]));
969
+
970
+ it('global member expression',
971
+ generateErrorTest('var x = a.b;',
972
+ [{ type: 'UndefinedIdentifier', 'identifier': 'a' }]));
973
+
974
+ it('global member expression with :: operator',
975
+ generateTest('var x = ::a.b;', 'let x = a.b;'));
976
+
977
+ it('global member expression with use statement',
978
+ generateTest('use a; var x = a.b;', 'let x = a.b;'));
979
+
980
+ it('global member expression with use statement and :: operator',
981
+ generateTest('use a; var x = ::a.b;', 'let x = a.b;'));
982
+
983
+ it('global member expression with use statement after the member expression',
984
+ generateErrorTest('var x = a.b; use a;',
985
+ [{ type: 'UndefinedIdentifier', 'identifier': 'a' }]));
986
+
987
+ it('use statement with 2 identifiers',
988
+ generateErrorTest('use a, b; var x = a + b;', []));
989
+
990
+ it('use statement with 3 identifiers',
991
+ generateErrorTest('use a, b, c; var x = a + b + c;', []));
992
+
993
+ it(':browser use statement',
994
+ generateErrorTest('use :browser; var x = document + console + window;', []));
995
+ });
996
+
997
+ describe('this keyword:', function () {
998
+ it('call statement with this',
999
+ generateTest('this.x();', 'this.x();'));
1000
+ it('call expression with this',
1001
+ generateTest('var a = this.x();', 'let a = this.x();'));
1002
+ it('member expression with this',
1003
+ generateTest('var a = this.x;', 'let a = this.x;'));
1004
+ it('call statement and member expression with this',
1005
+ generateTest('this.a.b();', 'this.a.b();'));
1006
+ });
1007
+
1008
+ describe('fn extends:', function () {
1009
+ it('extended function with no constructor',
1010
+ generateTest('fn A() {} fn B() extends A {}',
1011
+ 'function A() {\n}\nfunction B() {\n A.call(this);\n}\nB.prototype = Object.create(A);'));
1012
+
1013
+ it('extended function with empty constructor',
1014
+ generateTest('fn A() {} fn B() extends A() {}',
1015
+ 'function A() {\n}\nfunction B() {\n A.call(this);\n}\nB.prototype = Object.create(A);'));
1016
+
1017
+ it('extended function with 1-param constructor',
1018
+ generateTest('fn A() {} fn B() extends A(1) {}',
1019
+ 'function A() {\n}\nfunction B() {\n A.call(this, 1);\n}\nB.prototype = Object.create(A);'));
1020
+
1021
+ it('extended function with 2-params constructor',
1022
+ generateTest('fn A() {} fn B(a) extends A(1, a) {}',
1023
+ 'function A() {\n}\nfunction B(a) {\n A.call(this, 1, a);\n}\nB.prototype = Object.create(A);'));
1024
+
1025
+ it('extended function with global identifier',
1026
+ generateTest('fn B() extends ::A {}',
1027
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);'));
1028
+
1029
+ it('extended function expression with no constructor',
1030
+ generateTest('var A = fn () {}; var B = fn () extends A {};', 'let A = function () {\n};\nlet functionExpression0 = function () {\n A.call(this);\n};\nfunctionExpression0.prototype = Object.create(A);\nlet B = functionExpression0;'));
1031
+
1032
+ it('extended function expression with empty constructor',
1033
+ generateTest('var A = fn () {}; var b = fn () extends A() {};', 'let A = function () {\n};\nlet functionExpression0 = function () {\n A.call(this);\n};\nfunctionExpression0.prototype = Object.create(A);\nlet b = functionExpression0;'));
1034
+
1035
+ it('extended function expression with 1-param constructor',
1036
+ generateTest('var A = fn () {}; var B = fn () extends A(1) {};', 'let A = function () {\n};\nlet functionExpression0 = function () {\n A.call(this, 1);\n};\nfunctionExpression0.prototype = Object.create(A);\nlet B = functionExpression0;'));
1037
+
1038
+ it('extended function expression with 2-params constructor',
1039
+ generateTest('var A = fn () {}; var B = fn (a) extends A(1, a) {};', 'let A = function () {\n};\nlet functionExpression0 = function (a) {\n A.call(this, 1, a);\n};\nfunctionExpression0.prototype = Object.create(A);\nlet B = functionExpression0;'));
1040
+
1041
+ it('extended function expression with global identifier',
1042
+ generateTest('var B = fn () extends ::A {};', 'let functionExpression0 = function () {\n A.call(this);\n};\nfunctionExpression0.prototype = Object.create(A);\nlet B = functionExpression0;'));
1043
+ });
1044
+
1045
+ describe('super keyword:', function () {
1046
+ it('super call statement in a method',
1047
+ generateTest('fn B() extends ::A { this.test = fn () { super.test(); }; }',
1048
+ 'function B() {\n A.call(this);\n let _self = this;\n let _test = this.test;\n this.test = function () {\n _test.call(_self);\n };\n}\nB.prototype = Object.create(A);'));
1049
+
1050
+ it('super call statement in a method inside an anonymous function',
1051
+ generateTest('fn B() extends ::A { this.test = fn () { (() -> { return super.test(); })(); }; }',
1052
+ 'function B() {\n A.call(this);\n let _self = this;\n let _test = this.test;\n this.test = function () {\n (function () {\n return _test.call(_self);\n }());\n };\n}\nB.prototype = Object.create(A);'));
1053
+
1054
+ it('super call statement in a method inside 2 anonymous functions',
1055
+ generateTest('fn B() extends ::A { this.test = fn () { (() -> () -> { return super.test(); } )()(); }; }',
1056
+ 'function B() {\n A.call(this);\n let _self = this;\n let _test = this.test;\n this.test = function () {\n (function () {\n return function () {\n return _test.call(_self);\n };\n }()());\n };\n}\nB.prototype = Object.create(A);'));
1057
+
1058
+ it('super member expression in a method',
1059
+ generateTest('fn B() extends ::A { this.test = fn () { var x = super.x; }; }',
1060
+ 'function B() {\n A.call(this);\n let _x = this.x;\n this.test = function () {\n let x = _x;\n };\n}\nB.prototype = Object.create(A);'));
1061
+
1062
+ it('super member expression in a method inside an anonymous function',
1063
+ generateTest('fn B() extends ::A { this.test = fn () { var x = (() -> super.x)(); }; }',
1064
+ 'function B() {\n A.call(this);\n let _x = this.x;\n this.test = function () {\n let x = function () {\n return _x;\n }();\n };\n}\nB.prototype = Object.create(A);'));
1065
+
1066
+ it('super member expression in a method inside 2 anonymous functions',
1067
+ generateTest('fn B() extends ::A { this.test = fn () { var x = (() -> () -> super.x)()(); }; }',
1068
+ 'function B() {\n A.call(this);\n let _x = this.x;\n this.test = function () {\n let x = function () {\n return function () {\n return _x;\n };\n }()();\n };\n}\nB.prototype = Object.create(A);'));
1069
+
1070
+ it('super call statement in a prototype function',
1071
+ generateTest('fn B() extends ::A {} B.prototype.test = () -> { super.test(); };',
1072
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype.test = function () {\n A.prototype.test.call(this);\n};'));
1073
+
1074
+ it('super call statement in a prototype function inside an anonymous function',
1075
+ generateTest('fn B() extends ::A {} B.prototype.test = () -> { (() -> super.test())(); };',
1076
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype.test = function () {\n let _self = this;\n (function () {\n return A.prototype.test.call(_self);\n }());\n};'));
1077
+
1078
+ it('super member expression in a prototype function',
1079
+ generateTest('fn B() extends ::A {} B.prototype.test = () -> { var x = super.x; };',
1080
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype.test = function () {\n let x = this.x;\n};'));
1081
+
1082
+ it('super member expression in a prototype function inside an anonymous function',
1083
+ generateTest('fn B() extends ::A {} B.prototype.test = () -> { var x = (() -> { return super.x; })(); };',
1084
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype.test = function () {\n let _self = this;\n let x = function () {\n return _self.x;\n }();\n};'));
1085
+
1086
+ it('super call statement in a prototype object',
1087
+ generateTest('fn B() extends ::A {} B.prototype = { test: () -> { super.test(); } };',
1088
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype = {\n test: function () {\n A.prototype.test.call(this);\n }\n};'));
1089
+
1090
+ it('super call statement in a prototype object inside an anonymous function',
1091
+ generateTest('fn B() extends ::A {} B.prototype = { test: () -> { (() -> super.test())(); } };',
1092
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype = {\n test: function () {\n let _self = this;\n (function () {\n return A.prototype.test.call(_self);\n }());\n }\n};'));
1093
+
1094
+ it('super member expression in a prototype object',
1095
+ generateTest('fn B() extends ::A {} B.prototype = { test: () -> { var x = super.x; } };',
1096
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype = {\n test: function () {\n let x = this.x;\n }\n};'));
1097
+
1098
+ it('super member expression in a prototype object inside an anonymous function',
1099
+ generateTest('fn B() extends ::A {} B.prototype = { test: () -> { var x = (() -> { return super.x; })(); } };',
1100
+ 'function B() {\n A.call(this);\n}\nB.prototype = Object.create(A);\nB.prototype = {\n test: function () {\n let _self = this;\n let x = function () {\n return _self.x;\n }();\n }\n};'));
1101
+ });
1102
+
1103
+ describe('string interpolation:', function () {
1104
+ it('string interpolation',
1105
+ generateTest('var x = "test \\(a) test \\(2+a) \\(Math.pow(2, a)) test test";', 'let x = \"test \" + a + \" test \" + (2 + a) + \" \" + Math.pow(2, a) + \" test test\";'));
1106
+ });
1107
+
1108
+ describe('bitwise opreators:', function () {
1109
+ it('bitwise AND', generateTest('var x = a & b;', 'let x = a & b;'));
1110
+ it('bitwise OR', generateTest('var x = a | b;', 'let x = a | b;'));
1111
+ it('bitwise XOR', generateTest('var x = a ^ b;', 'let x = a ^ b;'));
1112
+
1113
+ it('arithmetic shift left', generateTest('var x = a << b;', 'let x = a << b;'));
1114
+ it('arithmetic shift right', generateTest('var x = a >> b;', 'let x = a >> b;'));
1115
+
1116
+ it('logical shift right', generateTest('var x = a >>> b;', 'let x = a >>> b;'));
1117
+ });
1118
+
1119
+ describe('throw statement:', function () {
1120
+ it('throw number', generateTest('throw 5;', 'throw 5;'));
1121
+ it('throw object', generateTest('throw { message: "test" };', 'throw { message: "test" };'));
1122
+ });
1123
+
1124
+ describe('control flow statements:', function () {
1125
+ it('break statement', generateTest('break;', 'break;'));
1126
+ it('continue statement', generateTest('continue;', 'continue;'));
1127
+ });
1128
+
1129
+ describe('range expressions:', function () {
1130
+ it('upward small inclusive numeric range expression',
1131
+ generateTest('var x = [1..5];', 'let x = [\n 1,\n 2,\n 3,\n 4,\n 5\n];'));
1132
+
1133
+ it('downward small inclusive numeric range expression',
1134
+ generateTest('var x = [5..1];', 'let x = [\n 5,\n 4,\n 3,\n 2,\n 1\n];'));
1135
+
1136
+ it('upward small exclusive numeric range expression',
1137
+ generateTest('var x = [1...5];', 'let x = [\n 1,\n 2,\n 3,\n 4\n];'));
1138
+
1139
+ it('downward small exclusive numeric range expression',
1140
+ generateTest('var x = [5...1];', 'let x = [\n 5,\n 4,\n 3,\n 2\n];'));
1141
+
1142
+ it('upward large inclusive numeric range expression',
1143
+ generateTest('var x = [1..25];', 'let x = function () {\n let _results = [];\n for (let _i = 1; _i <= 25; _i++) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1144
+
1145
+ it('downward large inclusive numeric range expression',
1146
+ generateTest('var x = [25..1];', 'let x = function () {\n let _results = [];\n for (let _i = 25; _i >= 1; _i--) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1147
+
1148
+ it('upward large exclusive numeric range expression',
1149
+ generateTest('var x = [1...25];', 'let x = function () {\n let _results = [];\n for (let _i = 1; _i < 25; _i++) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1150
+
1151
+ it('downward large exclusive numeric range expression',
1152
+ generateTest('var x = [25...1];', 'let x = function () {\n let _results = [];\n for (let _i = 25; _i > 1; _i--) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1153
+
1154
+ it('inclusive identifiers range expression',
1155
+ generateTest('var x = [a..b];', 'let x = function () {\n let _results = [];\n for (let _i = a; a <= b ? _i <= b : _i >= b; a <= b ? _i++ : _i--) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1156
+
1157
+ it('exclusive identifiers range expression',
1158
+ generateTest('var x = [a...b];', 'let x = function () {\n let _results = [];\n for (let _i = a; a <= b ? _i < b : _i > b; a <= b ? _i++ : _i--) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1159
+
1160
+ it('inclusive call range expression',
1161
+ generateTest('var x = [a()..b()];', 'let x = function () {\n let _results = [], _start = a(), _end = b();\n for (let _i = _start; _start <= _end ? _i <= _end : _i >= _end; _start <= _end ? _i++ : _i--) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1162
+
1163
+ it('exclusive call range expression',
1164
+ generateTest('var x = [a()...b()];', 'let x = function () {\n let _results = [], _start = a(), _end = b();\n for (let _i = _start; _start <= _end ? _i < _end : _i > _end; _start <= _end ? _i++ : _i--) {\n _results.push(_i);\n }\n return _results;\n}.apply(this);'));
1165
+ });
1166
+
1167
+ describe('debugger statement:', function () {
1168
+ it('debugger statement', generateTest('debugger;', 'debugger;'));
1169
+ });
1170
+
1171
+ describe('while and until statements:', function () {
1172
+ it('while statement', generateTest('while true {}', 'while (true) {\n}'));
1173
+ it('while statement without block', generateTest('while true a();', 'while (true) {\n a();\n}'));
1174
+
1175
+ it('until statement', generateTest('until true {}', 'while (!true) {\n}'));
1176
+ it('until statement without block', generateTest('until true a();', 'while (!true) {\n a();\n}'));
1177
+ });
1178
+
1179
+ describe('array slicing:', function () {
1180
+ it('inclusive array slice with empty from and to',
1181
+ generateTest('var x = a[..];', 'let x = a.slice(0);'));
1182
+
1183
+ it('inclusive array slice with numeric from and empty to',
1184
+ generateTest('var x = a[1..];', 'let x = a.slice(1);'));
1185
+
1186
+ it('inclusive array slice with empty from and numeric to',
1187
+ generateTest('var x = a[..1];', 'let x = a.slice(0, 2);'));
1188
+
1189
+ it('inclusive array slice with numeric from and numeric to',
1190
+ generateTest('var x = a[1..2];', 'let x = a.slice(1, 3);'));
1191
+
1192
+ it('inclusive array slice with identifier from and empty to',
1193
+ generateTest('var x = a[c..];', 'let x = a.slice(c);'));
1194
+
1195
+ it('inclusive array slice with empty from and identifier to',
1196
+ generateTest('var x = a[..c];', 'let x = a.slice(0, c + 1);'));
1197
+
1198
+ it('inclusive array slice with identifier from and identifier to',
1199
+ generateTest('var x = a[c..d];', 'let x = a.slice(c, d + 1);'));
1200
+
1201
+ it('exclusive array slice with empty from and to',
1202
+ generateTest('var x = a[...];', 'let x = a.slice(0);'));
1203
+
1204
+ it('exclusive array slice with numeric from and empty to',
1205
+ generateTest('var x = a[1...];', 'let x = a.slice(1);'));
1206
+
1207
+ it('exclusive array slice with empty from and numeric to',
1208
+ generateTest('var x = a[...1];', 'let x = a.slice(0, 1);'));
1209
+
1210
+ it('exclusive array slice with numeric from and numeric to',
1211
+ generateTest('var x = a[1...2];', 'let x = a.slice(1, 2);'));
1212
+
1213
+ it('exclusive array slice with identifier from and empty to',
1214
+ generateTest('var x = a[c...];', 'let x = a.slice(c);'));
1215
+
1216
+ it('exclusive array slice with empty from and identifier to',
1217
+ generateTest('var x = a[...c];', 'let x = a.slice(0, c);'));
1218
+
1219
+ it('exclusive array slice with identifier from and identifier to',
1220
+ generateTest('var x = a[c...d];', 'let x = a.slice(c, d);'));
1221
+ });
1222
+
1223
+ describe('array splicing:', function () {
1224
+ it('inclusive array splicing with empty from and to',
1225
+ generateTest('a[..] = [x];', '[].splice.apply(a, [\n 0,\n 9000000000\n].concat([x]));'));
1226
+
1227
+ it('inclusive array splicing with numeric from and empty to',
1228
+ generateTest('a[1..] = [x];', '[].splice.apply(a, [\n 1,\n 9000000000\n].concat([x]));'));
1229
+
1230
+ it('inclusive array splicing with empty from and numeric to',
1231
+ generateTest('a[..3] = [x];', '[].splice.apply(a, [\n 0,\n 4\n].concat([x]));'));
1232
+
1233
+ it('inclusive array splicing with numeric from and numeric to',
1234
+ generateTest('a[2..3] = [x];', '[].splice.apply(a, [\n 2,\n 2\n].concat([x]));'));
1235
+
1236
+ it('inclusive array splicing with identifier from and empty to',
1237
+ generateTest('a[t..] = [x];', '[].splice.apply(a, [\n t,\n 9000000000\n].concat([x]));'));
1238
+
1239
+ it('inclusive array splicing with empty from and numeric to',
1240
+ generateTest('a[..v] = [x];', '[].splice.apply(a, [\n 0,\n v + 1\n].concat([x]));'));
1241
+
1242
+ it('inclusive array splicing with numeric from and numeric to',
1243
+ generateTest('a[t..v] = [x];', '[].splice.apply(a, [\n t,\n v - t + 1\n].concat([x]));'));
1244
+
1245
+ it('exclusive array splicing with empty from and to',
1246
+ generateTest('a[...] = [x];', '[].splice.apply(a, [\n 0,\n 9000000000\n].concat([x]));'));
1247
+
1248
+ it('exclusive array splicing with numeric from and empty to',
1249
+ generateTest('a[1...] = [x];', '[].splice.apply(a, [\n 1,\n 9000000000\n].concat([x]));'));
1250
+
1251
+ it('exclusive array splicing with empty from and numeric to',
1252
+ generateTest('a[...3] = [x];', '[].splice.apply(a, [\n 0,\n 3\n].concat([x]));'));
1253
+
1254
+ it('exclusive array splicing with numeric from and numeric to',
1255
+ generateTest('a[2...3] = [x];', '[].splice.apply(a, [\n 2,\n 1\n].concat([x]));'));
1256
+
1257
+ it('exclusive array splicing with identifier from and empty to',
1258
+ generateTest('a[t...] = [x];', '[].splice.apply(a, [\n t,\n 9000000000\n].concat([x]));'));
1259
+
1260
+ it('exclusive array splicing with empty from and numeric to',
1261
+ generateTest('a[...v] = [x];', '[].splice.apply(a, [\n 0,\n v\n].concat([x]));'));
1262
+
1263
+ it('exclusive array splicing with numeric from and numeric to',
1264
+ generateTest('a[t...v] = [x];', '[].splice.apply(a, [\n t,\n v - t\n].concat([x]));'));
1265
+ });
1266
+
1267
+ describe('new expressions:', function () {
1268
+ it('new expression with 0 arguments',
1269
+ generateTest('var x = new A();', 'let x = new A();'));
1270
+
1271
+ it('new expression with 1 argument',
1272
+ generateTest('var x = new A(1);', 'let x = new A(1);'));
1273
+
1274
+ it('new expression with 2 argument',
1275
+ generateTest('var x = new A(1, b());', 'let x = new A(1, b());'));
1276
+ });
1277
+
1278
+ describe('default fn param value:', function () {
1279
+ it('fn decl with 1 param with default value',
1280
+ generateTest('fn f(a = 5) {}',
1281
+ 'function f(a = 5) {\n}'));
1282
+
1283
+ it('fn decl with 2 params with default values',
1284
+ generateTest('fn f(a = 5, b = 3) {}',
1285
+ 'function f(a = 5, b = 3) {\n}'));
1286
+
1287
+ it('fn decl with 2 params - first with default value and second without',
1288
+ generateTest('fn f(a = 5, b) {}',
1289
+ 'function f(a = 5, b) {\n}'));
1290
+
1291
+ it('fn decl with 2 params - second with default value and first without',
1292
+ generateTest('fn f(a, b = 3) {}',
1293
+ 'function f(a, b = 3) {\n}'));
1294
+
1295
+ it('fn decl with 3 params with default values',
1296
+ generateTest('fn f(a = 5, b = 3, k = { test: 1 }) {}',
1297
+ 'function f(a = 5, b = 3, k = { test: 1 }) {\n}'));
1298
+
1299
+ it('fn expression with 1 param with default value',
1300
+ generateTest('var x = (a = 5) -> a;', 'let x = function (a = 5) {\n return a;\n};'));
1301
+
1302
+ it('fn expression with 2 params with default values',
1303
+ generateTest('var x = fn (a = 5, b = 3) {};', 'let x = function (a = 5, b = 3) {\n};'));
1304
+
1305
+ it('fn expression with 2 params - first with default value and second without',
1306
+ generateTest('var x = fn (a = 5, b) {};', 'let x = function (a = 5, b) {\n};'));
1307
+
1308
+ it('fn expression with 2 params - second with default value and first without',
1309
+ generateTest('var x = fn (a, b = 3) {};', 'let x = function (a, b = 3) {\n};'));
1310
+
1311
+ it('fn expression with 3 params with default values',
1312
+ generateTest('var x = fn (a = 5, b = 3, k = { test: 1 }) {};', 'let x = function (a = 5, b = 3, k = { test: 1 }) {\n};'));
1313
+ });
1314
+
1315
+ describe('splat in function declaration:', function () {
1316
+ it('fn decl with splat',
1317
+ generateTest('fn f(a...) {}',
1318
+ 'function f() {\n let __splat, a = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];\n}'));
1319
+
1320
+ it('fn decl with splat, parameter',
1321
+ generateTest('fn f(a..., b) {}',
1322
+ 'function f() {\n let __splat, a = 2 <= arguments.length ? [].slice.call(arguments, 0, __splat = arguments.length - 1) : (__splat = 0, []), b = arguments[__splat++];\n}'));
1323
+
1324
+ it('fn decl with parameter, splat',
1325
+ generateTest('fn f(a, b...) {}',
1326
+ 'function f() {\n let __splat, a = arguments[0], b = 2 <= arguments.length ? [].slice.call(arguments, 1) : [];\n}'));
1327
+
1328
+ it('fn decl with parameter, splat, parameter',
1329
+ generateTest('fn f(a, b..., c) {}',
1330
+ 'function f() {\n let __splat, a = arguments[0], b = 3 <= arguments.length ? [].slice.call(arguments, 1, __splat = arguments.length - 1) : (__splat = 1, []), c = arguments[__splat++];\n}'));
1331
+
1332
+ it('fn decl with parameter, parameter, splat, parameter',
1333
+ generateTest('fn f(a, b, c..., d) {}',
1334
+ 'function f() {\n let __splat, a = arguments[0], b = arguments[1], c = 4 <= arguments.length ? [].slice.call(arguments, 2, __splat = arguments.length - 1) : (__splat = 2, []), d = arguments[__splat++];\n}'));
1335
+
1336
+ it('fn decl with parameter, splat, parameter, parameter',
1337
+ generateTest('fn f(a, b..., c, d) {}',
1338
+ 'function f() {\n let __splat, a = arguments[0], b = 4 <= arguments.length ? [].slice.call(arguments, 1, __splat = arguments.length - 2) : (__splat = 1, []), c = arguments[__splat++], d = arguments[__splat++];\n}'));
1339
+
1340
+ it('multiple splats in fn decl',
1341
+ generateErrorTest('fn f(a..., b...) {}', [{ type: "MultipleSplatsDisallowed" }]));
1342
+ });
1343
+
1344
+ describe('splat in call expressions:', function () {
1345
+ it('call expression with a splat',
1346
+ generateTest('f(a...);', 'f.apply(null, a);'));
1347
+
1348
+ it('call expression with splat, argument',
1349
+ generateTest('f(a..., b);', 'f.apply(null, [].slice.call(a).concat([b]));'));
1350
+
1351
+ it('call expression with argument, splat',
1352
+ generateTest('f(a, b...);', 'f.apply(null, [a].concat([].slice.call(b)));'));
1353
+
1354
+ it('call expression with splat, argument, argument',
1355
+ generateTest('f(a..., b, c);', 'f.apply(null, [].slice.call(a).concat([b], [c]));'));
1356
+
1357
+ it('call expression with argument, splat, argument',
1358
+ generateTest('f(a, b..., c);', 'f.apply(null, [a].concat([].slice.call(b), [c]));'));
1359
+
1360
+ it('call expression with argument, argument, splat, argument',
1361
+ generateTest('f(a, b, c..., d);', 'f.apply(null, [\n a,\n b\n].concat([].slice.call(c), [d]));'));
1362
+
1363
+ it('null check call expression with a splat',
1364
+ generateTest('f?(a...);', 'if (typeof f === \"function\") {\n f.apply(null, a);\n}'));
1365
+
1366
+ it('null check call expression with splat, argument',
1367
+ generateTest('f?(a..., b);', 'if (typeof f === \"function\") {\n f.apply(null, [].slice.call(a).concat([b]));\n}'));
1368
+
1369
+ it('null check call expression with argument, splat',
1370
+ generateTest('f?(a, b...);', 'if (typeof f === \"function\") {\n f.apply(null, [a].concat([].slice.call(b)));\n}'));
1371
+
1372
+ it('null check call expression with splat, argument, argument',
1373
+ generateTest('f?(a..., b, c);', 'if (typeof f === \"function\") {\n f.apply(null, [].slice.call(a).concat([b], [c]));\n}'));
1374
+
1375
+ it('null check call expression with argument, splat, argument',
1376
+ generateTest('f?(a, b..., c);', 'if (typeof f === \"function\") {\n f.apply(null, [a].concat([].slice.call(b), [c]));\n}'));
1377
+
1378
+ it('null check call expression with argument, argument, splat, argument',
1379
+ generateTest('f?(a, b, c..., d);', 'if (typeof f === \"function\") {\n f.apply(null, [\n a,\n b\n ].concat([].slice.call(c), [d]));\n}'));
1380
+ });
1381
+
1382
+ describe('conditional expressions:', function () {
1383
+ it('conditional expression',
1384
+ generateTest('var x = a() if b else c();', 'let x = b ? a() : c();'));
1385
+ });
1386
+
1387
+ describe('for in statement:', function () {
1388
+ it('for in statement without index',
1389
+ generateTest('for item in array {}',
1390
+ 'for (let item of array) {\n}'));
1391
+
1392
+ it('for in statement with index',
1393
+ generateTest('for item, index in array {}',
1394
+ 'let index = 0;\nfor (let item of array) {\n index++;\n}'));
1395
+ });
1396
+
1397
+ describe('for of statement:', function () {
1398
+ it('for of statement without value',
1399
+ generateTest('for key of object {}',
1400
+ 'for (let key of Object.keys(object)) {\n}'));
1401
+
1402
+ it('for of statement with value',
1403
+ generateTest('for key, value of object {}',
1404
+ 'for (let key of Object.keys(object)) {\n let value = object[key];\n}'));
1405
+
1406
+ it('for of statement of call expression without value',
1407
+ generateTest('for key of f() {}',
1408
+ 'for (let key of Object.keys(f())) {\n}'));
1409
+
1410
+ it('for of statement of call expression with value',
1411
+ generateTest('for key, value of f() {}',
1412
+ 'let forOf0 = f();\nfor (let key of Object.keys(forOf0)) {\n let value = forOf0[key];\n}'));
1413
+ });
1414
+
1415
+ describe('try statement:', function () {
1416
+ it('try statement without handler with finalizer',
1417
+ generateTest('try { a(); } finally { b(); }',
1418
+ 'try {\n a();\n} finally {\n b();\n}'));
1419
+
1420
+ it('try statement with handler without finalizer',
1421
+ generateTest('try { a(); } catch error { b(); }',
1422
+ 'try {\n a();\n} catch (error) {\n b();\n}'));
1423
+
1424
+ it('try statement with handler and finalizer',
1425
+ generateTest('try { a(); } catch error { b(); } finally { c(); }',
1426
+ 'try {\n a();\n} catch (error) {\n b();\n} finally {\n c();\n}'));
1427
+ });
1428
+
1429
+ describe('in expression:', function () {
1430
+ it('in expression with identifier',
1431
+ generateTest('var x = a in b;', 'let x = b instanceof Array ? b.indexOf(a) !== -1 : a in b;'));
1432
+
1433
+ it('in expression with call expression',
1434
+ generateTest('var x = a in b();', 'let inExpression0 = b();\nlet x = inExpression0 instanceof Array ? inExpression0.indexOf(a) !== -1 : a in inExpression0;'));
1435
+ });
1436
+
1437
+ describe('list comprehensions:', function () {
1438
+ it('list comprehension without condition and without index',
1439
+ generateTest('var x = [item + 1 for item in array];',
1440
+ 'let x = function () {\n let forIn0 = [];\n for (let item of array) {\n forIn0.push(item + 1);\n }\n return forIn0;\n}();'));
1441
+
1442
+ it('list comprehension with condition and without index',
1443
+ generateTest('var x = [item + 1 for item in array if condition];',
1444
+ 'let x = function () {\n let forIn0 = [];\n for (let item of array) {\n if (condition) {\n forIn0.push(item + 1);\n }\n }\n return forIn0;\n}();'));
1445
+
1446
+ it('list comprehension without condition and with index',
1447
+ generateTest('var x = [item + index for item, index in array];',
1448
+ 'let x = function () {\n let forIn0 = [];\n let index = 0;\n for (let item of array) {\n forIn0.push(item + index);\n index++;\n }\n return forIn0;\n}();'));
1449
+
1450
+ it('list comprehension with condition and with index',
1451
+ generateTest('var x = [item + index for item, index in array if index > 1];',
1452
+ 'let x = function () {\n let forIn0 = [];\n let index = 0;\n for (let item of array) {\n if (index > 1) {\n forIn0.push(item + index);\n }\n index++;\n }\n return forIn0;\n}();'));
1453
+ });
1454
+
1455
+ describe('switch statement:', function () {
1456
+ it('switch statement with single case',
1457
+ generateTest('switch n { case 1: { } }',
1458
+ 'if (n === 1) {\n}'));
1459
+
1460
+ it('switch statement with 2 cases',
1461
+ generateTest('switch n { case 1: { }, case 2: { } }',
1462
+ 'if (n === 1) {\n} else if (n === 2) {\n}'));
1463
+
1464
+ it('switch statement with 2 cases with multiple options',
1465
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { } }',
1466
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n}'));
1467
+
1468
+ it('switch statement with 2 cases with multiple options and default case',
1469
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, default: { } }',
1470
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else {\n}'));
1471
+
1472
+ it('switch statement with 2 cases with multiple options, inclusive range case and default case',
1473
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, case 5..6: { }, default: { } }',
1474
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else if (n >= 5 && n <= 6) {\n} else {\n}'));
1475
+
1476
+ it('switch statement with 2 cases with multiple options, inclusive range case without from and default case',
1477
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, case ..6: { }, default: { } }',
1478
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else if (n <= 6) {\n} else {\n}'));
1479
+
1480
+ it('switch statement with 2 cases with multiple options, inclusive range case without to and default case',
1481
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, case 5..: { }, default: { } }',
1482
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else if (n >= 5) {\n} else {\n}'));
1483
+
1484
+ it('switch statement with 2 cases with multiple options, exclusive range case and default case',
1485
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, case 5...6: { }, default: { } }',
1486
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else if (n >= 5 && n < 6) {\n} else {\n}'));
1487
+
1488
+ it('switch statement with 2 cases with multiple options, exclusive range case without from and default case',
1489
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, case ...6: { }, default: { } }',
1490
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else if (n < 6) {\n} else {\n}'));
1491
+
1492
+ it('switch statement with 2 cases with multiple options, exclusive range case without to and default case',
1493
+ generateTest('switch n { case 1, 2: { }, case 3, 4: { }, case 5...: { }, default: { } }',
1494
+ 'if (n === 1 || n === 2) {\n} else if (n === 3 || n === 4) {\n} else if (n >= 5) {\n} else {\n}'));
1495
+
1496
+ it('switch statement with single default case',
1497
+ generateErrorTest('switch ::n { default: { } }',
1498
+ [{ "type": "SingleDefaultClause" }]));
1499
+
1500
+ it('switch statement with range case without from and without to',
1501
+ generateErrorTest('switch ::n { case ..: { } }',
1502
+ [{ "type": "EmptyRange" }]));
1503
+ });
1504
+
1505
+ describe('fallthrough statement:', function () {
1506
+ it('switch with 2 fallthrough cases',
1507
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); fallthrough; } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n fallthrough0 = 1;\n}'));
1508
+
1509
+ it('switch with 3 fallthrough cases',
1510
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); fallthrough; }, case 1..6: { c(); fallthrough; } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n fallthrough0 = 1;\n}'));
1511
+
1512
+ it('switch with fallthrough-normal-fallthrough cases',
1513
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); }, case 1..6: { c(); fallthrough; } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n fallthrough0 = 1;\n}'));
1514
+
1515
+ it('switch with fallthrough-normal-normal-fallthrough cases',
1516
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); }, case 1..6: { c(); }, case 1..8: { d(); fallthrough; } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 8)) {\n fallthrough0 = 2;\n d();\n fallthrough0 = 1;\n}'));
1517
+
1518
+ it('switch with normal-fallthrough-normal-fallthrough cases',
1519
+ generateTest('switch n { case 1..2: { a(); }, case 1..4: { b(); fallthrough; }, case 1..6: { c(); }, case 1..8: { d(); fallthrough; } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n} else if (n >= 1 && n <= 4) {\n fallthrough0 = 2;\n b();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 8)) {\n fallthrough0 = 2;\n d();\n fallthrough0 = 1;\n}'));
1520
+
1521
+ it('switch with 2 fallthrough cases with default',
1522
+ generateTest('switch n() { case a(): { a(); fallthrough; }, case 1..4: { b(); fallthrough; }, default: { def(); } }', 'let fallthrough0 = 0;\nlet switchStatement0 = n();\nif (fallthrough0 < 2 && (switchStatement0 >= 1 && switchStatement0 <= 4)) {\n fallthrough0 = 2;\n b();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2) {\n def();\n}\nif (switchStatement0 === a()) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}'));
1523
+
1524
+ it('switch with 3 fallthrough cases with default',
1525
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); fallthrough; }, case 1..6: { c(); fallthrough; }, default: { def(); } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2) {\n def();\n}'));
1526
+
1527
+ it('switch with fallthrough-normal-fallthrough cases with default',
1528
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); }, case 1..6: { c(); fallthrough; }, default: { def(); } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2) {\n def();\n}'));
1529
+
1530
+ it('switch with fallthrough-normal-normal-fallthrough cases with default',
1531
+ generateTest('switch n { case 1..2: { a(); fallthrough; }, case 1..4: { b(); }, case 1..6: { c(); }, case 1..8: { d(); fallthrough; }, default: { def(); } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 4)) {\n fallthrough0 = 2;\n b();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 8)) {\n fallthrough0 = 2;\n d();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2) {\n def();\n}'));
1532
+
1533
+ it('switch with normal-fallthrough-normal-fallthrough cases with default',
1534
+ generateTest('switch n { case 1..2: { a(); }, case 1..4: { b(); fallthrough; }, case 1..6: { c(); }, case 1..8: { d(); fallthrough; }, default: { def(); } }', 'let fallthrough0 = 0;\nif (n >= 1 && n <= 2) {\n fallthrough0 = 2;\n a();\n} else if (n >= 1 && n <= 4) {\n fallthrough0 = 2;\n b();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2 && (n >= 1 && n <= 6)) {\n fallthrough0 = 2;\n c();\n} else if (fallthrough0 < 2 && (n >= 1 && n <= 8)) {\n fallthrough0 = 2;\n d();\n fallthrough0 = 1;\n}\nif (fallthrough0 < 2) {\n def();\n}'));
1535
+ });
1536
+
1537
+ describe('fat arrow:', function () {
1538
+ it('fat arrow function expression',
1539
+ generateTest('var x = () => this.test;', 'let x = () => {\n return this.test;\n};'));
1540
+
1541
+ it('fat arrow function expression inside another',
1542
+ generateTest('var x = () => () => this.test;', 'let x = () => {\n return () => {\n return this.test;\n };\n};'));
1543
+ });
1544
+
1545
+ describe('for-in and for-of with break and return:', function () {
1546
+ it('for-in with break',
1547
+ generateTest('for x in array { break; }',
1548
+ 'for (let x of array) {\n break;\n}'));
1549
+
1550
+ it('for-in with conditional break',
1551
+ generateTest('for x in array { if x == 5 { break; } }',
1552
+ 'for (let x of array) {\n if (x === 5) {\n break;\n }\n}'));
1553
+
1554
+ it('for-in with return',
1555
+ generateTest('for x in array { return 5; }',
1556
+ 'for (let x of array) {\n return 5;\n}'));
1557
+
1558
+ it('for-in with return w/o argument',
1559
+ generateTest('for x in array { return; }',
1560
+ 'for (let x of array) {\n return;\n}'));
1561
+
1562
+ it('for-in with conditional return',
1563
+ generateTest('for x in array { if x == 5 { return 5; } }',
1564
+ 'for (let x of array) {\n if (x === 5) {\n return 5;\n }\n}'));
1565
+
1566
+ it('for-of with break',
1567
+ generateTest('for x of obj { break; }',
1568
+ 'for (let x of Object.keys(obj)) {\n break;\n}'));
1569
+
1570
+ it('for-of with conditional break',
1571
+ generateTest('for x of obj { if x == 5 { break; } }',
1572
+ 'for (let x of Object.keys(obj)) {\n if (x === 5) {\n break;\n }\n}'));
1573
+
1574
+ it('for-of with return',
1575
+ generateTest('for x of obj { return 5; }',
1576
+ 'for (let x of Object.keys(obj)) {\n return 5;\n}'));
1577
+
1578
+ it('for-of with conditional return',
1579
+ generateTest('for x of obj { if x == 5 { return 5; } }',
1580
+ 'for (let x of Object.keys(obj)) {\n if (x === 5) {\n return 5;\n }\n}'));
1581
+ });
1582
+
1583
+ describe('regular expression literals:', function () {
1584
+ it('regular expression literal',
1585
+ generateTest('var re = /ab+c/g;', 'let re = /ab+c/g;'));
1586
+ });
1587
+
1588
+ describe('import statement:', function () {
1589
+ it('import with 1 identifier',
1590
+ generateTest('import foo from "foobar";',
1591
+ 'import { foo } from \"foobar\";'));
1592
+
1593
+ it('import with 2 identifiers',
1594
+ generateTest('import foo, bar from "foobar";',
1595
+ 'import {\n foo,\n bar\n} from \"foobar\";'));
1596
+
1597
+ it('import with 1 identifier with as',
1598
+ generateTest('import foo as a from "foobar";',
1599
+ 'import { foo as a } from \"foobar\";'));
1600
+
1601
+ it('import with 2 identifiers with as',
1602
+ generateTest('import foo as a, bar as b from "foobar";',
1603
+ 'import {\n foo as a,\n bar as b\n} from \"foobar\";'));
1604
+
1605
+ it('batch import',
1606
+ generateTest('import * as lib from "lib";',
1607
+ 'import * as lib from \"lib\";'));
1608
+
1609
+ it('import default',
1610
+ generateTest('import "jquery" as $;',
1611
+ 'import $ from "jquery";'));
1612
+ });
1613
+
1614
+ describe('export statement:', function () {
1615
+ it('export with 1 identifier',
1616
+ generateTest('export foo;',
1617
+ 'export {\n foo\n};'));
1618
+
1619
+ it('export with 2 identifiers',
1620
+ generateTest('export foo, bar;',
1621
+ 'export {\n foo,\n bar\n};'));
1622
+
1623
+ it('export with 1 identifier with as',
1624
+ generateTest('export foo as f;',
1625
+ 'export {\n foo as f\n};'));
1626
+
1627
+ it('export with 2 identifiers with as',
1628
+ generateTest('export foo as f, bar as b;',
1629
+ 'export {\n foo as f,\n bar as b\n};'));
1630
+
1631
+ it('export with 1 identifier with source',
1632
+ generateTest('export foo from "foo";',
1633
+ 'export {\n foo\n} from \"foo\";'));
1634
+
1635
+ it('export with 2 identifiers with source',
1636
+ generateTest('export foo, bar from "foobar";',
1637
+ 'export {\n foo,\n bar\n} from \"foobar\";'));
1638
+
1639
+ it('batch export',
1640
+ generateTest('export * from "foobar";',
1641
+ 'export * from \"foobar\";'));
1642
+
1643
+ it('export variable statement',
1644
+ generateTest('export var sqrt = Math.sqrt;',
1645
+ 'export let sqrt = Math.sqrt;'));
1646
+
1647
+ it('export function statement',
1648
+ generateTest('export fn x() {}',
1649
+ 'export function x() {\n}'));
1650
+
1651
+ it('export function statement with extends',
1652
+ generateTest('export fn x() extends A {}',
1653
+ 'export function x() {\n A.call(this);\n}\nx.prototype = Object.create(A);'));
1654
+
1655
+ it('export default identifier',
1656
+ generateTest('export default x;',
1657
+ 'export default x;'));
1658
+
1659
+ it('export default function expression',
1660
+ generateTest('export default () -> {};',
1661
+ 'export default function () {\n};'));
1662
+ });
1663
+
1664
+ describe('curried functions:', function () {
1665
+ it('single function curry',
1666
+ generateTest('var x = a^(1);',
1667
+ 'let x = function () {\n return a.apply(this, [1].concat([].slice.apply(arguments)));\n};'));
1668
+
1669
+ it('double function curry',
1670
+ generateTest('var x = a^(1)^(2, 3);',
1671
+ 'let x = function () {\n return function () {\n return a.apply(this, [1].concat([].slice.apply(arguments)));\n }.apply(this, [\n 2,\n 3\n ].concat([].slice.apply(arguments)));\n};'));
1672
+
1673
+ it('single function curry with member expression',
1674
+ generateTest('var x = m.a^(1);',
1675
+ 'let x = function () {\n return m.a.apply(this, [1].concat([].slice.apply(arguments)));\n};'));
1676
+
1677
+ it('double function curry with member expression',
1678
+ generateTest('var x = m.a^(1)^(2, 3);',
1679
+ 'let x = function () {\n return function () {\n return m.a.apply(this, [1].concat([].slice.apply(arguments)));\n }.apply(this, [\n 2,\n 3\n ].concat([].slice.apply(arguments)));\n};'));
1680
+
1681
+ it('curry function with splats',
1682
+ generateErrorTest('var x = ::a^(::s...);',
1683
+ [{ type: "InvalidFunctionCurrying" }]));
1684
+
1685
+ it('curry function with null propagating operator',
1686
+ generateErrorTest('var x = ::m?.a^();',
1687
+ [{ type: "InvalidFunctionCurrying" }]));
1688
+ });
1689
+
1690
+ describe('destructuring assignment:', function () {
1691
+ it('array pattern destructuring assignment',
1692
+ generateTest('var [m, d, y] = [3, 14, 1977];',
1693
+ 'let [\n m,\n d,\n y\n] = [\n 3,\n 14,\n 1977\n];'));
1694
+
1695
+ it('array pattern destructuring assignment with 1 null',
1696
+ generateTest('var [, d, y] = [3, 14, 1977];',
1697
+ 'let [\n ,\n d,\n y\n] = [\n 3,\n 14,\n 1977\n];'));
1698
+
1699
+ it('array pattern destructuring assignment with 2 nulls',
1700
+ generateTest('var [,, y] = [3, 14, 1977];',
1701
+ 'let [\n ,\n ,\n y\n] = [\n 3,\n 14,\n 1977\n];'));
1702
+
1703
+ it('array pattern destructuring assignment with sub array pattern',
1704
+ generateTest('var [,, [a,b,c]] = [3, 14, [1,2,3]];',
1705
+ 'let [\n ,\n ,\n [\n a,\n b,\n c\n ]\n] = [\n 3,\n 14,\n [\n 1,\n 2,\n 3\n ]\n];'));
1706
+
1707
+ it('object pattern destructuring assignment',
1708
+ generateTest('var { x: x } = f;',
1709
+ 'let {x: x} = f;'));
1710
+
1711
+ it('object pattern destructuring assignment with 2 properties',
1712
+ generateTest('var { x: x, y: test } = f;',
1713
+ 'let {\n x: x,\n y: test\n} = f;'));
1714
+
1715
+ it('object pattern destructuring assignment with sub object pattern',
1716
+ generateTest('var { x: x, y: { b: b } } = f;',
1717
+ 'let {\n x: x,\n y: {b: b}\n} = f;'));
1718
+
1719
+ it('swap',
1720
+ generateTest('[x,y]=[y,x];',
1721
+ '[\n x,\n y\n] = [\n y,\n x\n];'));
1722
+ });
1723
+
1724
+ describe('object initializer shorthand:', function () {
1725
+ it('object literal initializer shorthand',
1726
+ generateTest('var a = {x, y};',
1727
+ 'let a = {\n x,\n y\n};'));
1728
+
1729
+ it('object pattern initializer shorthand',
1730
+ generateTest('var {x, y} = {x: 1, y: 2};',
1731
+ 'let {x, y} = {\n x: 1,\n y: 2\n};'));
1732
+ });
1733
+
1734
+ describe('property method assignments:', function () {
1735
+ it('property method assignment',
1736
+ generateTest('var object = {value: 42, toString() { return this.value; }};',
1737
+ 'let object = {\n value: 42,\n toString() {\n return this.value;\n }\n};'));
1738
+ });
1739
+
1740
+ describe('pattern matching:', function () {
1741
+ it('pattern match',
1742
+ generateTest('switch [a,b] { case [,5]: {} case [5,,,6]: {}}',
1743
+ 'let switchStatement0 = [\n a,\n b\n];\nif (switchStatement0.length >= 2 && switchStatement0[1] === 5) {\n} else if (switchStatement0.length >= 4 && switchStatement0[0] === 5 && switchStatement0[3] === 6) {\n}'));
1744
+ });
1745
+
1746
+ describe('delete statement:', function () {
1747
+ it('delete statement',
1748
+ generateTest('delete x;', 'delete x;'));
1749
+ });
1750
+
1751
+ describe('do-while loop:', function () {
1752
+ it('do-while loop',
1753
+ generateTest('do { f(); } while true;', 'do {\n f();\n} while (true);'));
1754
+ });
1755
+
1756
+ describe('channels:', function () {
1757
+ it('get expression',
1758
+ generateTest('f(<-x);',
1759
+ 'f(await x.get());'));
1760
+
1761
+ it('push statement',
1762
+ generateTest('a <- b;',
1763
+ 'a.push(b);'));
1764
+
1765
+ it('go statement',
1766
+ generateTest('go { f(); };',
1767
+ '(async function () {\n f();\n})();'));
1768
+
1769
+ it('get operator in global context',
1770
+ generateErrorTest('::f(<-::x);',
1771
+ [{ type: "GetExpressionRequiresAsync" }]));
1772
+
1773
+ it('get operator in a normal function',
1774
+ generateErrorTest('fn h() { ::f(<-::x); }',
1775
+ [{ type: "GetExpressionRequiresAsync" }]));
1776
+
1777
+ it('get operator in an async function',
1778
+ generateErrorTest('async fn h() { ::f(<-::x); }', []));
1779
+
1780
+ it('get operator in an go statement',
1781
+ generateErrorTest('go { ::f(<-::x); };', []));
1782
+ });
1783
+
1784
+ describe('undefined literals:', function () {
1785
+ it('undefined literal',
1786
+ generateTest('undefined;', 'void 0;'));
1787
+ });