diff --git a/masque/ports.py b/masque/ports.py index ac48681..ff3a0e3 100644 --- a/masque/ports.py +++ b/masque/ports.py @@ -328,6 +328,9 @@ class PortList(metaclass=ABCMeta): duplicates = (set(self.ports.keys()) - set(mapping.keys())) & set(mapping.values()) if duplicates: raise PortError(f'Unrenamed ports would be overwritten: {duplicates}') + missing = set(mapping) - set(self.ports) + if missing: + raise PortError(f'Ports to rename were not found: {missing}') for kk, vv in mapping.items(): if vv is None or vv != kk: @@ -395,6 +398,14 @@ class PortList(metaclass=ABCMeta): Raises: `PortError` if the ports are not properly aligned. """ + if not connections: + raise PortError('Must provide at least one port connection') + missing_a = set(connections) - set(self.ports) + if missing_a: + raise PortError(f'Connection source ports were not found: {missing_a}') + missing_b = set(connections.values()) - set(self.ports) + if missing_b: + raise PortError(f'Connection destination ports were not found: {missing_b}') a_names, b_names = list(zip(*connections.items(), strict=True)) a_ports = [self.ports[pp] for pp in a_names] b_ports = [self.ports[pp] for pp in b_names] diff --git a/masque/test/test_ports.py b/masque/test/test_ports.py index 070bf8e..14dc982 100644 --- a/masque/test/test_ports.py +++ b/masque/test/test_ports.py @@ -70,6 +70,25 @@ def test_port_list_rename() -> None: assert "B" in pl.ports +def test_port_list_rename_missing_port_raises() -> None: + class MyPorts(PortList): + def __init__(self) -> None: + self._ports = {"A": Port((0, 0), 0)} + + @property + def ports(self) -> dict[str, Port]: + return self._ports + + @ports.setter + def ports(self, val: dict[str, Port]) -> None: + self._ports = val + + pl = MyPorts() + with pytest.raises(PortError, match="Ports to rename were not found"): + pl.rename_ports({"missing": "B"}) + assert set(pl.ports) == {"A"} + + def test_port_list_plugged() -> None: class MyPorts(PortList): def __init__(self) -> None: @@ -88,6 +107,25 @@ def test_port_list_plugged() -> None: assert not pl.ports # Both should be removed +def test_port_list_plugged_empty_raises() -> None: + class MyPorts(PortList): + def __init__(self) -> None: + self._ports = {"A": Port((10, 10), 0), "B": Port((10, 10), pi)} + + @property + def ports(self) -> dict[str, Port]: + return self._ports + + @ports.setter + def ports(self, val: dict[str, Port]) -> None: + self._ports = val + + pl = MyPorts() + with pytest.raises(PortError, match="Must provide at least one port connection"): + pl.plugged({}) + assert set(pl.ports) == {"A", "B"} + + def test_port_list_plugged_mismatch() -> None: class MyPorts(PortList): def __init__(self) -> None: