From cf1502cee9409f957de8fdc0516e4287ba2c4c0c Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 20 Jun 2026 00:45:47 -0600 Subject: [PATCH] Test templates registries and resolve_template precedence Covers the netlist-first precedence contract (names in both registries), asc-only/netlist-only resolution, unknown -> None, and the deduped union in all_template_names -- the lookup logic tune_circuit depends on. --- tests/test_templates.py | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/test_templates.py diff --git a/tests/test_templates.py b/tests/test_templates.py new file mode 100644 index 0000000..3c091f3 --- /dev/null +++ b/tests/test_templates.py @@ -0,0 +1,58 @@ +"""Tests for the circuit template registries and lookup helpers.""" + +from mcltspice.templates import ( + ASC_TEMPLATES, + NETLIST_TEMPLATES, + all_template_names, + resolve_template, +) + + +class TestRegistries: + def test_both_registries_populated(self): + assert len(NETLIST_TEMPLATES) == 15 + assert len(ASC_TEMPLATES) == 15 + + def test_every_entry_has_required_keys(self): + for reg in (NETLIST_TEMPLATES, ASC_TEMPLATES): + for name, entry in reg.items(): + assert callable(entry["func"]), name + assert isinstance(entry["description"], str) and entry["description"], name + assert isinstance(entry["params"], dict), name + + +class TestResolveTemplate: + def test_netlist_first_precedence(self): + """A name in both registries resolves to its netlist form.""" + assert "rc_lowpass" in NETLIST_TEMPLATES + assert "rc_lowpass" in ASC_TEMPLATES + entry, is_netlist = resolve_template("rc_lowpass") + assert is_netlist is True + assert entry is NETLIST_TEMPLATES["rc_lowpass"] + + def test_asc_only_name(self): + """A name only in the asc registry resolves there, is_netlist False.""" + assert "inverting_amp" in ASC_TEMPLATES + assert "inverting_amp" not in NETLIST_TEMPLATES + entry, is_netlist = resolve_template("inverting_amp") + assert is_netlist is False + assert entry is ASC_TEMPLATES["inverting_amp"] + + def test_netlist_only_name(self): + assert "inverting_amplifier" in NETLIST_TEMPLATES + entry, is_netlist = resolve_template("inverting_amplifier") + assert is_netlist is True + + def test_unknown_returns_none(self): + assert resolve_template("does_not_exist") is None + + +class TestAllTemplateNames: + def test_is_sorted_union(self): + names = all_template_names() + expected = sorted(set(NETLIST_TEMPLATES) | set(ASC_TEMPLATES)) + assert names == expected + + def test_dedupes_overlapping_names(self): + # 15 + 15 with 9 shared names -> 21 unique + assert len(all_template_names()) == 21