Skip to main content

#!/usr/bin/env python3 """ H.1.7: Tests for Component Metadata Registry

Tests the unified metadata registry that consolidates component metadata from multiple sources. """

import json import pytest import sys from pathlib import Path from unittest.mock import MagicMock, patch, mock_open

Add parent to path

sys.path.insert(0, str(Path(file).parent.parent.parent))

from scripts.core.component_metadata_registry import ( ComponentMetadataRegistry, ComponentMetadata, ComponentType, ComponentStatus, ActivationState, LLMBinding, CapabilityInfo, )

=============================================================================

Data Class Tests

=============================================================================

class TestLLMBinding: """Tests for LLMBinding dataclass."""

def test_default_values(self):
"""Test LLMBinding default values."""
binding = LLMBinding()
assert binding.provider == "anthropic-claude"
assert binding.model == "sonnet"
assert binding.temperature == 0.7
assert binding.max_tokens == 4096

def test_custom_values(self):
"""Test LLMBinding with custom values."""
binding = LLMBinding(
provider="openai",
model="gpt-4",
temperature=0.5,
max_tokens=8192
)
assert binding.provider == "openai"
assert binding.model == "gpt-4"
assert binding.temperature == 0.5
assert binding.max_tokens == 8192

def test_from_dict(self):
"""Test LLMBinding.from_dict()."""
data = {
"provider": "anthropic-claude",
"model": "opus",
"temperature": 0.3,
"max_tokens": 16384
}
binding = LLMBinding.from_dict(data)
assert binding.model == "opus"
assert binding.temperature == 0.3
assert binding.max_tokens == 16384

def test_from_dict_partial(self):
"""Test LLMBinding.from_dict() with partial data."""
data = {"model": "haiku"}
binding = LLMBinding.from_dict(data)
assert binding.model == "haiku"
assert binding.provider == "anthropic-claude" # Default
assert binding.temperature == 0.7 # Default

class TestCapabilityInfo: """Tests for CapabilityInfo dataclass."""

def test_creation(self):
"""Test CapabilityInfo creation."""
cap = CapabilityInfo(
name="security",
type="domain",
confidence=0.95,
source="agent_card"
)
assert cap.name == "security"
assert cap.type == "domain"
assert cap.confidence == 0.95
assert cap.source == "agent_card"

def test_default_values(self):
"""Test CapabilityInfo default values."""
cap = CapabilityInfo(name="test", type="tag")
assert cap.confidence == 1.0
assert cap.source == "registry"

class TestComponentMetadata: """Tests for ComponentMetadata dataclass."""

def test_minimal_creation(self):
"""Test ComponentMetadata with minimal fields."""
meta = ComponentMetadata(
id="agent/test",
name="test",
type=ComponentType.AGENT
)
assert meta.id == "agent/test"
assert meta.name == "test"
assert meta.type == ComponentType.AGENT
assert meta.version == "1.0.0"
assert meta.status == ComponentStatus.OPERATIONAL
assert meta.activation == ActivationState.ACTIVATED

def test_full_creation(self):
"""Test ComponentMetadata with all fields."""
binding = LLMBinding(model="opus")
caps = [CapabilityInfo("security", "domain")]

meta = ComponentMetadata(
id="agent/security-specialist",
name="security-specialist",
type=ComponentType.AGENT,
version="2.0.0",
description="Security expert",
category="security",
status=ComponentStatus.OPERATIONAL,
activation=ActivationState.ACTIVATED,
llm_binding=binding,
capabilities=caps,
tools=["Read", "Write"],
path="agents/security-specialist.md"
)

assert meta.version == "2.0.0"
assert meta.description == "Security expert"
assert meta.llm_binding.model == "opus"
assert len(meta.capabilities) == 1

def test_to_dict(self):
"""Test ComponentMetadata.to_dict()."""
meta = ComponentMetadata(
id="agent/test",
name="test",
type=ComponentType.AGENT,
description="Test agent",
llm_binding=LLMBinding(model="sonnet"),
capabilities=[CapabilityInfo("review", "action")]
)

data = meta.to_dict()

assert data["id"] == "agent/test"
assert data["name"] == "test"
assert data["type"] == "agent"
assert data["description"] == "Test agent"
assert data["llm_binding"]["model"] == "sonnet"
assert len(data["capabilities"]) == 1

=============================================================================

Enum Tests

=============================================================================

class TestEnums: """Tests for enum types."""

def test_component_types(self):
"""Test all ComponentType values exist."""
expected = ["agent", "command", "skill", "script", "hook", "workflow", "prompt"]
actual = [t.value for t in ComponentType]
for e in expected:
assert e in actual

def test_component_status(self):
"""Test all ComponentStatus values exist."""
expected = ["operational", "degraded", "maintenance", "deprecated", "experimental"]
actual = [s.value for s in ComponentStatus]
for e in expected:
assert e in actual

def test_activation_state(self):
"""Test all ActivationState values exist."""
assert ActivationState.ACTIVATED.value == "activated"
assert ActivationState.DEACTIVATED.value == "deactivated"

=============================================================================

Registry Tests (with mocked file loading)

=============================================================================

class TestComponentMetadataRegistryCore: """Tests for ComponentMetadataRegistry core functionality."""

def test_registry_initialization(self):
"""Test registry can be initialized without auto-load."""
registry = ComponentMetadataRegistry(auto_load=False)
assert registry._components == {}
assert registry._loaded_at is None

def test_get_nonexistent(self):
"""Test getting a nonexistent component."""
registry = ComponentMetadataRegistry(auto_load=False)
result = registry.get("agent/nonexistent")
assert result is None

def test_get_by_name_nonexistent(self):
"""Test get_by_name for nonexistent component."""
registry = ComponentMetadataRegistry(auto_load=False)
result = registry.get_by_name("nonexistent")
assert result is None

def test_list_by_type_empty(self):
"""Test listing components when empty."""
registry = ComponentMetadataRegistry(auto_load=False)
result = registry.list_by_type(ComponentType.AGENT)
assert result == []

def test_search_empty(self):
"""Test searching when empty."""
registry = ComponentMetadataRegistry(auto_load=False)
result = registry.search("test")
assert result == []

def test_get_stats_empty(self):
"""Test stats when empty."""
registry = ComponentMetadataRegistry(auto_load=False)
stats = registry.get_stats()
assert stats["total_components"] == 0
assert stats["activated"] == 0
assert stats["deactivated"] == 0

class TestComponentMetadataRegistryWithData: """Tests for ComponentMetadataRegistry with populated data."""

@pytest.fixture
def registry_with_data(self):
"""Create a registry with test data."""
registry = ComponentMetadataRegistry(auto_load=False)

# Add test components
registry._components = {
"agent/orchestrator": ComponentMetadata(
id="agent/orchestrator",
name="orchestrator",
type=ComponentType.AGENT,
description="Multi-agent orchestration",
llm_binding=LLMBinding(model="sonnet"),
capabilities=[
CapabilityInfo("orchestration", "domain"),
CapabilityInfo("workflow", "action"),
],
activation=ActivationState.ACTIVATED,
),
"agent/security": ComponentMetadata(
id="agent/security",
name="security",
type=ComponentType.AGENT,
description="Security specialist",
capabilities=[
CapabilityInfo("security", "domain"),
CapabilityInfo("audit", "action"),
],
activation=ActivationState.ACTIVATED,
),
"command/commit": ComponentMetadata(
id="command/commit",
name="commit",
type=ComponentType.COMMAND,
description="Git commit command",
activation=ActivationState.DEACTIVATED,
),
}

# Build indexes
registry._build_indexes()
registry._loaded_at = "2026-01-08T00:00:00Z"

return registry

def test_get(self, registry_with_data):
"""Test getting a component by ID."""
comp = registry_with_data.get("agent/orchestrator")
assert comp is not None
assert comp.name == "orchestrator"
assert comp.type == ComponentType.AGENT

def test_get_by_name_with_type(self, registry_with_data):
"""Test get_by_name with type specified."""
comp = registry_with_data.get_by_name("orchestrator", ComponentType.AGENT)
assert comp is not None
assert comp.id == "agent/orchestrator"

def test_get_by_name_without_type(self, registry_with_data):
"""Test get_by_name without type (searches all)."""
comp = registry_with_data.get_by_name("orchestrator")
assert comp is not None
assert comp.id == "agent/orchestrator"

def test_list_by_type(self, registry_with_data):
"""Test listing components by type."""
agents = registry_with_data.list_by_type(ComponentType.AGENT)
assert len(agents) == 2

commands = registry_with_data.list_by_type(ComponentType.COMMAND)
assert len(commands) == 1

def test_list_by_type_activated_only(self, registry_with_data):
"""Test listing only activated components."""
commands = registry_with_data.list_by_type(
ComponentType.COMMAND,
activated_only=True
)
assert len(commands) == 0 # commit is deactivated

def test_list_by_capability(self, registry_with_data):
"""Test listing components by capability."""
security_comps = registry_with_data.list_by_capability("security")
assert len(security_comps) == 1
assert security_comps[0].name == "security"

def test_search_by_name(self, registry_with_data):
"""Test searching by name."""
results = registry_with_data.search("orchestrator")
assert len(results) == 1
assert results[0].name == "orchestrator"

def test_search_by_description(self, registry_with_data):
"""Test searching by description."""
results = registry_with_data.search("multi-agent")
assert len(results) == 1
assert results[0].name == "orchestrator"

def test_search_by_capability(self, registry_with_data):
"""Test searching by capability name."""
results = registry_with_data.search("security")
assert len(results) >= 1

def test_search_with_type_filter(self, registry_with_data):
"""Test searching with type filter."""
results = registry_with_data.search("commit", ComponentType.COMMAND)
assert len(results) == 1
assert results[0].type == ComponentType.COMMAND

def test_get_capabilities(self, registry_with_data):
"""Test getting component capabilities."""
caps = registry_with_data.get_capabilities("agent/orchestrator")
assert len(caps) == 2
cap_names = [c.name for c in caps]
assert "orchestration" in cap_names
assert "workflow" in cap_names

def test_get_capabilities_nonexistent(self, registry_with_data):
"""Test getting capabilities for nonexistent component."""
caps = registry_with_data.get_capabilities("agent/nonexistent")
assert caps == []

def test_get_relationships(self, registry_with_data):
"""Test getting component relationships."""
rels = registry_with_data.get_relationships("agent/orchestrator")
assert "invokes" in rels
assert "invoked_by" in rels
assert "alternatives" in rels
assert "complements" in rels

def test_get_relationships_nonexistent(self, registry_with_data):
"""Test getting relationships for nonexistent component."""
rels = registry_with_data.get_relationships("agent/nonexistent")
assert rels == {}

def test_get_stats(self, registry_with_data):
"""Test getting registry statistics."""
stats = registry_with_data.get_stats()

assert stats["total_components"] == 3
assert stats["activated"] == 2
assert stats["deactivated"] == 1
assert stats["by_type"]["agent"] == 2
assert stats["by_type"]["command"] == 1

=============================================================================

Index Building Tests

=============================================================================

class TestIndexBuilding: """Tests for index building functionality."""

def test_build_indexes_by_type(self):
"""Test that by_type index is built correctly."""
registry = ComponentMetadataRegistry(auto_load=False)
registry._components = {
"agent/a": ComponentMetadata(id="agent/a", name="a", type=ComponentType.AGENT),
"agent/b": ComponentMetadata(id="agent/b", name="b", type=ComponentType.AGENT),
"command/c": ComponentMetadata(id="command/c", name="c", type=ComponentType.COMMAND),
}
registry._build_indexes()

assert len(registry._by_type[ComponentType.AGENT]) == 2
assert len(registry._by_type[ComponentType.COMMAND]) == 1

def test_build_indexes_by_capability(self):
"""Test that by_capability index is built correctly."""
registry = ComponentMetadataRegistry(auto_load=False)
registry._components = {
"agent/a": ComponentMetadata(
id="agent/a",
name="a",
type=ComponentType.AGENT,
capabilities=[CapabilityInfo("security", "domain")]
),
"agent/b": ComponentMetadata(
id="agent/b",
name="b",
type=ComponentType.AGENT,
capabilities=[CapabilityInfo("security", "domain"), CapabilityInfo("testing", "domain")]
),
}
registry._build_indexes()

assert len(registry._by_capability["security"]) == 2
assert len(registry._by_capability["testing"]) == 1

=============================================================================

Run Tests

=============================================================================

if name == "main": pytest.main([file, "-v", "--tb=short"])