docs(563): state each binder test's mechanism instead of its mutant colour, per the amended CLAIMS rule
`testing.mutation-claims-are-executed` was amended on main while this branch was in review (#881, merged as #914): a sentence asserting that a specific mutation reddens — or does not redden — a named test is now either a `CLAIMS` entry in `scripts/tests/mutation_manifest.py` that executes every run, or it is not written. This branch carried six such sentences and none of them can be declared: `Claim.node_id` resolves a proof to `scripts/tests/<node id>` and `run_pytest` invokes pytest, so an NUnit proof has no representation in that harness at all. Durable prose now states the mechanism each test is built on — which serializer difference, which engine branch — which a reader re-checks by reading the code rather than by trusting a remembered outcome. The record says that in one paragraph, so the limit is stated rather than papered over. The outcomes themselves are here. Re-measured 2026-09-05 on this branch's tree (the commit before this one), each mutant applied to the working tree and restored from the index between runs, tree verified clean afterwards: positive control ScriptedScheduleControllerTests Passed: 9, Failed: 0 OpenApiSerializerContractTests Passed: 4, Failed: 0 Bind<T> -> System.Text.Json with JsonSerializerDefaults.Web Failed: 2, Passed: 7 — Production_Body_Binder_Ignores_Required_Members, Production_Body_Binder_Keeps_Declared_Defaults_Over_An_Explicit_Null BodyBinderSettings = ApiJsonSettings.Create() -> new JsonSerializerSettings() Failed: 1, Passed: 8 — Production_Body_Binder_Keeps_Declared_Defaults_Over_An_Explicit_Null OpenApiSerializerContractTests RuntimeSettings -> new JsonSerializerSettings() Failed: 4, Passed: 0 — all four cases, on PascalCase keys ScriptedScheduleController AddDuration(..., request.Trim, ...) -> false Failed: 1, Passed: 8 — Committed_Script_Fixture_Produces_The_Pinned_Snapshot ScriptedScheduleController PadUntilExact(..., request.Trim, ...) -> false Failed: 1, Passed: 8 — Committed_Script_Fixture_Produces_The_Pinned_Snapshot The last one is the round-two finding closed and re-witnessed: before the fixture's pad target moved off the content boundary, that mutant left all nine green. A squash merge writes its own message, so these figures also belong in the PR description. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QqCpYFsKgnAnx6jVwrKiV
This commit is contained in:
@@ -68,7 +68,7 @@ public class ScriptedScheduleControllerTests
|
||||
private static readonly DateTimeOffset Start = new(2026, 1, 15, 6, 0, 0, TimeSpan.Zero);
|
||||
|
||||
// What Startup hands to AddNewtonsoftJson, from the same function rather than a hand-copy of it.
|
||||
// Replacing this with a plain `new()` reddens Production_Body_Binder_Keeps_Declared_Defaults_...
|
||||
// The two Production_Body_Binder_* tests below are what hold this to the production configuration.
|
||||
private static readonly JsonSerializerSettings BodyBinderSettings = ApiJsonSettings.Create();
|
||||
|
||||
// A body that omits the `required` member "collection"; Newtonsoft and System.Text.Json disagree.
|
||||
@@ -161,9 +161,9 @@ public class ScriptedScheduleControllerTests
|
||||
// The claim is about the SERIALIZER only — what MVC's validation layer then does with such a
|
||||
// body (non-nullable reference types pick up an implicit required check) is the uncovered
|
||||
// wrapper, not this. Binding through Bind itself is what gives this teeth: the fixture's own
|
||||
// bodies parse identically under either serializer, so only a body like this one witnesses the
|
||||
// swap. It witnesses THAT swap only — a Newtonsoft settings object that has merely lost the
|
||||
// production configuration still binds this body correctly, which is the sibling test's job.
|
||||
// bodies parse identically under either serializer, so only a body like this one separates them.
|
||||
// It separates THAT pair only — a Newtonsoft settings object that has merely lost the production
|
||||
// configuration reads this body exactly as production does, which is the sibling test's subject.
|
||||
using JsonDocument document = JsonDocument.Parse(BodyMissingRequiredMember);
|
||||
|
||||
ContentCollection bound = Bind<ContentCollection>(document.RootElement).ShouldNotBeNull();
|
||||
@@ -184,8 +184,8 @@ public class ScriptedScheduleControllerTests
|
||||
// production sets NullValueHandling.Ignore, so an explicit `"order": null` leaves ContentCollection
|
||||
// at its declared "shuffle" rather than overwriting it. Newtonsoft's own default is Include, which
|
||||
// writes the null through — and AddCollection's Enum.TryParse then rejects it as a 400. So this is
|
||||
// a behaviour difference a script would see, not a settings-shape assertion: it reddens if the bind
|
||||
// settings are replaced by a plain JsonSerializerSettings that merely looks like the production one.
|
||||
// a behaviour difference a script would see, not a settings-shape assertion — which is what makes
|
||||
// the "shuffle" and the OkResult below assertions about the production configuration itself.
|
||||
(ScriptedScheduleController controller, SchedulingEngine engine) = NewSession();
|
||||
|
||||
using JsonDocument document = JsonDocument.Parse(BodyWithExplicitNullOrder);
|
||||
|
||||
Reference in New Issue
Block a user