generated from coulomb/repo-seed
158 lines
5.5 KiB
Python
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.")
|