Spaces:
Sleeping
Sleeping
| import random | |
| from research.corpus import BaseTriple | |
| from research.defects import apply_operators, identity, swap_random, truncate_head | |
| def _triple(arxiv_id: str, abstract: str = "First sentence. Second sentence.") -> BaseTriple: | |
| return BaseTriple( | |
| paper_id="test/0001", | |
| cite_key=f"key_{arxiv_id}", | |
| cited_arxiv_id=arxiv_id, | |
| paragraph_text=f"A claim attributed to {arxiv_id}.", | |
| paragraph_line=1, | |
| abstract=abstract, | |
| cited_title=f"Title {arxiv_id}", | |
| ) | |
| def test_identity_preserves_abstract_and_labels_supports(): | |
| base = _triple("2301.00001") | |
| out = identity(base) | |
| assert out.abstract == base.abstract | |
| assert out.label == "supports" | |
| assert out.operator == "identity" | |
| def test_swap_random_replaces_abstract_and_labels_unrelated(): | |
| base = _triple("2301.00001", "Original abstract.") | |
| donor = _triple("2301.99999", "Donor abstract from unrelated paper.") | |
| rng = random.Random(0) | |
| out = swap_random(base, [base, donor], rng) | |
| assert out is not None | |
| assert out.abstract == donor.abstract | |
| assert out.label == "unrelated" | |
| assert "2301.99999" in out.notes | |
| def test_swap_random_returns_none_when_no_donors(): | |
| base = _triple("2301.00001") | |
| rng = random.Random(0) | |
| assert swap_random(base, [base], rng) is None | |
| def test_truncate_head_keeps_only_first_sentence(): | |
| base = _triple("2301.00001", "First. Second. Third.") | |
| out = truncate_head(base) | |
| assert out.abstract.rstrip(".").strip() == "First" | |
| assert out.label == "unclear" | |
| assert out.operator == "truncate_head" | |
| def test_truncate_head_handles_short_abstracts(): | |
| base = _triple("2301.00001", "Only one.") | |
| out = truncate_head(base) | |
| # No-op for single-sentence abstracts — we still produce the entry; label | |
| # mismatch will be caught by the primary-author spot-check per PLAN.md. | |
| assert out.abstract != "" | |
| assert out.operator == "truncate_head" | |
| def test_apply_operators_produces_one_per_base_per_op(): | |
| bases = [_triple(f"2301.{i:05d}") for i in range(1, 4)] | |
| out = apply_operators(bases, seed=42) | |
| ops = [d.operator for d in out] | |
| # identity + truncate_head always fire; swap_random needs a donor (always available | |
| # here) so we expect 3 per base. | |
| assert ops.count("identity") == 3 | |
| assert ops.count("truncate_head") == 3 | |
| assert ops.count("swap_random") == 3 | |
| def test_apply_operators_is_deterministic_under_fixed_seed(): | |
| bases = [_triple(f"2301.{i:05d}") for i in range(1, 6)] | |
| a = apply_operators(bases, seed=123) | |
| b = apply_operators(bases, seed=123) | |
| assert [d.notes for d in a] == [d.notes for d in b] | |