diff --git a/scripts/check-stubs.sh b/scripts/check-stubs.sh index 30c9ea4..6797724 100755 --- a/scripts/check-stubs.sh +++ b/scripts/check-stubs.sh @@ -1,24 +1,51 @@ #!/usr/bin/env bash # Usage: scripts/check-stubs.sh -# 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 }" 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