PR#30, the nightly build that measured werkcrappit itself
The Problem
The first nightly report of werkcrappit on itself showed 13 of 45 classes red, from 21 methods at a Mutation-CRAP of 9 or more.
Two kinds: methods whose mutants the tests did not notice, and methods too complex to be green even with every mutant killed, since Mutation-CRAP is never below the complexity.
Non-Goals
Every red method: RealLines.count, Gate.judge, CodeChartaExport.export and JsonReader.string are well tested but complex; splitting them is left for later.
New behaviour: only tests, smaller methods and one bug fix.
The Solution
Tests for the surviving mutants of Levelization.breakCycles (now package-private, so its rule is testable without a whole city), RealLines.endOfLiteral, Json.compact, the class files of the report's provenance, GateResult.describe and ClassReferences (class header, array, method descriptor, annotation and method-handle constants).
The Json.compact test found a bug: a null value threw a NullPointerException; the code city's checksum never had one so far.
MethodEvaluator.evaluate (complexity 16) is split into tally and state; CodeCity.metrics (complexity 11) reads each metric with an accessor of its definition instead of a switch.
A ratchet: werkcrappit { maxMutationCrap = 20 } for werkcrappit-pit, the highest value after these changes, 19.59, rounded up; the nightly mutationCrapCheck fails above it. codeCharta { colorRedFrom = 9 } keeps the next candidates red, which 90 % of 20 would not.
Version 0.16.2.
Follow-up PRs
Split the four complex but well tested methods above, then lower the limit.
## Related Links
- [PR#30](2026-10-03-PR%2330-nightly-mutation-testing.md), the nightly build that measured werkcrappit itself
## The Problem
The first nightly report of werkcrappit on itself showed 13 of 45 classes red, from 21 methods at a Mutation-CRAP of 9 or more.
Two kinds: methods whose mutants the tests did not notice, and methods too complex to be green even with every mutant killed, since Mutation-CRAP is never below the complexity.
## Non-Goals
- Every red method: `RealLines.count`, `Gate.judge`, `CodeChartaExport.export` and `JsonReader.string` are well tested but complex; splitting them is left for later.
- New behaviour: only tests, smaller methods and one bug fix.
## The Solution
- Tests for the surviving mutants of `Levelization.breakCycles` (now package-private, so its rule is testable without a whole city), `RealLines.endOfLiteral`, `Json.compact`, the class files of the report's provenance, `GateResult.describe` and `ClassReferences` (class header, array, method descriptor, annotation and method-handle constants).
- The `Json.compact` test found a bug: a `null` value threw a `NullPointerException`; the code city's checksum never had one so far.
- `MethodEvaluator.evaluate` (complexity 16) is split into `tally` and `state`; `CodeCity.metrics` (complexity 11) reads each metric with an accessor of its definition instead of a `switch`.
- A ratchet: `werkcrappit { maxMutationCrap = 20 }` for `werkcrappit-pit`, the highest value after these changes, 19.59, rounded up; the nightly `mutationCrapCheck` fails above it.
`codeCharta { colorRedFrom = 9 }` keeps the next candidates red, which 90 % of 20 would not.
- Version 0.16.2.
## Follow-up PRs
- Split the four complex but well tested methods above, then lower the limit.
## Attachments
### Local PIT runs of werkcrappit-pit
| | Nightly 2026-10-03 | After this PR |
|---|---|---|
| Highest Mutation-CRAP | 22.9 | 19.6 |
| Methods at 9 or more | 21 | 10 |
| Red classes (from 9) | 13 of 45 | 8 of 45 |
| Mutants killed | 82 % | 88 % |
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Related Links
The Problem
The first nightly report of werkcrappit on itself showed 13 of 45 classes red, from 21 methods at a Mutation-CRAP of 9 or more.
Two kinds: methods whose mutants the tests did not notice, and methods too complex to be green even with every mutant killed, since Mutation-CRAP is never below the complexity.
Non-Goals
RealLines.count,Gate.judge,CodeChartaExport.exportandJsonReader.stringare well tested but complex; splitting them is left for later.The Solution
Levelization.breakCycles(now package-private, so its rule is testable without a whole city),RealLines.endOfLiteral,Json.compact, the class files of the report's provenance,GateResult.describeandClassReferences(class header, array, method descriptor, annotation and method-handle constants).Json.compacttest found a bug: anullvalue threw aNullPointerException; the code city's checksum never had one so far.MethodEvaluator.evaluate(complexity 16) is split intotallyandstate;CodeCity.metrics(complexity 11) reads each metric with an accessor of its definition instead of aswitch.werkcrappit { maxMutationCrap = 20 }forwerkcrappit-pit, the highest value after these changes, 19.59, rounded up; the nightlymutationCrapCheckfails above it.codeCharta { colorRedFrom = 9 }keeps the next candidates red, which 90 % of 20 would not.Follow-up PRs
Attachments
Local PIT runs of werkcrappit-pit
🤖 Generated with Claude Code