aboutsummaryrefslogtreecommitdiff
path: root/test/mozilla-ast.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-05-15 02:37:53 +0800
committerGitHub <noreply@github.com>2017-05-15 02:37:53 +0800
commite005099fb1b9a1b87ac50ba8223255e52cec452d (patch)
tree5edef6298d3c79fc5352476c2fbfc236b626a9ee /test/mozilla-ast.js
parent504a436e9daac89f5226280e01ae2818fe4e8436 (diff)
downloadtracifyjs-e005099fb1b9a1b87ac50ba8223255e52cec452d.tar.gz
tracifyjs-e005099fb1b9a1b87ac50ba8223255e52cec452d.zip
fix & improve coverage of `estree` (#1935)
- fix `estree` conversion of getter/setter - fix non-directive literal in `to_mozilla_ast()` - revamp `test/mozilla-ast.js` - reuse `test/ufuzz.js` for code generation - use `acorn.parse()` for creating `estree` - extend `test/ufuzz.js` for `acorn` workaround - catch variable redefinition - non-trivial literal as directive - adjust options for tolerance Miscellaneous - optional semi-colon when parsing directives fixes #1914 closes #1915
Diffstat (limited to 'test/mozilla-ast.js')
-rw-r--r--test/mozilla-ast.js160
1 files changed, 65 insertions, 95 deletions
diff --git a/test/mozilla-ast.js b/test/mozilla-ast.js
index 544ce8bc..b8026de5 100644
--- a/test/mozilla-ast.js
+++ b/test/mozilla-ast.js
@@ -1,103 +1,73 @@
// Testing UglifyJS <-> SpiderMonkey AST conversion
-// through generative testing.
-
-var UglifyJS = require("./node"),
- escodegen = require("escodegen"),
- esfuzz = require("esfuzz"),
- estraverse = require("estraverse"),
- prefix = "\r ";
-
-// Normalizes input AST for UglifyJS in order to get correct comparison.
-
-function normalizeInput(ast) {
- return estraverse.replace(ast, {
- enter: function(node, parent) {
- switch (node.type) {
- // Internally mark all the properties with semi-standard type "Property".
- case "ObjectExpression":
- node.properties.forEach(function (property) {
- property.type = "Property";
- });
- break;
-
- // Since UglifyJS doesn"t recognize different types of property keys,
- // decision on SpiderMonkey node type is based on check whether key
- // can be valid identifier or not - so we do in input AST.
- case "Property":
- var key = node.key;
- if (key.type === "Literal" && typeof key.value === "string" && UglifyJS.is_identifier(key.value)) {
- node.key = {
- type: "Identifier",
- name: key.value
- };
- } else if (key.type === "Identifier" && !UglifyJS.is_identifier(key.name)) {
- node.key = {
- type: "Literal",
- value: key.name
- };
- }
- break;
-
- // UglifyJS internally flattens all the expression sequences - either
- // to one element (if sequence contains only one element) or flat list.
- case "SequenceExpression":
- node.expressions = node.expressions.reduce(function flatten(list, expr) {
- return list.concat(expr.type === "SequenceExpression" ? expr.expressions.reduce(flatten, []) : [expr]);
- }, []);
- if (node.expressions.length === 1) {
- return node.expressions[0];
- }
- break;
- }
+"use strict";
+
+var acorn = require("acorn");
+var ufuzz = require("./ufuzz");
+var UglifyJS = require("..");
+
+function try_beautify(code) {
+ var beautified = UglifyJS.minify(code, {
+ compress: false,
+ mangle: false,
+ output: {
+ beautify: true,
+ bracketize: true
}
});
+ if (beautified.error) {
+ console.log("// !!! beautify failed !!!");
+ console.log(beautified.error.stack);
+ console.log(code);
+ } else {
+ console.log("// (beautified)");
+ console.log(beautified.code);
+ }
}
-module.exports = function(options) {
- console.log("--- UglifyJS <-> Mozilla AST conversion");
-
- for (var counter = 0; counter < options.iterations; counter++) {
- process.stdout.write(prefix + counter + "/" + options.iterations);
-
- var ast1 = normalizeInput(esfuzz.generate({
- maxDepth: options.maxDepth
- }));
-
- var ast2 =
- UglifyJS
- .AST_Node
- .from_mozilla_ast(ast1)
- .to_mozilla_ast();
-
- var astPair = [
- {name: 'expected', value: ast1},
- {name: 'actual', value: ast2}
- ];
-
- var jsPair = astPair.map(function(item) {
- return {
- name: item.name,
- value: escodegen.generate(item.value)
- }
- });
-
- if (jsPair[0].value !== jsPair[1].value) {
- var fs = require("fs");
- var acorn = require("acorn");
-
- fs.existsSync("tmp") || fs.mkdirSync("tmp");
-
- jsPair.forEach(function (item) {
- var fileName = "tmp/dump_" + item.name;
- var ast = acorn.parse(item.value);
- fs.writeFileSync(fileName + ".js", item.value);
- fs.writeFileSync(fileName + ".json", JSON.stringify(ast, null, 2));
- });
-
- process.stdout.write("\n");
- throw new Error("Got different outputs, check out tmp/dump_*.{js,json} for codes and ASTs.");
+function test(original, estree, description) {
+ var transformed = UglifyJS.minify(UglifyJS.AST_Node.from_mozilla_ast(estree), {
+ compress: false,
+ mangle: false
+ });
+ if (transformed.error || original !== transformed.code) {
+ console.log("//=============================================================");
+ console.log("// !!!!!! Failed... round", round);
+ console.log("// original code");
+ try_beautify(original);
+ console.log();
+ console.log();
+ console.log("//-------------------------------------------------------------");
+ console.log("//", description);
+ if (transformed.error) {
+ console.log(transformed.error.stack);
+ } else {
+ try_beautify(transformed.code);
}
+ console.log("!!!!!! Failed... round", round);
+ process.exit(1);
}
+}
- process.stdout.write(prefix + "Probability of error is less than " + (100 / options.iterations) + "%, stopping.\n");
-};
+var num_iterations = ufuzz.num_iterations;
+for (var round = 1; round <= num_iterations; round++) {
+ process.stdout.write(round + " of " + num_iterations + "\r");
+ var code = ufuzz.createTopLevelCode();
+ var uglified = UglifyJS.minify(code, {
+ compress: false,
+ mangle: false,
+ output: {
+ ast: true
+ }
+ });
+ test(uglified.code, uglified.ast.to_mozilla_ast(), "AST_Node.to_mozilla_ast()");
+ try {
+ test(uglified.code, acorn.parse(code), "acorn.parse()");
+ } catch (e) {
+ console.log("//=============================================================");
+ console.log("// acorn parser failed... round", round);
+ console.log(e);
+ console.log("// original code");
+ console.log(code);
+ }
+}
+console.log();