Skip to content

test(hdf-converters): add adversarial schema-validation corpus - #242

Open
wdower wants to merge 1 commit into
mainfrom
fix/exporter-schema-conformance
Open

test(hdf-converters): add adversarial schema-validation corpus#242
wdower wants to merge 1 commit into
mainfrom
fix/exporter-schema-conformance

Conversation

@wdower

@wdower wdower commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Six exporters have schema-validation tests, but every one validates only fully-populated happy-path fixtures. Edge-case tests exist across most converters and assert on structs, thrown errors, or string contents — they never feed output back through the validator. Schema coverage and edge-case coverage are disjoint sets, which is why five spec-violating defects shipped undetected.

Add a shared corpus split into the two contracts an exporter owes, which are opposites and were previously conflated: sparse-but-schema-valid HDF must convert into schema-valid output, while HDF the source schema rejects must be refused — never with a panic, and never with a success carrying an invalid document. Each case's tier is asserted against the real HDF schema, so a mislabeled case fails loudly instead of quietly asserting the wrong contract.

The per-case contract is a pure function rather than assertions inside a subtest closure, so the runner's own logic is testable. Cross-language parity is enforced byte-for-byte: both sides canonicalize (sorted keys, matched escaping, normalized -0) against a Go-generated golden that TypeScript only verifies, so neither side can redefine the corpus to match itself.

Adoption is opt-in per converter; no exporter is wired up yet.

Six exporters have schema-validation tests, but every one validates only
fully-populated happy-path fixtures. Edge-case tests exist across most
converters and assert on structs, thrown errors, or string contents — they
never feed output back through the validator. Schema coverage and edge-case
coverage are disjoint sets, which is why five spec-violating defects shipped
undetected.

Add a shared corpus split into the two contracts an exporter owes, which are
opposites and were previously conflated: sparse-but-schema-valid HDF must
convert into schema-valid output, while HDF the source schema rejects must be
refused — never with a panic, and never with a success carrying an invalid
document. Each case's tier is asserted against the real HDF schema, so a
mislabeled case fails loudly instead of quietly asserting the wrong contract.

The per-case contract is a pure function rather than assertions inside a
subtest closure, so the runner's own logic is testable. Cross-language parity
is enforced byte-for-byte: both sides canonicalize (sorted keys, matched
escaping, normalized -0) against a Go-generated golden that TypeScript only
verifies, so neither side can redefine the corpus to match itself.

Adoption is opt-in per converter; no exporter is wired up yet.

Signed-off-by: Will Dower <will@dower.dev>
@wdower
wdower requested a lite review from Copilot August 24, 2026 00:49
@wdower wdower self-assigned this Aug 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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