Skip to content

Commit a424aa4

Browse files
test(coverage): mutation testing sprint β€” cache, reporter, rules, shield
- Add tests/test_cache.py (29 tests): full coverage of CacheManager including atomic save, corrupt-JSON fallback, parent-directory creation, and OSError handling via zenzic.core.cache.json.dump patch (Path.open vs builtins.open) - Add tests/test_reporter.py (12 tests): _read_snippet boundary conditions and _strip_prefix logic, killing or→and mutants on empty-file and zero-line guards - Add TestToCanonicalUrlMutantKill (15 tests) to test_rules.py: kills rstrip/lstrip, backslash normalization, index.md stripping, and source_dir/docs_root guard mutations - Add TestObfuscateSecretMutantKill (7 tests) to test_redteam_remediation.py: kills <= 8 boundary, prefix length, and star-count mutants in _obfuscate_secret - Add TestNormalizeLineForShieldMutantKill (4 tests) to test_shield_obfuscation.py: kills MDX comment, table pipe, and whitespace-join mutants docs: document sprint in CHANGELOG.md, CHANGELOG.it.md, RELEASE.md under [0.7.0] Test suite: 1,195 passing tests
1 parent 9ddb29d commit a424aa4

8 files changed

Lines changed: 756 additions & 0 deletions

β€ŽCHANGELOG.it.mdβ€Ž

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,46 @@ L'extra opzionale `[mkdocs]` non esiste piΓΉ. `pip install zenzic` Γ¨ l'installa
345345

346346
---
347347

348+
### Sprint Copertura Test & Mutation Testing (2026-04-24)
349+
350+
#### Aggiunto
351+
352+
- **`tests/test_cache.py`** (29 test) β€” copertura completa di `src/zenzic/core/cache.py`.
353+
Helper hash puri (`make_content_hash`, `make_config_hash`, `make_vsm_snapshot_hash`,
354+
`make_file_key`) e operazioni in-memory e I/O di `CacheManager` (`get`, `put`, `load`,
355+
`save`). Copre scrittura atomica, creazione directory parent, fallback JSON corrotto e
356+
pulizia OSError tramite monkeypatching di `json.dump`.
357+
358+
- **`tests/test_reporter.py`** (12 test) β€” copertura di `_read_snippet` e `_strip_prefix`
359+
in `src/zenzic/core/reporter.py`. Verifica la guardia `or`/`and` nel caso file vuoto /
360+
line_no non valido, il clamping del context-window a inizio e fine file, e la semantica
361+
dello strip del prefisso (bypass linea 0, ritenzione corrispondenza parziale).
362+
363+
- **`TestToCanonicalUrlMutantKill`** (15 test) aggiunto a `tests/test_rules.py` β€” targeta
364+
`VSMBrokenLinkRule._to_canonical_url`. Uccide le mutazioni `rstrip(None)` / `lstrip("/")`,
365+
normalizzazione backslash, strip `index.md` β†’ directory padre, risoluzione `..`
366+
context-aware, inversioni della logica di guardia `source_dir`/`docs_root` e caso limite
367+
path relativo `"."`.
368+
369+
- **`TestObfuscateSecretMutantKill`** (7 test) aggiunto a `tests/test_redteam_remediation.py`
370+
β€” targeta `_obfuscate_secret` in `reporter.py`. Uccide le mutazioni boundary `<= 8` β†’ `< 8`,
371+
`<= 8` β†’ `<= 9` e la mutazione di larghezza prefisso `raw[:4]` β†’ `raw[:5]`. Verifica che
372+
il conteggio asterischi sia `len(raw) - 8` e che la lunghezza totale sia sempre preservata.
373+
374+
- **`TestNormalizeLineForShieldMutantKill`** (4 test) aggiunto a
375+
`tests/test_shield_obfuscation.py` β€” uccide la sostituzione commento MDX β†’ `"XXXX"`
376+
(mutmut_22), pipe tabella β†’ `"XX XX"` (mutmut_40) e join spazio β†’ `"XX XX".join`
377+
(mutmut_42).
378+
379+
- **Run di mutation testing `mutmut`** su `rules.py`, `shield.py`, `reporter.py` β€” run
380+
completata. Oltre 200 mutanti sopravvissuti analizzati; i mutanti logici ad alto impatto
381+
in `_to_canonical_url`, `_obfuscate_secret` e `_normalize_line_for_shield` uccisi dai
382+
nuovi test. I mutanti sopravvissuti restanti classificati come equivalenti (variazioni di
383+
stringhe template in `SentinelReporter.render`, asserzioni difensive, o mutazioni
384+
`encoding="UTF-8"` / `errors="REPLACE"` con comportamento runtime identico).
385+
386+
---
387+
348388
## [0.6.1] β€” 2026-04-19 β€” Obsidian Glass [SUPERSEDED]
349389

350390
> ⚠ **[SUPERSEDED dalla v0.7.0]** β€” La versione 0.6.1 Γ¨ deprecata a causa di problemi di allineamento con le specifiche Docusaurus e terminologia legacy. Tutti gli utenti devono aggiornare alla v0.7.0 "Obsidian Maturity".

β€ŽCHANGELOG.mdβ€Ž

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,44 @@ The `[mkdocs]` optional extra no longer exists. `pip install zenzic` is the comp
391391

392392
---
393393

