fix: Befunde aus der QA-Prüfung (Prompt_Kontrolle.md)

- F1: Nicht beschreibbares Ausgabeziel liefert eine verständliche
  Meldung und Exit 1 statt "Interner Fehler" (Exit 4).
- F2: Anker von <dt id> stehen vor dem fett gesetzten Glossarbegriff
  statt innerhalb der **-Marker.
- F3: Formeln als <img src="*.svg"> erscheinen im Bericht mit
  origin "svg" statt "image".

Regressionstests für alle drei Befunde ergänzt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-05 19:47:45 +02:00
commit 3b07fcf01a
3 changed files with 54 additions and 13 deletions

View file

@ -114,3 +114,11 @@ def test_layout_table_headings_are_recognized(convert):
assert "# 3 Grundlagen" in text
assert "## 3.1 Einführung" in text
assert "<table" not in text
def test_glossary_anchor_is_placed_before_bold_term(convert):
"""QA-F2: the anchor of a <dt id> must not end up inside the bold markers."""
body = ('<h1>K</h1><p><a href="#g">API</a></p><section epub:type="glossary"><h2>Glossar</h2>'
'<dl><dt id="g">API</dt><dd>Schnittstelle.</dd></dl></section>')
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("002")
assert '<a id="g"></a>**API:** Schnittstelle.' in text

View file

@ -124,3 +124,20 @@ def test_example_books_structural_invariants(convert, epub: Path):
for m in report["media"]["files"]:
assert (run.out / m["file"]).is_file()
assert sum(c["stats"]["word_count"] for c in report["chapters"]) > 1000
def test_unwritable_output_parent_gives_clear_error(convert, tmp_path):
"""QA-F1: a permission problem at the target must not be reported as internal error (exit 4)."""
import os
import stat
parent = tmp_path / "readonly"
parent.mkdir()
os.chmod(parent, stat.S_IRUSR | stat.S_IXUSR)
try:
run = convert(simple_book(), out=parent / "ziel")
finally:
os.chmod(parent, stat.S_IRWXU)
assert run.rc == 1
assert "Interner Fehler" not in run.stderr
assert "nicht beschreibbar" in run.stderr or "Schreibfehler" in run.stderr

View file

@ -97,3 +97,10 @@ def test_math_image_mode(convert):
assert text.count("![") == 3 # svg + both formula images
assert "<math" in text # pure MathML without image is not lost
assert any(w["code"] == "mathml-no-image" for w in run.report["warnings"])
def test_svg_file_formula_is_reported_as_svg(convert):
"""QA-F3: <img src="*.svg"> inside a formula container is an SVG formula in the report."""
report = convert(math_book()).report
origins = {f["origin"] for f in report["formulas"]["items"]}
assert "svg" in origins