Files
chemenu/tools/chemenu/tests/test_blocks.py
T
torben 177c7e9ce8
CI / verify (push) Successful in 55s
Release / release (push) Successful in 38s
feat: Prosa ist kein Identifier - Link-Taxonomie als Enum, generierte Regionen mit Markern (4.0.0)
Files changed:
- .gitea/workflows/ci.yml
- AGENTS.md
- CHANGES.md
- VERSION
- instructions/CONTRACT.md
- instructions/link-taxonomy.md
- instructions/migrations/4.0.0-link-taxonomy.md
- instructions/setup-instance.md
- kb/CONTRACT.md
- kb/CONVENTIONS.md
- kb/CONVENTIONS.md.template
- kb/comparisons/COLLECTION.md
- kb/concepts/COLLECTION.md
- kb/entities/COLLECTION.md
- kb/sources/COLLECTION.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/blocks.py
- tools/chemenu/cli.py
- tools/chemenu/commands/cite_cmd.py
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/links_cmd.py
- tools/chemenu/commands/migrate_cmd.py
- tools/chemenu/commands/new_page.py
- tools/chemenu/commands/page_ops.py
- tools/chemenu/commands/run_budget.py
- tools/chemenu/commands/xref.py
- tools/chemenu/conventions.py
- tools/chemenu/corpus_diff.py
- tools/chemenu/frontmatter_io.py
- tools/chemenu/kb_collections.py
- tools/chemenu/kb_state.py
- tools/chemenu/links.py
- tools/chemenu/lint_core.py
- tools/chemenu/provenance.py
- tools/chemenu/sections.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_blocks.py
- tools/chemenu/tests/test_cite_cmd.py
- tools/chemenu/tests/test_conventions.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_doctor.py
- tools/chemenu/tests/test_migrate_cmd.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_pipeline_l0.py
- tools/chemenu/tests/test_types_cmd.py
- tools/chemenu/tests/test_xref.py
- types/concept.schema.yaml
- types/entity.md
- types/entity.schema.yaml
- types/instruction.schema.yaml
- types/type-spec.md
- work/link-taxonomy-migration/README.md
- work/link-taxonomy-migration/plan.md
2026-09-02 18:39:22 +02:00

91 lines
3.9 KiB
Python

"""Tests for generated regions - the delimiters that replaced heading matching.
The whole point is that a region's *identity* stops depending on its heading
text. Everything here is about the two questions the old approach answered by
guessing: where does the region start, and where does it stop.
"""
from __future__ import annotations
from chemenu import blocks
PROSE = "# Page\n\n## Beschreibung\n\nProse.\n"
def _links(heading="Beziehungen", lines=("- **uses:** [[X]]",)):
return blocks.render(blocks.LINKS, heading, list(lines))
def test_a_region_round_trips():
body = blocks.replace(PROSE, blocks.LINKS, _links())
assert blocks.find(body, blocks.LINKS) == "## Beziehungen\n\n- **uses:** [[X]]"
assert blocks.strip(body, blocks.LINKS) == PROSE
def test_replacing_does_not_append_a_second_region():
body = blocks.replace(PROSE, blocks.LINKS, _links())
again = blocks.replace(body, blocks.LINKS, _links(lines=["- **uses:** [[Y]]"]))
assert again.count(blocks.open_marker(blocks.LINKS)) == 1
assert "[[X]]" not in again and "[[Y]]" in again
def test_the_heading_inside_a_region_is_not_how_it_is_found():
"""A page whose region carries a heading the instance never declared - an
unconverted page, a hand-edit, another language - is still located exactly.
Under heading matching this was the case that silently created a second
section."""
body = blocks.replace(PROSE, blocks.LINKS, _links(heading="Something Else Entirely"))
assert "[[X]]" in blocks.find(body, blocks.LINKS)
assert blocks.strip(body, blocks.LINKS) == PROSE
def test_content_after_a_region_survives_a_rewrite():
"""The eight-page bug, as a test. The old block ran to the next heading -
and before that to the end of the file - so anything sitting after it was
deleted on the next write."""
body = blocks.replace(PROSE, blocks.LINKS, _links()) + "\n## Afterwards\n\nKeep me.\n"
rewritten = blocks.replace(body, blocks.LINKS, _links(lines=["- **uses:** [[Z]]"]))
assert "Keep me." in rewritten
assert rewritten.count("## Afterwards") == 1
def test_two_regions_coexist_without_reading_each_other():
body = blocks.replace(PROSE, blocks.LINKS, _links())
body = blocks.replace(
body, blocks.FOOTNOTES,
blocks.render(blocks.FOOTNOTES, "Fußnoten", ["[^s-x]: [[Source - X]]"]),
)
assert "[[X]]" in blocks.find(body, blocks.LINKS)
assert "[^s-x]" in blocks.find(body, blocks.FOOTNOTES)
assert blocks.marker_pairs(body) == {"links": 1, "footnotes": 1}
def test_an_empty_region_is_no_region_at_all():
"""A page that cites nothing must not carry an empty Footnotes heading."""
assert blocks.render(blocks.LINKS, "Beziehungen", []) == ""
body = blocks.replace(PROSE, blocks.LINKS, _links())
assert blocks.replace(body, blocks.LINKS, "") == PROSE
def test_an_absent_region_reads_as_none_not_as_empty():
"""None and "" have to stay distinguishable: one means the page has no
region, the other that it has one holding nothing."""
assert blocks.find(PROSE, blocks.LINKS) is None
def test_a_dropped_marker_is_detectable():
"""An agent rewriting prose at the boundary can lose one. Silent otherwise:
the region becomes ordinary prose and the next write appends a second one
beside it."""
body = blocks.replace(PROSE, blocks.LINKS, _links())
assert blocks.unbalanced_markers(body) == []
assert blocks.unbalanced_markers(body.replace(blocks.close_marker(blocks.LINKS), "")) == ["links"]
assert blocks.unbalanced_markers(body.replace(blocks.open_marker(blocks.LINKS), "")) == ["links"]
def test_marker_pairs_counts_rather_than_sets():
"""A page that went from one region to two has the same set of names and a
different count - which is why `migrate verify` compares counts."""
body = blocks.replace(PROSE, blocks.LINKS, _links())
doubled = body + "\n" + _links() + "\n"
assert blocks.marker_pairs(doubled) == {"links": 2}