Ejemplo n.º 1
0
def test_value_list_instantaneous():
    # A mix of instantaneous and continuous
    a = Value("a")
    b = Value()
    c = Value()

    lst = value_list([a, b, c])

    # Initial value should have passed through
    assert lst.value == ["a", NoValue, NoValue]

    m = Mock()
    lst.on_value_changed(m)

    # Changes should propagate through
    a.value = "A"
    assert lst.value == ["A", NoValue, NoValue]
    m.assert_called_once_with(["A", NoValue, NoValue])

    # Instantaneous values should propagate only into the callback
    m.reset_mock()
    b.set_instantaneous_value("b")
    assert lst.value == ["A", NoValue, NoValue]
    m.assert_called_once_with(["A", "b", NoValue])

    m.reset_mock()
    c.set_instantaneous_value("c")
    assert lst.value == ["A", NoValue, NoValue]
    m.assert_called_once_with(["A", NoValue, "c"])
Ejemplo n.º 2
0
def test_inst_positional_kwargs():
    m = Mock()
    
    @instantaneous_fn
    def example(*args, **kwargs):
        return (args, kwargs)
    
    a_value = Value()
    b_value = Value()
    
    # No value should be assigned
    result = example(a=a_value, b=b_value)
    result.on_value_changed(m)
    assert result.value is NoValue
    
    # Changes should propagate, callbacks should fire but no value should be
    # stored
    m.reset_mock()
    a_value.set_instantaneous_value(123)
    m.assert_called_once_with(((), {"a": 123, "b": NoValue}))
    assert result.value is NoValue
    
    m.reset_mock()
    b_value.set_instantaneous_value(123)
    m.assert_called_once_with(((), {"a": NoValue, "b": 123}))
    assert result.value is NoValue
Ejemplo n.º 3
0
async def test_send_event_register(qth_client, event_loop):
    a = Value()
    qth_yarp.send_event("foo/bar",
                        a,
                        register=True,
                        description="Something",
                        qth_client=qth_client)

    # Allow asyncio functions to run...
    await asyncio.sleep(0.1)

    # No initial value should have been sent to Qth
    assert len(qth_client.send_event.mock_calls) == 0

    # No registration should be made
    # Registration should have been sent
    qth_client.register.assert_called_once_with(
        "foo/bar",
        qth.EVENT_ONE_TO_MANY,
        "Something",
    )

    # Setting the qth value should update Qth
    a.set_instantaneous_value(321)
    await asyncio.sleep(0.1)
    qth_client.send_event.assert_called_with("foo/bar", 321)

    # And again...
    a.set_instantaneous_value(1234)
    await asyncio.sleep(0.1)
    qth_client.send_event.assert_called_with("foo/bar", 1234)
Ejemplo n.º 4
0
def test_value_dict_instantaneous():
    # A mix of instantaneous and continuous
    a = Value("a")
    b = Value()
    c = Value()

    dct = value_dict({"a": a, "b": b, "c": c})

    # Initial value should have passed through
    assert dct.value == {"a": "a", "b": NoValue, "c": NoValue}

    m = Mock()
    dct.on_value_changed(m)

    # Changes should propagate through
    a.value = "A"
    assert dct.value == {"a": "A", "b": NoValue, "c": NoValue}
    m.assert_called_once_with({"a": "A", "b": NoValue, "c": NoValue})

    # Instantaneous values should propagate only into the callback
    m.reset_mock()
    b.set_instantaneous_value("b")
    assert dct.value == {"a": "A", "b": NoValue, "c": NoValue}
    m.assert_called_once_with({"a": "A", "b": "b", "c": NoValue})

    m.reset_mock()
    c.set_instantaneous_value("c")
    assert dct.value == {"a": "A", "b": NoValue, "c": NoValue}
    m.assert_called_once_with({"a": "A", "b": NoValue, "c": "c"})
Ejemplo n.º 5
0
def test_value_tuple_instantaneous():
    # A mix of instantaneous and continuous
    a = Value("a")
    b = Value()
    c = Value()

    tup = value_tuple([a, b, c])

    # Initial value should have passed through
    assert tup.value == ("a", NoValue, NoValue)

    m = Mock()
    tup.on_value_changed(m)

    # Changes should propagate through
    a.value = "A"
    assert tup.value == ("A", NoValue, NoValue)
    m.assert_called_once_with(("A", NoValue, NoValue))

    # Instantaneous values should propagate only into the callback
    m.reset_mock()
    b.set_instantaneous_value("b")
    assert tup.value == ("A", NoValue, NoValue)
    m.assert_called_once_with(("A", "b", NoValue))

    m.reset_mock()
    c.set_instantaneous_value("c")
    assert tup.value == ("A", NoValue, NoValue)
    m.assert_called_once_with(("A", NoValue, "c"))
Ejemplo n.º 6
0
def test_change_callback_only():
    m = Mock()

    v = Value()
    v.on_value_changed(m)

    v.set_instantaneous_value(123)
    m.assert_called_once_with(123)
    assert v.value is NoValue
