restructure testing infrastructure to be more modular
This commit is contained in:
@@ -101,6 +101,13 @@ pp.parseMaybeAssign = function(noIn, refShorthandDefaultPos, afterLeftParse) {
|
||||
node.left = this.type === tt.eq ? this.toAssignable(left) : left
|
||||
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
|
||||
this.checkLVal(left)
|
||||
if (left.parenthesizedExpression) {
|
||||
if (left.type === "ObjectPattern") {
|
||||
this.raise(left.start, "You're trying to assign to a parenthesized expression, instead of `({ foo }) = {}` use `({ foo } = {})`");
|
||||
} else {
|
||||
this.raise(left.start, "Parenthesized left hand expressions are illegal");
|
||||
}
|
||||
}
|
||||
this.next()
|
||||
node.right = this.parseMaybeAssign(noIn)
|
||||
return this.finishNode(node, "AssignmentExpression")
|
||||
|
||||
@@ -9,14 +9,6 @@ const pp = Parser.prototype
|
||||
// if possible.
|
||||
|
||||
pp.toAssignable = function(node, isBinding) {
|
||||
if (node.parenthesizedExpression) {
|
||||
if (node.type === "ObjectExpression") {
|
||||
this.raise(node.start, "You're trying to assign to a parenthesized expression, instead of `({ foo }) = {}` use `({ foo } = {})`");
|
||||
} else {
|
||||
this.raise(node.start, "Parenthesized left hand expressions are illegal");
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.ecmaVersion >= 6 && node) {
|
||||
switch (node.type) {
|
||||
case "Identifier":
|
||||
|
||||
@@ -57,6 +57,10 @@ pp.updateContext = function(prevType) {
|
||||
// Token-specific context update code
|
||||
|
||||
tt.parenR.updateContext = tt.braceR.updateContext = function() {
|
||||
if (this.context.length == 1) {
|
||||
this.exprAllowed = true
|
||||
return
|
||||
}
|
||||
let out = this.context.pop()
|
||||
if (out === types.b_stat && this.curContext() === types.f_expr) {
|
||||
this.context.pop()
|
||||
@@ -64,7 +68,7 @@ tt.parenR.updateContext = tt.braceR.updateContext = function() {
|
||||
} else if (out === types.b_tmpl) {
|
||||
this.exprAllowed = true
|
||||
} else {
|
||||
this.exprAllowed = !(out && out.isExpr)
|
||||
this.exprAllowed = !out.isExpr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
(function(exports) {
|
||||
var tests = [];
|
||||
|
||||
exports.test = function(code, ast, options) {
|
||||
tests.push({code: code, ast: ast, options: options});
|
||||
};
|
||||
exports.testFail = function(code, message, options) {
|
||||
tests.push({code: code, error: message, options: options});
|
||||
};
|
||||
exports.testAssert = function(code, assert, options) {
|
||||
tests.push({code: code, assert: assert, options: options});
|
||||
};
|
||||
|
||||
exports.runTests = function(config, callback) {
|
||||
var parse = config.parse;
|
||||
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
var test = tests[i];
|
||||
if (config.filter && !config.filter(test)) continue;
|
||||
var testOpts = test.options || {locations: true};
|
||||
var expected = {};
|
||||
if (expected.onComment = testOpts.onComment)
|
||||
testOpts.onComment = []
|
||||
if (expected.onToken = testOpts.onToken)
|
||||
testOpts.onToken = [];
|
||||
|
||||
try {
|
||||
var ast = parse(test.code, testOpts);
|
||||
} catch(e) {
|
||||
if (!(e instanceof SyntaxError)) { console.log(e.stack); throw e; }
|
||||
if (test.error) {
|
||||
if (e.message == test.error) callback("ok", test.code);
|
||||
else callback("fail", test.code,
|
||||
"Expected error message: " + test.error + "\nGot error message: " + e.message);
|
||||
} else {
|
||||
callback("error", test.code, e.message || e.toString());
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (test.error) {
|
||||
if (config.loose) callback("ok", test.code);
|
||||
else callback("fail", test.code, "Expected error message: " + test.error + "\nBut parsing succeeded.");
|
||||
} else if (test.assert) {
|
||||
var error = test.assert(ast);
|
||||
if (error) callback("fail", test.code, "\n Assertion failed:\n " + error);
|
||||
else callback("ok", test.code);
|
||||
} else {
|
||||
var mis = misMatch(test.ast, ast);
|
||||
for (var name in expected) {
|
||||
if (mis) break;
|
||||
if (expected[name]) {
|
||||
mis = misMatch(expected[name], testOpts[name]);
|
||||
testOpts[name] = expected[name];
|
||||
}
|
||||
}
|
||||
if (mis) callback("fail", test.code, mis);
|
||||
else callback("ok", test.code);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function ppJSON(v) { return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); }
|
||||
function addPath(str, pt) {
|
||||
if (str.charAt(str.length-1) == ")")
|
||||
return str.slice(0, str.length-1) + "/" + pt + ")";
|
||||
return str + " (" + pt + ")";
|
||||
}
|
||||
|
||||
var misMatch = exports.misMatch = function(exp, act) {
|
||||
if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
|
||||
if (exp !== act && typeof exp != "function")
|
||||
return ppJSON(exp) + " !== " + ppJSON(act);
|
||||
} else if (exp instanceof RegExp || act instanceof RegExp) {
|
||||
var left = ppJSON(exp), right = ppJSON(act);
|
||||
if (left !== right) return left + " !== " + right;
|
||||
} else if (exp.splice) {
|
||||
if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act);
|
||||
if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length;
|
||||
for (var i = 0; i < act.length; ++i) {
|
||||
var mis = misMatch(exp[i], act[i]);
|
||||
if (mis) return addPath(mis, i);
|
||||
}
|
||||
} else {
|
||||
for (var prop in exp) {
|
||||
var mis = misMatch(exp[prop], act[prop]);
|
||||
if (mis) return addPath(mis, prop);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function mangle(ast) {
|
||||
if (typeof ast != "object" || !ast) return;
|
||||
if (ast.slice) {
|
||||
for (var i = 0; i < ast.length; ++i) mangle(ast[i]);
|
||||
} else {
|
||||
var loc = ast.start && ast.end && {start: ast.start, end: ast.end};
|
||||
if (loc) { delete ast.start; delete ast.end; }
|
||||
for (var name in ast) if (ast.hasOwnProperty(name)) mangle(ast[name]);
|
||||
if (loc) ast.loc = loc;
|
||||
}
|
||||
}
|
||||
|
||||
exports.printTests = function() {
|
||||
var out = "";
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
if (tests[i].error) continue;
|
||||
mangle(tests[i].ast);
|
||||
out += "test(" + JSON.stringify(tests[i].code) + ", " + JSON.stringify(tests[i].ast, null, 2) + ");\n\n";
|
||||
}
|
||||
document.body.innerHTML = "";
|
||||
document.body.appendChild(document.createElement("pre")).appendChild(document.createTextNode(out));
|
||||
};
|
||||
})(typeof exports == "undefined" ? window : exports);
|
||||
@@ -1,104 +0,0 @@
|
||||
(function() {
|
||||
var driver, acorn;
|
||||
|
||||
if (typeof require !== "undefined") {
|
||||
driver = require("./driver.js");
|
||||
require("./tests.js");
|
||||
require("./tests-harmony.js");
|
||||
require("./tests-flow.js");
|
||||
require("./tests-jsx.js");
|
||||
require("./tests-babel.js");
|
||||
require("babel/register")
|
||||
acorn = require("../src")
|
||||
} else {
|
||||
driver = window;
|
||||
acorn = window.acorn;
|
||||
}
|
||||
|
||||
var htmlLog = typeof document === "object" && document.getElementById('log');
|
||||
var htmlGroup = htmlLog;
|
||||
|
||||
function group(name) {
|
||||
if (htmlGroup) {
|
||||
var parentGroup = htmlGroup;
|
||||
htmlGroup = document.createElement("ul");
|
||||
var item = document.createElement("li");
|
||||
item.textContent = name;
|
||||
item.appendChild(htmlGroup);
|
||||
parentGroup.appendChild(item);
|
||||
}
|
||||
if (typeof console === "object" && console.group) {
|
||||
console.group(name);
|
||||
}
|
||||
}
|
||||
|
||||
function groupEnd() {
|
||||
if (htmlGroup) {
|
||||
htmlGroup = htmlGroup.parentElement.parentElement;
|
||||
}
|
||||
if (typeof console === "object" && console.groupEnd) {
|
||||
console.groupEnd(name);
|
||||
}
|
||||
}
|
||||
|
||||
function log(title, message) {
|
||||
if (htmlGroup) {
|
||||
var elem = document.createElement("li");
|
||||
elem.innerHTML = "<b>" + title + "</b> " + message;
|
||||
htmlGroup.appendChild(elem);
|
||||
}
|
||||
if (typeof console === "object") console.log(title, message);
|
||||
}
|
||||
|
||||
var stats, modes = {
|
||||
Normal: {
|
||||
config: {
|
||||
parse: acorn.parse
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function report(state, code, message) {
|
||||
if (state != "ok") {++stats.failed; log(code, message);}
|
||||
++stats.testsRun;
|
||||
}
|
||||
|
||||
group("Errors");
|
||||
|
||||
for (var name in modes) {
|
||||
group(name);
|
||||
var mode = modes[name];
|
||||
stats = mode.stats = {testsRun: 0, failed: 0};
|
||||
var t0 = +new Date;
|
||||
driver.runTests(mode.config, report);
|
||||
mode.stats.duration = +new Date - t0;
|
||||
groupEnd();
|
||||
}
|
||||
|
||||
groupEnd();
|
||||
|
||||
function outputStats(name, stats) {
|
||||
log(name + ":", stats.testsRun + " tests run in " + stats.duration + "ms; " +
|
||||
(stats.failed ? stats.failed + " failures." : "all passed."));
|
||||
}
|
||||
|
||||
var total = {testsRun: 0, failed: 0, duration: 0};
|
||||
|
||||
group("Stats");
|
||||
|
||||
for (var name in modes) {
|
||||
var stats = modes[name].stats;
|
||||
outputStats(name + " parser", stats);
|
||||
for (var key in stats) total[key] += stats[key];
|
||||
}
|
||||
|
||||
outputStats("Total", total);
|
||||
|
||||
groupEnd();
|
||||
|
||||
if (total.failed && typeof process === "object") {
|
||||
process.stdout.write("", function() {
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
28934
src/acorn/test/tests.js
28934
src/acorn/test/tests.js
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,8 @@ import fs from "fs";
|
||||
var cache = {};
|
||||
|
||||
function exists(filename) {
|
||||
if (!fs.existsSync) return false;
|
||||
|
||||
var cached = cache[filename];
|
||||
if (cached != null) return cached;
|
||||
return cache[filename] = fs.existsSync(filename);
|
||||
|
||||
Reference in New Issue
Block a user