spice2wireviz/tests/test_yaml_emitter.py
Ryan Malloy e20a956f51 Initial project structure for spice2wireviz
SPICE netlist to WireViz YAML converter with:
- Custom lightweight netlist parser (.net/.cir/.sp)
- Single-module mapper (subcircuit external interface)
- Inter-module mapper (multi-board wiring)
- Filter engine with glob patterns
- Click CLI with auto-detection, inspection commands
- Optional .asc parser via spicelib
- Comprehensive test suite with fixtures
2026-02-13 01:24:41 -07:00

125 lines
3.9 KiB
Python

"""Tests for the YAML emitter."""
import yaml
from spice2wireviz.emitter.yaml_emitter import (
assemble_wireviz_doc,
build_cable,
build_connection,
build_connector,
emit_yaml,
)
class TestBuildConnector:
def test_minimal_with_pinlabels(self):
conn = build_connector("J1", pinlabels=["A", "B"])
assert conn["pinlabels"] == ["A", "B"]
def test_minimal_with_pincount(self):
conn = build_connector("J1", pincount=4)
assert conn["pincount"] == 4
def test_with_type_and_notes(self):
conn = build_connector("J1", pinlabels=["A"], connector_type="DB9", notes="test")
assert conn["type"] == "DB9"
assert conn["notes"] == "test"
def test_simple_style(self):
conn = build_connector("TP1", pinlabels=["SIG"], style="simple")
assert conn["style"] == "simple"
def test_empty_strings_omitted(self):
conn = build_connector("J1", pinlabels=["A"])
assert "type" not in conn
assert "style" not in conn
assert "notes" not in conn
class TestBuildCable:
def test_with_wirecount(self):
cable = build_cable("W1", wirecount=3)
assert cable["wirecount"] == 3
def test_with_colors(self):
cable = build_cable("W1", colors=["BK", "RD", ""])
assert cable["colors"] == ["BK", "RD", ""]
def test_with_labels(self):
cable = build_cable("W1", wirecount=2, wirelabels=["GND", "VCC"])
assert cable["wirelabels"] == ["GND", "VCC"]
def test_bundle_category(self):
cable = build_cable("W1", wirecount=2, category="bundle")
assert cable["category"] == "bundle"
class TestBuildConnection:
def test_single_wire(self):
conn = build_connection("J1", [1], "W1", [1], "J2", [1])
assert len(conn) == 3
assert conn[0] == {"J1": 1}
assert conn[1] == {"W1": 1}
assert conn[2] == {"J2": 1}
def test_multi_wire(self):
conn = build_connection("J1", [1, 2, 3], "W1", [1, 2, 3], "J2", [1, 2, 3])
assert conn[0] == {"J1": [1, 2, 3]}
assert conn[1] == {"W1": [1, 2, 3]}
assert conn[2] == {"J2": [1, 2, 3]}
class TestAssembleDoc:
def test_minimal_doc(self):
doc = assemble_wireviz_doc(
connectors={"J1": {"pincount": 2}},
cables={"W1": {"wirecount": 1}},
connections=[[{"J1": 1}, {"W1": 1}, {"J2": 1}]],
)
assert "connectors" in doc
assert "cables" in doc
assert "connections" in doc
assert "metadata" not in doc
def test_with_metadata(self):
doc = assemble_wireviz_doc(
connectors={},
cables={},
connections=[],
metadata={"title": "Test"},
)
assert doc["metadata"]["title"] == "Test"
class TestEmitYaml:
def test_produces_valid_yaml(self):
doc = assemble_wireviz_doc(
connectors={"J1": {"pinlabels": ["A", "B"]}, "J2": {"pinlabels": ["C", "D"]}},
cables={"W1": {"wirecount": 2}},
connections=[[{"J1": [1, 2]}, {"W1": [1, 2]}, {"J2": [1, 2]}]],
)
yaml_str = emit_yaml(doc)
parsed = yaml.safe_load(yaml_str)
assert parsed["connectors"]["J1"]["pinlabels"] == ["A", "B"]
def test_deterministic_output(self):
doc = assemble_wireviz_doc(
connectors={"Z": {"pincount": 1}, "A": {"pincount": 1}},
cables={"W1": {"wirecount": 1}},
connections=[],
)
yaml1 = emit_yaml(doc)
yaml2 = emit_yaml(doc)
assert yaml1 == yaml2 # Byte-identical
def test_preserves_insertion_order(self):
doc = assemble_wireviz_doc(
connectors={"Z_conn": {"pincount": 1}, "A_conn": {"pincount": 1}},
cables={},
connections=[],
)
yaml_str = emit_yaml(doc)
z_pos = yaml_str.index("Z_conn")
a_pos = yaml_str.index("A_conn")
assert z_pos < a_pos # Order preserved, not sorted alphabetically