Ejemplo n.º 7
0
async def test_rate_limit_instantaneous(event_loop):
    v = Value()
    
    # No initial value to speak of
    rlv = rate_limit(v, 0.1, event_loop)
    assert rlv.value is NoValue
    
    log = []
    sem = asyncio.Semaphore(0, loop=event_loop)
    def on_change(new_value):
        log.append(new_value)
        sem.release()
    rlv.on_value_changed(on_change)
    
    # First change should make it through immediately
    v.set_instantaneous_value(1)
    assert rlv.value is NoValue
    assert len(log) == 1
    assert log[-1] == 1
    await sem.acquire()
    
    # Another change made immediately after should be delayed
    v.set_instantaneous_value(2)
    assert rlv.value is NoValue
    assert len(log) == 1
    
    # Change should come through after a delay
    before = time.time()
    await sem.acquire()
    assert time.time() - before >= 0.1
    assert rlv.value is NoValue
    assert len(log) == 2
    assert log[-1] == 2
    
    # After a suitable delay, the next change should come through immediately
    await asyncio.sleep(0.15, loop=event_loop)
    v.set_instantaneous_value(3)
    assert rlv.value is NoValue
    assert len(log) == 3
    assert log[-1] == 3
    await sem.acquire()
    
    # A rapid succession of calls should result in only the last value
    # comming out, and then only after a delay
    v.set_instantaneous_value(4)
    v.set_instantaneous_value(5)
    v.set_instantaneous_value(6)
    assert rlv.value is NoValue
    assert len(log) == 3
    before = time.time()
    await sem.acquire()
    assert time.time() - before >= 0.1
    assert rlv.value is NoValue
    assert len(log) == 4
    assert log[-1] == 6
Ejemplo n.º 8
0
def test_make_persistent():
    v = Value()

    # Initially no value to be found...
    pv = make_persistent(v)
    assert pv.value is NoValue

    m = Mock()
    pv.on_value_changed(m)

    assert pv.value is NoValue

    v.set_instantaneous_value(2)
    assert pv.value == 2
    m.assert_called_once_with(2)
Ejemplo n.º 9
0
def test_change_instantaneous():
    rule = lambda x: x < 10

    m = Mock()
    v = Value()
    fl = filter(v, rule)
    fl.on_value_changed(m)
    assert fl.value is NoValue

    v.set_instantaneous_value(2)
    assert fl.value is NoValue
    m.assert_called_once_with(2)

    # Above ten, shouldn't get through
    v.set_instantaneous_value(100)
    assert fl.value is NoValue
    m.assert_called_once_with(2)
Ejemplo n.º 10
0
def test_operator_wrapper_instantaneous():
    # Only test negation since others are defined in exactly the same way
    a = Value()

    not_a = instantaneous_not_(a)
    assert not_a.value is NoValue

    m = Mock()
    not_a.on_value_changed(m)

    a.set_instantaneous_value(True)
    assert not_a.value is NoValue
    m.assert_called_once_with(False)
    m.reset_mock()

    a.set_instantaneous_value(False)
    assert not_a.value is NoValue
    m.assert_called_once_with(True)
    m.reset_mock()
Ejemplo n.º 11
0
    async def test_instantaneous(self, event_loop):
        value = Value()

        delayed_value = delay(value, 0.1, loop=event_loop)
        assert delayed_value.value is NoValue

        # Monitor changes
        evt = asyncio.Event(loop=event_loop)
        m = Mock(side_effect=lambda *_: evt.set())
        delayed_value.on_value_changed(m)

        # Trigger a change for later...
        before = time.time()
        value.set_instantaneous_value(123)
        assert delayed_value.value is NoValue
        assert not m.mock_calls
        await evt.wait()
        assert time.time() - before >= 0.1
        m.assert_called_once_with(123)
        assert delayed_value.value is NoValue
Ejemplo n.º 12
0
async def test_send_event(qth_client, event_loop):
    a = Value()
    qth_yarp.send_event("foo/bar", a, qth_client=qth_client)

    # Allow asyncio functions to run...
    await asyncio.sleep(0.1)

    # No initial value should have been sent to Qth
    assert len(qth_client.send_event.mock_calls) == 0

    # No registration should be made
    assert len(qth_client.register.mock_calls) == 0

    # Setting the qth value should update Qth
    a.set_instantaneous_value(321)
    await asyncio.sleep(0.1)
    qth_client.send_event.assert_called_with("foo/bar", 321)

    # And again...
    a.set_instantaneous_value(1234)
    await asyncio.sleep(0.1)
    qth_client.send_event.assert_called_with("foo/bar", 1234)
Ejemplo n.º 13
0
def test_no_repeat_instantaneous():
    v = Value()

    nrv = no_repeat(v)
    assert nrv.value is NoValue

    m = Mock()
    nrv.on_value_changed(m)

    # New value should pass through
    v.set_instantaneous_value(1)
    m.assert_called_once_with(1)
    assert nrv.value is NoValue

    # Repeat should not
    m.reset_mock()
    v.set_instantaneous_value(1)
    assert not m.called
    assert nrv.value is NoValue

    # New value should pass through
    v.set_instantaneous_value(2)
    m.assert_called_once_with(2)
    assert nrv.value is NoValue