From 8559b7ae4d6fdedafc0d8412cf1ca2d3fdfe0ccb Mon Sep 17 00:00:00 2001 From: InauguralPhysicist Date: Wed, 5 Aug 2026 19:10:37 -0500 Subject: [PATCH] =?UTF-8?q?test:=20run=20the=20gfx=20examples=20=E2=80=94?= =?UTF-8?q?=20no=20build=20variant=20ever=20did=20(#886)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Section [97] skipped example programs by CONTENT: if grep -qE 'gfx_|net_listen' "$f"; then EX_SKIP=...; continue; fi That is unconditional. `make gfx` builds the extension and [132] exercises the real SDL renderer, but the nine gfx examples were skipped in EVERY variant, so nothing covered them anywhere. The suite reported it honestly ("10 gfx skipped"); the gap was that nothing else covered them either. The skip is now gated on build CAPABILITY — the same probe [132] uses — and under a gfx build each demo runs against the dummy video driver with a memory cap (an unbounded UI run can take the whole box). A gfx demo ends in `ui.app_loop`, an interactive event loop that no quit event ever reaches headlessly, so REACHING it (rc 124) is the pass signal: the program got through parse, module load, widget construction and layout without erroring. That is the failure class this section exists to catch. It deliberately does not verify loop behavior — [132] and the lib/ui sections own that — and the header says so rather than implying more coverage than it has. Validated by planting the issue's own bug back in (a call to the private `ui._layout` in ui_hex.eigs): the section fails with "gfx demo errored before its event loop". Both paths checked — with gfx the example count goes 72 -> 81; without it, 72 run and 10 skip as before. Reporting honestly: the broken example the issue names is ALREADY fixed. `b49e85c` — an unrelated sandbox/zlib PR — deleted the offending line by accident after the issue was filed. Which is the issue's point exactly: with nothing running these, they break and get fixed invisibly. This commit closes the coverage gap, not a live breakage. The net demo still needs `make net` and a free port, so it stays content-skipped, and the summary line now says which reason applied. Suite 3863/3863 under `make gfx`, 3804/3804 under `make` (release). Closes #886 Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 22 ++++++++++++++++ tests/run_all_tests.sh | 57 +++++++++++++++++++++++++++++++++++----- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d94dcbcd..09b94361 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -307,7 +307,7 @@ jobs: run: make gfx - if: needs.scope.outputs.code == 'true' - name: Run full suite against gfx build (executes audio section [62]) + name: Run full suite against gfx build (audio [62], containment [132], gfx examples [97]) run: cd tests && bash run_all_tests.sh - if: needs.scope.outputs.code == 'true' diff --git a/CHANGELOG.md b/CHANGELOG.md index c54f40ce..01750885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -284,6 +284,28 @@ All notable changes to EigenScript are documented here. so clients decoded byte offsets as UTF-16 code units and every range after a non-ASCII character landed in the wrong place, drifting further along the line with each one. +- **The gfx examples are actually run now — no build variant ever ran + them (#886).** Section [97] skipped example programs by **content** + (`grep -qE 'gfx_|net_listen'`), which is unconditional: `make gfx` + builds the extension and [132] exercises the real SDL renderer, but + the nine `gfx_` examples were skipped in every variant, so nothing + covered them anywhere. The suite reported this honestly ("10 gfx + skipped"); the gap was that nothing else covered them either. + The skip is now gated on build capability (the same probe [132] uses), + and under a gfx build each demo runs against the dummy video driver, + memory-capped. A gfx demo ends in `ui.app_loop`, an interactive event + loop that no quit event ever reaches headlessly — so *reaching* it + (rc 124) is the pass signal: the program got through parse, module + load, widget construction and layout without erroring, which is the + failure class this catches. It deliberately does not verify loop + behavior; [132] and the lib/ui sections own that. Validated with the + issue's own bug planted back in (a call to the private `ui._layout`), + which the section catches. + Worth recording: that bug is **already gone** — `b49e85c`, an + unrelated sandbox/zlib PR, deleted the offending line by accident + after the issue was filed. Which is the issue's point exactly: with + nothing running these, they break and get fixed invisibly. The example + count under a gfx build goes 72 → 81. - **`unobserved:` leaked its depth on every exit edge but one, silently killing the observer for the rest of the process (#871, found while diff --git a/tests/run_all_tests.sh b/tests/run_all_tests.sh index d5891f5b..1954ca14 100755 --- a/tests/run_all_tests.sh +++ b/tests/run_all_tests.sh @@ -3873,14 +3873,36 @@ done echo "" # [97] Example programs — every examples/*.eigs (and examples/stem/*.eigs) -# must run to a clean exit. examples/errors/ is covered by [90]; the gfx -# demos (gfx_* builtins) need `make gfx`, the net demos (net_listen) need -# `make net`, and both are skipped unconditionally here — their dedicated -# sections ([62], [125]) exercise them under the right build. +# must run to a clean exit. examples/errors/ is covered by [90]. +# +# #886: the gfx demos used to be skipped by CONTENT (`grep gfx_`), which is +# unconditional — so NO build variant ever ran them, and one sat broken +# (`ui._layout`, a private member) until an unrelated PR deleted the line by +# accident. They are now skipped only when the binary lacks gfx, and run under +# the dummy video driver otherwise. The net demos still need `make net` and a +# free port, so they stay content-skipped. +# +# A gfx demo ends in `ui.app_loop`, which is an interactive event loop: under +# the dummy driver no quit event ever arrives, so reaching it means timing out. +# That is the PASS signal here — rc 124 means the program got through parse, +# module load, widget construction and layout without erroring, which is the +# failure class this section exists to catch. It deliberately does NOT verify +# loop behavior; [132] and the lib/ui sections own that. +# +# Every gfx run is memory-capped: an unbounded UI run can take the whole box. # Each runs from its own directory (so relative paths resolve) with stdin # closed. rc_ok tolerates the spawn-thread LeakSanitizer floor; no non-gfx # example uses spawn, so this stays leak-clean. -echo "[97] Example programs (examples/*.eigs; gfx demos skipped)" +EX_GFX_PROBE=$(mktemp /tmp/eigs_ex_gfx_XXXXXX.eigs) +echo 'print of (gfx_text_width of ["m", 1])' > "$EX_GFX_PROBE" +EX_HAS_GFX=0 +if ! ./eigenscript "$EX_GFX_PROBE" 2>&1 | grep -q "undefined variable"; then EX_HAS_GFX=1; fi +rm -f "$EX_GFX_PROBE" +if [ "$EX_HAS_GFX" = "1" ]; then + echo "[97] Example programs (examples/*.eigs; gfx demos INCLUDED)" +else + echo "[97] Example programs (examples/*.eigs; gfx demos skipped — no gfx build)" +fi EX_PASS=0; EX_FAIL=0; EX_SKIP=0 EIGS_ABS="$(pwd)/eigenscript" # Runaway guard reuses the shared $EIGS_TMO (defined near the top). The old @@ -3889,7 +3911,24 @@ EIGS_ABS="$(pwd)/eigenscript" # (#616). $EIGS_TMO's generous budget keeps this a runaway backstop, not a perf # gate — a genuine hang still fails, a slow-but-working example does not. for f in $(find ../examples -name '*.eigs' -not -path '*/errors/*' | sort); do - if grep -qE 'gfx_|net_listen' "$f"; then EX_SKIP=$((EX_SKIP + 1)); continue; fi + if grep -q 'net_listen' "$f"; then EX_SKIP=$((EX_SKIP + 1)); continue; fi + if grep -q 'gfx_' "$f"; then + if [ "$EX_HAS_GFX" != "1" ]; then EX_SKIP=$((EX_SKIP + 1)); continue; fi + # #886: reaching the event loop (rc 124) is the pass; any other + # nonzero rc is a real setup failure. Memory-capped — an unbounded + # UI run can take the whole machine. + EX_OUT=$( cd "$(dirname "$f")" && ulimit -v 2000000 2>/dev/null; \ + cd "$(dirname "$f")" && SDL_VIDEODRIVER=dummy timeout 3 \ + "$EIGS_ABS" "$(basename "$f")" &1 ); EX_RC=$? + if [ "$EX_RC" = "124" ] || [ "$EX_RC" = "0" ]; then + EX_PASS=$((EX_PASS + 1)) + else + echo " FAIL($EX_RC): $f (gfx demo errored before its event loop)" + printf '%s\n' "$EX_OUT" | tail -2 | sed 's/^/ /' + EX_FAIL=$((EX_FAIL + 1)) + fi + continue + fi EX_OUT=$( cd "$(dirname "$f")" && $EIGS_TMO "$EIGS_ABS" "$(basename "$f")" &1 ); EX_RC=$? if [ "$EX_RC" = "124" ]; then echo " FAIL(124): $f (timed out after ${EIGS_TEST_TIMEOUT}s — runaway)" @@ -3908,7 +3947,11 @@ FAIL=$((FAIL + EX_FAIL)) if [ "$EX_FAIL" -gt 0 ]; then echo " FAIL: $EX_FAIL example(s) errored" else - echo " PASS: all $EX_PASS example programs run clean ($EX_SKIP gfx skipped)" + if [ "$EX_HAS_GFX" = "1" ]; then + echo " PASS: all $EX_PASS example programs run clean (gfx demos included; $EX_SKIP net skipped)" + else + echo " PASS: all $EX_PASS example programs run clean ($EX_SKIP gfx/net skipped — no gfx build)" + fi fi echo ""