示例#1
0
async def test_throttle_errorhandler(event_loop):
    from broqer import default_error_handler

    p = Publisher()
    mock_sink = mock.Mock()
    mock_error_handler = mock.Mock()

    default_error_handler.set(mock_error_handler)

    throttle = p | op.Throttle(0.1)
    disposable = throttle.subscribe(Sink(mock_sink))

    mock_sink.side_effect = (None, ZeroDivisionError('FAIL'))

    # test error_handler
    p.notify(1)
    await asyncio.sleep(0.05, loop=event_loop)
    mock_sink.assert_called_once_with(1)
    p.notify(2)
    await asyncio.sleep(0.1, loop=event_loop)
    mock_error_handler.assert_called_once_with(ZeroDivisionError, mock.ANY,
                                               mock.ANY)
    mock_sink.assert_has_calls((mock.call(1), mock.call(2)))

    mock_sink.reset_mock()
async def test_errorhandler(operator_cls, publisher, args, capsys):
    mock = Mock(side_effect=ZeroDivisionError)

    # test default error handler
    if publisher is not None:
        dut = publisher | operator_cls(*args)
    else:
        dut = operator_cls(*args)

    dut | op.Sink(mock)

    await asyncio.sleep(0.1)

    captured = capsys.readouterr()
    assert 'Traceback' in captured.err
    assert 'ZeroDivisionError' in captured.err

    # test custom default error handler
    mock_errorhandler = Mock()
    default_error_handler.set(mock_errorhandler)

    if publisher is not None:
        dut = publisher | operator_cls(*args)
    else:
        dut = operator_cls(*args)

    dut | op.Sink(mock)

    await asyncio.sleep(0.1)

    mock_errorhandler.assert_called_with(ZeroDivisionError, ANY, ANY)

    default_error_handler.reset()

    # test custom error handler
    mock_errorhandler_custom = Mock()

    if publisher is not None:
        dut = publisher | operator_cls(*args,
                                       error_callback=mock_errorhandler_custom)
    else:
        dut = operator_cls(*args, error_callback=mock_errorhandler_custom)

    dut | op.Sink(mock)

    await asyncio.sleep(0.1)

    mock_errorhandler_custom.assert_called_with(ZeroDivisionError, ANY, ANY)

    default_error_handler.reset()
async def test_sink_async():
    p = Publisher()
    mock_error_handler = mock.Mock()

    default_error_handler.set(mock_error_handler)

    # test error_handler for map coroutine
    async def _fail(v):
        raise ValueError()

    p2 = Publisher()
    disposable = p2 | SinkAsync(_fail)
    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)
示例#4
0
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()
async def test_throttle():
    import asyncio
    from broqer import default_error_handler, Publisher, op

    p = Publisher()
    mock_sink = mock.Mock()
    mock_error_handler = mock.Mock()

    default_error_handler.set(mock_error_handler)

    disposable = p | op.Throttle(0.1) | op.Sink(mock_sink)

    mock_sink.side_effect = (None, ZeroDivisionError('FAIL'))

    # test error_handler
    p.notify(1)
    await asyncio.sleep(0.05)
    mock_sink.assert_called_once_with(1)
    p.notify(2)
    await asyncio.sleep(0.1)
    mock_error_handler.assert_called_once_with(ZeroDivisionError, mock.ANY,
                                               mock.ANY)

    mock_sink.reset_mock()

    # test unsubscribe
    p.notify(2)
    mock_sink.reset_mock()
    await asyncio.sleep(0.05)
    disposable.dispose()
    await asyncio.sleep(0.1)
    mock_sink.assert_called_once_with(2)

    # test reset
    mock_sink.reset_mock()
    mock_sink.side_effect = None
    throttle = p | op.Throttle(0.1)
    disposable = throttle | op.Sink(mock_sink)
    p.notify(1)
    mock_sink.reset_mock()
    await asyncio.sleep(0.05)
    throttle.reset()
    p.notify(2)
    await asyncio.sleep(0.05)
    mock_sink.assert_called_once_with(2)

    disposable.dispose()

    # test reset again
    mock_sink.reset_mock()
    mock_sink.side_effect = None
    throttle = p | op.Throttle(0.1)
    disposable = throttle | op.Sink(mock_sink)

    # resubscribe
    mock_sink.reset_mock()
    p.notify(1)
    await asyncio.sleep(0.05)
    mock_sink.assert_called_once_with(1)

    disposable.dispose()

    throttle | op.Sink()

    p.notify(2)
    await asyncio.sleep(0.05)
    p.notify(3)

    with pytest.raises(ValueError):
        throttle.get()
    assert await throttle == 3
    mock_sink.assert_called_once_with(1)

    # reset when nothing is to be emitted
    disposable = throttle | op.Sink(mock_sink)
    mock_sink.reset_mock()
    await asyncio.sleep(0.15)

    throttle.reset()
    p.notify(4)
    mock_sink.assert_called_once_with(4)
示例#6
0
async def test_debounce():
    import asyncio
    from broqer import default_error_handler, Publisher, op

    p = Publisher()
    mock_sink = mock.Mock()
    mock_error_handler = mock.Mock()

    default_error_handler.set(mock_error_handler)

    disposable = p | op.Debounce(0.1) | op.Sink(mock_sink)

    mock_sink.side_effect = ZeroDivisionError('FAIL')

    # test error_handler
    p.notify(1)
    mock_error_handler.assert_not_called()
    await asyncio.sleep(0.05)
    mock_error_handler.assert_not_called()
    await asyncio.sleep(0.1)
    mock_error_handler.assert_called_once_with(ZeroDivisionError, mock.ANY,
                                               mock.ANY)
    mock_sink.assert_called_once_with(1)

    mock_sink.reset_mock()

    # test unsubscribe
    p.notify(2)
    await asyncio.sleep(0.05)
    disposable.dispose()
    await asyncio.sleep(0.1)
    mock_sink.assert_not_called()

    # test reset
    mock_sink.reset_mock()
    debounce = p | op.Debounce(0.1)
    disposable = debounce | op.Sink(mock_sink)
    p.notify(1)
    await asyncio.sleep(0.05)
    debounce.reset()
    await asyncio.sleep(0.1)
    mock_sink.assert_not_called()

    disposable.dispose()

    # test reset again
    mock_sink.reset_mock()
    mock_sink.side_effect = None
    debounce = p | op.Debounce(0, False)
    disposable = debounce | op.Sink(mock_sink)
    p.notify(True)
    await asyncio.sleep(0.05)
    debounce.reset()
    mock_sink.assert_has_calls(
        (mock.call(False), mock.call(True), mock.call(False)))

    # resubscribe
    mock_sink.reset_mock()
    p.notify(True)
    await asyncio.sleep(0.05)
    mock_sink.assert_called_once_with(True)

    disposable.dispose()

    debounce | op.Sink()

    p.notify(True)

    await asyncio.sleep(0.05)

    assert debounce.get() == True
    await debounce | op.True_()
    mock_sink.assert_called_once_with(True)

    # test argument check
    with pytest.raises(ValueError):
        op.Debounce(-1)