#! /usr/bin/env node var parseJS = require("../lib/parse-js"); var sys = require("sys"); // write debug in a very straightforward manner var debug = function(){ sys.log(Array.prototype.slice.call(arguments).join(', ')); }; ParserTestSuite(function(i, input, desc){ try { parseJS.parse(input); debug("ok " + i + ": " + desc); } catch(e){ debug("FAIL " + i + " " + desc + " (" + e + ")"); } }); function ParserTestSuite(callback){ var inps = [ ["var abc;", "Regular variable statement w/o assignment"], ["var abc = 5;", "Regular variable statement with assignment"], ["/* */;", "Multiline comment"], ['/** **/;', 'Double star multiline comment'], ["var f = function(){;};", "Function expression in var assignment"], ['hi; // moo\n;', 'single line comment'], ['var varwithfunction;', 'Dont match keywords as substrings'], // difference between `var withsomevar` and `"str"` (local search and lits) ['a + b;', 'addition'], ["'a';", 'single string literal'], ["'a\\n';", 'single string literal with escaped return'], ['"a";', 'double string literal'], ['"a\\n";', 'double string literal with escaped return'], ['"var";', 'string is a keyword'], ['"variable";', 'string starts with a keyword'], ['"somevariable";', 'string contains a keyword'], ['"somevar";', 'string ends with a keyword'], ['500;', 'int literal'], ['500.;', 'float literal w/o decimals'], ['500.432;', 'float literal with decimals'], ['.432432;', 'float literal w/o int'], ['(a,b,c);', 'parens and comma'], ['[1,2,abc];', 'array literal'], ['var o = {a:1};', 'object literal unquoted key'], ['var o = {"b":2};', 'object literal quoted key'], // opening curly may not be at the start of a statement... ['var o = {c:c};', 'object literal keyname is identifier'], ['var o = {a:1,"b":2,c:c};', 'object literal combinations'], ['var x;\nvar y;', 'two lines'], ['var x;\nfunction n(){; }', 'function def'], ['var x;\nfunction n(abc){; }', 'function def with arg'], ['var x;\nfunction n(abc, def){ ;}', 'function def with args'], ['function n(){ "hello"; }', 'function def with body'], ['/a/;', 'regex literal'], ['/a/b;', 'regex literal with flag'], ['/a/ / /b/;', 'regex div regex'], ['a/b/c;', 'triple division looks like regex'], ['+function(){/regex/;};', 'regex at start of function body'], // http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=86 // http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=430 // first tests for the lexer, should also parse as program (when you append a semi) // comments ['//foo!@#^&$1234\nbar;', 'single line comment'], ['/* abcd!@#@$* { } && null*/;', 'single line multi line comment'], ['/*foo\nbar*/;','multi line comment'], ['/*x*x*/;','multi line comment with *'], ['/**/;','empty comment'], // identifiers ["x;",'1 identifier'], ["_x;",'2 identifier'], ["xyz;",'3 identifier'], ["$x;",'4 identifier'], ["x$;",'5 identifier'], ["_;",'6 identifier'], ["x5;",'7 identifier'], ["x_y;",'8 identifier'], ["x+5;",'9 identifier'], ["xyz123;",'10 identifier'], ["x1y1z1;",'11 identifier'], ["foo\\u00D8bar;",'12 identifier unicode escape'], //["foo�bar;",'13 identifier unicode embedded (might fail)'], // numbers ["5;", '1 number'], ["5.5;", '2 number'], ["0;", '3 number'], ["0.0;", '4 number'], ["0.001;", '5 number'], ["1.e2;", '6 number'], ["1.e-2;", '7 number'], ["1.E2;", '8 number'], ["1.E-2;", '9 number'], [".5;", '10 number'], [".5e3;", '11 number'], [".5e-3;", '12 number'], ["0.5e3;", '13 number'], ["55;", '14 number'], ["123;", '15 number'], ["55.55;", '16 number'], ["55.55e10;", '17 number'], ["123.456;", '18 number'], ["1+e;", '20 number'], ["0x01;", '22 number'], ["0XCAFE;", '23 number'], ["0x12345678;", '24 number'], ["0x1234ABCD;", '25 number'], ["0x0001;", '26 number'], // strings ["\"foo\";", '1 string'], ["\'foo\';", '2 string'], ["\"x\";", '3 string'], ["\'\';", '4 string'], ["\"foo\\tbar\";", '5 string'], ["\"!@#$%^&*()_+{}[]\";", '6 string'], ["\"/*test*/\";", '7 string'], ["\"//test\";", '8 string'], ["\"\\\\\";", '9 string'], ["\"\\u0001\";", '10 string'], ["\"\\uFEFF\";", '11 string'], ["\"\\u10002\";", '12 string'], ["\"\\x55\";", '13 string'], ["\"\\x55a\";", '14 string'], ["\"a\\\\nb\";", '15 string'], ['";"', '16 string: semi in a string'], ['"a\\\nb";', '17 string: line terminator escape'], // literals ["null;", "null"], ["true;", "true"], ["false;", "false"], // regex ["/a/;", "1 regex"], ["/abc/;", "2 regex"], ["/abc[a-z]*def/g;", "3 regex"], ["/\\b/;", "4 regex"], ["/[a-zA-Z]/;", "5 regex"], // program tests (for as far as they havent been covered above) // regexp ["/foo(.*)/g;", "another regexp"], // arrays ["[];", "1 array"], ["[ ];", "2 array"], ["[1];", "3 array"], ["[1,2];", "4 array"], ["[1,2,,];", "5 array"], ["[1,2,3];", "6 array"], ["[1,2,3,,,];", "7 array"], // objects ["{};", "1 object"], ["({x:5});", "2 object"], ["({x:5,y:6});", "3 object"], ["({x:5,});", "4 object"], ["({if:5});", "5 object"], ["({ get x() {42;} });", "6 object"], ["({ set y(a) {1;} });", "7 object"], // member expression ["o.m;", "1 member expression"], ["o['m'];", "2 member expression"], ["o['n']['m'];", "3 member expression"], ["o.n.m;", "4 member expression"], ["o.if;", "5 member expression"], // call and invoke expressions ["f();", "1 call/invoke expression"], ["f(x);", "2 call/invoke expression"], ["f(x,y);", "3 call/invoke expression"], ["o.m();", "4 call/invoke expression"], ["o['m'];", "5 call/invoke expression"], ["o.m(x);", "6 call/invoke expression"], ["o['m'](x);", "7 call/invoke expression"], ["o.m(x,y);", "8 call/invoke expression"], ["o['m'](x,y);", "9 call/invoke expression"], ["f(x)(y);", "10 call/invoke expression"], ["f().x;", "11 call/invoke expression"], // eval ["eval('x');", "1 eval"], ["(eval)('x');", "2 eval"], ["(1,eval)('x');", "3 eval"], ["eval(x,y);", "4 eval"], // new expression ["new f();", "1 new expression"], ["new o;", "2 new expression"], ["new o.m;", "3 new expression"], ["new o.m(x);", "4 new expression"], ["new o.m(x,y);", "5 new expression"], // prefix/postfix ["++x;", "1 pre/postfix"], ["x++;", "2 pre/postfix"], ["--x;", "3 pre/postfix"], ["x--;", "4 pre/postfix"], ["x ++;", "5 pre/postfix"], ["x /* comment */ ++;", "6 pre/postfix"], ["++ /* comment */ x;", "7 pre/postfix"], // unary operators ["delete x;", "1 unary operator"], ["void x;", "2 unary operator"], ["+ x;", "3 unary operator"], ["-x;", "4 unary operator"], ["~x;", "5 unary operator"], ["!x;", "6 unary operator"], // meh ["new Date++;", "new date ++"], ["+x++;", " + x ++"], // expression expressions ["1 * 2;", "1 expression expressions"], ["1 / 2;", "2 expression expressions"], ["1 % 2;", "3 expression expressions"], ["1 + 2;", "4 expression expressions"], ["1 - 2;", "5 expression expressions"], ["1 << 2;", "6 expression expressions"], ["1 >>> 2;", "7 expression expressions"], ["1 >> 2;", "8 expression expressions"], ["1 * 2 + 3;", "9 expression expressions"], ["(1+2)*3;", "10 expression expressions"], ["1*(2+3);", "11 expression expressions"], ["xy;", "13 expression expressions"], ["x<=y;", "14 expression expressions"], ["x>=y;", "15 expression expressions"], ["x instanceof y;", "16 expression expressions"], ["x in y;", "17 expression expressions"], ["x&y;", "18 expression expressions"], ["x^y;", "19 expression expressions"], ["x|y;", "20 expression expressions"], ["x+y>>= y;", "1 assignment"], ["x <<= y;", "2 assignment"], ["x = y;", "3 assignment"], ["x += y;", "4 assignment"], ["x /= y;", "5 assignment"], // comma ["x, y;", "comma"], // block ["{};", "1 block"], ["{x;};", "2 block"], ["{x;y;};", "3 block"], // vars ["var x;", "1 var"], ["var x,y;", "2 var"], ["var x=1,y=2;", "3 var"], ["var x,y=2;", "4 var"], // empty [";", "1 empty"], ["\n;", "2 empty"], // expression statement ["x;", "1 expression statement"], ["5;", "2 expression statement"], ["1+2;", "3 expression statement"], // if ["if (c) x; else y;", "1 if statement"], ["if (c) x;", "2 if statement"], ["if (c) {} else {};", "3 if statement"], ["if (c1) if (c2) s1; else s2;", "4 if statement"], // while ["do s; while (e);", "1 while statement"], ["do { s; } while (e);", "2 while statement"], ["while (e) s;", "3 while statement"], ["while (e) { s; };", "4 while statement"], // for ["for (;;) ;", "1 for statement"], ["for (;c;x++) x;", "2 for statement"], ["for (i;i