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) <noreply@anthropic.com>
This commit is contained in:
13
.githooks/pre-commit
Normal file
13
.githooks/pre-commit
Normal file
@@ -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
|
||||
104
README.md
104
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
|
||||
|
||||
<!-- topology:start (auto-generated; do not edit) -->
|
||||
```mermaid
|
||||
graph LR
|
||||
this["lib-core.maps-test"]
|
||||
lib_core_maps["lib-core.maps"]
|
||||
this --> lib_core_maps
|
||||
engine["engine.*"]
|
||||
this --> engine
|
||||
```
|
||||
<!-- topology:end -->
|
||||
|
||||
## 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=<libs-path> --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`
|
||||
|
||||
3
scripts/install-hooks.sh
Normal file
3
scripts/install-hooks.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
git config core.hooksPath .githooks
|
||||
echo "Hooks activated."
|
||||
Reference in New Issue
Block a user