Skip to content

test(fallacy): pin 8 LinkXxFallback cascade contracts + null-floor discovery - #558

Merged
jsboige merged 1 commit into
masterfrom
test/fallacy-link-fallback-contract
Jun 20, 2026
Merged

test(fallacy): pin 8 LinkXxFallback cascade contracts + null-floor discovery#558
jsboige merged 1 commit into
masterfrom
test/fallacy-link-fallback-contract

Conversation

@jsboige

@jsboige jsboige commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

What

Pin the 8 per-language LinkXxFallback cascades on Fallacy (Fr/En = 2-deep, Ru/Pt/Es/Ar/Fa/Zh = 3-deep: target → En → Fr) — the mind-map link resolution that feeds FallacyMindMapDocumentConfig.LinkExpression ({item.LinkFrFallback}). 29 contract tests, additive only, no production code change. Full suite 417/0/5.

This is the ai-01 "couverture tests" runway (dispatched at the 05:08Z tick after merging #555/#556/#557).

Why

French is the source language. The cascade design is intentionally asymmetric — a subtle fragility that had zero unit coverage despite being referenced in MmGeneratorTests and MindMapLocalizationRegressionTests:

  • LinkFrFallback / LinkEnFallback are 2-deep (Fr↔En: the two source-ish languages).
  • LinkRu/Pt/Es/Ar/Fa/Zh are 3-deep: target → En → Fr.

The silent-wrong-output risk: a fallacy that ships with only a French link must still resolve to French in every non-source export. A refactor that "symmetrizes" the cascade (e.g. makes every language a 2-deep target→Fr, or reorders En/Fr) would drop the French floor — producing a mind-map node with an empty link, no exception, no log, invisible except by opening every generated mind-map.

Discovery surfaced by writing the tests

The cascade floor is null, not string.Empty. When all three link sources are null, the expression IsNullOrEmpty(LinkEn) ? LinkFr : LinkEn returns LinkFr which is null. 7 of the initial assertions had to flip from BeEmpty() to BeNull() — the tests now pin the real contract, not an idealized one. This null-propagation (empty text in Mustache, but null to any C# consumer) is itself a silent-wrong-output hazard worth documenting.

The 29 tests (FallacyLinkFallbackTests)

Group Tests What it pins
LinkFrFallback (2-deep) 3 primary present → Fr; primary null → En; both null → null (documented)
LinkEnFallback (2-deep inverse) 2 primary present → En; primary null → Fr
Non-source × 6 langs (Theory ×4) 24 target→En→Fr cascade: target present (short-circuit); target null + En present → En; target+En null + Fr present → Fr (the fragile floor); all null → null

Reflection helpers (SetLink/GetFallback) let one [Theory] cover all 6 non-source languages uniformly — 4 branches × 6 languages = 24 assertions from 4 methods.

Verification

  • New tests: 29/29 pass.
  • Full suite: 417 passed / 0 failed / 5 skipped — no regression (baseline 388 + 29 new).
  • Build: 0 errors.
  • No production code touched — pure additive coverage.

Related

🤖 Generated with Claude Code

…scovery

Pin the 8 per-language LinkXxFallback cascades on Fallacy (Fr/En = 2-deep,
Ru/Pt/Es/Ar/Fa/Zh = 3-deep: target → En → Fr), the mind-map link resolution that
feeds FallacyMindMapDocumentConfig.LinkExpression ({item.LinkFrFallback}) and is
referenced — but NOT behavior-pinned — by MmGeneratorTests and
MindMapLocalizationRegressionTests.

29 contract tests (3 Fr + 2 En + 6×4 Theory for non-source languages) via reflection
helpers so one Theory covers all 6 languages uniformly.

Discovery surfaced by the tests: the cascade floor is NULL, not string.Empty — when
all three link sources are null, the expression returns null (not ""), which propagates
into the Mustache template as empty text but is null to any C# consumer. A silent-
wrong-output hazard documented explicitly (7 of the initial assertions had to flip from
BeEmpty to BeNull — the test now pins the REAL contract).

This is the ai-01 "couverture tests" runway. No production code change — additive tests
only. Full suite green (417/0/5, baseline 388 + 29 new).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NanoClaw]#558 (test(fallacy): 8 LinkXxFallback cascade contracts + null-floor discovery)

Verdict: clean additive contract suite, mergeable as-is.

Tests are real assertions, not stubs. All 29 use FluentAssertions on actual Fallacy.LinkXxFallback resolution — e.g. LinkFrFallback_PrimaryNull_FallsBackToEn asserts .Should().Be("en-link") against a Fallacy with LinkFr = null, and NonSource_TargetAndEnNull_FrPresent_ReturnsFr (Theory ×6) asserts the fragile French floor .Should().Be("fr-link"). No Assert.True(true), no empty bodies.

8 cascades are coherent and match the body. Fr/En are 2-deep (5 [Fact]s: Fr→En primary/fallback/null + En→Fr primary/fallback), the 6 non-source langs (Ru/Pt/Es/Ar/Fa/Zh) are 3-deep via 4 [Theory] branches ×6 = 24. Spot-checked the 3-deep chain: when LinkRu=null, LinkEn="en-link", the test asserts the fallback returns "en-link" (target→En), and when only LinkFr is set it asserts "fr-link" (the source-language floor) — that's the real target→En→Fr cascade, not a symmetric 2-deep.

Null-floor discovery is genuine and well-documented. The body's claim holds: IsNullOrEmpty(LinkFr) ? LinkEn : LinkFr with both null returns LinkEn which is null — NOT string.Empty. The LinkFrFallback_BothNull_ReturnsNull and NonSource_AllNull_ReturnsNull (Theory ×6) tests pin this real behavior. The author notes 7 initial assertions had to flip from BeEmpty() to BeNull() — i.e. the tests were corrected to match the actual contract rather than an idealized one. Worth knowing because that null propagates to Mustache as empty text but stays null to any C# consumer — a silent-wrong-output hazard the contract now documents.

Additive-only confirmed: single new file FallacyLinkFallbackTests.cs, +167/-0, zero production .cs modified. Class compiles-coherent: proper using (xunit, FluentAssertions, Entities), correct [Fact]/[Theory]/[InlineData] attributes, namespace matches folder structure, reflection helpers (SetLink/GetFallback) are well-formed for the 6-lang Theory fan-out. Security scan clean — no secrets/keys/paths, all test data synthetic ("fr-link", "xx-link").

Comment-only (self-review cap).

@jsboige
jsboige merged commit 5105eb2 into master Jun 20, 2026
3 checks passed
@jsboige
jsboige deleted the test/fallacy-link-fallback-contract branch June 20, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants