105 lines
3.4 KiB
Python
105 lines
3.4 KiB
Python
"""Tests for diagram renderer and factory routing."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from md2gost.diagram_renderer import (
|
|
DIAGRAM_LANGS,
|
|
prepare_source,
|
|
render_diagram,
|
|
configure_diagrams,
|
|
)
|
|
from md2gost.extended_markdown import markdown
|
|
from md2gost.extended_markdown.caption import Caption as CapEl
|
|
from md2gost.renderable.caption import CaptionInfo
|
|
from md2gost.renderable.diagram import DiagramFigure
|
|
from md2gost.renderable.listing import Listing
|
|
from md2gost.renderable_factory import RenderableFactory
|
|
|
|
|
|
def test_prepare_uml_wraps_startuml():
|
|
src, dtype = prepare_source("uml", "A -> B")
|
|
assert "@startuml" in src
|
|
assert dtype == "plantuml"
|
|
|
|
|
|
def test_prepare_c4_adds_include():
|
|
src, dtype = prepare_source("c4", "Person(user, \"User\")")
|
|
assert "!include" in src
|
|
assert dtype == "plantuml"
|
|
|
|
|
|
def test_prepare_bpmn():
|
|
src, dtype = prepare_source("bpmn", "start -> end")
|
|
assert dtype == "bpmn"
|
|
assert "@startbpmn" in src.lower() or "start" in src
|
|
|
|
|
|
def test_caption_plus_listing():
|
|
doc = markdown.parse("%fig Demo +listing\n\n```uml\nA->B\n```\n")
|
|
caps = [c for c in doc.children if isinstance(c, CapEl)]
|
|
assert len(caps) == 1
|
|
assert caps[0].with_listing is True
|
|
assert caps[0].text == "Demo"
|
|
assert caps[0].unique_name == "fig"
|
|
|
|
|
|
def test_factory_routes_uml_to_diagram():
|
|
from docx import Document
|
|
from md2gost import package_dir
|
|
import os
|
|
|
|
md = "%d1 Use case +listing\n\n```uml\n@startuml\nA -> B\n@enduml\n```\n"
|
|
parsed = markdown.parse(md)
|
|
doc = Document(os.path.join(package_dir(), "Template.docx"))
|
|
factory = RenderableFactory(doc._body)
|
|
caption = None
|
|
renderables = []
|
|
for el in parsed.children:
|
|
from marko.block import BlankLine
|
|
if isinstance(el, BlankLine):
|
|
continue
|
|
if isinstance(el, CapEl):
|
|
caption = CaptionInfo(el.unique_name, el.text, el.with_listing)
|
|
continue
|
|
renderables.append(factory.create(el, caption))
|
|
caption = None
|
|
|
|
assert len(renderables) == 1
|
|
assert isinstance(renderables[0], DiagramFigure)
|
|
assert renderables[0].listing is not None
|
|
assert isinstance(renderables[0].listing, Listing)
|
|
|
|
|
|
def test_render_diagram_uses_cache(tmp_path):
|
|
png = b"\x89PNG\r\n\x1a\n" + b"\x00" * 20
|
|
|
|
def fake_kroki(source, diagram_type, base_url, out_png):
|
|
out_png.write_bytes(png)
|
|
return True
|
|
|
|
configure_diagrams(fallback="remote", cache_dir=str(tmp_path))
|
|
with patch("md2gost.diagram_renderer._render_plantuml_jar", return_value=False), \
|
|
patch("md2gost.diagram_renderer._render_kroki", side_effect=fake_kroki):
|
|
path1 = render_diagram("uml", "A -> B", cache_dir=str(tmp_path))
|
|
path2 = render_diagram("uml", "A -> B", cache_dir=str(tmp_path))
|
|
assert path1 == path2
|
|
assert open(path1, "rb").read().startswith(b"\x89PNG")
|
|
|
|
|
|
def test_render_diagram_off_raises(tmp_path):
|
|
configure_diagrams(fallback="off", cache_dir=str(tmp_path))
|
|
with patch("md2gost.diagram_renderer._render_plantuml_jar", return_value=False), \
|
|
patch("md2gost.diagram_renderer._render_kroki", return_value=False):
|
|
with pytest.raises(RuntimeError):
|
|
render_diagram("uml", "A -> B", fallback="off", cache_dir=str(tmp_path))
|
|
|
|
|
|
def test_diagram_langs():
|
|
assert "uml" in DIAGRAM_LANGS
|
|
assert "c4" in DIAGRAM_LANGS
|
|
assert "bpmn" in DIAGRAM_LANGS
|