fix: make check-stubs distinguish test failures from tooling errors

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Lucas Winther
2026-10-28 23:36:25 +01:00
co-authored by Claude Opus 5.5
parent e150b7fefb
commit 5be3cebe71
+33 -6
View File
@@ -1,24 +1,51 @@
#!/usr/bin/env bash
# Usage: scripts/check-stubs.sh <js|scala|fsharp>
# Runs each module M01..M11 that has tests against the stubs in src/. Fails if any module's tests pass.
# Runs each module M01..M11 that has tests against the stubs in src/. Fails if any module's tests pass,
# and also fails (exit 2) on tooling/build errors, so a broken toolchain can never look like "stubs fail".
set -uo pipefail
track="${1:?usage: check-stubs.sh <js|scala|fsharp>}"
repo="$(cd "$(dirname "$0")/.." && pwd)"
dir="$repo/$track"
export PATH="$HOME/.dotnet:$HOME/.local/bin:$PATH"
case "$track" in
js) has() { compgen -G "$dir/test/m$1-*.test.js" >/dev/null; } ;;
scala) has() { compgen -G "$dir/test/M$1*.test.scala" >/dev/null; } ;;
fsharp) has() { compgen -G "$dir/tests/M$1*.fs" >/dev/null; } ;;
js) tool=node; has() { compgen -G "$dir/test/m$1-*.test.js" >/dev/null; } ;;
scala) tool="${SCALA_CLI:-scala-cli}"; has() { compgen -G "$dir/test/M$1*.test.scala" >/dev/null; } ;;
fsharp) tool=dotnet; has() { compgen -G "$dir/tests/M$1*.fs" >/dev/null; } ;;
*) echo "unknown track: $track" >&2; exit 2 ;;
esac
if ! command -v "$tool" >/dev/null 2>&1; then
echo "check-stubs: required tool '$tool' not found on PATH" >&2; exit 2
fi
[ -x "$dir/test.sh" ] || { echo "check-stubs: $dir/test.sh missing or not executable" >&2; exit 2; }
# Succeeds if the (ANSI-stripped) output in $1 shows tests really ran and at least one failed
# (stub throws / ??? / failwith count as failures), as opposed to a compile or tooling error.
tests_failed() {
case "$track" in
js) ! grep -qE 'SyntaxError|ERR_MODULE_NOT_FOUND|does not provide an export|ReferenceError' <<<"$1" \
&& grep -qE '^ℹ tests [1-9]' <<<"$1" && grep -qE '^ℹ fail [1-9]' <<<"$1" ;;
scala) ! grep -qE 'Compilation failed|\[error\]|Error compiling|Downloading failed' <<<"$1" \
&& grep -qE '==> X' <<<"$1" ;;
fsharp) ! grep -qE 'error (FS|MSB|NU)[0-9]+|[Bb]uild failed|Build FAILED' <<<"$1" \
&& grep -qE '[1-9][0-9]* (failed|errored)' <<<"$1" ;;
esac
}
status=0
for n in 01 02 03 04 05 06 07 08 09 10 11; do
m="M$n"
if ! has "$n"; then echo "$m: no tests"; continue; fi
if (cd "$dir" && ./test.sh "$m") >/dev/null 2>&1; then
out="$(cd "$dir" && ./test.sh "$m" 2>&1)"; rc=$?
out="$(sed $'s/\x1b\\[[0-9;?]*[A-Za-z]//g' <<<"$out")"
if [ $rc -eq 0 ]; then
echo "$m: FAIL (tests pass against stubs)"; status=1
else
elif tests_failed "$out"; then
echo "$m: ok (fails against stubs)"
else
echo "$m: ERROR (tooling/build error, exit $rc; not a test failure)" >&2
echo "$out" >&2
exit 2
fi
done
exit $status