"""Tests for PDFRenderer — Markdown → PDF mapping (U4).""" from __future__ import annotations from pathlib import Path from agentkit.documents.renderers.pdf_renderer import PDFRenderer def _render(markdown: str, tmp_path: Path) -> Path: out = tmp_path / "test.pdf" PDFRenderer().render(markdown, out) return out def test_basic_pdf_generation(tmp_path: Path) -> None: """Markdown with heading + paragraph produces a valid PDF.""" md = "# Title\n\nThis is a paragraph.\n" path = _render(md, tmp_path) assert path.exists() assert path.stat().st_size > 0 # PDF magic bytes assert path.read_bytes()[:4] == b"%PDF" def test_empty_markdown(tmp_path: Path) -> None: """Empty Markdown produces a valid (minimal) PDF.""" path = _render("", tmp_path) assert path.exists() assert path.read_bytes()[:4] == b"%PDF" def test_headings(tmp_path: Path) -> None: """Multiple heading levels render without error.""" md = "# H1\n## H2\n### H3\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" def test_bullet_list(tmp_path: Path) -> None: """Bullet list renders without error.""" md = "- Apple\n- Banana\n- Cherry\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" def test_numbered_list(tmp_path: Path) -> None: """Numbered list renders without error.""" md = "1. First\n2. Second\n3. Third\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" def test_table(tmp_path: Path) -> None: """GFM table renders without error.""" md = "| Name | Age |\n| --- | --- |\n| Alice | 30 |\n| Bob | 25 |\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" def test_bold_italic(tmp_path: Path) -> None: """Bold and italic inline formatting render without error.""" md = "This has **bold** and *italic* text.\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" def test_chinese_text(tmp_path: Path) -> None: """Chinese characters produce a valid PDF (font fallback is OK).""" md = "# 中文标题\n\n这是中文段落内容。\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" assert path.stat().st_size > 0 def test_mixed_content(tmp_path: Path) -> None: """Heading + paragraph + list + table renders without error.""" md = """# Report Intro paragraph. - Item one - Item two | Col A | Col B | | ----- | ----- | | 1 | 2 | Final paragraph. """ path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF" def test_xml_special_chars(tmp_path: Path) -> None: """XML special characters (<, >, &) are escaped and don't break rendering.""" md = "Use & entities like **bold**.\n" path = _render(md, tmp_path) assert path.read_bytes()[:4] == b"%PDF"