def test_build(build_kwargs, init_args, init_kwargs, ref_args, ref_kwargs, exception): mock_cb = mock.Mock(return_value=(0,0)) ref_mock_cb = mock.Mock(return_value=(0,0)) try: if build_kwargs is None: dut = build_reduce(mock_cb)(*init_args, **init_kwargs) else: dut = build_reduce(**build_kwargs)(mock_cb)(*init_args, **init_kwargs) except Exception as e: assert isinstance(e, exception) return else: assert exception is None reference = Reduce(ref_mock_cb, *ref_args, **ref_kwargs) assert dut._init == reference._init assert dut._state == reference._state assert dut._result == reference._result v = StatefulPublisher(1) v | dut | Sink() v | reference | Sink() assert mock_cb.mock_calls == ref_mock_cb.mock_calls assert len(mock_cb.mock_calls) == 1
def test_build(build_kwargs, init_args, init_kwargs, ref_args, ref_kwargs, exception): mock_cb = mock.Mock() ref_mock_cb = mock.Mock() try: if build_kwargs is None: dut = build_filter(mock_cb)(*init_args, **init_kwargs) else: dut = build_filter(**build_kwargs)(mock_cb)(*init_args, **init_kwargs) except Exception as e: assert isinstance(e, exception) return else: assert exception is None reference = Filter(ref_mock_cb, *ref_args, **ref_kwargs) assert dut._unpack == reference._unpack v = StatefulPublisher((1, 2)) v | dut | Sink() v | reference | Sink() assert mock_cb.mock_calls == ref_mock_cb.mock_calls assert len(mock_cb.mock_calls) == 1
def test_build(build_kwargs, init_args, init_kwargs, ref_args, ref_kwargs, exception): mock_cb = mock.Mock() ref_mock_cb = mock.Mock() async def mock_cb_coro(*args, **kwargs): mock_cb(*args, **kwargs) async def ref_mock_cb_coro(*args, **kwargs): ref_mock_cb(*args, **kwargs) try: if build_kwargs is None: dut = build_map_async(mock_cb_coro)(*init_args, **init_kwargs) else: dut = build_map_async(**build_kwargs)(mock_cb_coro)(*init_args, **init_kwargs) except Exception as e: assert isinstance(e, exception) return else: assert exception is None reference = MapAsync(ref_mock_cb_coro, *ref_args, **ref_kwargs) assert dut._options[1:] == reference._options[1:] # don't compare coro v = StatefulPublisher((1, 2)) v | dut | Sink() v | reference | Sink() asyncio.get_event_loop().run_until_complete(asyncio.sleep(0.01)) assert mock_cb.mock_calls == ref_mock_cb.mock_calls assert len(mock_cb.mock_calls) == 1
async def test_polling(): mock = Mock() dut = FromPolling(0.1, itertools.count().__next__) with pytest.raises(ValueError): dut.get() disposable = dut | Sink(mock) mock.assert_called_once_with(0) mock.reset_mock() await asyncio.sleep(0.15) mock.assert_called_once_with(1) mock.reset_mock() await asyncio.sleep(0.1) mock.assert_called_once_with(2) # unsubscribe mock.reset_mock() disposable.dispose() await asyncio.sleep(0.3) mock.assert_not_called() # resubscribe disposable = dut | Sink(mock)
def __init__( self, # pylint: disable=keyword-arg-before-vararg function: Optional[Callable[..., None]] = None, *args, unpack=False, label=None, **kwargs) -> None: Sink.__init__(self, function, *args, unpack=unpack, **kwargs) self._label = label
def test_subscribe_all(subscribe_all): p_select = StatefulPublisher('a') p1 = StatefulPublisher(0) p2 = StatefulPublisher(1) dut = Switch({'a': p1, 'b': p2, 'c': 2}, subscribe_all=subscribe_all) assert not p_select.subscriptions assert not p1.subscriptions assert not p2.subscriptions assert not dut.subscriptions mock_cb = mock.Mock() disposable = p_select | dut | Sink(mock_cb) assert len(dut.subscriptions) == 1 assert len(p_select.subscriptions) == 1 assert len(p1.subscriptions) == 1 assert len(p2.subscriptions) == (1 if subscribe_all else 0) p_select.notify('b') assert len(dut.subscriptions) == 1 assert len(p_select.subscriptions) == 1 assert len(p1.subscriptions) == (1 if subscribe_all else 0) assert len(p2.subscriptions) == 1 disposable.dispose() assert not p_select.subscriptions assert not p1.subscriptions assert not p2.subscriptions assert not dut.subscriptions
async def test_errorhandler(): mock = Mock(side_effect=ZeroDivisionError) mock_errorhandler = Mock() dut = FromPolling(0.1, lambda: 0, error_callback=mock_errorhandler) dut | Sink(mock) await asyncio.sleep(0.05) mock_errorhandler.assert_called_once_with(ZeroDivisionError, ANY, ANY) mock.assert_called_once_with(0)
def test_partition(): mock = Mock() p = Publisher() dut = p | Partition(3) dut | Sink(mock) p.notify(1) p.notify(2) mock.assert_not_called() dut.flush() mock.assert_called_once_with((1, 2))
async def test_once(): mock = Mock() err_mock = Mock() dut = FromPolling(None, mock, error_callback=err_mock) disposable = dut | Sink() assert mock.call_count == 1 await asyncio.sleep(0.25) assert mock.call_count == 1 disposable.dispose() await asyncio.sleep(0.3) assert mock.call_count == 1 err_mock.assert_not_called() mock.reset_mock() mock.side_effect = ValueError disposable = dut | Sink() assert mock.call_count == 1 assert err_mock.call_count == 1
def test_allow_stateless_extensive(): source1 = StatefulPublisher(0) source2 = Publisher() source3 = StatefulPublisher(0) source4 = Publisher() dut = CombineLatest(source1, source2, source3, source4, allow_stateless=True, emit_on=(source2, source3)) with pytest.raises(ValueError): dut | Sink() # source4 is stateless but not in emit_on list def reverse(s1, s2, s3, s4): return (s4, s3, s2, s1) dut = CombineLatest(source1, source2, source3, source4, map_=reverse, allow_stateless=True, emit_on=(source2, source3, source4)) with pytest.raises(ValueError): dut.get() collector = Collector() dut.subscribe(collector) with pytest.raises(ValueError): dut.get() assert collector.result_vector == () collector.reset() source1.notify(1) source2.notify(2) with pytest.raises(ValueError): dut.get() assert collector.result_vector == ((NONE, 0, 2, 1), ) collector.reset() source3.notify(3) source4.notify(4) with pytest.raises(ValueError): dut.get() assert collector.result_vector == ( (NONE, 3, NONE, 1), (4, 3, NONE, 1), )
def test_uninitialised_with_publisher(): source = Publisher() dut = source | Cache() cb = mock.Mock() dut | Sink(cb) cb.assert_not_called() source.notify(1) cb.assert_called_once_with(1) source.notify(1) cb.assert_called_once_with(1)
async def test_cancel_on_unsubscribe(): mock = Mock() dut = FromPolling(0.1, mock) disposable = dut | Sink() assert mock.call_count == 1 await asyncio.sleep(0.25) assert mock.call_count == 3 disposable.dispose() await asyncio.sleep(0.3) assert mock.call_count == 3
async def test_errorhandler(): mock = Mock(side_effect=ZeroDivisionError) mock_errorhandler = Mock() p = Publisher() dut = p | Delay(0.1, error_callback=mock_errorhandler) dut | Sink(mock) p.notify(1) await asyncio.sleep(0.15) mock.assert_called_once_with(1) mock_errorhandler.assert_called_once_with(ZeroDivisionError, ANY, ANY)
async def test_map_async(): p = Publisher() mock_sink = mock.Mock() mock_error_handler = mock.Mock() default_error_handler.set(mock_error_handler) async def _map(v): return v disposable = p | MapAsync(_map) | Sink(mock_sink) mock_sink.side_effect = ZeroDivisionError('FAIL') # test error_handler for notify p.notify(1) mock_error_handler.assert_not_called() await asyncio.sleep(0.01) mock_error_handler.assert_called_once_with(ZeroDivisionError, mock.ANY, mock.ANY) disposable.dispose() mock_error_handler.reset_mock() mock_sink.reset_mock() mock_sink.side_effect = None # test error_handler for map coroutine async def _fail(v): raise ValueError() p2 = Publisher() disposable = p2 | MapAsync(_fail) | Sink(mock_sink) p2.notify(2) await asyncio.sleep(0.01) print(mock_error_handler.mock_calls) mock_error_handler.assert_called_once_with(ValueError, mock.ANY, mock.ANY) mock_sink.assert_not_called()
def test_uninitialised_with_stateful(): source = StatefulPublisher(1) dut = source | Cache() cb = mock.Mock() dut | Sink(cb) cb.assert_called_once_with(1) source.notify(1) cb.assert_called_once_with(1) cb.reset_mock() source.notify(2) cb.assert_called_once_with(2)
async def test_with_args(args, kwargs, result_vector): counter = itertools.count() def poll(offset=1): return next(counter) + offset dut = FromPolling(0.1, poll, *args, **kwargs) mock = Mock() dut | Sink(mock) await asyncio.sleep(0.05) for result in result_vector[:-2]: mock.assert_called_once_with(result) mock.reset_mock() await asyncio.sleep(0.1) mock.assert_called_once_with(result_vector[-2]) mock.reset_mock() mock2 = Mock() dut | Sink(mock2) await asyncio.sleep(0.1) mock2.assert_called_once_with(result_vector[-1])
def test_initialised_with_publisher(): source = Publisher() dut = source | Cache(1) cb = mock.Mock() dut | Sink(cb) cb.assert_called_once_with(1) cb.reset_mock() source.notify(2) cb.assert_called_once_with(2) source.notify(2) cb.assert_called_once_with(2) with pytest.raises(ValueError): Publisher() | dut
def test_operator_concat(): DUT = OperatorConcat(Map(lambda v: v / 2), Reduce(lambda s, v: s + v, init=0)) mock_cb = mock.Mock() p = StatefulPublisher(0) p | DUT assert DUT.get() == 0 DUT | Sink(mock_cb) for v in range(5): p.notify(v) mock_cb.assert_has_calls([ mock.call(0), mock.call(0.5), mock.call(1.5), mock.call(3), mock.call(5) ]) assert DUT.get() == 5
def test_flush(): p = Publisher() mock = Mock() dut = p | SlidingWindow(3) dut | Sink(mock) mock.assert_not_called() p.notify(1) mock.assert_not_called() p.notify(2) mock.assert_not_called() dut.flush() mock.assert_called_once_with( (1,2) ) mock.reset_mock() p.notify(1) p.notify(2) mock.assert_not_called() p.notify(3) mock.assert_called_once_with( (1,2,3) ) dut.flush() mock.assert_called_once_with( (1,2,3) )
def emit(self, value: Any, who: Publisher): self._trace_handler(who, value, label=self._label) Sink.emit(self, value, who=who)