def test_with_publisher(operator, l_value, r_value, result): vl = Value(l_value) vr = Value(r_value) cl = l_value cr = r_value o1 = operator(vl, vr) o2 = operator(vl, cr) o3 = operator(cl, vr) try: o4 = operator(cl, cr) except Exception as e: assert isinstance(e, result) o4 = result # to pass the following test mock_sink_o3 = mock.Mock() try: o3.subscribe(Sink(mock_sink_o3)) except Exception as e: assert isinstance(e, result) for output in (o1, o2, o3): assert isinstance(output, Publisher) assert o4 == result for output in (o1, o2, o3): try: assert output.get() == result except Exception as e: assert isinstance(e, result)
def test_assign_subscribe_emit(factory): hub = Hub(topic_factory=factory) # assign, subscribe and emit value1 = Value(0) assert not hub['value1'].assigned assert hub['value1'].subject is None hub['value1'].assign(value1) with pytest.raises(ValueError): hub['value1'].assign(value1) assert hub['value1'].path == 'value1' assert hub['value1'].assigned assert 'value1' in hub assert hub['value1'] is not value1 assert hub['value1'].subject is value1 assert len(value1._subscriptions) == 0 assert len(hub['value1']._subscriptions) == 0 value2 = Subject() hub['value2'].assign(value2) mock_sink1 = mock.Mock() mock_sink2 = mock.Mock() dispose_value1 = hub['value1'] | op.Sink(mock_sink1) dispose_value2 = hub['value2'] | op.Sink(mock_sink2) assert len(value1._subscriptions) == 1 assert len(hub['value1']._subscriptions) == 1 mock_sink1.assert_called_once_with(0) assert len(value1._subscriptions) == 1 assert len(hub['value1']._subscriptions) == 1 mock_sink2.assert_not_called() mock_sink1.reset_mock() mock_sink2.reset_mock() hub['value1'].emit(1) hub['value2'].emit(1) mock_sink1.assert_called_once_with(1) mock_sink2.assert_called_once_with(1) assert value1.get() == 1 mock_sink1b = mock.Mock() dispose_value1b = hub['value1'] | op.Sink(mock_sink1b) mock_sink1b.assert_called_once_with(1) dispose_value1.dispose() dispose_value1b.dispose() mock_sink2b = mock.Mock() hub['value2'] | op.Sink(mock_sink2b) mock_sink2b.assert_not_called() assert len(value1._subscriptions) == 0 assert len(hub['value1']._subscriptions) == 0
def test_sink_without_function(operator_cls): s = Value() sink_instance = s.subscribe(operator_cls()) assert isinstance(sink_instance, Disposable) assert len(s.subscriptions) == 1 s.emit(1)
def test_operator_with_publishers(): v1 = Value(0) v2 = Value(0) o = v1 + v2 assert isinstance(o, Publisher) assert not isinstance(o, Subscriber) assert o.get() == 0 v1.emit(1) assert o.get() == 1 assert len(o.subscriptions) == 0 mock_sink = mock.Mock() o | op.Sink(mock_sink) assert len(o.subscriptions) == 1 mock_sink.assert_called_once_with(1) mock_sink.reset_mock() v2.emit(3) mock_sink.assert_called_once_with(4) with pytest.raises(ValueError): o.emit_op(0, who=Publisher()) with pytest.raises(AttributeError): Value(1) | o
def test_getitem(): v1 = Value(('a', 'b', 'c')) v2 = Value(2) o = (v1[v2]) assert isinstance(o, Publisher) assert o.get() == 'c' v2.emit(1) assert o.get() == 'b'
def test_concat(): v1 = StatefulPublisher((1, 2)) v2 = Value((0, 0)) o = v1 + v2 assert isinstance(o, Publisher) assert o.get() == (1, 2, 0, 0) v2.emit((1, 3)) assert o.get() == (1, 2, 1, 3)
def test_mod_str(): v1 = StatefulPublisher('%.2f %d') v2 = Value((0, 0)) o = v1 % v2 assert isinstance(o, Publisher) assert o.get() == '0.00 0' v2.emit((1, 3)) assert o.get() == '1.00 3'
def test_freeze(): hub = Hub() hub['value1'].assign(StatefulPublisher(0)) assert 'value1' in hub hub.freeze() assert len(tuple(hub)) == 1 hub.freeze(False) hub['value2'] | op.Sink() hub['value3'].emit(1) assert 'value2' in hub assert 'value3' in hub with pytest.raises(ValueError): hub.freeze() hub['value2'].assign(Value(0)) hub['value3'].assign(Value(0)) hub.freeze() with pytest.raises(ValueError): hub['value4'].assign(StatefulPublisher(0)) with pytest.raises(ValueError): hub['value5'] | op.Sink() with pytest.raises(ValueError): hub['value6'].emit(1) assert len(tuple(hub)) == 3 hub.freeze(False) hub['value4'] | op.Sink() hub['value5'].assign(StatefulPublisher(0)) hub['value6'].emit(1) assert 'value4' in hub assert 'value5' in hub assert 'value6' in hub assert len(tuple(hub)) == 6
def test_subscribe_emit_assign(factory): hub = Hub(topic_factory=factory) mock_sink = mock.Mock() mock_sink2 = mock.Mock() disposable = hub['value1'] | op.Sink(mock_sink) mock_sink.assert_not_called() assert len(hub['value1']._subscriptions) == 1 hub['value1'].emit(1) hub['value1'].emit(2) mock_sink.assert_not_called() disposable.dispose() assert len(hub['value1']._subscriptions) == 0 hub['value1'] | op.Sink(mock_sink) hub['value1'] | op.Sink(mock_sink2) value = Value(0) hub['value1'].assign(value) mock_sink.calls(mock.call(0), mock.call(1), mock.call(2))
def test_filter_factory_keyword(): m = op.build_filter_factory(lambda v: v) v = Value() with pytest.raises(TypeError, message='"unpack" has to be defined by decorator'): o = v | m(unpack=True)
def test_operator_with_constant(): v1 = Value(0) v2 = 1 o = v1 + v2 assert isinstance(o, Publisher) assert o.get() == 1 v1.emit(1) assert o.get() == 2 assert len(o.subscriptions) == 0 mock_sink = mock.Mock() o.subscribe(Sink(mock_sink)) assert len(o.subscriptions) == 1 mock_sink.assert_called_once_with(2) mock_sink.reset_mock() v1.emit(3) mock_sink.assert_called_once_with(4) with pytest.raises(TypeError): Value(1) | o with pytest.raises(ValueError): o.emit(0, who=Publisher())
def test_operator_with_constant_r(): v1 = 1 v2 = Value(0) o = v1 - v2 assert isinstance(o, Publisher) assert o.get() == 1 v2.emit(1) assert o.get() == 0 assert len(o.subscriptions) == 0 mock_sink = mock.Mock() o | op.Sink(mock_sink) assert len(o.subscriptions) == 1 mock_sink.assert_called_once_with(0) mock_sink.reset_mock() v2.emit(3) mock_sink.assert_called_once_with(-2) with pytest.raises(ValueError): Value(1) | o with pytest.raises(ValueError): o.emit_op(0, who=Publisher())
def test_sub_hub(): hub = Hub() hub['value1'].assign(Value(0)) hub['prefix.value2'].assign(Value(1)) sub_hub = SubHub(hub, 'prefix') assert sub_hub['value2'] is hub['prefix.value2'] sub_hub['value3'].assign(Value(3)) assert hub['prefix.value3'] is sub_hub['value3'] assert sub_hub.prefix == 'prefix' with pytest.raises(ValueError): SubHub(hub, '') with pytest.raises(ValueError): SubHub(hub, 'test.')
def test_sink2(operator_cls): cb = mock.Mock() s = Value() sink_instance = s.subscribe(operator_cls(cb, unpack=True)) assert isinstance(sink_instance, Disposable) # test various emits on source with pytest.raises(TypeError): s.emit() with pytest.raises(TypeError): s.emit(1) cb.assert_not_called() s.emit((1, 2)) cb.assert_called_with(1, 2)
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 test_meta_topic(): hub = Hub(topic_factory=MetaTopic) assert hub['value1'].meta == dict() with pytest.raises(AttributeError): hub['value1'].meta = dict() hub['value1'].meta.update({'a': 1, 'b': 2}) assert hub['value1'].meta == {'a': 1, 'b': 2} hub['value1'].meta['b'] = 3 hub['value1'].assign(Value(0), meta={'b': 4, 'c': 3}) assert hub['value1'].meta == {'a': 1, 'b': 4, 'c': 3}
def test_topic_mapper(): d = dict() hub = Hub() hub['topic1'].assign(Value(0)) hub['topic2'].assign(Subject()) mapper_instance = TopicMapper(d) assert not d hub['topic1'] | mapper_instance assert d == {'topic1': 0} hub['topic2'] | mapper_instance assert d == {'topic1': 0} hub['topic2'].emit(2) assert d == {'topic1': 0, 'topic2': 2} hub['topic1'].emit(1) assert d == {'topic1': 1, 'topic2': 2} with pytest.raises(TypeError): Value(0) | mapper_instance
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 test_in_operator(): pi = Value(1) ci = 1 pc = Value((1, 2, 3)) cc = (1, 2, 3) dut1 = op.In(pi, pc) dut2 = op.In(ci, pc) dut3 = op.In(pi, cc) with pytest.raises(TypeError): op.In(ci, cc) assert dut1.get() == True assert dut2.get() == True assert dut3.get() == True pi.emit('a') pc.emit((2.3, 'b')) assert dut1.get() == False assert dut2.get() == False assert dut3.get() == False
def test_sink_on_subscription(operator): cb = mock.Mock() s = Value(0) sink_instance = s.subscribe(operator(cb)) assert isinstance(sink_instance, Disposable) cb.assert_called_with(0) assert len(s.subscriptions) == 1 s.emit(1) cb.assert_called_with(1) # testing dispose() cb.reset_mock() sink_instance.dispose() assert len(s.subscriptions) == 0 s.emit(1) assert not cb.called
def test_unary_operators(operator, value, result): v = StatefulPublisher(value) try: value_applied = operator(v).get() except Exception as e: assert isinstance(e, result) else: assert value_applied == result cb = mock.Mock() try: operator(v) | op.Sink(cb) except Exception as e: assert isinstance(e, result) else: assert cb.mock_called_once_with(result) with pytest.raises(ValueError): Value(1) | operator(v) with pytest.raises(ValueError): operator(v).emit_op(0, who=Publisher())
def test_stateful_publisher(): p = StatefulPublisher() v = Value(0) with pytest.raises(ValueError): p.get() mock_sink = mock.Mock() disposable = p | v v | op.Sink(mock_sink) mock_sink.assert_called_once_with(0) mock_sink.reset_mock() p.notify(1) mock_sink.assert_called_once_with(1) assert p.get() == 1 mock_sink.reset_mock() p.notify(1) assert p.get() == 1 mock_sink.assert_not_called() p.notify(2) assert p.get() == 2 mock_sink.assert_called_once_with(2) p.reset_state() with pytest.raises(ValueError): p.get() p.reset_state(3) assert p.get() == 3
def test_with_publisher(operator, l_value, r_value, result): vl = Value(l_value) vr = Value(r_value) pl = Publisher() pr = Publisher() cl = l_value cr = r_value o1 = operator(vl, vr) o2 = operator(vl, cr) o3 = operator(vl, pr) o4 = operator(pl, vr) o5 = operator(pl, cr) o6 = operator(pl, pr) o7 = operator(cl, vr) try: o8 = operator(cl, cr) except Exception as e: assert isinstance(e, result) o8 = result # to pass the following test o9 = operator(cl, pr) mock_sink_o3 = mock.Mock() mock_sink_o4 = mock.Mock() mock_sink_o5 = mock.Mock() mock_sink_o6 = mock.Mock() mock_sink_o9 = mock.Mock() o3 | op.Sink(mock_sink_o3) o4 | op.Sink(mock_sink_o4) o5 | op.Sink(mock_sink_o5) o6 | op.Sink(mock_sink_o6) o9 | op.Sink(mock_sink_o9) for output in (o1, o2, o3, o4, o5, o6, o7, o9): assert isinstance(output, Publisher) assert o8 == result for output in (o1, o2, o7): try: assert output.get() == result except Exception as e: assert isinstance(e, result) for output in (o3, o4, o5, o6, o9): with pytest.raises(ValueError): output.get() mock_sink_o3.assert_not_called() mock_sink_o4.assert_not_called() mock_sink_o5.assert_not_called() mock_sink_o6.assert_not_called() mock_sink_o9.assert_not_called() try: pl.notify(l_value) except Exception as e: assert isinstance(e, result) else: mock_sink_o3.assert_not_called() mock_sink_o4.assert_called_once_with(result) mock_sink_o5.assert_called_once_with(result) mock_sink_o6.assert_not_called() mock_sink_o9.assert_not_called() try: pr.notify(r_value) except Exception as e: assert isinstance(e, result) else: mock_sink_o3.assert_called_once_with(result) mock_sink_o4.assert_called_once_with(result) mock_sink_o5.assert_called_once_with(result) mock_sink_o6.assert_called_once_with(result) mock_sink_o9.assert_called_once_with(result)
def test_sink_partial(operator_cls): cb = mock.Mock() s = Value() sink_instance = s.subscribe(operator_cls(cb, 1, 2, 3, a=1)) assert isinstance(sink_instance, Disposable) assert not cb.called assert len(s.subscriptions) == 1 # test various emits on source s.emit(None) cb.assert_called_with(1, 2, 3, None, a=1) s.emit(1) cb.assert_called_with(1, 2, 3, 1, a=1) s.emit((1, 2)) cb.assert_called_with(1, 2, 3, (1, 2), a=1) # testing dispose() cb.reset_mock() sink_instance.dispose() assert len(s.subscriptions) == 0 s.emit(1) assert not cb.called
def test_sink(operator_cls): cb = mock.Mock() s = Value() sink_instance = s.subscribe(operator_cls(cb)) assert isinstance(sink_instance, Disposable) assert not cb.called assert len(s.subscriptions) == 1 # test various emits on source with pytest.raises(TypeError): s.emit() s.emit(None) cb.assert_called_with(None) s.emit(1) cb.assert_called_with(1) s.emit((1, 2)) cb.assert_called_with((1, 2)) # testing dispose()s cb.reset_mock() sink_instance.dispose() assert len(s.subscriptions) == 0 s.emit(1) assert not cb.called