Skip to content

tests(exit_parity): single return-only fixture can't catch the throw/panic/exit divergences its doc claims to guard (masks #779) #945

@dekobon

Description

@dekobon

Summary

tests/exit_cross_language_parity.rs documents itself as the guardian of cross-language exit-metric parity, but its single fixture exercises only return — the one exit construct counted identically in every language — so it is structurally incapable of detecting the throw/raise/panic/error/exit/yield divergences that are the real cross-language inconsistencies (e.g. #779). The module doc's claims overstate what the test guards.

Location

  • tests/exit_cross_language_parity.rs:8-22 (module doc)
  • tests/exit_cross_language_parity.rs:38-205 (the single early_exit_in_while_loop_parity test)

Evidence

The module doc claims comprehensive cross-language coverage:

//! Per lesson 11 ... the same logical construct must produce the same
//! metric value across every language we support ...
//!
//! ... Every supported language tested below reports `exit_max() == 1`.

Two problems make this misleading:

  1. "every language we support" / "Every supported language tested below" is false.
    src/metrics/nexits.rs implements Exit for 23 languages (Python, Mozjs,
    Javascript, Typescript, Tsx, Cpp, Mozcpp, C, Objc, Java, Groovy, Rust, Csharp,
    Go, Perl, Kotlin, Lua, Bash, Tcl, Irules, Php, Ruby, Elixir). The test covers
    only 12 (Rust, Cpp, Java, Javascript, Typescript, Csharp, Php, Python, Bash,
    Kotlin, Groovy, Go). Lua, Ruby, Elixir, Perl, Tcl, Irules, Objc, C, Mozjs,
    Mozcpp, and Tsx are absent — including the two languages named in the open
    divergence metrics(nexits): Go panic and Lua error/os.exit uncounted as exits (cross-language inconsistency) #779 (Lua is omitted entirely; Go is present but see point 2).

  2. The fixture only exercises return, which is uniform everywhere. The body
    is a while/if-guarded single return. Every language's Exit impl counts
    its return node, so this path is trivially in parity. The genuine
    cross-language exit divergences live in the non-return constructs:

    Because the fixture never uses any of these, the test passes identically
    whether or not metrics(nexits): Go panic and Lua error/os.exit uncounted as exits (cross-language inconsistency) #779 is fixed. It cannot catch metrics(nexits): Go panic and Lua error/os.exit uncounted as exits (cross-language inconsistency) #779, metrics(npa): PHP counts enum cases as attributes; Java/Kotlin/Rust/C# do not (cross-language inconsistency) #781, or metrics(loc): multi-line string interior rows counted as PLOC in Python but as blank in Perl (cross-language inconsistency) #778-style
    divergence — yet its doc tells a reader those are guarded.

The sibling tests/cyclomatic_cross_language_parity.rs covers a broader set
(including Tcl, Irules, Objc) and multiple fixture shapes, underscoring that
the exit-parity test's single trivial fixture is the gap, not a deliberate
minimalism.

Expected Behavior

Either the doc should be scoped down to what the test actually proves ("the
return exit construct is in parity across these 12 languages"), or — better —
the test should add fixtures that exercise the divergent exit constructs
(throw/raise/panic/error/os.exit/yield) across the languages that
support them, so the suite actually guards the cross-language exit-parity
contract it claims to.

Actual Behavior

The doc claims the test guards exit parity across "every supported language,"
but the test only proves return-parity across 12 of 23 languages and is blind
to the exact divergences (#779) it implies it protects against. A reviewer
trusting this file would wrongly believe Go-panic / Lua-error parity is covered.

Impact

False confidence in cross-language exit-metric parity. A regression that breaks
non-return exit counting in any language — or a new language wired up with an
incomplete Exit set — sails past this suite while the module doc asserts it is
covered. This is the test-quality masking gap behind #779 remaining open without
a guarding test.


Resolution (commit 6a671493)

Fixed (preferred option): tests/exit_cross_language_parity.rs now
exercises the divergent exit constructs. Each language fixture has two
counted exits — a return plus its abrupt-exit construct
(throw/raise/panic/error/process-exit), or two returns for
return-only languages — asserting nexits_sum() == 2 per language.
Coverage extended from 12 to all 23 languages with an Exit impl. The
module doc was rewritten to match. Test-via-revert confirmed the new
fixtures catch dropped Go-panic/Lua-error/Kotlin-throw counting
(the #779 masking gap). See the resolution comment for details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions