Files
markitect-quarkdown/tests/test_quarkdown_adapter.py

158 lines
5.5 KiB
Python

from pathlib import Path
import shutil
import pytest
from markitect_tool.render import RenderExportRequest
from markitect_quarkdown import (
MARKITECT_QUARKDOWN_VERSION_POLICY,
MarkitectQuarkdownAdapter,
QuarkdownProcessResult,
build_quarkdown_execution_plan,
export_quarkdown_source,
quarkdown_adapter_descriptor,
quarkdown_profile_for,
validate_quarkdown_artifact,
)
def test_quarkdown_descriptor_matches_markitect_render_contract():
descriptor = quarkdown_adapter_descriptor()
data = descriptor.to_dict()
assert descriptor.id == "render.quarkdown"
assert data["kind"] == "render-export"
assert descriptor.operations == ["inspect-profile", "export-source", "render-artifact"]
assert "pdf" in descriptor.output_profiles
assert "application/pdf" in descriptor.artifact_media_types
assert descriptor.safety["external_process"] is True
assert descriptor.metadata["version_policy"] == MARKITECT_QUARKDOWN_VERSION_POLICY
assert descriptor.metadata["open_reuse_integration"] == "integration/quarkdown.integration.yaml"
def test_profile_matrix_maps_markitect_profiles_to_quarkdown_modes():
pdf = quarkdown_profile_for("pdf")
docs = quarkdown_profile_for("docs")
static_site = quarkdown_profile_for("static-site")
assert pdf.quarkdown_document_type == "paged"
assert pdf.output_format == "pdf"
assert pdf.artifact_extension == ".pdf"
assert docs.quarkdown_document_type == "docs"
assert static_site.output_format == "html"
def test_export_source_preserves_render_manifest_identifier():
request = RenderExportRequest(
source="# Demo",
operation="export-source",
profile="docs",
render_manifest={"manifest_id": "render-manifest:test"},
)
exported = export_quarkdown_source(request)
assert "<!-- generated-by: markitect-quarkdown -->" in exported
assert "<!-- markitect-profile: docs -->" in exported
assert "<!-- render-reference-manifest: render-manifest:test -->" in exported
assert exported.endswith("# Demo")
def test_adapter_exports_quarkdown_source_without_invoking_runtime():
adapter = MarkitectQuarkdownAdapter(command_resolver=lambda _command: None)
request = RenderExportRequest(
source="# Demo",
operation="export-source",
profile="docs",
source_path="docs/demo.md",
)
result = adapter.render(request)
assert result.valid
assert result.exported_source is not None
assert result.artifacts[0].role == "renderer-source"
assert result.metadata["external_renderer_invoked"] is False
def test_render_artifact_reports_missing_runtime_as_structured_diagnostic():
adapter = MarkitectQuarkdownAdapter(command_resolver=lambda _command: None)
request = RenderExportRequest(source="# Demo", operation="render-artifact", profile="pdf")
result = adapter.render(request)
assert not result.valid
assert result.diagnostics[0].code == "render.quarkdown.runtime_missing"
assert result.metadata["external_renderer_invoked"] is False
def test_execution_plan_maps_permissions_and_output_conventions(tmp_path: Path):
request = RenderExportRequest(
source="# Demo",
operation="render-artifact",
profile="pdf",
options={"artifact_stem": "demo", "permissions": ["project-read"], "deny_network": True},
)
plan = build_quarkdown_execution_plan(
request,
source_path=tmp_path / "source.qd",
output_dir=tmp_path / "out",
command="/usr/bin/quarkdown",
)
assert plan.expected_artifact_path.endswith("demo.pdf")
assert "--allow" in plan.command
assert "project-read" in plan.command
assert "--deny" in plan.command
assert "network" in plan.command
assert plan.environment["requires_java"] == "17+"
assert plan.environment["requires_node_for_pdf"] == "true"
def test_adapter_validates_fake_runner_artifact(tmp_path: Path):
def fake_runner(plan):
Path(plan.expected_artifact_path).write_text("<html>rendered</html>", encoding="utf-8")
return QuarkdownProcessResult(returncode=0, stdout="ok")
adapter = MarkitectQuarkdownAdapter(
command_resolver=lambda _command: "/usr/bin/quarkdown",
runner=fake_runner,
)
request = RenderExportRequest(
source="# Demo",
operation="render-artifact",
profile="docs",
source_path="docs/demo.md",
options={"workspace": str(tmp_path), "output_dir": str(tmp_path / "out"), "artifact_stem": "demo"},
)
result = adapter.render(request)
assert result.valid
assert result.metadata["external_renderer_invoked"] is True
assert result.artifacts[1].role == "rendered-artifact"
assert result.artifacts[1].media_type == "text/html"
assert result.artifacts[1].path.endswith("demo.html")
assert result.artifacts[1].digest.startswith("sha256:")
assert result.provenance[0].artifact_id == result.artifacts[1].artifact_id
def test_artifact_validation_reports_missing_artifact(tmp_path: Path):
request = RenderExportRequest(source="# Demo", operation="render-artifact", profile="pdf")
plan = build_quarkdown_execution_plan(
request,
source_path=tmp_path / "source.qd",
output_dir=tmp_path / "out",
)
artifact, diagnostics = validate_quarkdown_artifact(plan)
assert artifact is None
assert diagnostics[0].code == "render.quarkdown.artifact_missing"
def test_real_quarkdown_runtime_smoke_skips_when_unavailable():
if shutil.which("quarkdown") is None:
pytest.skip("Quarkdown CLI is not installed in this environment.")