Repository navigation
test(config): add grid-style silent-drop guards - #175
Merged
Merged
Conversation
The grid-style editor maintains ~80 style fields in three parallel blocks
(property declarations, Seed, BuildRecord). A field surfaced in Seed but
missing from BuildRecord's `_source with { … }` compiles fine and silently
reverts on save, with no compile or test guard. Issue #118 will rewrite
exactly these blocks (nest the record, type colors, split the view model),
so land the anti-regression net first.
Add three directional guards, split by direction and field kind so each
catches what the others structurally cannot, driven by one distinct-value
fixture (77 unique, valid fields):
- Seed-populates: after seeding, assert every surfaced property equals the
fixture -- catches a dropped or cross-wired Seed line, including the
nullable and italic fields a naive round-trip is blind to.
- Perturbation (exact-one-field): change each property from its seeded
value, assert BuildRecord changed in exactly that property's mapped
field -- catches a dropped or mis-targeted BuildRecord line. A plain
round-trip cannot: `with` keeps _source, which is the seed source.
- Save->load: round-trip the fixture through the facade -- catches a
GridStyleDtoMapper drop / GridStyleMapper mis-wire (the flatten/unflatten
layer the nest slice rewrites).
A count assert (77) guards the reflection filter against drift. Each guard
is proven non-vacuous by scratch checks (delete a line, confirm the
matching test goes red, revert). The one residual -- a bool-to-bool Seed
cross-wire among the five italics -- is inherent to a two-valued type and
documented.
Tests only; no production change. This net unblocks the #118 debloat.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The grid-style editor (
GridStyleEditorViewModel) maintains ~80 style fields in three parallel blocks — property declarations,Seed, andBuildRecord— sitting 200+ lines apart in a 523-line file. A field surfaced inSeedbut missing fromBuildRecord's_source with { … }compiles fine and silently reverts on save, with no compile or test guard. Issue #118 will rewrite exactly these blocks (nest the flat record, type colors, split the view model), which is the highest-risk moment for re-introducing a silent drop. This lands the anti-regression net first.What changed (tests only — no production change)
Three directional guards, split by direction and field kind so each catches what the others structurally cannot, all driven by one distinct-value fixture (
GridStyleOptionsTestData.Distinct()— 77 unique, valid, in-range fields):Seedline — including the nullable (decimal?/FontFamily) and italic fields a naive round-trip is blind toBuildRecordline — a plainBuildRecord(Seed(x)) == xround-trip cannot (withkeeps_source, which is the seed source)GridStyleDtoMapperdrop /GridStyleMappermis-wire — the flatten/unflatten layer the nest slice rewritesA
count == 77assert guards the reflection filter against drift.Why three guards, not one: the existing round-trip test seeds
Default(32 identical#000000colors, masks cross-wires) and structurally cannot fail on a droppedBuildRecordline, nor on a droppedSeedline for the 14 nullable-fallback fields (null→BuildRecordrestores_source). The three directional guards close all of that.Verification
dotnet build SemiStep.slnx— 0 warnings;dotnet test— 1687 passed, 0 failed;dotnet formatclean.BuildRecordline (InfoColor) → perturbation test red, names the field;Seedline (ValidationPanelMaxHeight) → Seed-populates red (0 vs 150.5);Seedline → red (false vs true);GridStyleDtoMapperline (CellWeight) → save→load red (loaded 400 vs fixture 800).CellFontWeight: 400equalledDefault, and since that DTO field maps?? default, a dropped mapper line would substitute 400 and leave the save→load guard green; changed to 800, and two reviewers independently re-verified all 78 fields now differ fromDefault.Seedcross-wire among the five all-trueitalics is inherently undetectable with a two-valued type — lower-probability than a dropped line.This net unblocks the #118 debloat (slices 2–5: async
Save, nest the record, type colors asStyleColor, split the view model into per-group drafts). #118 stays open.Per-task commits before collapse
🤖 Generated with Claude Code