def test_reset_state(): """ Test .reset_state() """ m = mock.Mock() p = Publisher() p.subscribe(Sink(m, 1)) m.assert_not_called() # test .reset_state() before and after subscribing p.reset_state() assert p.get() == NONE p.subscribe(Sink(m, 2)) m.assert_not_called() m.reset_mock() # test .reset_state() after notify p.notify('check') assert p.get() == 'check' m.assert_has_calls([mock.call(1, 'check'), mock.call(2, 'check')]) m.reset_mock() # test no subscribers get notified p.reset_state() m.assert_not_called() assert p.get() == NONE
async def test_future_return(): class S(Subscriber): def __init__(self): self.future = asyncio.get_event_loop().create_future() def emit(self, value, who: Publisher) -> asyncio.Future: return self.future p = Publisher() s1 = S() p.subscribe(s1) assert p.notify(None) is s1.future s2 = S() p.subscribe(s2) gathered_future = p.notify(None) await asyncio.sleep(0) assert not gathered_future.done() s1.future.set_result(1) await asyncio.sleep(0) assert not gathered_future.done() s2.future.set_result(1) await asyncio.sleep(0) assert gathered_future.done()
def test_build(build_kwargs, init_args, init_kwargs, ref_args, ref_kwargs, exception): mock_cb = mock.Mock() ref_mock_cb = mock.Mock() reference = Sink(ref_mock_cb, *ref_args, **ref_kwargs) try: if build_kwargs is None: dut = build_sink_factory(mock_cb)(*init_args, **init_kwargs) else: dut = build_sink_factory(**build_kwargs)(mock_cb)(*init_args, **init_kwargs) except Exception as e: assert isinstance(e, exception) return else: assert exception is None assert dut._unpack == reference._unpack v = Publisher((1, 2)) v.subscribe(dut) v.subscribe(reference) assert mock_cb.mock_calls == ref_mock_cb.mock_calls assert len(mock_cb.mock_calls) == 1
def test_notify(init, number_of_subscribers): """ Testing .notify(v) method """ p = Publisher(init) m = mock.Mock() # subscribing Sinks to the publisher and test .notify on subscribe subscribers = [Sink(m, i) for i in range(number_of_subscribers)] m.assert_not_called() for s in subscribers: p.subscribe(s) if init is not NONE: m.assert_has_calls([mock.call(i, init) for i in range(number_of_subscribers)]) else: m.assert_not_called() m.reset_mock() # test .notify() for listening subscribers p.notify(1) m.assert_has_calls([mock.call(i, 1) for i in range(number_of_subscribers)]) m.reset_mock() # re- .notify() with the same value p.notify(1) m.assert_has_calls([mock.call(i, 1) for i in range(number_of_subscribers)])
def subscribe(self, subscriber: 'Subscriber', prepend: bool = False) -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber, prepend) if len(self._subscriptions) == 1: # if this was the first subscription self._orginator.subscribe(self) return disposable
def subscribe(self, subscriber: 'Subscriber', prepend: bool = False) -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber, prepend) if len(self._subscriptions) == 1: # if this was the first subscription for publisher in self._originators: # subscribe to all dependent publishers publisher.subscribe(self) return disposable
def test_subscription_disposable(): p = Publisher() v = Value(0) assert len(p.subscriptions) == 0 disposable = p.subscribe(v) assert len(p.subscriptions) == 1 assert disposable.publisher is p assert disposable.subscriber is v disposable.dispose() assert len(p.subscriptions) == 0 with p.subscribe(v): assert len(p.subscriptions) == 1 assert len(p.subscriptions) == 0
def subscribe(self, subscriber: Subscriber, prepend: bool = False) -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber, prepend) if self._interval is None: try: result = self._poll_func() subscriber.emit(result, who=self) except Exception: # pylint: disable=broad-except self._error_callback(*sys.exc_info()) elif self._call_later_handler is None: self._poll_callback() return disposable
def test_subscribe(): """ Testing .subscribe() and .unsubscibe() of Publisher. """ s1 = Value() s2 = Value() publisher = Publisher() assert len(publisher.subscriptions) == 0 # subscribe first subscriber d1 = publisher.subscribe(s1) assert any(s1 is s for s in publisher.subscriptions) assert not any(s2 is s for s in publisher.subscriptions) assert len(publisher.subscriptions) == 1 # re - subscribe should fail with pytest.raises(SubscriptionError): publisher.subscribe(s1) # subscribe second subscriber d2 = publisher.subscribe(s2) assert len(publisher.subscriptions) == 2 assert any(s1 is s for s in publisher.subscriptions) assert any(s2 is s for s in publisher.subscriptions) # unsubscribe both subscribers d2.dispose() assert len(publisher.subscriptions) == 1 publisher.unsubscribe(s1) assert len(publisher.subscriptions) == 0 # re - unsubscribing should fail with pytest.raises(SubscriptionError): d1.dispose() with pytest.raises(SubscriptionError): publisher.unsubscribe(s1) with pytest.raises(SubscriptionError): d2.dispose()
def subscribe(self, subscriber: 'Subscriber', prepend: bool = False) -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber, prepend) if len(self._subscriptions) == 1: # if this was the first subscription self._publisher.subscribe(self._emit_sink) else: try: value = self.get() except ValueError: pass else: subscriber.emit(value, who=self) return disposable
def test_subscription_callback(): """ testing .register_on_subscription_callback() """ m = mock.Mock() p = Publisher() p.register_on_subscription_callback(m) # callback should be called on first subscription (with True as argument) d1 = p.subscribe(Sink()) m.assert_called_once_with(True) m.reset_mock() # it should not be called until the last subscriber is unsubscribing d2 = p.subscribe(Sink()) d1.dispose() m.assert_not_called() # callback should be called with False as argument on last unsubscription d2.dispose() m.assert_called_once_with(False) m.reset_mock() # callback should again be called with True as argument on first subscription d3 = p.subscribe(Sink()) m.assert_called_once_with(True) m.reset_mock() # after reseting callback it should no be called again p.register_on_subscription_callback(None) d3.dispose() p.subscribe(Sink()) m.assert_not_called() # check if callback is called when subscriber is already available p.register_on_subscription_callback(m) m.assert_called_once_with(True)
def test_prepend(): """ Testing the prepend argument in .subscribe() """ m = mock.Mock() p = Publisher() s1 = Sink(m, 1) s2 = Sink(m, 2) s3 = Sink(m, 3) s4 = Sink(m, 4) p.subscribe(s1) p.subscribe(s2, prepend=True) # will be inserted before s1 p.subscribe(s3) # will be appended after s1 p.subscribe(s4, prepend=True) # will be inserted even before s2 p.notify('test') # notification order should now be: s4, s2, s1, s3 m.assert_has_calls([mock.call(4, 'test'), mock.call(2, 'test'), mock.call(1, 'test'), mock.call(3, 'test')])
def subscribe(self, subscriber: Subscriber, prepend: bool = False) -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber, prepend) old_state = self._state # to check if .emit was called if len(self._subscriptions) == 1: # if this was the first subscription self._publisher.subscribe(self._emit_sink) try: value = self._publisher.get() except ValueError: if self._state is not NONE: subscriber.emit(self._state, who=self) else: if len(self._subscriptions) > 1 or old_state == self._state: subscriber.emit(value, who=self) return disposable
def subscribe(self, subscriber: Subscriber, prepend: bool = False) -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber, prepend) if self._subject is not None: if not isinstance(self._subject, Publisher): raise TypeError('Topic %r has to be a Publisher when using' ' .subscribe()' % self._path) if len(self._subscriptions) == 1: self._subject.subscribe(self) else: try: value = self._subject.get() except ValueError: pass else: subscriber.emit(value, who=self) return disposable
def __ror__( self, publisher: Publisher ) -> Union[SubscriptionDisposable, Publisher, 'Subscriber']: return publisher.subscribe(self)
def subscribe(self, subscriber: 'Subscriber') -> SubscriptionDisposable: disposable = Publisher.subscribe(self, subscriber) if self._state is not NONE : subscriber.emit(self._state, who=self) return disposable
def __ror__( self, publisher: Publisher ) -> Union[SubscriptionDisposable, 'Publisher', 'Subscriber']: return publisher.subscribe(self, prepend=True)
def __ror__( self, publisher: Publisher ) -> Union[SubscriptionDisposable, 'Publisher', 'Subscriber']: self._publisher = publisher publisher.subscribe(self) return self