Skip to content

test: Make every invalid fixture fail for the reason it is named for - #1432

Open
isaacschepp wants to merge 5 commits into
mainfrom
test/invalid-fixtures
Open

isaacschepp wants to merge 5 commits into
mainfrom
test/invalid-fixtures

Conversation

@isaacschepp

@isaacschepp isaacschepp commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

A review of glx/testdata/invalid/assertion-participant-invalid-person/archive.glx found that it fails validation, but never for the broken person reference it is named for. No test loads it, so nothing noticed. Validating every invalid fixture showed most of them had drifted the same way as the schema changed. They "failed", but only on fields the schema dropped or vocabularies they never defined, so they guarded nothing.

Fixture Failed on (before) Now fails on
assertion-participant-invalid-person subject as a bare string, event without participants Person references non-existent persons: person-nonexistent only
assertion-participant-invalid-role same Role references non-existent participant_roles: invalid-role only
assertion-participant-and-value bare-string subject, plus its rule the participant/value exclusion only
assertion-participant-and-property its rule, plus event without participants the participant/property exclusion only
broken-references top-level locator, text_from_source, description, tags; missing roles and source types its 3 broken references only
comprehensive-broken-references top-level locator; value_type: reference its 6 broken references only
missing-required-fields its fields, plus locator and second missing fields one error per entity, each the field it is named for
invalid-relationship-participants its reference, plus 6 missing-role errors its reference only

The fixes move each stale field to its current home (properties.locator, properties.description, …), give the assertion fixtures a typed subject and event participants, and give each fixture the vocabulary entries it uses. Directory fixtures get copies of the standard files, checked by TestExampleVocabulariesMatchStandard. Single-file fixtures get only the inline entries they need. That way no fixture depends on how #1355 (directory archives not falling back to the standard vocabularies) is resolved.

A second commit cuts broken-references down from about 30 files, a near-copy of the complete-family example, to the one assertion it tests: the citation and source it validly references, and the confidence vocabulary it uses. All the filler was valid, read by no test, and had to follow every schema change; it is what made the fixture fail on removed fields in the first place.

A test that keeps them honest

TestInvalidFixtures (glx/testdata_fixtures_test.go) validates every directory under testdata/invalid as a directory, which runs the cross-reference stage as well. It then checks:

  • every error listed for the fixture in invalidFixtures is reported;
  • every reported error line matches one of them, so an unrelated failure fails the test;
  • every directory has an entry, and every entry has a directory.

Putting the old assertion-participant-invalid-person back makes it fail with unexpected error, so the fixture fails for another reason: - /assertions/assertion-invalid/subject: 'oneOf' failed.

Fixtures that were never invalid

Three never failed, and should not. They move to testdata/valid/, and TestValidFixturesWithWarnings checks them:

  • assertion-unknown-property: its own header says it must pass, with a warning. It was failing only on an undefined medium confidence. It now passes, but it cannot warn yet, because the validator does not check assertion property names (Validator never checks assertion property against property vocabularies, despite the spec saying it does #1224).
  • invalid-properties → unknown-person-properties: unknown person properties are warnings by design. It now passes with exactly its two warnings.
  • missing-vocabularies: the standard vocabularies fill in, so a person with standard properties is valid with no warning. The README had claimed it should warn.

invalid-assertion-properties stays in invalid/, skipped with a pointer to #1224. With its missing citation added, it will fail for the right reason once that lands.

Related issues

Refs #1224 and #1355. Neither is closed by this PR.

Review focus

  • The expected-error lists in invalidFixtures. The two mutual-exclusion fixtures can only be asserted as 'not' failed, because the schema validator does not name the rule. I confirmed that each passes once its conflicting field is removed.
  • Moving three fixtures to valid/, one of them under a new name.

Testing

  • go test -count=1 ./glx/... passes (both packages). 13 invalid fixtures pass and 1 is skipped; 3 valid-with-warnings cases pass.
  • golangci-lint run ./glx/... reports nothing for the new test file.
  • Mutation check: restoring the old invalid-person fixture fails the test, as described above.

Breaking changes

None. Tests and test data only, so no CHANGELOG entry.

Most testdata/invalid archives had drifted as the schema changed and failed
validation for unrelated reasons, so they guarded nothing:

- The four assertion-participant fixtures gave subject as a bare string (the
  schema wants a typed reference such as {event: ...}), their event had no
  participants, and they defined no vocabularies. invalid-person and
  invalid-role never reached the check they are named for.
- broken-references, comprehensive-broken-references and
  missing-required-fields used fields that now live under properties
  (locator, text_from_source, description), dropped fields (tags), a removed
  value_type: reference, and a stale source type, so validation stopped at the
  schema stage before any reference was checked.
- invalid-properties, invalid-relationship-participants and
  invalid-assertion-properties failed only on vocabularies they never defined.

Each fixture now defines what it uses and fails only for its stated error.

TestInvalidFixtures validates every directory under testdata/invalid, checks
the errors listed for it, and fails on any other reported error, or on a
directory with no entry. Putting the old invalid-person fixture back makes it
fail with "unexpected error, so the fixture fails for another reason".

Three fixtures never failed and are not invalid, so they move to
testdata/valid: assertion-unknown-property (meant to pass, with a warning that
needs #1224), invalid-properties as unknown-person-properties
(unknown person properties are warnings by design) and missing-vocabularies
(the standard vocabularies fill in). TestValidFixturesWithWarnings checks
them. invalid-assertion-properties stays, skipped until #1224
lands.

The testdata README now lists every fixture, says which test checks it, and
notes that validating a single file skips cross-reference checks.

Signed-off-by: Isaac Schepp <isaac.schepp@gmail.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Deploying genealogix with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9dc6abd
Status: ✅  Deploy successful!
Preview URL: https://ebc5e3d3.genealogix.pages.dev
Branch Preview URL: https://test-invalid-fixtures.genealogix.pages.dev

View logs

@codecov

codecov Bot commented Oct 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

isaacschepp and others added 4 commits October 28, 2026 12:55
The fixture was a near-copy of the complete-family example: about 30 files
of persons, places, events, relationships, repositories and vocabularies,
around one assertion with three broken references. All of that filler was
valid, read by no test, and had to follow every schema change. It did not:
it is what made the fixture fail on removed fields instead of its references.

It now holds only the assertion, the citation and source the assertion
validly references, and the confidence vocabulary it uses. Validation reports
exactly the three broken references, as TestInvalidFixtures requires.

Removing the events also removes the review findings on event-births.glx:
the non-canonical subject role, the trailing whitespace and the descriptions
that restated the event.

Signed-off-by: Isaac Schepp <isaac.schepp@gmail.com>
source-census.glx, citation-census.glx and assertion-john-birth.glx held source-census-1851, citation-census-john and assertion-john-birth-date. Each file now carries its entity's ID, the layout glx writes and the complete-family example uses.

Signed-off-by: Isaac Schepp <isaac.schepp@gmail.com>
citation-birth exists to test its two broken references. The locator was unrelated to them, had already broken the fixture once, and relied on a citation_properties vocabulary the fixture does not ship. The trailing blank line goes with it.

Signed-off-by: Isaac Schepp <isaac.schepp@gmail.com>
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.

1 participant