1 | (function(exports) {
|
2 | var tests = [];
|
3 | var acorn = typeof require == "undefined" ? window.acorn : require("../acorn.js");
|
4 |
|
5 | exports.test = function(code, ast, options) {
|
6 | tests.push({code: code, ast: ast, options: options});
|
7 | };
|
8 | exports.testFail = function(code, message, options) {
|
9 | tests.push({code: code, error: message, options: options});
|
10 | };
|
11 | exports.testAssert = function(code, assert, options) {
|
12 | tests.push({code: code, assert: assert, options: options});
|
13 | };
|
14 |
|
15 | exports.runTests = function(callback) {
|
16 | var opts = {locations: true};
|
17 | for (var i = 0; i < tests.length; ++i) {
|
18 | var test = tests[i];
|
19 | try {
|
20 | var ast = acorn.parse(test.code, test.options || opts);
|
21 | if (test.error) callback("fail", test.code,
|
22 | "Expected error message: " + test.error + "\nBut parsing succeeded.");
|
23 | else if (test.assert) {
|
24 | var error = test.assert(ast);
|
25 | if (error) callback("fail", test.code,
|
26 | "\n Assertion failed:\n " + error);
|
27 | else callback("ok", test.code);
|
28 | } else {
|
29 | var mis = misMatch(test.ast, ast);
|
30 | if (!mis) callback("ok", test.code);
|
31 | else callback("fail", test.code, mis);
|
32 | }
|
33 | } catch(e) {
|
34 | if (test.error && e instanceof SyntaxError) {
|
35 | if (e.message == test.error) callback("ok", test.code);
|
36 | else callback("fail", test.code,
|
37 | "Expected error message: " + test.error + "\nGot error message: " + e.message);
|
38 | } else {
|
39 | callback("error", test.code, e.message || e.toString());
|
40 | }
|
41 | }
|
42 | }
|
43 | };
|
44 |
|
45 | function ppJSON(v) { return JSON.stringify(v, null, 2); }
|
46 | function addPath(str, pt) {
|
47 | if (str.charAt(str.length-1) == ")")
|
48 | return str.slice(0, str.length-1) + "/" + pt + ")";
|
49 | return str + " (" + pt + ")";
|
50 | }
|
51 |
|
52 | function misMatch(exp, act) {
|
53 | if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
|
54 | if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act);
|
55 | } else if (exp.splice) {
|
56 | if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act);
|
57 | if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length;
|
58 | for (var i = 0; i < act.length; ++i) {
|
59 | var mis = misMatch(exp[i], act[i]);
|
60 | if (mis) return addPath(mis, i);
|
61 | }
|
62 | } else {
|
63 | for (var prop in exp) {
|
64 | var mis = misMatch(exp[prop], act[prop]);
|
65 | if (mis) return addPath(mis, prop);
|
66 | }
|
67 | }
|
68 | }
|
69 |
|
70 | function mangle(ast) {
|
71 | if (typeof ast != "object" || !ast) return;
|
72 | if (ast.slice) {
|
73 | for (var i = 0; i < ast.length; ++i) mangle(ast[i]);
|
74 | } else {
|
75 | var loc = ast.start && ast.end && {start: ast.start, end: ast.end};
|
76 | if (loc) { delete ast.start; delete ast.end; }
|
77 | for (var name in ast) if (ast.hasOwnProperty(name)) mangle(ast[name]);
|
78 | if (loc) ast.loc = loc;
|
79 | }
|
80 | }
|
81 |
|
82 | exports.printTests = function() {
|
83 | var out = "";
|
84 | for (var i = 0; i < tests.length; ++i) {
|
85 | if (tests[i].error) continue;
|
86 | mangle(tests[i].ast);
|
87 | out += "test(" + JSON.stringify(tests[i].code) + ", " + JSON.stringify(tests[i].ast, null, 2) + ");\n\n";
|
88 | }
|
89 | document.body.innerHTML = "";
|
90 | document.body.appendChild(document.createElement("pre")).appendChild(document.createTextNode(out));
|
91 | };
|
92 | })(typeof exports == "undefined" ? window : exports);
|