"""Tests for the Pydantic data models."""
import pytest
from models import (
ParameterInfo,
PortInfo,
BlockSummary,
BlockInfo,
FlowgraphHandle,
ConnectionInfo,
ValidationResult,
ValidationError,
GeneratedCode,
ConverterSuggestionInfo,
ConnectionCompatibilityInfo,
FilterInfo,
BlockReference,
)
class TestParameterInfo:
"""Tests for ParameterInfo model."""
def test_basic_creation(self):
p = ParameterInfo(
id="freq",
label="Frequency",
dtype="real",
)
assert p.id == "freq"
assert p.label == "Frequency"
assert p.dtype == "real"
def test_optional_fields_default(self):
p = ParameterInfo(id="freq", label="Frequency", dtype="real")
assert p.default is None
assert p.options is None
assert p.hide == "none"
def test_with_enum_options(self):
p = ParameterInfo(
id="type",
label="Type",
dtype="enum",
options=["complex", "float", "int"],
)
assert p.options == ["complex", "float", "int"]
class TestPortInfo:
"""Tests for PortInfo model."""
def test_stream_port(self):
p = PortInfo(id="0", domain="stream", dtype="complex")
assert p.domain == "stream"
assert p.vlen == 1
assert p.optional is False
def test_message_port(self):
p = PortInfo(id="msg", domain="message", dtype="message")
assert p.domain == "message"
def test_vector_port(self):
p = PortInfo(id="0", domain="stream", dtype="float", vlen=1024)
assert p.vlen == 1024
class TestBlockSummary:
"""Tests for BlockSummary model."""
def test_creation(self):
b = BlockSummary(
id="analog_sig_source_x",
label="Signal Source",
category=["Waveform Generators"],
)
assert b.id == "analog_sig_source_x"
assert b.label == "Signal Source"
class TestBlockInfo:
"""Tests for BlockInfo model."""
def test_full_block(self):
b = BlockInfo(
id="analog_sig_source_x",
label="Signal Source",
category=["Waveform Generators"],
parameters=[
ParameterInfo(id="freq", label="Frequency", dtype="real", default="1000"),
],
inputs=[],
outputs=[
PortInfo(id="0", domain="stream", dtype="complex"),
],
)
assert len(b.parameters) == 1
assert len(b.inputs) == 0
assert len(b.outputs) == 1
def test_default_flags(self):
b = BlockInfo(
id="test",
label="Test",
category=[],
parameters=[],
inputs=[],
outputs=[],
)
assert b.flags == []
assert b.documentation == ""
class TestFlowgraphHandle:
"""Tests for FlowgraphHandle model."""
def test_creation(self):
h = FlowgraphHandle(
id="abc-123",
name="test_flowgraph",
block_count=5,
connection_count=4,
)
assert h.id == "abc-123"
assert h.is_active is False
class TestConnectionInfo:
"""Tests for ConnectionInfo model."""
def test_creation(self):
c = ConnectionInfo(
source_block="sig_source_0",
source_port="0",
sink_block="throttle_0",
sink_port="0",
)
assert c.source_block == "sig_source_0"
class TestValidationResult:
"""Tests for ValidationResult model."""
def test_valid_flowgraph(self):
v = ValidationResult(valid=True, flowgraph_id="abc-123")
assert v.valid is True
assert v.errors == []
assert v.warnings == []
def test_invalid_with_errors(self):
v = ValidationResult(
valid=False,
flowgraph_id="abc-123",
errors=[
ValidationError(
message="Missing connection",
block_name="sig_source_0",
),
],
)
assert v.valid is False
assert len(v.errors) == 1
assert v.errors[0].severity == "error"
class TestGeneratedCode:
"""Tests for GeneratedCode model."""
def test_creation(self):
g = GeneratedCode(
code="#!/usr/bin/env python3\n# test",
flowgraph_id="abc-123",
class_name="test_flowgraph",
)
assert g.code.startswith("#!/usr/bin/env python3")
assert g.filepath is None
class TestConnectionCompatibilityInfo:
"""Tests for ConnectionCompatibilityInfo model."""
def test_compatible(self):
c = ConnectionCompatibilityInfo(
compatible=True,
source_type="complex",
source_domain="stream",
sink_type="complex",
sink_domain="stream",
reason="Types are compatible",
)
assert c.compatible is True
assert c.suggestions == []
def test_incompatible_with_suggestions(self):
c = ConnectionCompatibilityInfo(
compatible=False,
source_type="complex",
source_domain="stream",
sink_type="float",
sink_domain="stream",
reason="Type mismatch",
suggestions=[
ConverterSuggestionInfo(
block_id="blocks_complex_to_float",
description="Split complex into real/imag",
),
],
)
assert c.compatible is False
assert len(c.suggestions) == 1
class TestSerializationRoundTrip:
"""Test that models serialize and deserialize correctly."""
def test_block_info_json_roundtrip(self):
original = BlockInfo(
id="test_block",
label="Test Block",
category=["Test"],
parameters=[
ParameterInfo(id="p1", label="Param 1", dtype="real", default="42"),
],
inputs=[PortInfo(id="0", domain="stream", dtype="float")],
outputs=[PortInfo(id="0", domain="stream", dtype="float")],
)
json_str = original.model_dump_json()
restored = BlockInfo.model_validate_json(json_str)
assert restored.id == original.id
assert restored.parameters[0].default == "42"
def test_validation_result_json_roundtrip(self):
original = ValidationResult(
valid=False,
flowgraph_id="test-id",
errors=[ValidationError(message="test error")],
)
json_str = original.model_dump_json()
restored = ValidationResult.model_validate_json(json_str)
assert restored.valid is False
assert len(restored.errors) == 1