test(parsing): #204 ClassMap regression tests — Rule/ArgumentVirtue/Scenario/Virtue (+9, 159→168) - #476
Merged
Merged
Conversation
…/Scenario/Virtue Adds 9 additive unit tests covering the real CsvHelper ClassMaps of the four entity types that carried historical mapping bugs (Fallacy already has coverage). Baseline 159/0/5 -> 168/0/5. Tests exercise the REAL load path (CsvBase<T,TMap>.LoadFromContent) — which registers the ClassMap, applies PrepareHeaderForMatch (diacritics/underscore/ hyphen/space stripping + lowercasing), treats MissingFieldFound as a non-fatal log, and assigns 0-based RowIndex post-load — using self-contained inline CSV (no external fixture files). No existing test or production code is modified. Rule (4): - every column -> property (pk, Text + 8 localized, print_and_play) - GetId() returns Pk when present - GetId() returns sequential Rules_01/02/03 from RowIndex when Pk absent (the historical bug: GetId() used to return string.Empty) - optional localized columns (es/ar/fa/zh) absent -> no throw, props null ArgumentVirtue (2): - pk column -> Pk property + GetId()==Pk (historical bug: Id/pk was unmapped) - optional en/ru/pt/es columns absent -> no throw Scenario (2): - accented FR headers (coordonnées, catégorie, sous-catégorie, édition février 2022) resolve via PrepareHeaderForMatch — a regression here would silently zero out the FR fields - GetId() returns the path column Virtue (1): - pk column maps to BOTH Id (CsvBase base) and Pk (VirtueClassMap maps both), so base GetId() resolves DoD: 159->168 pass, 0 fail, 5 skip. Additive only. Docs/issue #204. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jsboige
added a commit
that referenced
this pull request
Jun 15, 2026
…columns guard (+2) (#485) Fallacy is the largest entity (~1408 rows) yet had no LoadFromContent regression coverage — the #476 note "Fallacy already has coverage elsewhere" is stale (only an incidental ClassMap registration in MmGeneratorTests existed, asserting no mappings). Two tests via the real CsvBase<Fallacy,FallacyClassMap>.LoadFromContent path: - MapsRequiredColumns: pins pk→PK+Id (GetId resolves), FR required columns, and that present localized columns (en/zh) map. - OptionalLocalizedColumns_AbsentDoesNotThrow [highest value]: a FR-only header set parses without throwing and leaves every representative Optional column null across all 8 languages + Latin/print_and_play. Guards the multilingual harvest — a single localized column losing its .Optional() would crash HeaderValidated (#216/#477 class). Additive only: new file, no existing test/production code modified. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
jsboige
added a commit
that referenced
this pull request
Jun 15, 2026
…HeaderValidationException (#488) New additive test file pinning the bidirectional CSV load contract of the production CsvBase<T,TMap>.LoadFromContent (CsvHelper 31.0.4). The existing ClassMap regression suites (#476 EntityClassMapRegressionTests, #485 FallacyClassMapRegressionTests) covered only ONE direction of the contract ("Optional absent -> no throw"). This pins the inverse half + isolation. Contract halves via a synthetic ContractEntity (decoupled from evolving domain ClassMaps), exercising the REAL CsvBase configuration: - required (non-Optional) column absent from header -> HeaderValidationException. The guard that catches a dropped .Optional() at load time instead of silently zeroing a field (the #216/#477 localization fragility class). - Optional column absent from header -> no throw, property null. - short data row -> MissingFieldFound (non-fatal Logger override) -> no throw; the missing bound field resolves to EMPTY STRING, not null (distinct from the Optional-absent-from-header case which yields null). 3 tests, all green. Full suite 251 passed / 0 failed / 5 skipped (no regression). Additive only: no production code or existing test modified. Dispatch 4rkh1s secondaire (#204 fragile zone, new test file). Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Jun 20, 2026
jsboige
added a commit
that referenced
this pull request
Jun 20, 2026
…sts) (#561) Add TestFallacyCardClassMapRegressionTests — the LAST entity ClassMap without a dedicated regression suite. This closes the ClassMap matrix at 100%: Fallacy (#485), Rule/ArgumentVirtue/Scenario (#476), Virtue (#559), DnnUiString, and now TestFallacyCard. TestFallacyCard is the simplified fallacy entity for visual-test card generation. Its ClassMap declares 5 columns ALL required (non-Optional): Id, Title, Type, IllustrationPath, Description. 5 contract tests via the real load path CsvBase<T,TMap>.LoadFromContent: - MapsAllColumns: all 5 required columns map to their properties. - GetIdReturnsId: GetId() returns Id (the image-generator output-dictionary key). - RequiredColumnAbsent_Throws: a required column drift fails LOUD (HeaderValidationException), not silent null — the data-loss-prevention contract. - ShortRow_DoesNotThrow: a ragged row yields string.Empty for missing fields (MissingFieldFound is a log callback, not throw) — mirrors CsvBaseStrictContractTests. - MultipleRows_LoadInOrder. This is the ai-01 SECONDAIRE dispatch ("TestFallacyCard ClassMap — ferme la matrice"). Additive only, no production code change. Full suite green (434/0/5, baseline 429 + 5). Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <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.
What
9 additive ClassMap regression tests for the 4 entity types that carried historical mapping bugs (Fallacy already covered). Baseline 159/0/5 → 168/0/5 (proven by full suite run).
Why
CsvParserTests.csonly exercises a dummyFallacyRecord/CsvParseron tiny fixtures — it never touches the real entity ClassMaps. So the regressions documented in CLAUDE.md (Rule.GetId() empty, ArgumentVirtue.Pk unmapped, accented FR headers, #216-adjacent mapping) had zero regression coverage. Issue #204 flagged "CsvHelper mapping — verify all entity ClassMap classes parse correctly with real CSV headers" as Medium Priority.Design — real load path, self-contained
Tests call
CsvBase<T,TMap>.LoadFromContent(inlineCsv)— the actual production loader — which:PrepareHeaderForMatch(strips diacritics/underscore/hyphen/space + lowercases) so accented FR headers resolve,MissingFieldFoundas a non-fatal log,RowIndexpost-load (used byRule.GetId()).Inline CSV = self-contained, no external fixture files. No existing test or production code modified (additive only).
Coverage
GetId()==Pk·GetId()==Rules_01/02/03from RowIndex when Pk absent · optional es/ar/fa/zh absent → no throwRules_01…)pk→Pk+GetId()==Pk· optional en/ru/pt/es absent → no throwcoordonnées/catégorie/sous-catégorie/édition février 2022) resolve ·GetId()==pathpkmaps to bothId+Pk(VirtueClassMap maps both) so baseGetId()resolvesNuance discovered (documented in test comments)
CsvHelper has two distinct hooks:
MissingFieldFound(overridden inCsvBase→ logs only) andHeaderValidated(not overridden → keeps default that throwsValidationExceptionif a non-OptionalClassMap member is absent from the header). This is why the real CSVs carry complete headers, and why the test CSVs for Scenario/ArgumentVirtue/Virtue include every non-Optional column. Not a bug — the tests document the real contract.DoD
Scope / notes
Docs/test only — no CSV, no template, no rendering, no config. Serves #204 (test coverage expansion). Release-independent: the mapping logic doesn't change regardless of the visual validation outcome.
🤖 Worker po-2024 on dispatch
3a0d2l. Verdict QA visuelle stays ai-01 — this is unit-test parsing logic, not a visual PASS.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com