generated from coulomb/repo-seed
115 lines
3.5 KiB
Python
115 lines
3.5 KiB
Python
import pytest
|
|
|
|
from markitect_tool.extension import (
|
|
ExtensionDescriptor,
|
|
ExtensionRegistry,
|
|
ExtensionRegistryError,
|
|
OptionalDependency,
|
|
ProcessingCapability,
|
|
)
|
|
|
|
|
|
def test_extension_descriptor_serializes_contract_metadata():
|
|
descriptor = ExtensionDescriptor(
|
|
id="query.selector",
|
|
kind="query-engine",
|
|
summary="Small selector query engine.",
|
|
capabilities=[ProcessingCapability(id="ast", kind="read")],
|
|
input_contract="Document + selector",
|
|
output_contract="QueryMatch[]",
|
|
diagnostics_namespace="query",
|
|
provenance_prefix="query.selector",
|
|
cli={"command": "mkt query"},
|
|
docs=["docs/query-extraction.md"],
|
|
)
|
|
|
|
data = descriptor.to_dict()
|
|
|
|
assert data["id"] == "query.selector"
|
|
assert data["kind"] == "query-engine"
|
|
assert data["capabilities"][0]["id"] == "ast"
|
|
assert data["cli"]["command"] == "mkt query"
|
|
|
|
|
|
def test_extension_registry_lists_by_kind_and_capability():
|
|
selector = ExtensionDescriptor(
|
|
id="query.selector",
|
|
kind="query-engine",
|
|
capabilities=[ProcessingCapability(id="ast")],
|
|
)
|
|
local = ExtensionDescriptor(
|
|
id="backend.local-sqlite",
|
|
kind="backend",
|
|
capabilities=[ProcessingCapability(id="snapshots"), ProcessingCapability(id="fts")],
|
|
)
|
|
registry = ExtensionRegistry([local, selector])
|
|
|
|
assert [descriptor.id for descriptor in registry.list()] == [
|
|
"backend.local-sqlite",
|
|
"query.selector",
|
|
]
|
|
assert [descriptor.id for descriptor in registry.list(kind="query-engine")] == [
|
|
"query.selector"
|
|
]
|
|
assert [descriptor.id for descriptor in registry.require_capability("fts")] == [
|
|
"backend.local-sqlite"
|
|
]
|
|
assert registry.require_capability("missing") == []
|
|
assert registry.list(kind="missing") == []
|
|
|
|
|
|
def test_extension_registry_rejects_duplicate_ids():
|
|
descriptor = ExtensionDescriptor(id="query.selector", kind="query-engine")
|
|
registry = ExtensionRegistry([descriptor])
|
|
|
|
with pytest.raises(ExtensionRegistryError, match="Duplicate extension id"):
|
|
registry.register(descriptor)
|
|
|
|
|
|
def test_extension_registry_checks_optional_dependencies():
|
|
registry = ExtensionRegistry(
|
|
[
|
|
ExtensionDescriptor(
|
|
id="query.jsonpath",
|
|
kind="query-engine",
|
|
optional_dependencies=[
|
|
OptionalDependency(
|
|
name="jsonpath_ng",
|
|
package="jsonpath-ng",
|
|
extra="query",
|
|
required=True,
|
|
),
|
|
OptionalDependency(name="tabulate"),
|
|
],
|
|
)
|
|
]
|
|
)
|
|
|
|
missing = registry.check_dependencies("query.jsonpath", available_modules=set())
|
|
available = registry.check_dependencies(
|
|
"query.jsonpath",
|
|
available_modules={"jsonpath_ng", "tabulate"},
|
|
)
|
|
|
|
assert not missing.compatible
|
|
assert missing.missing == ["jsonpath_ng"]
|
|
assert missing.optional_missing == ["tabulate"]
|
|
assert available.compatible
|
|
|
|
|
|
def test_extension_descriptor_instantiates_factory():
|
|
descriptor = ExtensionDescriptor(
|
|
id="fake.extension",
|
|
kind="test",
|
|
factory=lambda: {"ready": True},
|
|
)
|
|
|
|
assert descriptor.instantiate() == {"ready": True}
|
|
|
|
|
|
def test_extension_descriptor_requires_factory_to_instantiate():
|
|
descriptor = ExtensionDescriptor(id="fake.extension", kind="test")
|
|
|
|
with pytest.raises(ExtensionRegistryError, match="has no factory"):
|
|
descriptor.instantiate()
|