3
var parseJS = require("../lib/parse-js");
4
var sys = require("sys");
6
// write debug in a very straightforward manner
7
var debug = function(){
8
sys.log(Array.prototype.slice.call(arguments).join(', '));
11
ParserTestSuite(function(i, input, desc){
14
debug("ok " + i + ": " + desc);
16
debug("FAIL " + i + " " + desc + " (" + e + ")");
20
function ParserTestSuite(callback){
22
["var abc;", "Regular variable statement w/o assignment"],
23
["var abc = 5;", "Regular variable statement with assignment"],
24
["/* */;", "Multiline comment"],
25
['/** **/;', 'Double star multiline comment'],
26
["var f = function(){;};", "Function expression in var assignment"],
27
['hi; // moo\n;', 'single line comment'],
28
['var varwithfunction;', 'Dont match keywords as substrings'], // difference between `var withsomevar` and `"str"` (local search and lits)
29
['a + b;', 'addition'],
30
["'a';", 'single string literal'],
31
["'a\\n';", 'single string literal with escaped return'],
32
['"a";', 'double string literal'],
33
['"a\\n";', 'double string literal with escaped return'],
34
['"var";', 'string is a keyword'],
35
['"variable";', 'string starts with a keyword'],
36
['"somevariable";', 'string contains a keyword'],
37
['"somevar";', 'string ends with a keyword'],
38
['500;', 'int literal'],
39
['500.;', 'float literal w/o decimals'],
40
['500.432;', 'float literal with decimals'],
41
['.432432;', 'float literal w/o int'],
42
['(a,b,c);', 'parens and comma'],
43
['[1,2,abc];', 'array literal'],
44
['var o = {a:1};', 'object literal unquoted key'],
45
['var o = {"b":2};', 'object literal quoted key'], // opening curly may not be at the start of a statement...
46
['var o = {c:c};', 'object literal keyname is identifier'],
47
['var o = {a:1,"b":2,c:c};', 'object literal combinations'],
48
['var x;\nvar y;', 'two lines'],
49
['var x;\nfunction n(){; }', 'function def'],
50
['var x;\nfunction n(abc){; }', 'function def with arg'],
51
['var x;\nfunction n(abc, def){ ;}', 'function def with args'],
52
['function n(){ "hello"; }', 'function def with body'],
53
['/a/;', 'regex literal'],
54
['/a/b;', 'regex literal with flag'],
55
['/a/ / /b/;', 'regex div regex'],
56
['a/b/c;', 'triple division looks like regex'],
57
['+function(){/regex/;};', 'regex at start of function body'],
58
// http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=86
59
// http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=430
61
// first tests for the lexer, should also parse as program (when you append a semi)
64
['//foo!@#^&$1234\nbar;', 'single line comment'],
65
['/* abcd!@#@$* { } && null*/;', 'single line multi line comment'],
66
['/*foo\nbar*/;','multi line comment'],
67
['/*x*x*/;','multi line comment with *'],
68
['/**/;','empty comment'],
70
["x;",'1 identifier'],
71
["_x;",'2 identifier'],
72
["xyz;",'3 identifier'],
73
["$x;",'4 identifier'],
74
["x$;",'5 identifier'],
75
["_;",'6 identifier'],
76
["x5;",'7 identifier'],
77
["x_y;",'8 identifier'],
78
["x+5;",'9 identifier'],
79
["xyz123;",'10 identifier'],
80
["x1y1z1;",'11 identifier'],
81
["foo\\u00D8bar;",'12 identifier unicode escape'],
82
//["fooļæ½bar;",'13 identifier unicode embedded (might fail)'],
88
["0.001;", '5 number'],
89
["1.e2;", '6 number'],
90
["1.e-2;", '7 number'],
91
["1.E2;", '8 number'],
92
["1.E-2;", '9 number'],
94
[".5e3;", '11 number'],
95
[".5e-3;", '12 number'],
96
["0.5e3;", '13 number'],
98
["123;", '15 number'],
99
["55.55;", '16 number'],
100
["55.55e10;", '17 number'],
101
["123.456;", '18 number'],
102
["1+e;", '20 number'],
103
["0x01;", '22 number'],
104
["0XCAFE;", '23 number'],
105
["0x12345678;", '24 number'],
106
["0x1234ABCD;", '25 number'],
107
["0x0001;", '26 number'],
109
["\"foo\";", '1 string'],
110
["\'foo\';", '2 string'],
111
["\"x\";", '3 string'],
112
["\'\';", '4 string'],
113
["\"foo\\tbar\";", '5 string'],
114
["\"!@#$%^&*()_+{}[]\";", '6 string'],
115
["\"/*test*/\";", '7 string'],
116
["\"//test\";", '8 string'],
117
["\"\\\\\";", '9 string'],
118
["\"\\u0001\";", '10 string'],
119
["\"\\uFEFF\";", '11 string'],
120
["\"\\u10002\";", '12 string'],
121
["\"\\x55\";", '13 string'],
122
["\"\\x55a\";", '14 string'],
123
["\"a\\\\nb\";", '15 string'],
124
['";"', '16 string: semi in a string'],
125
['"a\\\nb";', '17 string: line terminator escape'],
132
["/abc/;", "2 regex"],
133
["/abc[a-z]*def/g;", "3 regex"],
134
["/\\b/;", "4 regex"],
135
["/[a-zA-Z]/;", "5 regex"],
137
// program tests (for as far as they havent been covered above)
140
["/foo(.*)/g;", "another regexp"],
145
["[1,2];", "4 array"],
146
["[1,2,,];", "5 array"],
147
["[1,2,3];", "6 array"],
148
["[1,2,3,,,];", "7 array"],
151
["({x:5});", "2 object"],
152
["({x:5,y:6});", "3 object"],
153
["({x:5,});", "4 object"],
154
["({if:5});", "5 object"],
155
["({ get x() {42;} });", "6 object"],
156
["({ set y(a) {1;} });", "7 object"],
158
["o.m;", "1 member expression"],
159
["o['m'];", "2 member expression"],
160
["o['n']['m'];", "3 member expression"],
161
["o.n.m;", "4 member expression"],
162
["o.if;", "5 member expression"],
163
// call and invoke expressions
164
["f();", "1 call/invoke expression"],
165
["f(x);", "2 call/invoke expression"],
166
["f(x,y);", "3 call/invoke expression"],
167
["o.m();", "4 call/invoke expression"],
168
["o['m'];", "5 call/invoke expression"],
169
["o.m(x);", "6 call/invoke expression"],
170
["o['m'](x);", "7 call/invoke expression"],
171
["o.m(x,y);", "8 call/invoke expression"],
172
["o['m'](x,y);", "9 call/invoke expression"],
173
["f(x)(y);", "10 call/invoke expression"],
174
["f().x;", "11 call/invoke expression"],
177
["eval('x');", "1 eval"],
178
["(eval)('x');", "2 eval"],
179
["(1,eval)('x');", "3 eval"],
180
["eval(x,y);", "4 eval"],
182
["new f();", "1 new expression"],
183
["new o;", "2 new expression"],
184
["new o.m;", "3 new expression"],
185
["new o.m(x);", "4 new expression"],
186
["new o.m(x,y);", "5 new expression"],
188
["++x;", "1 pre/postfix"],
189
["x++;", "2 pre/postfix"],
190
["--x;", "3 pre/postfix"],
191
["x--;", "4 pre/postfix"],
192
["x ++;", "5 pre/postfix"],
193
["x /* comment */ ++;", "6 pre/postfix"],
194
["++ /* comment */ x;", "7 pre/postfix"],
196
["delete x;", "1 unary operator"],
197
["void x;", "2 unary operator"],
198
["+ x;", "3 unary operator"],
199
["-x;", "4 unary operator"],
200
["~x;", "5 unary operator"],
201
["!x;", "6 unary operator"],
203
["new Date++;", "new date ++"],
204
["+x++;", " + x ++"],
205
// expression expressions
206
["1 * 2;", "1 expression expressions"],
207
["1 / 2;", "2 expression expressions"],
208
["1 % 2;", "3 expression expressions"],
209
["1 + 2;", "4 expression expressions"],
210
["1 - 2;", "5 expression expressions"],
211
["1 << 2;", "6 expression expressions"],
212
["1 >>> 2;", "7 expression expressions"],
213
["1 >> 2;", "8 expression expressions"],
214
["1 * 2 + 3;", "9 expression expressions"],
215
["(1+2)*3;", "10 expression expressions"],
216
["1*(2+3);", "11 expression expressions"],
217
["x<y;", "12 expression expressions"],
218
["x>y;", "13 expression expressions"],
219
["x<=y;", "14 expression expressions"],
220
["x>=y;", "15 expression expressions"],
221
["x instanceof y;", "16 expression expressions"],
222
["x in y;", "17 expression expressions"],
223
["x&y;", "18 expression expressions"],
224
["x^y;", "19 expression expressions"],
225
["x|y;", "20 expression expressions"],
226
["x+y<z;", "21 expression expressions"],
227
["x<y+z;", "22 expression expressions"],
228
["x+y+z;", "23 expression expressions"],
229
["x+y<z;", "24 expression expressions"],
230
["x<y+z;", "25 expression expressions"],
231
["x&y|z;", "26 expression expressions"],
232
["x&&y;", "27 expression expressions"],
233
["x||y;", "28 expression expressions"],
234
["x&&y||z;", "29 expression expressions"],
235
["x||y&&z;", "30 expression expressions"],
236
["x<y?z:w;", "31 expression expressions"],
238
["x >>>= y;", "1 assignment"],
239
["x <<= y;", "2 assignment"],
240
["x = y;", "3 assignment"],
241
["x += y;", "4 assignment"],
242
["x /= y;", "5 assignment"],
247
["{x;};", "2 block"],
248
["{x;y;};", "3 block"],
251
["var x,y;", "2 var"],
252
["var x=1,y=2;", "3 var"],
253
["var x,y=2;", "4 var"],
257
// expression statement
258
["x;", "1 expression statement"],
259
["5;", "2 expression statement"],
260
["1+2;", "3 expression statement"],
262
["if (c) x; else y;", "1 if statement"],
263
["if (c) x;", "2 if statement"],
264
["if (c) {} else {};", "3 if statement"],
265
["if (c1) if (c2) s1; else s2;", "4 if statement"],
267
["do s; while (e);", "1 while statement"],
268
["do { s; } while (e);", "2 while statement"],
269
["while (e) s;", "3 while statement"],
270
["while (e) { s; };", "4 while statement"],
272
["for (;;) ;", "1 for statement"],
273
["for (;c;x++) x;", "2 for statement"],
274
["for (i;i<len;++i){};", "3 for statement"],
275
["for (var i=0;i<len;++i) {};", "4 for statement"],
276
["for (var i=0,j=0;;){};", "5 for statement"],
277
//["for (x in b; c; u) {};", "6 for statement"],
278
["for ((x in b); c; u) {};", "7 for statement"],
279
["for (x in a);", "8 for statement"],
280
["for (var x in a){};", "9 for statement"],
281
["for (var x=5 in a) {};", "10 for statement"],
282
["for (var x = a in b in c) {};", "11 for statement"],
283
["for (var x=function(){a+b;}; a<b; ++i) some;", "11 for statement, testing for parsingForHeader reset with the function"],
284
["for (var x=function(){for (x=0; x<15; ++x) alert(foo); }; a<b; ++i) some;", "11 for statement, testing for parsingForHeader reset with the function"],
286
["while(1){ continue; }", "1 flow statement"],
287
["label: while(1){ continue label; }", "2 flow statement"],
288
["while(1){ break; }", "3 flow statement"],
289
["somewhere: while(1){ break somewhere; }", "4 flow statement"],
290
["while(1){ continue /* comment */ ; }", "5 flow statement"],
291
["while(1){ continue \n; }", "6 flow statement"],
292
["(function(){ return; })()", "7 flow statement"],
293
["(function(){ return 0; })()", "8 flow statement"],
294
["(function(){ return 0 + \n 1; })()", "9 flow statement"],
296
["with (e) s;", "with statement"],
298
["switch (e) { case x: s; };", "1 switch statement"],
299
["switch (e) { case x: s1;s2; default: s3; case y: s4; };", "2 switch statement"],
300
["switch (e) { default: s1; case x: s2; case y: s3; };", "3 switch statement"],
301
["switch (e) { default: s; };", "4 switch statement"],
302
["switch (e) { case x: s1; case y: s2; };", "5 switch statement"],
304
["foo : x;", " flow statement"],
306
["throw x;", "1 throw statement"],
307
["throw x\n;", "2 throw statement"],
309
["try { s1; } catch (e) { s2; };", "1 trycatchfinally statement"],
310
["try { s1; } finally { s2; };", "2 trycatchfinally statement"],
311
["try { s1; } catch (e) { s2; } finally { s3; };", "3 trycatchfinally statement"],
313
["debugger;", "debuger statement"],
315
["function f(x) { e; return x; };", "1 function declaration"],
316
["function f() { x; y; };", "2 function declaration"],
317
["function f(x,y) { var z; return x; };", "3 function declaration"],
319
["(function f(x) { return x; });", "1 function expression"],
320
["(function empty() {;});", "2 function expression"],
321
["(function empty() {;});", "3 function expression"],
322
["(function (x) {; });", "4 function expression"],
324
["var x; function f(){;}; null;", "1 program"],
326
["{ x; y; z; }", "3 program"],
327
["function f(){ function g(){;}};", "4 program"],
328
["x;\n/*foo*/\n ;", "5 program"],
331
["foo: while(1){ continue \n foo; }", "1 asi"],
332
["foo: while(1){ break \n foo; }", "2 asi"],
333
["(function(){ return\nfoo; })()", "3 asi"],
334
["var x; { 1 \n 2 } 3", "4 asi"],
335
["ab /* hi */\ncd", "5 asi"],
336
["ab/*\n*/cd", "6 asi (multi line multilinecomment counts as eol)"],
337
["foo: while(1){ continue /* wtf \n busta */ foo; }", "7 asi illegal with multi line comment"],
338
["function f() { s }", "8 asi"],
339
["function f() { return }", "9 asi"],
342
// XXX: some of these should actually fail?
343
// no support for "use strict" yet...
344
['"use strict"; \'bla\'\n; foo;', "1 directive"],
345
['(function() { "use strict"; \'bla\';\n foo; });', "2 directive"],
346
['"use\\n strict";', "3 directive"],
347
['foo; "use strict";', "4 directive"],
349
// tests from http://es5conform.codeplex.com/
351
['"use strict"; var o = { eval: 42};', "8.7.2-3-1-s: the use of eval as property name is allowed"],
352
['({foo:0,foo:1});', 'Duplicate property name allowed in not strict mode'],
353
['function foo(a,a){}', 'Duplicate parameter name allowed in not strict mode'],
354
['(function foo(eval){})', 'Eval allowed as parameter name in non strict mode'],
355
['(function foo(arguments){})', 'Arguments allowed as parameter name in non strict mode'],
359
['', '1 Empty program'],
360
['// test', '2 Empty program'],
361
['//test\n', '3 Empty program'],
362
['\n// test', '4 Empty program'],
363
['\n// test\n', '5 Empty program'],
364
['/* */', '6 Empty program'],
365
['/*\ns,fd\n*/', '7 Empty program'],
366
['/*\ns,fd\n*/\n', '8 Empty program'],
367
[' ', '9 Empty program'],
368
[' /*\nsmeh*/ \n ', '10 Empty program'],
370
// trailing whitespace
372
['a ', '1 Trailing whitespace'],
373
['a /* something */', '2 Trailing whitespace'],
374
['a\n // hah', '3 Trailing whitespace'],
375
['/abc/de//f', '4 Trailing whitespace'],
376
['/abc/de/*f*/\n ', '5 Trailing whitespace'],
378
// things the parser tripped over at one point or the other (prevents regression bugs)
379
['for (x;function(){ a\nb };z) x;', 'for header with function body forcing ASI'],
380
['c=function(){return;return};', 'resetting noAsi after literal'],
381
['d\nd()', 'asi exception causing token overflow'],
382
['for(;;){x=function(){}}', 'function expression in a for header'],
383
['for(var k;;){}', 'parser failing due to ASI accepting the incorrect "for" rule'],
384
['({get foo(){ }})', 'getter with empty function body'],
385
['\nreturnr', 'eol causes return statement to ignore local search requirement'],
386
[' / /', '1 whitespace before regex causes regex to fail?'],
387
['/ // / /', '2 whitespace before regex causes regex to fail?'],
388
['/ / / / /', '3 whitespace before regex causes regex to fail?'],
390
['\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/;\n\ttrimRight = /\\s+$/;\t\n','turned out this didnt crash (the test below did), but whatever.'],
391
['/[\\/]/;', 'escaped forward slash inside class group (would choke on fwd slash)'],
392
['/[/]/;', 'also broke but is valid in es5 (not es3)'],
393
['({get:5});','get property name thats not a getter'],
394
['({set:5});','set property name thats not a setter'],
395
['l !== "px" && (d.style(h, c, (k || 1) + l), j = (k || 1) / f.cur() * j, d.style(h, c, j + l)), i[1] && (k = (i[1] === "-=" ? -1 : 1) * k + j), f.custom(j, k, l)', 'this choked regex/div at some point'],
396
['(/\'/g, \'\\\\\\\'\') + "\'";', 'the sequence of escaped characters confused the tokenizer']
399
for (var i=0; i<inps.length; ++i) {
400
callback(i, inps[i][0], inps[i][1]);