diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f1bf59..663f40c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Changed - `bashunit doc ` says `No assertion matches ''` instead of printing nothing, which was indistinguishable from a broken install. Mirrors the existing `--custom` wording; the exit code stays 0 because `doc` is informational (#1201) +- The `example/` demo is covered by the suite. `docs/examples.md` and `example/README.md` send new users to `./bashunit example` as their first contact with the framework, and nothing ran it — `make test` collects from `tests/` only — so it could break while CI stayed green. The dead `EXAMPLE_TEST_SCRIPTS` variable, pointing at a file deleted several releases ago, is gone with it (#1219) - Docs: an empty entry in the `-e/--env/--boot` file assigns an empty value rather than restoring the built-in default, so blanking a boolean disables it; the guide said it "wipes" the value, which reads as a reset. The rest of the precedence ladder is now covered by tests (#1217) - Docs: the test-function name rule is stated correctly — the prefix is a literal, lowercase `test_`, so the guide's own `testRenderAllTestsPassedWhenNotFailedTests` example and its claim that names are case-insensitive were both wrong, and a function named either way is silently never run (#1215) - Docs: `assert_matches` runs `grep -E` in a subprocess per call — ~2.5ms against ~0.065ms for `assert_same`, about 38x — so hot loops matching a fixed substring should prefer `assert_contains`. The subprocess is required by the Bash 3.0 floor (#1187) diff --git a/Makefile b/Makefile index 5de3194e..0caeeb56 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,6 @@ help: SRC_SCRIPTS_DIR=src TEST_SCRIPTS_DIR=tests -EXAMPLE_TEST_SCRIPTS=./example/logic_test.sh PRE_COMMIT_SCRIPTS_FILE=./bin/pre-commit # Collected recursively so tests/unit/ can mirror the src/ module layout. A diff --git a/tests/acceptance/bashunit_example_demo_test.sh b/tests/acceptance/bashunit_example_demo_test.sh new file mode 100644 index 00000000..ed5457c0 --- /dev/null +++ b/tests/acceptance/bashunit_example_demo_test.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -euo pipefail + +# `docs/examples.md` sends readers to `example/` first, and `example/README.md` +# tells them to run `./bashunit example` from the project root. That is a new +# user's first contact with the framework, and nothing ran it: `make test` +# collects from `tests/` only, no workflow mentions the folder, and no test +# referenced it. It could rot -- a renamed assertion, a moved source file -- +# while CI stayed green (#1219). +# +# Assert on the outcome, not on a test count, so adding an example does not +# fail this; what must never happen is the demo failing. + +function set_up_before_script() { + ROOT_DIR="$(pwd)" +} + +function _run_example() { # $@ = extra flags + (cd "$ROOT_DIR" && ./bashunit "$@" example 2>&1) || echo "EXIT_FAILURE" +} + +# The command the README documents, verbatim -- no trailing slash. +function test_the_documented_example_command_succeeds() { + local output + output="$(_run_example --no-parallel | strip_ansi)" + + assert_not_contains "EXIT_FAILURE" "$output" + assert_contains "All tests passed" "$output" +} + +# The demo is also what a user copies into their own project, where the run is +# as likely to be parallel. +function test_the_example_folder_passes_in_parallel_too() { + local output + output="$(_run_example --parallel | strip_ansi)" + + assert_not_contains "EXIT_FAILURE" "$output" + assert_contains "All tests passed" "$output" +} + +# A guard that runs zero tests would pass forever. The folder holding no tests +# at all is itself the failure this is here to catch. +function test_the_example_folder_actually_holds_tests() { + local output + output="$(_run_example --no-parallel --list)" + + assert_not_contains "EXIT_FAILURE" "$output" + assert_matches "[1-9][0-9]* tests" "$output" +}