UNPKG

3.46 kBJavaScriptView Raw
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);