394+
### Test Coverage & Mutation Testing Sprint (2026-04-24)
395+
396+
#### Added
397+
398+
- **`tests/test_cache.py`** (29 tests) β€” full coverage of `src/zenzic/core/cache.py`.
399+
Pure hash helpers (`make_content_hash`, `make_config_hash`, `make_vsm_snapshot_hash`,
400+
`make_file_key`) and `CacheManager` in-memory and I/O operations (`get`, `put`, `load`,
401+
`save`). Covers atomic write, parent-dir creation, corrupt-JSON fallback, and OSError
402+
cleanup via `json.dump` monkeypatching.
403+
404+
- **`tests/test_reporter.py`** (12 tests) β€” coverage of `_read_snippet` and `_strip_prefix`
405+
in `src/zenzic/core/reporter.py`. Exercises `or`/`and` boundary in the empty-file /
406+
invalid-line-no guard, context-window clamping at file start and end, and prefix
407+
stripping semantics (line 0 bypass, partial-match retention).
408+
409+
- **`TestToCanonicalUrlMutantKill`** (15 tests) added to `tests/test_rules.py` β€” targets
410+
`VSMBrokenLinkRule._to_canonical_url`. Kills `rstrip(None)` / `lstrip("/")` mutations,
411+
backslash normalisation, `index.md` β†’ parent-dir strip, context-aware `..` resolution,
412+
`source_dir`/`docs_root` guard logic inversions, and `"."` relative-path edge case.
413+
414+
- **`TestObfuscateSecretMutantKill`** (7 tests) added to `tests/test_redteam_remediation.py`
415+
β€” targets `_obfuscate_secret` in `reporter.py`. Kills `<= 8` β†’ `< 8`, `<= 8` β†’ `<= 9`
416+
boundary mutations and `raw[:4]` β†’ `raw[:5]` prefix-width mutation. Verifies star count
417+
equals `len(raw) - 8` and total length is always preserved.
418+
419+
- **`TestNormalizeLineForShieldMutantKill`** (4 tests) added to
420+
`tests/test_shield_obfuscation.py` β€” kills MDX-comment sub β†’ `"XXXX"` (mutmut_22),
421+
table-pipe sub β†’ `"XX XX"` (mutmut_40), and whitespace join β†’ `"XX XX".join` (mutmut_42).
422+
423+
- **`mutmut` mutation testing run** on `rules.py`, `shield.py`, `reporter.py` β€” full run
424+
completed. 200+ surviving mutants analysed; high-impact logic mutants in
425+
`_to_canonical_url`, `_obfuscate_secret`, and `_normalize_line_for_shield` killed by new
426+
tests. Remaining surviving mutants classified as equivalent (template string variations in
427+
`SentinelReporter.render`, defensive assertions, or `encoding="UTF-8"` / `errors="REPLACE"`
428+
mutations with identical runtime behaviour).
429+
430+
---
431+
394432
## [0.6.1] β€” 2026-04-19 β€” Obsidian Glass [SUPERSEDED]
395433

396434
> ⚠ **[SUPERSEDED by v0.7.0]** β€” Version 0.6.1 is deprecated due to alignment issues with Docusaurus specifications and legacy terminology. All users must upgrade to v0.7.0 "Obsidian Maturity".

β€ŽRELEASE.mdβ€Ž

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,40 @@ reminder for when pip ships a fix.
7474

7575
---
7676

77+
### 🧬 Test Coverage & Mutation Testing Sprint (2026-04-24)
78+
79+
A targeted sprint to measure and strengthen the test suite using both line coverage
80+
and mutation testing (`mutmut`). The output: 1 195 passing tests, a new `test_cache.py`
81+
module from scratch, and targeted mutant-killing tests for three critical subsystems.
82+
83+
#### New Test Modules
84+
85+
- **`tests/test_cache.py`** β€” 29 tests covering the entire content-addressable cache
86+
(`cache.py`). Pure hash stability, `CacheManager` get/put/overwrite, hit-rate tracking,
87+
atomic save, parent-dir creation, corrupt-JSON resilience, and OSError cleanup.
88+
- **`tests/test_reporter.py`** β€” 12 tests for `_read_snippet` and `_strip_prefix`.
89+
Exercises the `or`/`and` boundary that guards against empty files and invalid line
90+
numbers, context-window clamping, and prefix-stripping semantics.
91+
92+
#### Mutation Testing Results
93+
94+
Full `mutmut` run across `rules.py`, `shield.py`, and `reporter.py`. High-impact logic
95+
mutants confirmed killed:
96+
97+
| Mutant class | Function | Representative mutation | Killed by |
98+
|---|---|---|---|
99+
| Boundary | `_obfuscate_secret` | `<= 8` β†’ `< 8` | `TestObfuscateSecretMutantKill` |
100+
| Logic inversion | `_to_canonical_url` | `and "…" in path` β†’ `or` | `TestToCanonicalUrlMutantKill` |
101+
| Strip substitution | `_normalize_line_for_shield` | MDX sub β†’ `"XXXX"` | `TestNormalizeLineForShieldMutantKill` |
102+
| String mutation | `_to_canonical_url` | `rstrip("/")` β†’ `rstrip(None)` | `test_trailing_slash_is_stripped_*` |
103+
| Index arithmetic | `_to_canonical_url` | `parts[:-1]` β†’ `parts[:+1]` | `test_nested_index_removed` |
104+
105+
Remaining survivors are equivalent mutants: template string variations in
106+
`SentinelReporter.render` output formatting and `encoding`/`errors` argument
107+
mutations that Python's codec system normalises at runtime.
108+
109+
---
110+
77111
### πŸš€ What Changed
78112

79113
#### 1. Z104 Proactive Suggestion Engine (New)

0 commit comments

Comments
Β (0)