From 30b909a54fed5b9eaa1be2f23f392d1ec48ecd4c Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Sat, 16 May 2026 16:49:05 +0200 Subject: [PATCH] docs: migrate README to API-Doc-Convention (S2-cascade.libs test-lib) Restructured per ADR-0038 with Coverage-Statement-Block per Fault- Injection-Audit-Convention. Topology auto-populated. Pre-commit hook installed. Co-Authored-By: Claude Opus 4.7 (1M context) --- .githooks/pre-commit | 13 +++++ README.md | 104 +++++++++++++++++++++++++++------------ scripts/install-hooks.sh | 3 ++ 3 files changed, 89 insertions(+), 31 deletions(-) create mode 100644 .githooks/pre-commit create mode 100644 scripts/install-hooks.sh diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100644 index 0000000..1ebdad0 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,13 @@ +#!/bin/sh +# Sporel API-Doc-Convention pre-commit hook. +SPOREL_EXE="${SPOREL_EXE:-$(command -v Sporel.exe 2>/dev/null || command -v sporel 2>/dev/null)}" +if [ -z "$SPOREL_EXE" ]; then + echo "INFO: Sporel.exe not on PATH. Skipping lint." >&2 + exit 0 +fi +"$SPOREL_EXE" --lint="$(pwd)" --fix +RC=$? +if git diff --cached --name-only | grep -qx 'README.md'; then + git add README.md +fi +exit $RC diff --git a/README.md b/README.md index 608c7a0..f0c1eaa 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,83 @@ -# sporel-module-lib-core.maps-test +# lib-core.maps-test -P.3.1 reference test-module — validates `lib-core.maps` API contracts -via the `engine.test.*` assertion surface. +Test-lib for `lib-core.maps` (Tests-as-Libs per ADR-0037). -- Module-ID: `lib-core.maps-test` -- Version: `0.1.0` -- Kind: `test-module` (headless; runs init() once + exits) -- Spec: `meta/docs/superpowers/specs/2026-05-10-test-module-pattern-design.md` +**Version:** 0.1.0 +**Lib-ID:** lib-core.maps-test +**Requires:** lib-core.maps v>=0.1.1 +**Tags:** test, maps -## Run +## Topology + + +```mermaid +graph LR + this["lib-core.maps-test"] + lib_core_maps["lib-core.maps"] + this --> lib_core_maps + engine["engine.*"] + this --> engine +``` + + +## Coverage Statement + +Per Fault-Injection-Audit-Convention (2026-05-16): + +| Section | Assertion-Count | Coverage | +|---|---|---| +| Geometry | 3 | `size.w == 16`, `size.h == 16`, `tile_size() == 32` | +| Tile-Lookup + Walkability | 4 | `tile_at(0,0) == stone`, `tile_at(5,5) == grass`, `is_walkable(0,0) == false`, `is_walkable(5,5) == true` | +| Arity-flex tile_at | 1 | 3-arg with `nil` map_id falls back to current_map | +| Out-of-bounds | 2 | `tile_at(-1, 0) == nil`, `tile_at(0, 16) == nil` | +| `list()` | 1 | Returns 1 registered map after `load` | +| **TOTAL** | **11** | | + +### Tested-Surface +- `maps.load`, `maps.set_current` +- `maps.size`, `maps.tile_size` +- `maps.tile_at` (2-arg and 3-arg nil-fallback forms) +- `maps.is_walkable` +- `maps.list` + +### Fault-Injection Audit (2026-05-16) + +Verified via deliberate-mutation in fixture-mirror; mutations reverted after observation. + +#### Caught Mutations + +| # | Mutation | Caught by | +|---|---|---| +| M1 | `M.tile_at` renamed (API-break) | Runtime error "attempt to call a nil value (field 'tile_at')" — test aborts at assertion 4 | +| M2 | `M.is_walkable` body prefixed with `do return false end` | Assertion `grass interior walkable` fails (`not ok`, actual=false) | + +#### Uncaught Mutations (Gaps) + +| # | Mutation | Why uncaught | Severity | +|---|---|---|---| +| M3 | OOB guard in `M.tile_at` removed | Lua's 1-indexed tables return `nil` for index 0 and negative indices — tested OOB coordinates (`-1,0` and `0,16`) still produce `nil` without the guard | Low | + +**Resolution:** Headless-reachable in principle, but guard is coincidentally shadowed by Lua nil-on-out-of-range semantics for all tested coordinates. Cheap fill would require a wrapping scenario — not applicable here. Future-Slice B: no cheap fix available; asserting the guard itself is not meaningful headless-side. + +### Structurally Untestable +- Render-output of `maps.draw` (not part of API tested here; verified manually). + +### Deferred +- Tile-mutation API (none in v0.1.x — read-only maps). + +## Running + +Via `--test-libs=lib-core.maps-test` (Smoke P0-S-batch Stage): ```bash -Sporel.exe --module=lib-core.maps-test +Sporel.exe --libs-dir= --test-libs=lib-core.maps-test ``` Output is TAP version 13 on stdout; exit-code = failure-count (0 = all pass). -## Coverage Statements (2026-05-16 Fault-Injection Audit) +## References -Verified via deliberate-mutation in fixture-mirror; mutations reverted after observation. - -### Caught Mutations - -| # | Mutation | Caught by | -|---|---|---| -| M1 | `M.tile_at` renamed to `M._tile_at_disabled` (API-break) | Runtime error "attempt to call a nil value (field 'tile_at')" — test aborts at assertion 4 | -| M2 | `M.is_walkable` body prefixed with `do return false end` (always-false logic) | Assertion "grass interior walkable" (ok 7) — `not ok` with actual=false | - -### Uncaught Mutations (Gaps) - -| # | Mutation | Why uncaught | Severity | -|---|---|---|---| -| M3 | OOB guard in `M.tile_at` removed (`if tx < 0 or ...` commented out) | Lua's 1-indexed tables return `nil` for index 0 and negative indices, so all tested OOB coordinates (`-1,0` and `0,16`) still incidentally produce `nil` without the guard | Low | - -**Resolution per Gap:** -- Gap M3: Headless-reachable in principle, but OOB guard is coincidentally shadowed by Lua nil-on-out-of-range semantics for all tested coordinates. The existing assertions (`tile_at(-1,0)=nil`, `tile_at(0,16)=nil`) pass whether the guard is present or not. Cheap fill would require a case where removal causes *non-nil* (e.g. a wrapping scenario) — not applicable here. Classify as Future-Slice B: note that guard correctness is invisible to current test vectors; no cheap fix available (asserting the guard itself is not meaningful headless-side). - -### Tested Production-Lib Surface - -`lib-core.maps` v0.1.0 — Tests cover behavior of: `maps.load`, `maps.set_current`, `maps.size`, `maps.tile_size`, `maps.tile_at` (2-arg and 3-arg nil-fallback forms), `maps.is_walkable`, `maps.list`. +- ADR-0037 (Tests-as-Libs Convention) +- ADR-0038 (API-Doc-Convention) +- Production-Lib: `~/Projects/Sporel/sporel-libs/lib-core/maps/README.md` +- Spec: `meta/docs/superpowers/specs/2026-05-10-test-module-pattern-design.md` diff --git a/scripts/install-hooks.sh b/scripts/install-hooks.sh new file mode 100644 index 0000000..2ff6e41 --- /dev/null +++ b/scripts/install-hooks.sh @@ -0,0 +1,3 @@ +#!/bin/sh +git config core.hooksPath .githooks +echo "Hooks activated."