From 3236d0f58ce9c1734122021d209eb121434b8c97 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 18:30:51 +0000 Subject: [PATCH] build: run the JustDummies analyzers on our own code (ADR-0061) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accepts ADR-0061 and implements it. The record argued that a rule's unit suite proves only that it fires on a snippet its own author wrote for it, so a wrong model of the library passes both sides — and that every model error the catalogue has had was caught instead on realistic code, by a sweep nothing in the repository asked for. Eight projects now load the analyzers at build and in the IDE: the two JustDummies suites, the xUnit adapter and its suite, FirstClassErrors' own suite, the Testing package and its suite, and the binder's suite. Two consumers are deliberately left out, each with the reason recorded where someone would otherwise "fix" the omission: * JustDummies.Analyzers.UnitTests — its subject IS these analyzers. Loading them into the compilation that builds them makes the analyzer under test also the analyzer running, and a rule changed there would report on the source that defines it. This is the circularity the ADR names among its risks. * tools/justdummies-check — consumes the PACKED package on purpose, so that asset selection is exercised as a real consumer sees it. Wiring would require the ProjectReference that project exists to avoid, and a diagnostic about how the library is called says nothing about which asset NuGet resolved. The two duplicate-collapsing tests gain the suppression the other five sites already carried: the duplicate IS the subject, and without it there is nothing to collapse. Three things were measured rather than assumed. The whole solution builds with zero diagnostics in Debug and in Release, and 2 168 tests pass. A planted violation fires in all eight wired projects, so a clean build means clean rather than never-loaded — the trap an earlier sweep fell into. And packing JustDummies.Xunit and FirstClassErrors.Testing shows no new dependency: PrivateAssets keeps the analyzer off the shipped surface, which matters because both are packable, unlike the sample the FirstClassErrors analyzers are dogfooded on. The net472 floor legs build. The ADR's follow-up actions stay open. In particular this verifies the LOUD rules: JD020, JD022 and JD024 are Info and do not surface at default verbosity, and JD011 and JD019 ship disabled. A clean build reads as full coverage while those five are not exercised, which is the risk the record states and defers. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01GKqyhG9Y4AfdxEYekP2Evq --- .../FirstClassErrors.RequestBinder.UnitTests.csproj | 8 ++++++++ .../FirstClassErrors.Testing.UnitTests.csproj | 8 ++++++++ FirstClassErrors.Testing/FirstClassErrors.Testing.csproj | 8 ++++++++ .../FirstClassErrors.UnitTests.csproj | 8 ++++++++ .../JustDummies.Analyzers.UnitTests.csproj | 6 ++++++ .../JustDummies.PropertyTests.csproj | 8 ++++++++ JustDummies.UnitTests/AnyOneOfTests.cs | 4 ++++ JustDummies.UnitTests/AnyStringValueSetTests.cs | 4 ++++ JustDummies.UnitTests/JustDummies.UnitTests.csproj | 8 ++++++++ .../JustDummies.Xunit.UnitTests.csproj | 8 ++++++++ JustDummies.Xunit/JustDummies.Xunit.csproj | 8 ++++++++ ...stdummies-analyzers-on-the-repository-s-own-code.fr.md | 3 ++- ...-justdummies-analyzers-on-the-repository-s-own-code.md | 3 ++- doc/handwritten/for-maintainers/adr/README.md | 2 +- tools/justdummies-check/JustDummiesCheck.csproj | 6 ++++++ 15 files changed, 89 insertions(+), 3 deletions(-) diff --git a/FirstClassErrors.RequestBinder.UnitTests/FirstClassErrors.RequestBinder.UnitTests.csproj b/FirstClassErrors.RequestBinder.UnitTests/FirstClassErrors.RequestBinder.UnitTests.csproj index 7d84bdb4..ac0c5613 100644 --- a/FirstClassErrors.RequestBinder.UnitTests/FirstClassErrors.RequestBinder.UnitTests.csproj +++ b/FirstClassErrors.RequestBinder.UnitTests/FirstClassErrors.RequestBinder.UnitTests.csproj @@ -29,6 +29,14 @@ + + + diff --git a/FirstClassErrors.Testing.UnitTests/FirstClassErrors.Testing.UnitTests.csproj b/FirstClassErrors.Testing.UnitTests/FirstClassErrors.Testing.UnitTests.csproj index df15035a..098a74d5 100644 --- a/FirstClassErrors.Testing.UnitTests/FirstClassErrors.Testing.UnitTests.csproj +++ b/FirstClassErrors.Testing.UnitTests/FirstClassErrors.Testing.UnitTests.csproj @@ -26,6 +26,14 @@ + + + diff --git a/FirstClassErrors.Testing/FirstClassErrors.Testing.csproj b/FirstClassErrors.Testing/FirstClassErrors.Testing.csproj index 6ab9ddf7..6f5c826b 100644 --- a/FirstClassErrors.Testing/FirstClassErrors.Testing.csproj +++ b/FirstClassErrors.Testing/FirstClassErrors.Testing.csproj @@ -60,6 +60,14 @@ reference it privately and embed its assembly in this package (see the pack target below); switch to a NuGet PackageReference once JustDummies is published. --> + + + + + + diff --git a/JustDummies.Analyzers.UnitTests/JustDummies.Analyzers.UnitTests.csproj b/JustDummies.Analyzers.UnitTests/JustDummies.Analyzers.UnitTests.csproj index d56c1670..63256295 100644 --- a/JustDummies.Analyzers.UnitTests/JustDummies.Analyzers.UnitTests.csproj +++ b/JustDummies.Analyzers.UnitTests/JustDummies.Analyzers.UnitTests.csproj @@ -28,6 +28,12 @@ + + diff --git a/JustDummies.PropertyTests/JustDummies.PropertyTests.csproj b/JustDummies.PropertyTests/JustDummies.PropertyTests.csproj index 92aecf31..711864e8 100644 --- a/JustDummies.PropertyTests/JustDummies.PropertyTests.csproj +++ b/JustDummies.PropertyTests/JustDummies.PropertyTests.csproj @@ -33,6 +33,14 @@ + + + diff --git a/JustDummies.UnitTests/AnyOneOfTests.cs b/JustDummies.UnitTests/AnyOneOfTests.cs index 7512b82d..cd27aa38 100644 --- a/JustDummies.UnitTests/AnyOneOfTests.cs +++ b/JustDummies.UnitTests/AnyOneOfTests.cs @@ -57,6 +57,10 @@ public void VariesAcrossDraws() { } [Fact(DisplayName = "Duplicate values are collapsed under the default comparer: both distinct values are still drawn, nothing else.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("JustDummies.Constraints", "JD025:The same value is listed twice in a pool", + Justification = + "The duplicate IS the subject. This pins the collapsing JD025 reports: without it there is nothing to collapse and the test " + + "asserts nothing.")] public void DuplicatesAreCollapsed() { HashSet seen = [.. Samples(Any.OneOf(1, 1, 2))]; diff --git a/JustDummies.UnitTests/AnyStringValueSetTests.cs b/JustDummies.UnitTests/AnyStringValueSetTests.cs index 700932ef..46251127 100644 --- a/JustDummies.UnitTests/AnyStringValueSetTests.cs +++ b/JustDummies.UnitTests/AnyStringValueSetTests.cs @@ -68,6 +68,10 @@ public void VariesAcrossDraws() { } [Fact(DisplayName = "Duplicate values are collapsed: both distinct values are still drawn, nothing else.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("JustDummies.Constraints", "JD025:The same value is listed twice in a pool", + Justification = + "The duplicate IS the subject. This pins the collapsing JD025 reports: without it there is nothing to collapse and the test " + + "asserts nothing.")] public void DuplicatesAreCollapsed() { HashSet seen = [.. Samples(Any.String().OneOf("a", "a", "b"))]; diff --git a/JustDummies.UnitTests/JustDummies.UnitTests.csproj b/JustDummies.UnitTests/JustDummies.UnitTests.csproj index 169c294e..d957a576 100644 --- a/JustDummies.UnitTests/JustDummies.UnitTests.csproj +++ b/JustDummies.UnitTests/JustDummies.UnitTests.csproj @@ -47,6 +47,14 @@ + + + diff --git a/JustDummies.Xunit.UnitTests/JustDummies.Xunit.UnitTests.csproj b/JustDummies.Xunit.UnitTests/JustDummies.Xunit.UnitTests.csproj index 626bef02..b65023ba 100644 --- a/JustDummies.Xunit.UnitTests/JustDummies.Xunit.UnitTests.csproj +++ b/JustDummies.Xunit.UnitTests/JustDummies.Xunit.UnitTests.csproj @@ -31,6 +31,14 @@ + + + diff --git a/JustDummies.Xunit/JustDummies.Xunit.csproj b/JustDummies.Xunit/JustDummies.Xunit.csproj index 4542de15..7f90419d 100644 --- a/JustDummies.Xunit/JustDummies.Xunit.csproj +++ b/JustDummies.Xunit/JustDummies.Xunit.csproj @@ -69,6 +69,14 @@ + + + diff --git a/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.fr.md b/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.fr.md index 9715c03a..4173679b 100644 --- a/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.fr.md +++ b/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.fr.md @@ -2,8 +2,9 @@ 🌍 🇫🇷 Français (ce fichier) · 🇬🇧 [English](0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md) -**Statut :** Proposé +**Statut :** Accepté **Proposé :** 2026-07-29 +**Accepté :** 2026-07-29 **Décideurs :** Reefact ## Contexte diff --git a/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md b/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md index b602c96f..9ba1ce10 100644 --- a/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md +++ b/doc/handwritten/for-maintainers/adr/0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md @@ -2,8 +2,9 @@ 🌍 🇬🇧 English (this file) · 🇫🇷 [Français](0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.fr.md) -**Status:** Proposed +**Status:** Accepted **Proposed:** 2026-07-29 +**Accepted:** 2026-07-29 **Decision Makers:** Reefact ## Context diff --git a/doc/handwritten/for-maintainers/adr/README.md b/doc/handwritten/for-maintainers/adr/README.md index 8e6a8495..c5235a1a 100644 --- a/doc/handwritten/for-maintainers/adr/README.md +++ b/doc/handwritten/for-maintainers/adr/README.md @@ -262,4 +262,4 @@ Optional supporting material: | [ADR-0058](0058-suppress-ca1510-while-the-netstandard-floor-stands.md) | Suppress CA1510 while the pre-.NET-6 floor stands | Accepted | | [ADR-0059](0059-guard-the-recipe-versus-value-boundary-with-analyzers.md) | Guard the recipe-versus-value boundary with analyzers where the type system cannot reach it | Proposed | | [ADR-0060](0060-let-stated-intent-outrank-generic-analyzer-advice.md) | Let stated intent outrank generic analyzer advice, and record the refusal beside the rule | Proposed | -| [ADR-0061](0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md) | Run the JustDummies analyzers on the repository's own code, so the rules are verified against code not written to please them | Proposed | +| [ADR-0061](0061-run-the-justdummies-analyzers-on-the-repository-s-own-code.md) | Run the JustDummies analyzers on the repository's own code, so the rules are verified against code not written to please them | Accepted | diff --git a/tools/justdummies-check/JustDummiesCheck.csproj b/tools/justdummies-check/JustDummiesCheck.csproj index 28b1bff3..29a5294a 100644 --- a/tools/justdummies-check/JustDummiesCheck.csproj +++ b/tools/justdummies-check/JustDummiesCheck.csproj @@ -76,6 +76,12 @@ version is pinned EXACTLY, not floated, and nuget.config maps the id to the local feed only, so a future stable JustDummies on nuget.org can never be substituted for the artifact under test. --> + +