Polecat#108: Audit test-library projections against the source-generator-only dispatch#110
Merged
Merged
Conversation
…audit report)
Pre-4.0 sweep verifying that every projection type in the Polecat test
libraries (Polecat.Tests + Polecat.EntityFrameworkCore.Tests +
Polecat.AspNetCore.Testing + Polecat.AotSmoke; DcbLoadTest has no
projections) either gets a [GeneratedEvolver] dispatcher emitted by
JasperFx.Events.SourceGenerator or deliberately bypasses that path.
Headline:
- 50 projection-shaped types inventoried
- 38 SG [GeneratedEvolver] outputs across the solution
(27 self-aggregating-doc evolvers + 8 EventProjection partial overrides
+ 3 PartialProjection Evolver overrides + 1 TypeRegistration-only)
- 41 ✅ generated + verified
- 9 ⚠ deliberate bypass (Evolve / EvolveAsync / DetermineActionAsync /
ApplyAsync override, or FlatTableProjection / EfCoreSingleStreamProjection
with their own dispatch)
- 0 ❌ SG-discovery gaps filed against JasperFx#276
Reproducible with:
dotnet build polecat.slnx -c Release \
-p:EmitCompilerGeneratedFiles=true \
-p:CompilerGeneratedFilesOutputPath=$(pwd)/_gensg
then inspecting _gensg/**/JasperFx.Events.SourceGenerator/**.
Includes shape-coverage check confirming every emit-expected shape has
at least one behavioral test in the existing Polecat test suite (no new
per-shape behavioral tests required — all shapes already exercised).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rness `src/Polecat.Tests/Projections/projection_sg_dispatch_audit_tests.cs` — two xUnit theories (`self_aggregating_doc_dispatcher_resolves` + `projection_subclass_dispatcher_resolves`) that register every emit-expected test-library projection through a fresh `DocumentStore` (`AutoCreate.None`, bogus connection string) and assert construction completes without `InvalidProjectionException`. The `DocumentStore` ctor runs `options.Projections.DiscoverGeneratedEvolvers(...)` + `options.Projections.AssertValidity(...)` before any SQL is touched — that's where the post-#276 fail-fast fires when the SG silently fails to emit a `[GeneratedEvolver]` for a registered shape. No `IntegrationContext`, no database setup, ~70ms for all 32 rows. Future `JasperFx.Events.SourceGenerator` regressions surface here immediately rather than waiting for the broader test suite's slow SQL-backed fixtures to fail with the same diagnostic across many files. Each row carries a descriptive label so the xUnit failure message identifies which shape regressed. Deliberately not covered (per `docs/projection-sg-audit-108.md`'s deliberate-bypass column): - `CompositeOrderProjection` / `OrderShippingNotificationProjection` (Evolve override) - `InlineSeProjection` (RaiseSideEffects only; delegates to the `InlineSeAggregate` self-aggregating evolver — which IS covered) - `FlatTableProjection` subclasses (own `_handlers` dispatch) - `EfCoreSingleStreamProjection` subclasses (in `Polecat.EntityFrameworkCore.Tests`, different inheritance chain) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 19, 2026
Closed
jeremydmiller
added a commit
that referenced
this pull request
May 19, 2026
… Weasel alpha.5 + cut 4.0.0-alpha.6 (#111) * Re-pin to current JasperFx + Weasel alphas (close the Marten gap) Polecat was 3 alphas behind on every JasperFx package and 2 alphas behind on Weasel; Marten Phase 2 already re-pinned to the latest matrix. This brings Polecat in lockstep with Marten 9 + the post-PR-#306 SG fixes: JasperFx 2.0.0-alpha.13 → 2.0.0-alpha.16 JasperFx.Events 2.0.0-alpha.12 → 2.0.0-alpha.15 JasperFx.Events.SourceGenerator 2.0.0-alpha.5 → 2.0.0-alpha.8 Weasel.SqlServer 9.0.0-alpha.3 → 9.0.0-alpha.5 Weasel.EntityFrameworkCore 9.0.0-alpha.3 → 9.0.0-alpha.5 Adds two sibling JasperFx package pins for parity with Marten's matrix (Polecat doesn't currently reference these directly, but the pin keeps the lockstep matrix coherent when transitive resolution surfaces them through JasperFx / JasperFx.Events updates): JasperFx.RuntimeCompiler — → 5.0.0-alpha.4 JasperFx.SourceGeneration — → 2.0.0-alpha.5 Pins the 5.x line of JasperFx.RuntimeCompiler (the active continuation of the 4.x lineage) — NOT the parallel stale 2.0.x series Marten was briefly on before fixing it. Refreshes the foundation pin table in docs/migration-guide.md to match. The post-PR-#306 SG changes (per-event wrap in DetermineActionAsync overrides; JasperFx#305 follow-up to #303/#304) didn't trip any of Polecat's existing projection shapes — verified via the 32-row projection_sg_dispatch_audit_tests harness from PR #110, which stays green against the new alphas (56ms locally). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop removed IEventStore.TeardownExistingProjectionProgressAsync impl JasperFx.Events 2.0.0-alpha.13/.14/.15 removed IEventStore<,>.TeardownExistingProjectionProgressAsync from the interface (it had been [Obsolete] in earlier alphas). Polecat's explicit-interface implementation was wrapped in `#pragma warning disable CS0618` to silence the obsolete warning, but the alpha.15 removal turns that into a CS0539 build error: 'DocumentStore.TeardownExistingProjectionProgressAsync(IEventDatabase, string, CancellationToken)' in explicit interface declaration is not found among members of the interface that can be implemented Callers should use TeardownExistingProjectionStateAsync (the canonical non-obsolete API, which Polecat already implements just below the removed one). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Bump Polecat to 4.0.0-alpha.6 First Polecat alpha consuming the post-Phase-2 JasperFx matrix (JasperFx alpha.16 / JasperFx.Events alpha.15 / SourceGenerator alpha.8 / Weasel alpha.5) — matching Marten 9.0.0-alpha.\* lockstep. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (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.
Closes #108.
Summary
Pre-4.0 sweep verifying that every projection type in the Polecat test libraries either gets a
[GeneratedEvolver]dispatcher emitted byJasperFx.Events.SourceGeneratoror deliberately bypasses that path (Evolve/EvolveAsync/DetermineActionAsync/ApplyAsyncoverride, or non-SG dispatch viaFlatTableProjection/EfCoreSingleStreamProjection).Headline: 50 projection-shaped types audited. 41 generated ✅. 9 deliberate bypass ⚠. 0 SG-discovery gaps filed.
Two artifacts
1.
docs/projection-sg-audit-108.md(commit7af2eaf)Full inventory table with file path, base class, method shapes,
partialstatus, SG output file, and ✅/⚠/❌ status per projection. Split into three sections:Plus a shape-coverage check confirming every emit-expected shape has at least one behavioral test in the existing Polecat suite (no new per-shape tests required — coverage already there).
2.
src/Polecat.Tests/Projections/projection_sg_dispatch_audit_tests.cs(commitc62c013)Fast-feedback regression harness — two xUnit theories that register every emit-expected test-library projection through a fresh
DocumentStoreand assert noInvalidProjectionException. The ctor runsProjections.DiscoverGeneratedEvolvers(...)+Projections.AssertValidity(...)before any SQL is opened — that's where the post-#276 fail-fast fires.No
IntegrationContext, no DB setup, ~70ms for all 32 rows. Each row carries a descriptive label so future xUnit failure messages identify which shape regressed (e.g."QuestParty (Guid, has ShouldDelete — the JasperFx#298 repro)").SG gaps filed back
None. The post-#298 fix in
JasperFx.Events 2.0.0-alpha.12(PR JasperFx/jasperfx#300) unblocked the last shape that was tripping the runtime (self-aggregating docs withShouldDeletegoing throughIGeneratedSyncDetermineAction). Every projection in the inventory either generates correctly or falls into the deliberate-bypass column.Commits
7af2eaf— Audit report (docs/projection-sg-audit-108.md)c62c013— Regression harness (src/Polecat.Tests/Projections/projection_sg_dispatch_audit_tests.cs)Reproducing the SG-emit inspection
🤖 Generated with Claude Code