spice2wireviz/tests/test_inter_module.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

146 lines
5.1 KiB
Python

"""Tests for the inter-module mapper."""
from pathlib import Path
from spice2wireviz.filter import FilterConfig
from spice2wireviz.mapper.inter_module import map_inter_module
from spice2wireviz.parser.netlist import parse_netlist
FIXTURES = Path(__file__).parent / "fixtures"
class TestInterModuleMapping:
def test_multi_board_connectors(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
connectors = result["connectors"]
# Should have connectors for each X instance and top-level components
assert "X1" in connectors
assert "X2" in connectors
assert "X3" in connectors
assert "J_CHASSIS" in connectors
assert "TP_VCC" in connectors
def test_instance_connector_type(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
x1 = result["connectors"]["X1"]
assert x1["type"] == "power_supply"
def test_instance_pinlabels(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
x2 = result["connectors"]["X2"]
assert "VIN" in x2["pinlabels"]
assert "GND" in x2["pinlabels"]
assert "VOUT" in x2["pinlabels"]
def test_cables_for_shared_nets(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
# Should have cables connecting modules via shared nets
cables = result["cables"]
assert len(cables) >= 1
def test_connections_exist(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
connections = result["connections"]
assert len(connections) >= 1
def test_traceability_notes(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
x1 = result["connectors"]["X1"]
assert "SPICE instance" in x1["notes"]
def test_top_level_test_point_style(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
result = map_inter_module(netlist)
tp = result["connectors"]["TP_VCC"]
assert tp.get("style") == "simple"
class TestInterModuleFiltering:
def test_exclude_instance(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
config = FilterConfig(exclude_refs=["X1"])
result = map_inter_module(netlist, config)
assert "X1" not in result["connectors"]
assert "X2" in result["connectors"]
def test_exclude_subcircuit(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
config = FilterConfig(exclude_subcircuits=["power_supply"])
result = map_inter_module(netlist, config)
assert "X1" not in result["connectors"]
def test_no_ground_filter(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
config = FilterConfig(show_ground=False)
result = map_inter_module(netlist, config)
# GND should not appear in any connector's pinlabels
for name, conn in result["connectors"].items():
if "pinlabels" in conn:
assert "GND" not in conn["pinlabels"], f"GND found in {name}"
def test_no_power_filter(self):
netlist = parse_netlist(FIXTURES / "multi_board.net")
config = FilterConfig(show_power=False)
result = map_inter_module(netlist, config)
for name, conn in result["connectors"].items():
if "pinlabels" in conn:
assert "VCC" not in conn["pinlabels"], f"VCC found in {name}"
class TestHierarchicalInterModule:
def test_hierarchical_instances(self):
netlist = parse_netlist(FIXTURES / "hierarchical.net")
result = map_inter_module(netlist)
connectors = result["connectors"]
assert "X_REG" in connectors
assert "X_SENSOR" in connectors
assert "X_MAIN" in connectors
def test_external_connectors(self):
netlist = parse_netlist(FIXTURES / "hierarchical.net")
result = map_inter_module(netlist)
connectors = result["connectors"]
assert "J_PWR" in connectors
assert "J_USB" in connectors
assert "TP_3V3" in connectors
def test_grouped_parallel_wires(self):
"""Parallel wires between same modules should be grouped."""
netlist = parse_netlist(FIXTURES / "hierarchical.net")
config = FilterConfig(group_parallel_wires=True)
result = map_inter_module(netlist, config)
# With grouping, fewer cables than total net connections
cables = result["cables"]
connections = result["connections"]
assert len(cables) == len(connections)
def test_ungrouped_wires(self):
"""Without grouping, each wire gets its own cable."""
netlist = parse_netlist(FIXTURES / "hierarchical.net")
config = FilterConfig(group_parallel_wires=False)
result = map_inter_module(netlist, config)
# Each cable should have wirecount=1
for cable in result["cables"].values():
assert cable.get("wirecount", 1) == 1 or len(cable.get("colors", [])) == 1