test(localization): #204 field-mapping regression — Rules/Virtues/Scenarii (#216 root cause) - #477
Merged
Merged
Conversation
…narii (#216 root cause) Adds 3 NEW additive test files covering the localization field-mapping for the three remaining card types, guarding the #216 class of bug (FrontFieldConversions referencing field names that don't exist in the template -> template.Replace is a silent no-op -> non-FR PDFs ship French content). Baseline 168/0/5 -> 182/0/5. NEW files (dispatch #204 amend 3xvx9d): created separately so FallaciesLocalizationTests.cs stays untouched (owned by PR #444, avoids merge collision). Each file applies the REAL substitution chain (mirrors CardSetLocalization.TranslateCardSetInfo front branch) against the template on disk — no mocking: - RulesLocalizationTests.cs (3): {{markdown Text}} -> {{markdown Text_<lang>}} per language; root-cause guard (every FrontFieldConversions source must exist as a token in the template); 7-language coverage of the Text conversion. - VirtuesLocalizationTests.cs (3): title/description/remark/family/subfamily/subsubfamily _fr -> _<lang> for all 7 languages; root-cause token-existence guard; suffix-overlap invariant (documents why the non-most-specific-first Virtues order still produces correct bindings — the trailing "}}" suffix + matching "_<lang>" destination makes the overlap idempotent). - ScenariiLocalizationTests.cs (3): FR tokens (titre/catégorie/contexte/enjeu/baratineur/ piocheur) -> localized columns for en/ru/pt; root-cause token-existence guard (accented catégorie included); ExceptionPatterns presence guard (category-based asset filenames must backtrack to FR catégorie or images break in non-FR Scenarii). DoD: 168 -> 182 pass, 0 fail, 5 skip. Additive only (3 new files, no existing file modified). No bug revealed: all conversions produce correct bindings; the Virtues ordering test was rewritten from a too-strong substring invariant to an empirical end-binding check after reasoning showed the overlap is benign (idempotent under matching suffix). 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>
jsboige
added a commit
that referenced
this pull request
Jun 16, 2026
#491) Pin the two fragile zones of the DocumentLocalization mechanism that existing coverage (MmGeneratorTests) missed: 1. Ordering contract (headline). The family-hierarchy DocumentLocalization in AssetConverterConfig carries the documented comment "Order: most specific first (Soussousfamille > SousFamille > Famille) to avoid partial matches" because DoStaticConversions is a naive substring Replace and "Famille" is a substring of "SousFamille". No test pinned this contract. New theory runs the REAL family-hierarchy entry (located by TargetProperties, not list index) on a template carrying all three family keywords, for all 7 target langs, asserting each resolves to its distinct localized property with no "SousFamily" contamination — the corruption signature of a broken ordering. Same substring fragility class as the card-set mapping (#477) and CSV contract (#488). 2. 8-language release scope. The existing MindMapLocalization theory covers only en/ru/pt; the release targets 8 langs and the config declares 7 target langs (en/ru/pt/es/ar/fa/zh). New theory closes the gap for es/ar/fa/zh across every Fallacy text + family expression, so a dropped conversion surfaces immediately. Additive only: 1 new file (MindMapLocalizationRegressionTests.cs), 11 tests, zero production code and zero existing test modified. Verified: 11/11 new tests green; full suite 270 passed / 0 failed / 5 skipped. Co-authored-by: Your <your.email@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Jun 16, 2026
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
3 NEW additive test files covering the localization field-mapping for the three remaining card types, guarding the #216 class of bug (FrontFieldConversions referencing field names absent from the template →
template.Replaceis a silent no-op → non-FR PDFs ship French content). Baseline 168/0/5 → 182/0/5.Why
#216 was caused exactly by this: Fallacies conversions pointed at
Titre/Definition/Exemplewhich never existed in the template. The Fallacies file already has regression tests, but Rules/Virtues/Scenarii had none — the same silent-contamination bug could recur there undetected. Issue #204 flagged "LocalizationConfig — field conversion logic" as Medium Priority.NEW files (dispatch
3xvx9damend)Per ai-01's amend, created as separate files so
FallaciesLocalizationTests.csstays untouched (owned by PR #444 — avoids merge collision). Each applies the real substitution chain (mirrorsCardSetLocalization.TranslateCardSetInfofront branch) against the template on disk — no mocking:RulesLocalizationTests.cs{{markdown Text}}→{{markdown Text_<lang>}}per language · root-cause guard (everysourceFieldNamemust exist as a token in template) · 7-language Text conversionVirtuesLocalizationTests.cs_fr→_<lang>for all 7 langs · root-cause token-existence guard · suffix-overlap invariantScenariiLocalizationTests.csRoot-cause guard pattern
Each file has a
*_Front_Conversions_Reference_Only_Template_Existing_Tokenstest: loops over everysourceFieldNamein the FrontFieldConversions and asserts the formatted pattern actually appears in the template. If anyone adds a conversion pointing at a non-existent field, this fails immediately instead of silently shipping FR content. All passed — no latent bug found.Investigation honesty — one test rewritten
The first Virtues ordering test (
Virtues_Front_Conversions_Are_Ordered_MostSpecificFirst) failed: the config ordersfamily_frbeforesubfamily_fr/subsubfamily_fr(not most-specific-first). I reasoned through it (didn't "verdir" by flipping the assertion):family_fr}}is a suffix-substring ofsubfamily_fr}}(overlap exists),.Replace("family_fr}}","family_en}}")on{{subfamily_fr}}yields{{subfamily_en}}, and the subsequent steps find nosubfamily_fr}}to match (harmless no-op),_endestination suffix matches the field suffix.Rewrote as
Virtues_Family_Subtokens_Resist_Suffix_Overlap_Under_Config_Order— empirically asserts the end bindings are correct across all 7 languages (no residual_fr). Documents why the non-most-specific-first order is safe here. No bug; just a fragile-by-chance invariant made explicit.DoD
FallaciesLocalizationTests.csuntouched)Scope
Test-only — no CSV, no template, no rendering, no config, no existing test changed. Serves #204 (coverage) + guards #216 recurrence. Release-independent (mapping logic stable regardless of visual validation outcome).
🤖 Worker po-2024 on dispatch
3a0d2l(secondary, per amend3xvx9d). Verdict QA visuelle stays ai-01.Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com