Close the test gaps mutation testing found in audio and draw
A mutation smoke run scored src/audio.c at 50% and src/draw.c at 70% and named three real holes: - Nothing asserted that an unconfigured voice is audible, which is the entire reason the voice table defaults to a square wave at full level instead of a zeroed struct. Deleting the defaults survived. - No envelope test used a non-zero attack and decay together, so the decay measuring from the start of the note rather than from the end of the attack survived. - The circle was only checked at its four axis points, which a mis-signed octant reflection survives. It now checks that every plotted pixel has a mirror in the other three quadrants. Also adds a backend that exists but was never given an SDL_Renderer, which is the state a host is in between allocating one and initializing it; every draw entry point has to report it rather than dereference it. audio 50% -> 75%, draw 70% -> 90%. The survivors are recorded in TODO.md and are honestly untestable from here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
35
TODO.md
35
TODO.md
@@ -407,12 +407,39 @@ came from elsewhere in the tree and this note was never updated.)
|
||||
| `src/util.c` | 121/131 (92%) | 7/8 |
|
||||
| `src/version.c` | 2/2 (100%) | 1/1 |
|
||||
|
||||
Branch coverage reads 20.8% and should not be used as a target. The akerror
|
||||
Branch coverage reads 21.2% and should not be used as a target. The akerror
|
||||
control-flow macros (`ATTEMPT`/`CATCH`/`PROCESS`/`FINISH`, `FAIL_*_RETURN`)
|
||||
expand into large branch trees per call site, most of them unreachable in normal
|
||||
operation — `src/game.c` reports over 1700 branches across 230 lines. Track line
|
||||
and function coverage; treat branch coverage as a relative signal within a file.
|
||||
|
||||
### Mutation testing
|
||||
|
||||
`scripts/mutation_test.py` was run over the three new files as a smoke check
|
||||
(`--max-mutants 8` to 10 each, so these are samples rather than exhaustive
|
||||
scores):
|
||||
|
||||
| File | Score | Surviving mutants |
|
||||
|---|---|---|
|
||||
| `src/draw.c` | 90% | Deleting the `FAIL_ZERO_BREAK` on `SDL_CreateTextureFromSurface` in `akgl_draw_flood_fill` |
|
||||
| `src/audio.c` | 75% | Deleting `SUCCEED_RETURN` from the static `check_voice`; deleting `spec.freq` before opening a device |
|
||||
| `src/text.c` | 50% | Three in `akgl_text_rendertextat`, which has no test yet, plus one `SUCCEED_RETURN` deletion |
|
||||
|
||||
The first pass over `src/audio.c` scored 50% and named two real gaps, both of
|
||||
which are now tested: nothing asserted that an *unconfigured* voice is audible
|
||||
(the whole reason the table defaults to a square wave at full level rather than
|
||||
a zeroed struct), and no envelope test used a non-zero attack *and* decay
|
||||
together, so the decay measuring from the wrong origin survived. `src/draw.c`
|
||||
scored 70% first and named one: the circle was only checked at its four axis
|
||||
points, which a mis-signed octant reflection survives, so it now checks that
|
||||
every plotted pixel has a mirror in the other three quadrants.
|
||||
|
||||
What is left is honestly untestable from here. Deleting a `SUCCEED_RETURN`
|
||||
leaves a non-void function falling off its end, which is undefined rather than
|
||||
observably wrong, and the surviving SDL branches are allocation failures the
|
||||
suite has no way to provoke. The `src/text.c` survivors go away with the
|
||||
offscreen harness.
|
||||
|
||||
### Suites
|
||||
|
||||
Every suite is registered through the `AKGL_TEST_SUITES` list in
|
||||
@@ -634,6 +661,12 @@ Each was found by a test written to assert correct behavior.
|
||||
The `build*/` entry in `.gitignore` hides these trees from `git status`,
|
||||
which makes the state easier to get into and no easier to notice.
|
||||
|
||||
A second, smaller version of the same thing: rebuilding an existing
|
||||
coverage tree after editing a test leaves `.gcda` files describing the old
|
||||
object layout, and `coverage_reset` -- whose whole job is to delete them --
|
||||
fails with `GCOV returncode was 5` before it gets the chance. `find
|
||||
build-coverage -name '*.gcda' -delete` clears it. Observed with gcovr 7.0.
|
||||
|
||||
Fix: pass the build tree to gcovr as an explicit search path instead of
|
||||
letting it default to `--root`, so only the tree under measurement is
|
||||
considered. Touches the two `add_test` blocks at `CMakeLists.txt:204-211`
|
||||
|
||||
Reference in New Issue
Block a user