Skip to content

test: cover deeply nested evidence traversal in the reference plugin#51

Merged
cmungall merged 1 commit into
mainfrom
test/deep-nested-evidence-traversal
Jun 17, 2026
Merged

test: cover deeply nested evidence traversal in the reference plugin#51
cmungall merged 1 commit into
mainfrom
test/deep-nested-evidence-traversal

Conversation

@cmungall

Copy link
Copy Markdown
Member

What

Adds a test suite verifying that ReferenceValidationPlugin recursively discovers and validates evidence nested 2+ levels below the tree root, e.g.:

Community (root) -> MemberRecord  -> EvidenceItem (reference + snippet)
Community (root) -> Interaction   -> EvidenceItem

The existing test_schema.yaml only exercised 1-level nesting (Statement -> Evidence). This mirrors real-world schemas like CommunityMech (MicrobialCommunity -> TaxonomicComposition -> EvidenceItem).

Coverage

  • process() path: traversal through members and interactions, multiple members × multiple evidence, valid snippets pass / invalid snippets caught.
  • Field detection: implements annotations (reference + excerpt) discovered on EvidenceItem at depth; root class correctly has none.
  • Full linkml.validator.Validator pipeline (the same path the CLI validate data uses).

Why a separate PR

These tests are independent of the full-text/PDF framework in #48 (they don't touch that subsystem) and pass against the current plugin on main — the recursive traversal already works; this locks in that behavior. Keeping them out of #48 keeps that PR focused.

10 tests, all green (pytest + mypy + ruff). New fixtures: a deep-nesting schema and valid/invalid data files.

Ref: CultureBotAI/CommunityMech#3

🤖 Generated with Claude Code

Adds tests verifying ReferenceValidationPlugin recursively discovers and
validates evidence nested 2+ levels below the tree root
(Community -> MemberRecord/Interaction -> EvidenceItem), mirroring schemas
like CommunityMech. The existing test_schema only exercised 1-level
nesting (Statement -> Evidence).

Covers both the plugin's process() path and the full
linkml.validator.Validator pipeline (the CLI path), plus field detection
of implements annotations at depth.

These pass against the current plugin (the traversal already works) and
are independent of the full-text/PDF work in #48, so they ship separately.

Ref: CultureBotAI/CommunityMech#3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Claude finished @cmungall's task in 1m 30s —— View job


Review: deep nested evidence traversal tests

  • Read the new test files and fixtures
  • Read the plugin under test (reference_validation_plugin.py)
  • Assess code quality, correctness, coverage
  • Post review feedback

This is a clean, well-documented, test-only PR that locks in recursive traversal behavior already present on main. I traced the new tests against ReferenceValidationPlugin._validate_instance and the fixtures — the wiring is correct:

  • Community → members[MemberRecord] → evidence[EvidenceItem] recursion is handled by the isinstance(value, list) branch (plugin lines 265–273), and EvidenceItem exposes reference (implements: linkml:authoritative_reference) + snippet (implements: linkml:excerpt), which the legacy-URI detection in _find_reference_fields/_find_excerpt_fields picks up. ✅
  • Fixtures back the assertions: PMID_TEST001.txt contains "Protein X functions in cell cycle regulation" and "plays a critical role in DNA repair"; PMID_TEST002.txt contains "Protein Y inhibits apoptosis" — so the valid-data test legitimately expects 0 errors, and the fabricated snippets in the invalid data legitimately fail. ✅
  • Tests are hermetic: references are pre-seeded into a tmp_path cache and rate_limit_delay=0.0, so no network. ✅

Suggestions (all non-blocking)

1. Duplicated cache-seeding boilerplate. The fixture-copy loop appears 3× — in the plugin_with_fixtures fixture (lines 59–62) and inlined in both full-pipeline tests (lines 318–321, 375–378). Worth extracting a small helper to keep them in sync:

def _seed_cache(cache_dir: Path) -> None:
    for pattern in ("*.md", "*.txt"):
        for f in FIXTURES_DIR.glob(pattern):
            (cache_dir / f.name).write_text(f.read_text())

Fix this →

2. "Bug reproduction" wording is slightly misleading. Comments call these "the core bug reproduction" / "the actual bug" (lines 105, 113–115), but the PR body states the behavior already works on main. These are regression guards, not repros — consider rewording so a future reader doesn't go hunting for a live bug.

3. Coverage gap vs. the PR's "2+ levels" claim. Every test nests exactly 2 levels (Community → Container → EvidenceItem). To truly cover "2+", consider one case at 3 levels (e.g. Community → MemberRecord → sub-container → EvidenceItem), which is closer to arbitrarily-deep real schemas. Optional, but it would make the title literally true.

4. No mixed valid+invalid-in-one-tree case. test_deep_nesting_multiple_members_multiple_evidence uses all-invalid snippets and asserts >= 3. A tree that mixes valid and invalid evidence and asserts exactly the invalid count would guard against false positives on the valid siblings (the >= assertions can't catch over-reporting). Minor.

5. FIXTURES_DIR is implicitly required. The plugin_with_fixtures fixture silently no-ops if tests/fixtures/ were ever empty/missing, which would turn the == 0 valid-data assertion into a vacuous pass (no cache → ... actually it'd fail to find refs). Not a real problem today since the dir is populated, just noting the implicit dependency.

Verdict

Solid, hermetic, well-isolated regression coverage that mirrors the real CommunityMech pattern. None of the above blocks merge — they're polish. Nice work keeping it decoupled from #48.

Note: I was unable to execute pytest/mypy/ruff in this environment (command approval), so the green-build claim rests on CI. I verified correctness by reading the plugin, schema, data, and fixtures.

@cmungall cmungall merged commit bd47893 into main Jun 17, 2026
7 checks passed
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