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
|
|
@ -63,7 +63,7 @@ def test_default_is_byte_identical_with_and_without_the_new_parameter(tmp_path:
|
|||
# The additivity claim at the byte level. If this ever fails, the feature
|
||||
# stopped being additive and every existing Door B bundle churns.
|
||||
for label in ("implicit", "explicit"):
|
||||
drop(tmp_path / label, "n500-vegbygging.md", "# Vegbygging\n\nSee N200.\n")
|
||||
drop(tmp_path / label, "q500-surdeigsbaking.md", "# Surdeigsbaking\n\nSee Q200.\n")
|
||||
process_inbox(
|
||||
tmp_path / "implicit",
|
||||
tmp_path / "a",
|
||||
|
|
@ -79,7 +79,7 @@ def test_default_is_byte_identical_with_and_without_the_new_parameter(tmp_path:
|
|||
gate=gate,
|
||||
profile=DEFAULT,
|
||||
)
|
||||
for name in ("index.md", "inbox-n500-vegbygging.md"):
|
||||
for name in ("index.md", "inbox-q500-surdeigsbaking.md"):
|
||||
assert (tmp_path / "a" / name).read_bytes() == (tmp_path / "b" / name).read_bytes()
|
||||
|
||||
|
||||
|
|
@ -87,9 +87,9 @@ def test_default_still_labels_the_entry_with_the_filename_stem(tmp_path: Path) -
|
|||
# Title derivation arrives with the profile that asked for it. DEFAULT
|
||||
# states commons' index layer, and changing its label source from here
|
||||
# would change a contract this repo does not own.
|
||||
drop(tmp_path / "round", "n500-vegbygging.md", "# Vegbygging\n\nbody\n")
|
||||
drop(tmp_path / "round", "q500-surdeigsbaking.md", "# Surdeigsbaking\n\nbody\n")
|
||||
run(tmp_path, profile=DEFAULT)
|
||||
assert "- [n500-vegbygging](inbox-n500-vegbygging.md)\n" == index_of(tmp_path)
|
||||
assert "- [q500-surdeigsbaking](inbox-q500-surdeigsbaking.md)\n" == index_of(tmp_path)
|
||||
|
||||
|
||||
# --- what STRUCTURED_V1 adds ----------------------------------------------
|
||||
|
|
@ -97,20 +97,20 @@ def test_default_still_labels_the_entry_with_the_filename_stem(tmp_path: Path) -
|
|||
|
||||
def test_the_title_is_derived_from_the_leading_heading(tmp_path: Path) -> None:
|
||||
# The answer recorded in dc9ea59 for the Door B / Door A capability gap.
|
||||
drop(tmp_path / "round", "n500-vegbygging.md", "# Vegbygging\n\nbody\n")
|
||||
drop(tmp_path / "round", "q500-surdeigsbaking.md", "# Surdeigsbaking\n\nbody\n")
|
||||
run(tmp_path)
|
||||
assert "title: Vegbygging" in concept(tmp_path, "inbox-n500-vegbygging.md")
|
||||
assert "- [Vegbygging](inbox-n500-vegbygging.md)" in index_of(tmp_path)
|
||||
assert "title: Surdeigsbaking" in concept(tmp_path, "inbox-q500-surdeigsbaking.md")
|
||||
assert "- [Surdeigsbaking](inbox-q500-surdeigsbaking.md)" in index_of(tmp_path)
|
||||
|
||||
|
||||
def test_the_concept_carries_the_derived_structure_in_its_own_frontmatter(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
drop(tmp_path / "round", "n500-vegbygging.md", "# Vegbygging\n\nSee N200.\n")
|
||||
drop(tmp_path / "round", "q500-surdeigsbaking.md", "# Surdeigsbaking\n\nSee Q200.\n")
|
||||
run(tmp_path)
|
||||
head = concept(tmp_path, "inbox-n500-vegbygging.md").split("---")[1]
|
||||
assert "number: N500" in head
|
||||
assert "references: [N200]" in head
|
||||
head = concept(tmp_path, "inbox-q500-surdeigsbaking.md").split("---")[1]
|
||||
assert "number: Q500" in head
|
||||
assert "references: [Q200]" in head
|
||||
# The confidence marker, without which the two lines above are assertions
|
||||
# a consumer cannot audit.
|
||||
assert "derived: [title, number, references]" in head
|
||||
|
|
@ -121,18 +121,18 @@ def test_the_index_entry_carries_the_facets_its_document_carries(tmp_path: Path)
|
|||
# documents was the whole reason the OKF arm lost on trap exposure.
|
||||
drop(
|
||||
tmp_path / "round",
|
||||
"n500-vegbygging.md",
|
||||
"---\nstatus: gjeldende\ndate: 2026-01-01\n---\n\n# Vegbygging\n\nbody\n",
|
||||
"q500-surdeigsbaking.md",
|
||||
"---\nstatus: gjeldende\ndate: 2026-01-01\n---\n\n# Surdeigsbaking\n\nbody\n",
|
||||
)
|
||||
run(tmp_path)
|
||||
entry = index_of(tmp_path).strip()
|
||||
assert "number: N500" in entry
|
||||
assert "number: Q500" in entry
|
||||
assert "status: gjeldende" in entry
|
||||
assert "date: 2026-01-01" in entry
|
||||
|
||||
|
||||
def test_a_declared_value_is_not_marked_derived_in_the_index(tmp_path: Path) -> None:
|
||||
drop(tmp_path / "round", "x.md", "---\ntitle: Declared\nnumber: N500\n---\n\nbody\n")
|
||||
drop(tmp_path / "round", "x.md", "---\ntitle: Declared\nnumber: Q500\n---\n\nbody\n")
|
||||
run(tmp_path)
|
||||
assert "derived:" not in index_of(tmp_path)
|
||||
|
||||
|
|
@ -143,20 +143,20 @@ def test_a_declared_value_is_not_marked_derived_in_the_index(tmp_path: Path) ->
|
|||
def test_a_reference_to_a_document_not_yet_dropped_is_marked_unresolved(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
drop(tmp_path / "round", "n500-x.md", "# A\n\nSee N200.\n")
|
||||
drop(tmp_path / "round", "q500-x.md", "# A\n\nSee Q200.\n")
|
||||
run(tmp_path)
|
||||
assert "references: [N200?]" in index_of(tmp_path)
|
||||
assert "references: [Q200?]" in index_of(tmp_path)
|
||||
|
||||
|
||||
def test_the_marker_clears_when_the_target_arrives_in_a_later_round(tmp_path: Path) -> None:
|
||||
drop(tmp_path / "r1", "n500-x.md", "# A\n\nSee N200.\n")
|
||||
drop(tmp_path / "r1", "q500-x.md", "# A\n\nSee Q200.\n")
|
||||
run(tmp_path, round_name="r1")
|
||||
assert "references: [N200?]" in index_of(tmp_path)
|
||||
assert "references: [Q200?]" in index_of(tmp_path)
|
||||
|
||||
drop(tmp_path / "r2", "n200-y.md", "# B\n\nbody\n")
|
||||
drop(tmp_path / "r2", "q200-y.md", "# B\n\nbody\n")
|
||||
run(tmp_path, round_name="r2")
|
||||
index = index_of(tmp_path)
|
||||
assert "references: [N200]" in index
|
||||
assert "references: [Q200]" in index
|
||||
assert "?" not in index
|
||||
|
||||
|
||||
|
|
@ -165,14 +165,14 @@ def test_a_later_round_can_supersede_an_earlier_one_and_the_index_UPDATES(
|
|||
) -> None:
|
||||
# An index that could only be appended to would leave the round-1 entry
|
||||
# claiming to be current forever.
|
||||
drop(tmp_path / "r1", "old.md", "---\nnumber: N500\nversion: '2018'\n---\n\n# Old\n")
|
||||
drop(tmp_path / "r1", "old.md", "---\nnumber: Q500\nversion: '2018'\n---\n\n# Old\n")
|
||||
run(tmp_path, round_name="r1")
|
||||
assert "supersedes" not in index_of(tmp_path)
|
||||
|
||||
drop(tmp_path / "r2", "new.md", "---\nnumber: N500\nversion: '2021'\n---\n\n# New\n")
|
||||
drop(tmp_path / "r2", "new.md", "---\nnumber: Q500\nversion: '2021'\n---\n\n# New\n")
|
||||
run(tmp_path, round_name="r2")
|
||||
index = index_of(tmp_path)
|
||||
assert "supersedes: [N500]" in index
|
||||
assert "supersedes: [Q500]" in index
|
||||
# ...and the relation is marked as one this library PROPOSED, alongside the
|
||||
# title it also inferred. Both are heuristics and both say so.
|
||||
assert "derived: [title, supersedes]" in index
|
||||
|
|
@ -184,9 +184,9 @@ def test_rebuild_from_scratch_and_incremental_update_agree_byte_for_byte(
|
|||
# The single most load-bearing test in this delivery. If these two ever
|
||||
# part company, "additive" stops being a property and becomes a hope.
|
||||
files = {
|
||||
"n500-x.md": "# Vegbygging\n\nSee N200 and N300.\n",
|
||||
"n200-y.md": "---\nstatus: gjeldende\n---\n\n# Grunnlag\n\nSee N500.\n",
|
||||
"n300-z.md": "# Tredje\n\nbody\n",
|
||||
"q500-x.md": "# Surdeigsbaking\n\nSee Q200 and Q300.\n",
|
||||
"q200-y.md": "---\nstatus: gjeldende\n---\n\n# Grunnlag\n\nSee Q500.\n",
|
||||
"q300-z.md": "# Tredje\n\nbody\n",
|
||||
}
|
||||
incremental = tmp_path / "incremental"
|
||||
for round_index, (name, text) in enumerate(files.items(), start=1):
|
||||
|
|
@ -218,13 +218,13 @@ def test_rebuild_from_scratch_and_incremental_update_agree_byte_for_byte(
|
|||
|
||||
|
||||
def test_dropping_the_same_file_twice_yields_one_entry(tmp_path: Path) -> None:
|
||||
text = "# Vegbygging\n\nSee N200.\n"
|
||||
text = "# Surdeigsbaking\n\nSee Q200.\n"
|
||||
for round_name in ("r1", "r2"):
|
||||
drop(tmp_path / round_name, "n500-x.md", text)
|
||||
drop(tmp_path / round_name, "q500-x.md", text)
|
||||
run(tmp_path, round_name=round_name)
|
||||
index = index_of(tmp_path)
|
||||
assert index.count("inbox-n500-x.md") == 1
|
||||
assert index.count("N200") == 1
|
||||
assert index.count("inbox-q500-x.md") == 1
|
||||
assert index.count("Q200") == 1
|
||||
|
||||
|
||||
def test_curated_prose_in_the_index_survives_reprojection(tmp_path: Path) -> None:
|
||||
|
|
@ -233,15 +233,15 @@ def test_curated_prose_in_the_index_survives_reprojection(tmp_path: Path) -> Non
|
|||
bundle = tmp_path / "bundle"
|
||||
bundle.mkdir(parents=True)
|
||||
(bundle / "index.md").write_text(
|
||||
"# Bundle\n\nSome curated prose about inbox-n500-x.md.\n",
|
||||
"# Bundle\n\nSome curated prose about inbox-q500-x.md.\n",
|
||||
encoding="utf-8",
|
||||
newline="",
|
||||
)
|
||||
drop(tmp_path / "round", "n500-x.md", "# A\n\nbody\n")
|
||||
drop(tmp_path / "round", "q500-x.md", "# A\n\nbody\n")
|
||||
run(tmp_path)
|
||||
index = index_of(tmp_path)
|
||||
assert "# Bundle" in index
|
||||
assert "Some curated prose about inbox-n500-x.md." in index
|
||||
assert "Some curated prose about inbox-q500-x.md." in index
|
||||
|
||||
|
||||
def test_a_curated_link_is_not_claimed_by_reprojection(tmp_path: Path) -> None:
|
||||
|
|
@ -249,13 +249,13 @@ def test_a_curated_link_is_not_claimed_by_reprojection(tmp_path: Path) -> None:
|
|||
bundle.mkdir(parents=True)
|
||||
(bundle / "index.md").write_text("- [Hand written](curated.md)\n", encoding="utf-8", newline="")
|
||||
(bundle / "curated.md").write_text("# Curated\n", encoding="utf-8", newline="")
|
||||
drop(tmp_path / "round", "n500-x.md", "# A\n\nbody\n")
|
||||
drop(tmp_path / "round", "q500-x.md", "# A\n\nbody\n")
|
||||
run(tmp_path)
|
||||
assert "- [Hand written](curated.md)\n" in index_of(tmp_path)
|
||||
|
||||
|
||||
def test_reprojection_is_idempotent_when_nothing_new_arrives(tmp_path: Path) -> None:
|
||||
drop(tmp_path / "r1", "n500-x.md", "# A\n\nSee N200.\n")
|
||||
drop(tmp_path / "r1", "q500-x.md", "# A\n\nSee Q200.\n")
|
||||
run(tmp_path, round_name="r1")
|
||||
first = (tmp_path / "bundle" / "index.md").read_bytes()
|
||||
(tmp_path / "r2").mkdir()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue