Prompt to embedded mujs engine

This commit is contained in:
kamkow1
2025-03-09 15:22:48 +01:00
parent a3c8f8d9f0
commit 93f329328a
58 changed files with 22871 additions and 19 deletions

139
mujs/tools/test262 Executable file
View 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 ]
)

View 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)