test(fixtures): replace sector-specific example material with generic, fictitious examples — green
Every fixture, test document, tool example and document now uses an invented kitchen-and-baking handbook series, written in this repository. The package's behaviour is unchanged; src/ changes are comments and help text only. - Generated fixtures are regenerated from their generators. Their structural counts are identical before and after: elements, images, rows, cells, headings, bookmarks and the witness inventory's per-document totals. The image-inbox and accounting documents are renamed kapittel-84-*. - tools/okf_accounting_gate.py: the two options that named one real corpus each are replaced by a generic, repeatable --corpus PATH with no default. Row 5 compares the PDF pair alone. Gate verdict unchanged: RED rows 2, 3, 6. - tools/okf_witness.py: the STS JSON reader for one publisher's delivery is removed, along with its three twins and five tests. The mutation harness loses W09. - docs/: 13 dated reports that documented runs on a retired reference corpus are removed, and 40 are neutralized. Dead links are removed, and no new dangling path is introduced. - The synthetic MCP-gate corpus and the residual probe words are neutral. Valgt: keep the `okf quality --fasit` bar value (the measured fraction, one corpus) and rewrite only its provenance, because the verdict stays unchanged and the number names nothing. Term check with the local list: 0 of 411 tracked files, 0 file names, 0 of 27 binary fixtures. Suite after git add: 2457 passed, 1 skipped. The base tree had 2460 passed and 2 skipped; five tests went with the JSON reader and four were added by the term check. ruff, ruff format and mypy --strict src/ are clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1e7345a401
commit
9d1f4b14ed
174 changed files with 1889 additions and 6512 deletions
|
|
@ -48,7 +48,7 @@ PLAN_AT = "2026-08-30T09:00:00Z"
|
|||
DOCUMENT = (
|
||||
"0 Forord: bakgrunn for konseptet.\n"
|
||||
"1 Brannkonsept: krav til seksjonering.\n"
|
||||
"2 Roemning: to uavhengige veier.\n"
|
||||
"2 Roemning: to uavhengige utganger.\n"
|
||||
"3 Baereevne: R60 for hovedbaeresystem.\n"
|
||||
"4 Slokkeanlegg: sprinkler i hele bygget.\n"
|
||||
)
|
||||
|
|
@ -179,7 +179,7 @@ def frontmatter_of(document: str) -> dict[str, str]:
|
|||
|
||||
|
||||
def test_a_five_entry_plan_yields_exactly_five_concepts(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT))
|
||||
found = concepts(tmp_path / "bundle")
|
||||
assert len(found) == 5
|
||||
|
|
@ -190,15 +190,15 @@ def test_a_five_entry_plan_yields_exactly_five_concepts(tmp_path: Path) -> None:
|
|||
def test_without_a_plan_the_same_fixture_yields_exactly_one_concept(tmp_path: Path) -> None:
|
||||
# The discriminating negative control. Without it, a test that counts five
|
||||
# concepts proves nothing about whether the PLAN caused the split.
|
||||
drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
run(tmp_path, plan=None)
|
||||
found = concepts(tmp_path / "bundle")
|
||||
assert len(found) == 1
|
||||
assert set(found) == {"inbox-n500.md"}
|
||||
assert set(found) == {"inbox-q500.md"}
|
||||
|
||||
|
||||
def test_each_segment_id_maps_to_the_path_its_entry_declares(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT)
|
||||
run(tmp_path, plan=plan)
|
||||
found = concepts(tmp_path / "bundle")
|
||||
|
|
@ -207,7 +207,7 @@ def test_each_segment_id_maps_to_the_path_its_entry_declares(tmp_path: Path) ->
|
|||
|
||||
|
||||
def test_each_body_equals_the_span_its_own_entry_declares(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT)
|
||||
run(tmp_path, plan=plan)
|
||||
found = concepts(tmp_path / "bundle")
|
||||
|
|
@ -217,7 +217,7 @@ def test_each_body_equals_the_span_its_own_entry_declares(tmp_path: Path) -> Non
|
|||
|
||||
|
||||
def test_concepts_land_on_nested_paths_across_several_directories(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT))
|
||||
found = concepts(tmp_path / "bundle")
|
||||
directories = {str(Path(path).parent) for path in found}
|
||||
|
|
@ -232,7 +232,7 @@ def test_concepts_land_on_nested_paths_across_several_directories(tmp_path: Path
|
|||
|
||||
|
||||
def test_the_plan_timestamp_reaches_every_concept(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT))
|
||||
for document in concepts(tmp_path / "bundle").values():
|
||||
keys = frontmatter_of(document)
|
||||
|
|
@ -272,7 +272,7 @@ def test_a_csv_body_equals_the_span_of_the_extracted_text(tmp_path: Path) -> Non
|
|||
|
||||
|
||||
def test_a_plan_against_a_profile_without_the_capability_is_refused(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT), profile=DEFAULT, values={})
|
||||
assert excinfo.value.code == "segmentation_unsupported_profile"
|
||||
|
|
@ -283,7 +283,7 @@ def test_a_plan_without_a_bundle_id_is_refused_before_any_write(tmp_path: Path)
|
|||
# The assertion Step 5 deferred to here: `process_inbox` gains its
|
||||
# `segmentation` parameter at THIS step, so this is the first point at
|
||||
# which the required-bundle_id branch can be reached at all.
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT), values={})
|
||||
assert excinfo.value.code == "segmentation_plan_invalid"
|
||||
|
|
@ -292,12 +292,12 @@ def test_a_plan_without_a_bundle_id_is_refused_before_any_write(tmp_path: Path)
|
|||
|
||||
|
||||
def test_a_refused_plan_leaves_an_existing_bundle_untouched(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "one", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "one", "q500.md", DOCUMENT)
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT), round_name="one")
|
||||
before = tree(tmp_path / "bundle")
|
||||
assert before != {}
|
||||
|
||||
drop(tmp_path / "two", "v720.md", DOCUMENT)
|
||||
drop(tmp_path / "two", "w720.md", DOCUMENT)
|
||||
with pytest.raises(SegmentationError):
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT), values={}, round_name="two")
|
||||
assert tree(tmp_path / "bundle") == before
|
||||
|
|
@ -307,7 +307,7 @@ def test_a_refused_plan_leaves_an_existing_bundle_untouched(tmp_path: Path) -> N
|
|||
|
||||
|
||||
def test_one_quarantined_segment_persists_nothing_for_that_document(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT)
|
||||
third = DOCUMENT[plan.entries[2].span[0] : plan.entries[2].span[1]]
|
||||
|
||||
|
|
@ -321,12 +321,12 @@ def test_one_quarantined_segment_persists_nothing_for_that_document(tmp_path: Pa
|
|||
result = run(tmp_path, plan=plan, guard=quarantining)
|
||||
assert concepts(tmp_path / "bundle") == {}
|
||||
assert len(result.quarantined) == 1
|
||||
assert result.quarantined[0].source_file == "n500.md"
|
||||
assert result.quarantined[0].source_file == "q500.md"
|
||||
assert result.persisted == ()
|
||||
|
||||
|
||||
def test_every_segment_is_gated_before_any_is_written(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT)
|
||||
calls: list[str] = []
|
||||
written_when_gated: list[int] = []
|
||||
|
|
@ -348,12 +348,12 @@ def test_a_plan_covering_one_of_two_documents_leaves_the_other_flat(tmp_path: Pa
|
|||
# files with identical content are both covered by one plan and land every
|
||||
# segment on the same path -- which is the intra-run collision Step 8's gate
|
||||
# exists to refuse, not something to demonstrate here.
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
drop(tmp_path / "round", "v720.md", "V720 Tunnel: egne krav.\n")
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
drop(tmp_path / "round", "w720.md", "W720 Kjeller: egne krav.\n")
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT))
|
||||
found = concepts(tmp_path / "bundle")
|
||||
assert set(PATHS) <= set(found)
|
||||
assert "inbox-v720.md" in found
|
||||
assert "inbox-w720.md" in found
|
||||
assert len(found) == 6
|
||||
|
||||
|
||||
|
|
@ -366,11 +366,11 @@ def test_a_plan_matching_no_dropped_file_is_refused(tmp_path: Path) -> None:
|
|||
`_plan_covering` selects on content hash, so a mistyped `source_sha256`
|
||||
matches nothing, every dropped file falls through to the one-concept rule,
|
||||
and the run reports a perfectly ordinary success. The operator asked for
|
||||
segmentation and got a flat bundle with no error to read. `vegnormal-okf`
|
||||
is about to put an N500 corpus through this path; a silent zero there would
|
||||
segmentation and got a flat bundle with no error to read. A downstream
|
||||
consumer was about to put a regulatory corpus through this path; a silent zero there would
|
||||
read as "the corpus has no concepts".
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT, source_sha256="0" * 64)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(tmp_path, plan=plan)
|
||||
|
|
@ -386,8 +386,8 @@ def test_a_plan_matching_one_of_several_dropped_files_is_not_refused(tmp_path: P
|
|||
have replaced a silent skip with a refusal of the normal case, so this test
|
||||
is what keeps the new gate honest rather than merely loud.
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
drop(tmp_path / "round", "v720.md", "V720 Tunnel: egne krav.\n")
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
drop(tmp_path / "round", "w720.md", "W720 Kjeller: egne krav.\n")
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT))
|
||||
assert len(concepts(tmp_path / "bundle")) == 6
|
||||
|
||||
|
|
@ -402,8 +402,8 @@ def test_an_unreadable_dropped_file_does_not_mask_an_unmatched_plan(tmp_path: Pa
|
|||
hashed over the unreadable file's OWN bytes, so it is the only drop that
|
||||
could ever have matched.
|
||||
"""
|
||||
drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
other = "V720 Tunnel: egne krav.\n"
|
||||
drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
other = "W720 Kjeller: egne krav.\n"
|
||||
unreadable = drop(tmp_path / "round", "locked.md", other)
|
||||
unreadable.chmod(0o000)
|
||||
try:
|
||||
|
|
@ -411,7 +411,7 @@ def test_an_unreadable_dropped_file_does_not_mask_an_unmatched_plan(tmp_path: Pa
|
|||
# would read the file fine and pass for the wrong reason.
|
||||
with pytest.raises(OSError):
|
||||
unreadable.read_bytes()
|
||||
plan = build_plan(other.encode("utf-8"), other, paths=("krav/tunnel.md",))
|
||||
plan = build_plan(other.encode("utf-8"), other, paths=("krav/kjeller.md",))
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(tmp_path, plan=plan)
|
||||
assert excinfo.value.code == "segmentation_plan_unmatched"
|
||||
|
|
@ -429,7 +429,7 @@ def test_a_matched_plan_with_a_refused_path_keeps_its_own_per_file_code(tmp_path
|
|||
plan that matched nothing. The operator would have been told to check a
|
||||
hash that was already correct. Coverage is recorded at SELECTION.
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT, paths=("krav/" + "a" * 300 + ".md",))
|
||||
result = run(tmp_path, plan=plan)
|
||||
assert {entry.error.code for entry in result.failed} == {"inbox_slug_too_long"}
|
||||
|
|
@ -444,7 +444,7 @@ def test_without_the_capability_an_unmatched_plan_is_still_the_earlier_refusal(
|
|||
Both conditions hold in this call -- no capability AND no matching file --
|
||||
and the operator's first problem is the profile, not the hash.
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT, source_sha256="0" * 64)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(tmp_path, plan=plan, profile=DEFAULT, values={})
|
||||
|
|
@ -470,7 +470,7 @@ def test_a_plan_whose_extracted_text_hash_moved_is_refused(tmp_path: Path) -> No
|
|||
moving the hash rather than the converter, because the property under test
|
||||
is that the component is COMPARED at all.
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT, text_sha256="0" * 64)
|
||||
result = run(tmp_path, plan=plan)
|
||||
assert {entry.error.code for entry in result.failed} == {"segmentation_extractor_mismatch"}
|
||||
|
|
@ -480,7 +480,7 @@ def test_a_plan_whose_extracted_text_hash_moved_is_refused(tmp_path: Path) -> No
|
|||
|
||||
def test_a_plan_whose_extractor_version_moved_is_refused(tmp_path: Path) -> None:
|
||||
"""The half of S5b that compared a value with itself."""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT, extractor_version="not-the-one-that-ran")
|
||||
result = run(tmp_path, plan=plan)
|
||||
assert {entry.error.code for entry in result.failed} == {"segmentation_extractor_mismatch"}
|
||||
|
|
@ -522,14 +522,14 @@ OTHER_PATHS = ("annen/innledning.md", "annen/virkeomraade.md")
|
|||
|
||||
|
||||
def test_two_documents_with_two_plans_both_segment_in_one_run(tmp_path: Path) -> None:
|
||||
first = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
second = drop(tmp_path / "round", "n200.md", OTHER)
|
||||
first = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
second = drop(tmp_path / "round", "q200.md", OTHER)
|
||||
run(
|
||||
tmp_path,
|
||||
plan=None,
|
||||
plans={
|
||||
"n500.md": build_plan(first.read_bytes(), DOCUMENT),
|
||||
"n200.md": build_plan(second.read_bytes(), OTHER, paths=OTHER_PATHS),
|
||||
"q500.md": build_plan(first.read_bytes(), DOCUMENT),
|
||||
"q200.md": build_plan(second.read_bytes(), OTHER, paths=OTHER_PATHS),
|
||||
},
|
||||
)
|
||||
found = concepts(tmp_path / "bundle")
|
||||
|
|
@ -545,7 +545,7 @@ def test_a_mapping_selects_by_content_not_by_the_name_it_is_keyed_under(
|
|||
it was adjudicated over. Anything else would make a rename silently produce
|
||||
a flat bundle.
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
run(
|
||||
tmp_path,
|
||||
plan=None,
|
||||
|
|
@ -563,13 +563,13 @@ def test_a_plan_in_the_mapping_that_matches_nothing_is_still_refused(
|
|||
matched would otherwise report success over four segmented documents and
|
||||
one flat one, which is exactly the silent zero this refusal exists for.
|
||||
"""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(
|
||||
tmp_path,
|
||||
plan=None,
|
||||
plans={
|
||||
"n500.md": build_plan(source.read_bytes(), DOCUMENT),
|
||||
"q500.md": build_plan(source.read_bytes(), DOCUMENT),
|
||||
"ghost.md": build_plan(source.read_bytes(), DOCUMENT, source_sha256="0" * 64),
|
||||
},
|
||||
)
|
||||
|
|
@ -579,17 +579,17 @@ def test_a_plan_in_the_mapping_that_matches_nothing_is_still_refused(
|
|||
|
||||
def test_passing_both_forms_at_once_is_refused(tmp_path: Path) -> None:
|
||||
"""Two ways to say the same thing invite a silent disagreement."""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
plan = build_plan(source.read_bytes(), DOCUMENT)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(tmp_path, plan=plan, plans={"n500.md": plan})
|
||||
run(tmp_path, plan=plan, plans={"q500.md": plan})
|
||||
assert excinfo.value.code == "segmentation_plan_invalid"
|
||||
assert tree(tmp_path / "bundle") == {}
|
||||
|
||||
|
||||
def test_two_plans_claiming_the_same_bytes_are_refused(tmp_path: Path) -> None:
|
||||
"""Which one would have segmented the document is not a coin toss."""
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
with pytest.raises(SegmentationError) as excinfo:
|
||||
run(
|
||||
tmp_path,
|
||||
|
|
@ -604,6 +604,6 @@ def test_two_plans_claiming_the_same_bytes_are_refused(tmp_path: Path) -> None:
|
|||
|
||||
|
||||
def test_the_single_plan_form_is_unchanged(tmp_path: Path) -> None:
|
||||
source = drop(tmp_path / "round", "n500.md", DOCUMENT)
|
||||
source = drop(tmp_path / "round", "q500.md", DOCUMENT)
|
||||
run(tmp_path, plan=build_plan(source.read_bytes(), DOCUMENT))
|
||||
assert set(concepts(tmp_path / "bundle")) == set(PATHS)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue