def test_disconnecting_ports_via_shadow(self): shadow = ShadowPortArray([self.array_a, self.array_b]) shadow.connect_port('in_both', lambda: 'both') shadow.connect_port('a_only', lambda: 'a') shadow.connect_port('b_only', lambda: 'b') shadow.disconnect_port('in_both') shadow.disconnect_port('b_only') with self.assertRaisesRegexp(DisconnectedPort, 'Port "in_both" has not been connected'): self.array_a.in_both() with self.assertRaisesRegexp(DisconnectedPort, 'Port "in_both" has not been connected'): self.array_b.in_both() with self.assertRaisesRegexp(DisconnectedPort, 'Port "b_only" has not been connected'): self.array_b.b_only() self.assertEqual('a', self.array_a.a_only()) # this should remain connected
def __init__(self): super(Domain, self).__init__() self._service_map = service_map = self._instantiate_and_map_services() # replace 'meta' with a variant for the instance (don't share self.__class__.meta) self.meta = self.__class__.meta.get_instance_metadata( service_map=service_map) # replace 'deps' with a ShadowPortArray which serves as proxy to the deps of internal services components = service_map.values() component_deps = [ c.deps for c in components if isinstance(getattr(c, 'deps', None), (PortArray, ShadowPortArray)) ] discovered = AutoDiscoverConnections(components=components) self.deps = ShadowPortArray(arrays=component_deps, ignore_ports=discovered.satisfied_needs()) # materialize connections between services wire_up_discovered_connections(discovered=discovered)
def test_shadow_does_not_inherit_ignored_ports(self): shadow = ShadowPortArray([self.array_a, self.array_b], ignore_ports=['in_both', 'also_a_only', 'fluff']) self.assertItemsEqual(['a_only', 'b_only'], shadow.get_ports())
def test_raise_UnknownPort_when_disconnecting_an_unknown_port(self): shadow = ShadowPortArray([self.array_a, self.array_b]) with self.assertRaisesRegexp(UnknownPort, '"hello" is not a valid port'): shadow.disconnect_port('hello')
def test_raises_WiringError_when_connecting_port_to_non_callable(self): shadow = ShadowPortArray([self.array_a, self.array_b]) with self.assertRaisesRegexp(WiringError, 'Cannot connect port to a non-callable object'): shadow.connect_port('in_both', None)
def test_shadow_with_multiple_children(self): shadow = ShadowPortArray([self.array_a, self.array_b]) self.assertItemsEqual(['a_only', 'also_a_only', 'b_only', 'in_both'], shadow.get_ports())
def test_shadow_with_only_one_child(self): shadow = ShadowPortArray([self.array_b]) self.assertItemsEqual(['b_only', 'in_both'], shadow.get_ports())
def test_empty_shadow_port_array_can_be_created(self): shadow = ShadowPortArray([]) self.assertEqual([], shadow.get_ports())
class Domain(INeed, IProvide): """ @DynamicAttrs <-- let pycharm know to expect dynamically added attributes """ __metaclass__ = DomainMetaclass __services__ = ( ) # must be overridden in subclass to define list of services within this domain __provides__ = ( ) # must be overridden to expose ports that this domain provides def __init__(self): super(Domain, self).__init__() self._service_map = service_map = self._instantiate_and_map_services() # replace 'meta' with a variant for the instance (don't share self.__class__.meta) self.meta = self.__class__.meta.get_instance_metadata( service_map=service_map) # replace 'deps' with a ShadowPortArray which serves as proxy to the deps of internal services components = service_map.values() component_deps = [ c.deps for c in components if isinstance(getattr(c, 'deps', None), (PortArray, ShadowPortArray)) ] discovered = AutoDiscoverConnections(components=components) self.deps = ShadowPortArray(arrays=component_deps, ignore_ports=discovered.satisfied_needs()) # materialize connections between services wire_up_discovered_connections(discovered=discovered) def _instantiate_and_map_services(self): mapper = { service_class: service_class() for service_class in self.__services__ } return mapper # ---- implement INeed ---- @classmethod def get_needs(cls): return cls.deps.get_ports() def _is_compatible_provider(self, port_name, provider): return True # no flag checking for now def _satisfy_need(self, port_name, func): self.deps.connect_port(port_name, func) # ---- implement IProvide ---- @classmethod def get_provides(cls): return cls.meta.get_provides() def get_provider_func(self, port_name): provider = self.meta.get_provider(port_name=port_name) provider_func = provider.get_provider_func(port_name=port_name) return provider_func @classmethod def get_provider_flag(cls, port_name, flag_name): return cls.meta.get_provider_flag(port_name, flag_name) @classmethod def get_provider_flags(cls, port_name): return cls.meta.get_provider_flags(port_name)