aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2018-03-04 04:50:00 +0800
committerGitHub <noreply@github.com>2018-03-04 04:50:00 +0800
commit798fc21530cf15049767af1e38aeae04f81ec5e2 (patch)
tree421d8ba53c6fc5c79ed090e329d90f4398068d6c
parenta75a046abbc1f93fbb2235c99a1fc1d543faf9e9 (diff)
downloadtracifyjs-798fc21530cf15049767af1e38aeae04f81ec5e2.tar.gz
tracifyjs-798fc21530cf15049767af1e38aeae04f81ec5e2.zip
improve `test/run-test.js` performance (#2971)
- allow reuse of contextified sandbox - minimise bottleneck from `vm.createContext()`
-rwxr-xr-xtest/run-tests.js6
-rw-r--r--test/sandbox.js48
2 files changed, 36 insertions, 18 deletions
diff --git a/test/run-tests.js b/test/run-tests.js
index d3238370..dcc7cc1e 100755
--- a/test/run-tests.js
+++ b/test/run-tests.js
@@ -182,7 +182,7 @@ function run_compress_tests() {
}
if (test.expect_stdout
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
- var stdout = sandbox.run_code(input_code);
+ var stdout = sandbox.run_code(input_code, true);
if (test.expect_stdout === true) {
test.expect_stdout = stdout;
}
@@ -196,7 +196,7 @@ function run_compress_tests() {
});
return false;
}
- stdout = sandbox.run_code(output);
+ stdout = sandbox.run_code(output, true);
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
input: input_formatted,
@@ -378,7 +378,7 @@ function reminify(orig_options, input_code, input_formatted, expect_stdout) {
});
return false;
} else {
- var stdout = sandbox.run_code(result.code);
+ var stdout = sandbox.run_code(result.code, true);
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
stdout = expect_stdout;
}
diff --git a/test/sandbox.js b/test/sandbox.js
index bef63df0..13cfe088 100644
--- a/test/sandbox.js
+++ b/test/sandbox.js
@@ -1,6 +1,27 @@
var semver = require("semver");
var vm = require("vm");
+function createContext() {
+ var context = Object.create(null);
+ Object.defineProperty(context, "console", {
+ value: function() {
+ var con = Object.create(null);
+ Object.defineProperty(con, "log", {
+ value: function(msg) {
+ if (arguments.length == 1 && typeof msg == "string") {
+ return console.log("%s", msg);
+ }
+ return console.log.apply(console, [].map.call(arguments, function(arg) {
+ return safe_log(arg, 3);
+ }));
+ }
+ });
+ return con;
+ }()
+ });
+ return vm.createContext(context);
+}
+
function safe_log(arg, level) {
if (arg) switch (typeof arg) {
case "function":
@@ -9,7 +30,8 @@ function safe_log(arg, level) {
if (/Error$/.test(arg.name)) return arg.toString();
arg.constructor.toString();
if (level--) for (var key in arg) {
- if (!Object.getOwnPropertyDescriptor(arg, key).get) {
+ var desc = Object.getOwnPropertyDescriptor(arg, key);
+ if (!desc || !desc.get) {
arg[key] = safe_log(arg[key], level);
}
}
@@ -21,6 +43,7 @@ function strip_func_ids(text) {
return text.toString().replace(/F[0-9]{6}N/g, "<F<>N>");
}
+var context;
var FUNC_TOSTRING = [
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String].forEach(function(f) {",
" f.toString = Function.prototype.toString;",
@@ -43,35 +66,30 @@ var FUNC_TOSTRING = [
" };",
"}();",
]).join("\n");
-exports.run_code = function(code) {
+exports.run_code = function(code, reuse) {
var stdout = "";
var original_write = process.stdout.write;
process.stdout.write = function(chunk) {
stdout += chunk;
};
try {
- vm.runInNewContext([
+ if (!reuse || !context) context = createContext();
+ vm.runInContext([
FUNC_TOSTRING,
"!function() {",
code,
"}();",
- ].join("\n"), {
- console: {
- log: function(msg) {
- if (arguments.length == 1 && typeof msg == "string") {
- return console.log("%s", msg);
- }
- return console.log.apply(console, [].map.call(arguments, function(arg) {
- return safe_log(arg, 3);
- }));
- }
- }
- }, { timeout: 5000 });
+ ].join("\n"), context, { timeout: 5000 });
return stdout;
} catch (ex) {
return ex;
} finally {
process.stdout.write = original_write;
+ if (!reuse || /prototype/.test(code)) {
+ context = null;
+ } else for (var key in context) {
+ delete context[key];
+ }
}
};
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {