Prompt to embedded mujs engine
This commit is contained in:
139
mujs/tools/test262
Executable file
139
mujs/tools/test262
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
[ "${1-}" ] && { to=2; >&$to printf "Error: %s\n" "$1"; } || to=1
|
||||
>&$to echo "Usage: ${0##*/} [OPTIONS] test-file | test-dir"
|
||||
>&$to echo "Run test-262 ES5 test file or directory (at the test262 dir)."
|
||||
>&$to echo " -s Print source code of failed tests."
|
||||
>&$to echo " -p Print every test name before running it"
|
||||
>&$to echo " -f Display full paths and full stack trace when possible"
|
||||
>&$to echo " -l file.js Load file.js after the harness and before the test (up to one)"
|
||||
>&$to echo " -m MUJS MUJS is [path/to/]mujs binary to test"
|
||||
>&$to echo " Default is $(dirname "$0")/../build/release/mujs or mujs at \$PATH"
|
||||
>&$to echo " -b Don't skip known bad (crashing/hanging) tests"
|
||||
>&$to echo " -B Run only known bad tests"
|
||||
exit $((to-1))
|
||||
}
|
||||
|
||||
KNOWN_BAD="
|
||||
--hang-with-sta.js:
|
||||
S15.1.3.2_A2.5_T1.js
|
||||
S15.1.3.1_A2.5_T1.js
|
||||
|
||||
--Hang-(or-taking-more-than-few-seconds):
|
||||
15.4.4.18-3-14.js
|
||||
15.4.4.20-3-14.js
|
||||
S15.4.4.10_A3_T2.js
|
||||
S15.4.4.10_A3_T1.js
|
||||
15.4.4.19-3-29.js
|
||||
15.4.4.19-3-28.js
|
||||
15.4.4.19-3-8.js
|
||||
15.4.4.19-3-14.js
|
||||
S15.4.4.8_A3_T3.js
|
||||
15.4.4.22-3-9.js
|
||||
15.4.4.22-3-7.js
|
||||
15.4.4.22-3-25.js
|
||||
15.4.4.22-3-14.js
|
||||
15.4.4.21-3-14.js
|
||||
15.4.4.15-3-28.js
|
||||
15.4.4.15-3-14.js
|
||||
15.4.4.15-3-7.js
|
||||
15.4.4.15-3-25.js
|
||||
15.4.4.15-3-9.js
|
||||
"
|
||||
|
||||
SKIP_KNOWN=yes # "yes": skip bad "no": don't skip "neg": run only bad
|
||||
PRINT_ALL=
|
||||
EXTRA_ARGS=
|
||||
mujs= lopt=
|
||||
|
||||
while getopts bBfhl:ps o; do
|
||||
case $o in
|
||||
h) usage ;;
|
||||
b) SKIP_KNOWN=no ;;
|
||||
B) SKIP_KNOWN=neg ;;
|
||||
p) PRINT_ALL=yes ;;
|
||||
s) EXTRA_ARGS="$EXTRA_ARGS -s" ;;
|
||||
f) EXTRA_ARGS="$EXTRA_ARGS -f" ;;
|
||||
l) [ "$OPTARG" ] && lopt=$OPTARG || usage "empty file for -l" ;;
|
||||
m) mujs=$OPTARG;;
|
||||
*) usage "unknown option -$o" ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
[ $# = 1 ] || usage "expecting one file/dir"
|
||||
|
||||
BAD=
|
||||
if [ "$SKIP_KNOWN" != no ]; then
|
||||
for b in $KNOWN_BAD; do
|
||||
BAD="$BAD $b "
|
||||
done
|
||||
fi
|
||||
|
||||
find_root() {
|
||||
ROOT=$1
|
||||
n=0
|
||||
while ! [ -e "$ROOT"/test/harness/sta.js ]; do
|
||||
ROOT=$ROOT/..
|
||||
n=$((n+1))
|
||||
[ $n -lt 10 ] || usage "can't find test-suite root"
|
||||
done
|
||||
}
|
||||
|
||||
if [ -d "$1" ]; then
|
||||
find_root "$1"
|
||||
|
||||
if [ "$ROOT" = "$1" ]; then
|
||||
FILES_CMD='find "$1/test/suite" -name "*.js" | sort -V'
|
||||
else
|
||||
FILES_CMD='find "$1" -name "*.js" | sort -V'
|
||||
fi
|
||||
else
|
||||
find_root "$(dirname "$1")"
|
||||
FILES_CMD='printf "%s\n" "$1"'
|
||||
fi
|
||||
|
||||
if ! [ "$mujs" ]; then
|
||||
# try to use a recently built mujs rather than a global one
|
||||
mujs=$(dirname "$0")/../build/release/mujs
|
||||
[ -e "$mujs" ] || mujs=mujs
|
||||
fi
|
||||
jsharness=$(dirname "$0")/test262-harness.js
|
||||
|
||||
total=0
|
||||
skipped=0
|
||||
failed=0
|
||||
|
||||
eval "$FILES_CMD" | (
|
||||
while IFS= read -r f && [ "$f" ]; do
|
||||
total=$((total+1))
|
||||
base=${f##*/}
|
||||
|
||||
case $BAD in *" $base "*) bad=yes;; *) bad=no;; esac
|
||||
|
||||
case $bad-$SKIP_KNOWN in
|
||||
yes-yes)
|
||||
skipped=$((skipped+1))
|
||||
printf "[Skipping: $base]\n\n"
|
||||
;;
|
||||
no-neg) # not known bad and running only bad - don't print anything
|
||||
skipped=$((skipped+1))
|
||||
;;
|
||||
*)
|
||||
[ "$PRINT_ALL" ] && echo "Testing: $f"
|
||||
if ! "$mujs" -- "$jsharness" $EXTRA_ARGS ${lopt:+-l "$lopt"} "$ROOT" "$f" 2>&1; then
|
||||
failed=$((failed+1))
|
||||
echo
|
||||
fi
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $total -gt 1 ]; then
|
||||
printf "Total: $total\n"
|
||||
printf "Pass: %${#total}s\n" $((total - skipped - failed))
|
||||
printf "Skip: %${#total}s\n" $skipped
|
||||
printf "Fail: %${#total}s\n" $failed
|
||||
fi
|
||||
|
||||
[ "$failed" = 0 ]
|
||||
)
|
||||
152
mujs/tools/test262-harness.js
Normal file
152
mujs/tools/test262-harness.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Runs one test file from the ES5 test suite test-262
|
||||
* Usage: mujs <this-file> [-s ] [-f] [-l file1.js -l ...] suit-root test-file
|
||||
* -s: print test source on failure
|
||||
* -f: print full paths/stacktraces if possible
|
||||
* -l: load a js file after the harness and before the test (to override things)
|
||||
*
|
||||
* If there are errors, print them and exits with code 1, else exit code is 0.
|
||||
*
|
||||
* The test suite is at: https://github.com/tc39/test262.git
|
||||
* The ES5 suite is at branch "es5-tests"
|
||||
*
|
||||
* - The test suite throws on any error, possibly with info at ex.message .
|
||||
* - Some tests make irreversible changes to global attrubutes, therefore it's
|
||||
* required to run each test file in a new mujs instance.
|
||||
*/
|
||||
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
// clean the global environment
|
||||
var mujs = {};
|
||||
|
||||
["gc", "load", "compile", "print", "write", "read", "readline", "quit", "scriptArgs"]
|
||||
.forEach(function(a) {
|
||||
mujs[a] = global[a];
|
||||
delete global[a];
|
||||
});
|
||||
|
||||
// restore the original Error.toString behavior - it's being tested too
|
||||
Error.prototype.toString = function() {
|
||||
return this.name + ': ' + this.message;
|
||||
}
|
||||
|
||||
function die_usage(str) {
|
||||
if (str)
|
||||
mujs.print(str);
|
||||
mujs.print("Usage: mujs <this-file> [-f] [-l file1.js -l ...] suit-root test-file");
|
||||
mujs.quit(1);
|
||||
}
|
||||
|
||||
// our file loader
|
||||
function load(str, as_filename) {
|
||||
try {
|
||||
var runtime_err = false;
|
||||
var compiled = mujs.compile(str, as_filename);
|
||||
runtime_err = true;
|
||||
compiled();
|
||||
return false;
|
||||
} catch (e) {
|
||||
return {err: e, runtime: runtime_err};
|
||||
}
|
||||
}
|
||||
|
||||
var args = mujs.scriptArgs;
|
||||
var full_mode = false;
|
||||
var print_src = false;
|
||||
var overrides = [];
|
||||
while ((""+args[0])[0] == "-") {
|
||||
switch (args[0]) {
|
||||
case "-f": full_mode = true;
|
||||
break;
|
||||
case "-s": print_src = true;
|
||||
break;
|
||||
case "-l": args.shift();
|
||||
overrides.push(args[0]);
|
||||
break;
|
||||
default: die_usage("Unknown option " + args[0]);
|
||||
}
|
||||
args.shift();
|
||||
}
|
||||
if (args.length != 2)
|
||||
die_usage("Exactly 2 paths are expected");
|
||||
var root_path = args[0];
|
||||
var test_path = args[1];
|
||||
|
||||
// load suite utils
|
||||
["sta.js", "testBuiltInObject.js", "testIntl.js"]
|
||||
.forEach(function(u) {
|
||||
var path = root_path + "/test/harness/" + u;
|
||||
var as_file = full_mode ? path : "test/harness/" + u;
|
||||
var err = load(mujs.read(path), as_file);
|
||||
if (err) throw (err.err);
|
||||
});
|
||||
|
||||
// load user overrides (e.g. reduced getPrecision), with a global mujs
|
||||
if (overrides.length) {
|
||||
global.mujs = mujs
|
||||
overrides.forEach(function(f) {
|
||||
var err = load(mujs.read(f), f);
|
||||
if (err) throw (err.err);
|
||||
});
|
||||
delete global.mujs;
|
||||
}
|
||||
|
||||
// the actual test
|
||||
var source = mujs.read(test_path);
|
||||
var negative = !!source.match(/@negative/);
|
||||
if (negative)
|
||||
var neg_str = (source.match(/@negative (.*)/) || [])[1];
|
||||
var as_file = test_path;
|
||||
if (!full_mode) {
|
||||
as_file = test_path.replace(/\\/g, "/");
|
||||
var sub = as_file.indexOf("/suite/");
|
||||
if (sub >= 0)
|
||||
as_file = "test" + as_file.substring(sub);
|
||||
}
|
||||
|
||||
var result = load(mujs.read(test_path), as_file);
|
||||
if (!!result == negative) {
|
||||
// The docs don't really help about matching str, but this covers all cases
|
||||
if (neg_str)
|
||||
var err_for_match = /NotEarlyError/.test(neg_str) ? result.err.message : result.err.name;
|
||||
if (!negative || !neg_str || RegExp(neg_str).exec(err_for_match))
|
||||
mujs.quit(0);
|
||||
}
|
||||
|
||||
// failed
|
||||
// FIXME: @description can span lines. E.g. test/suite/bestPractice/Sbp_A3_T2.js
|
||||
var desc = source.match(/@description (.*)/);
|
||||
var info = "[File] " + as_file +
|
||||
(desc ? "\n[Desc] " + desc[1] : "") +
|
||||
"\n";
|
||||
|
||||
if (result) {
|
||||
var err = result.err;
|
||||
var msg = !neg_str ? err : "[Mismatch @negative " + neg_str + "]" + "\n " + err;
|
||||
|
||||
info += (result.runtime ? "[run] " : "[load] ") + msg;
|
||||
if (err && err.stackTrace && (result.runtime || full_mode)) {
|
||||
if (full_mode) {
|
||||
info += err.stackTrace;
|
||||
} else {
|
||||
// trim the internal loader from the trace
|
||||
var internal = err.stackTrace.indexOf("\n" + load("mujs_blahblah()").err.stackTrace.trim().split("\n")[1]);
|
||||
if (internal >= 0)
|
||||
info += err.stackTrace.substring(0, internal);
|
||||
else
|
||||
info += err.stackTrace;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info += "[run] [Error expected but none thrown]";
|
||||
}
|
||||
|
||||
if (print_src)
|
||||
info += "\n[Source]\n" + source;
|
||||
|
||||
mujs.print(info);
|
||||
mujs.quit(1);
|
||||
|
||||
})(this)
|
||||
Reference in New Issue
Block a user