from pathlib import Path from markitect_tool.extension import ( ProcessingCapability, ProcessingContext, ProcessingProvenance, ProcessingRequest, ProcessingResult, ProcessingTrace, ) def test_processing_request_serializes_context_and_cache_key(): request = ProcessingRequest( operation="query.selector", input={"selector": "sections[heading=Decision]"}, context=ProcessingContext(root=Path("/workspace"), caller="cli"), options={"format": "json"}, capabilities=[ProcessingCapability(id="ast", description="Read parsed AST")], ) data = request.to_dict() assert data["operation"] == "query.selector" assert data["context"]["root"] == "/workspace" assert data["context"]["caller"] == "cli" assert data["capabilities"][0]["id"] == "ast" assert request.cache_key.startswith("processing:") assert request.cache_key == ProcessingRequest( operation="query.selector", input={"selector": "sections[heading=Decision]"}, context=ProcessingContext(root=Path("/other")), options={"format": "json"}, capabilities=[ProcessingCapability(id="ast", description="Read parsed AST")], ).cache_key assert request.cache_key != ProcessingRequest( operation="query.selector", input={"selector": "sections[heading=Decision]"}, context=ProcessingContext(source_path=Path("other.md")), options={"format": "json"}, capabilities=[ProcessingCapability(id="ast", description="Read parsed AST")], ).cache_key def test_processing_result_validity_provenance_and_trace(): result = ProcessingResult( output={"count": 1}, provenance=[ ProcessingProvenance( operation="query.selector", source_path="doc.md", content_hash="sha256:abc", dependencies=["doc.md"], ) ], trace=[ProcessingTrace(event="query.start", metadata={"engine": "selector"})], ) data = result.to_dict() assert result.valid assert data["valid"] is True assert data["output"]["count"] == 1 assert data["provenance"][0]["operation"] == "query.selector" assert data["trace"][0]["metadata"]["engine"] == "selector" def test_processing_result_with_trace_preserves_envelope_fields(): result = ProcessingResult( output={"count": 1}, dependencies=["doc.md"], metadata={"engine": "selector"}, ) traced = result.with_trace(ProcessingTrace(event="query.done")) assert traced.output == result.output assert traced.dependencies == ["doc.md"] assert traced.metadata == {"engine": "selector"} assert traced.trace[0].event == "query.done" def test_processing_result_from_error_normalizes_diagnostics(): result = ProcessingResult.from_error( code="extension.missing_dependency", message="Install optional dependency.", source_path="doc.md", line=3, details={"dependency": "jsonpath-ng"}, ) data = result.to_dict() assert not result.valid assert data["diagnostics"][0]["severity"] == "error" assert data["diagnostics"][0]["source"]["path"] == "doc.md" assert data["diagnostics"][0]["details"]["dependency"] == "jsonpath-ng"