Esempio n. 1
0
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
Esempio n. 2
0
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()
Esempio n. 3
0
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
Esempio n. 4
0
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)])
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
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
Esempio n. 8
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
Esempio n. 9
0
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()
Esempio n. 10
0
 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
Esempio n. 11
0
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)
Esempio n. 12
0
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')])
Esempio n. 13
0
    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
Esempio n. 14
0
    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
Esempio n. 15
0
 def __ror__(
     self, publisher: Publisher
 ) -> Union[SubscriptionDisposable, Publisher, 'Subscriber']:
     return publisher.subscribe(self)
Esempio n. 16
0
 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
Esempio n. 17
0
 def __ror__(
     self, publisher: Publisher
 ) -> Union[SubscriptionDisposable, 'Publisher', 'Subscriber']:
     return publisher.subscribe(self, prepend=True)
Esempio n. 18
0
 def __ror__(
     self, publisher: Publisher
 ) -> Union[SubscriptionDisposable, 'Publisher', 'Subscriber']:
     self._publisher = publisher
     publisher.subscribe(self)
     return self