> Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation. ## The Problem The nightly mutation build has been red since the gate reached the target of 15 (PR#126). Five methods are above 15; three of them belong to the build lists and are above 15 in every run: | Method | Mutation-CRAP | Complexity | Killed / eligible | |--------------------------|--------------:|-----------:|------------------:| | `RepoSummaryView.from` | 17.44 | 13 | 26 / 37 | | `BuildRowView.from` | 16.40 | 10 | 6 / 10 | | `UiController.baseModel` | 15.69 | 10 | 8 / 13 | PR#126 missed them: the method list came from the build log, which shows only the five highest scores. - `RepoSummaryView.from` counted with the inline `count` three times, so three loops and their overflow checks were compiled into one method. - `BuildRowView.from(BuildResult, …)` was a second copy of the row mapping, used by the artifact page only. Every other page builds its row from the API's `BuildResultDto` since PR#43, and only those were tested well. - `UiController.baseModel` also assembled the forge name and the footer. ## Non-Goals - The other two methods above 15, `RepositoryPrivacy.isPrivate` and `ConfigLoader.renameLegacySandbox`, follow in their own pull requests. - No change of what any page shows. ## The Solution - `RepoSummaryView.from` names each part through one `phrase` step: the count of matching repositories, or null when none matches. - The artifact page builds its row like every other page, through `BuildResultDto.from` and `BuildRowView.from(BuildResultDto, …)`. The copy `BuildRowView.from(BuildResult, …)` is gone, so a field can no longer be mapped one way on the artifact page and another way in the lists. - `UiController.baseModel` takes the forge name from `forgeName` and fills the footer with `addFooter`. - The test of the summary line also checks that every part is left out when no repository matches. Measured locally with PIT on the changed classes: | Method | Mutation-CRAP before | after | |----------------------------------------|---------------------:|-----------:| | `RepoSummaryView.from` | 17.44 | no mutants | | `RepoSummaryView.phrase` | new | 2.00 | | `BuildRowView.from(BuildResult, …)` | 16.40 | gone | | `UiController.baseModel` | 15.69 | 8.81 | | `BuildRowView.from(BuildResultDto, …)` | < 13.7 | 11.19 | | highest of the three classes | 17.44 | 13.08 | The gate stays at 15. ## Follow-up PRs - `RepositoryPrivacy.isPrivate` (16.40) gets tests for its surviving mutants. - `ConfigLoader.renameLegacySandbox` (15.93) is split, and `ConfigLoader.checkRestartsInstance` (exactly 15.00) gets room below the target. --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: claude-code <claude-code@javagil.de> Reviewed-on: #129
3.2 KiB
3.2 KiB
PR#129: Build Rows, Repository Summary and Page Model Split into Steps
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
The Problem
The nightly mutation build has been red since the gate reached the target of 15 (PR#126). Five methods are above 15; three of them belong to the build lists and are above 15 in every run:
| Method | Mutation-CRAP | Complexity | Killed / eligible |
|---|---|---|---|
RepoSummaryView.from |
17.44 | 13 | 26 / 37 |
BuildRowView.from |
16.40 | 10 | 6 / 10 |
UiController.baseModel |
15.69 | 10 | 8 / 13 |
PR#126 missed them: the method list came from the build log, which shows only the five highest scores.
RepoSummaryView.fromcounted with the inlinecountthree times, so three loops and their overflow checks were compiled into one method.BuildRowView.from(BuildResult, …)was a second copy of the row mapping, used by the artifact page only. Every other page builds its row from the API'sBuildResultDtosince PR#43, and only those were tested well.UiController.baseModelalso assembled the forge name and the footer.
Non-Goals
- The other two methods above 15,
RepositoryPrivacy.isPrivateandConfigLoader.renameLegacySandbox, follow in their own pull requests. - No change of what any page shows.
The Solution
RepoSummaryView.fromnames each part through onephrasestep: the count of matching repositories, or null when none matches.- The artifact page builds its row like every other page, through
BuildResultDto.fromandBuildRowView.from(BuildResultDto, …). The copyBuildRowView.from(BuildResult, …)is gone, so a field can no longer be mapped one way on the artifact page and another way in the lists. UiController.baseModeltakes the forge name fromforgeNameand fills the footer withaddFooter.- The test of the summary line also checks that every part is left out when no repository matches.
Measured locally with PIT on the changed classes:
| Method | Mutation-CRAP before | after |
|---|---|---|
RepoSummaryView.from |
17.44 | no mutants |
RepoSummaryView.phrase |
new | 2.00 |
BuildRowView.from(BuildResult, …) |
16.40 | gone |
UiController.baseModel |
15.69 | 8.81 |
BuildRowView.from(BuildResultDto, …) |
< 13.7 | 11.19 |
| highest of the three classes | 17.44 | 13.08 |
The gate stays at 15.
Follow-up PRs
RepositoryPrivacy.isPrivate(16.40) gets tests for its surviving mutants.ConfigLoader.renameLegacySandbox(15.93) is split, andConfigLoader.checkRestartsInstance(exactly 15.00) gets room below the target.