Exemple #1
0
def test_signature_and_get_conf(circuit):
    """Test input signature related functions."""
    blk1 = Noop('test1', comment=' without unnamed inputs').connect(
        inp2=20, inp3=30, inp1=10)

    blk2 = Noop('test2', comment='with unnamed inputs', ).connect(
        100, 101, 102, 103,         # unnamed (group '_')
        inpA=edzed.Const('A2'),     # named single input
        inpB=[edzed.Const('B2')],   # named sequence
        inpC=range(5),              # named iterator
        )
    assert 'inputs' not in blk1.get_conf()  # no data before finalization
    init(circuit)

    assert blk1.input_signature() == ({'inp1': None, 'inp2': None, 'inp3': None,})
    conf1 = blk1.get_conf()
    conf1ok = {
        # future versions may add additional keys to get_conf()
        'class': 'Noop',
        'debug': False,
        'comment': ' without unnamed inputs',
        'inputs': {
            'inp1': "<Const 10>",
            'inp2': "<Const 20>",
            'inp3': "<Const 30>",
            },
        'name': 'test1',
        'type': 'combinational',
        }
    assert all(conf1[key] == value for key, value in conf1ok.items())

    assert blk2.input_signature() == ({'inpA': None, '_': 4, 'inpB': 1, 'inpC': 5})
    assert blk2.get_conf()['inputs'] == {
        '_': ('<Const 100>', '<Const 101>', '<Const 102>', '<Const 103>'),
        'inpA': "<Const 'A2'>",
        'inpB': ("<Const 'B2'>",),      # a 1-tuple
        'inpC': ('<Const 0>', '<Const 1>', '<Const 2>', '<Const 3>', '<Const 4>'),
        }

    blk2.check_signature({'inpA': None, '_': 4, 'inpB': 1, 'inpC': 5})
    blk2.check_signature({'inpA': None, '_': [4, 5], 'inpB': [None, None], 'inpC': [0, 5]})

    with pytest.raises(ValueError, match="missing: 'extra'"):
        blk2.check_signature({'inpA': None, 'extra': None, '_': 4, 'inpB': 1, 'inpC': 5})
    with pytest.raises(ValueError, match="unexpected: 'inpA'"):
        blk2.check_signature({'_': 4, 'inpB': 1, 'inpC': 5})
    with pytest.raises(ValueError, match="count is 5, expected was 10"):
        blk2.check_signature({'inpA': None, '_': 4, 'inpB': 1, 'inpC': 10})
    with pytest.raises(ValueError, match="did you mean 'inp_A'"):
        blk2.check_signature({'inp_A': None, '_': 4, 'inpB': 1, 'inpC': 5})
    with pytest.raises(ValueError, match="count is 1, minimum is 2"):
        blk2.check_signature({'inpA': None, '_': 4, 'inpB': [2, None], 'inpC': 5})
    with pytest.raises(ValueError, match="count is 4, maximum is 3"):
        blk2.check_signature({'inpA': None, '_': (2, 3), 'inpB': [0, 1], 'inpC': 5})
    with pytest.raises(ValueError, match="invalid"):
        blk2.check_signature({'inpA': None, '_': 4.5, 'inpB': 1, 'inpC': 5})
    with pytest.raises(ValueError, match="invalid"):
        blk2.check_signature({'inpA': None, '_': [4], 'inpB': 1, 'inpC': 5})
    with pytest.raises(ValueError, match="invalid"):
        blk2.check_signature({'inpA': None, '_': [0, 1, 2, 3], 'inpB': 1, 'inpC': 5})
Exemple #2
0
def test_const():
    """Const objects are reused."""
    CONST = 'some value'
    ch1 = edzed.Const(CONST)
    assert ch1.output == CONST
    ch2 = edzed.Const(CONST)
    assert ch1 is ch2  # ch1 was reused
    # make sure our implementation with a dict of all instances
    # can handle also unhashable values
    UNHASHABLE = [0]
    cu1 = edzed.Const(UNHASHABLE)
    assert cu1.output == UNHASHABLE
Exemple #3
0
def test_named_inputs(circuit):
    """
    Named inputs are ordered by name.

    This test also covers that no unnamed inputs is a special case in FuncBlock.
    """
    d4 = edzed.FuncBlock(
        '4 digits', func=lambda a, b, c, d: 1000*a + 100*b + 10*c + d
        ).connect(d=9, c=edzed.Const(1), a=2, b=edzed.Const(0))
    init(circuit)

    d4.eval_block()
    assert d4.output == 2019
Exemple #4
0
def test_no_invert_invert(circuit):
    """_not__not_name has no special meaning."""
    edzed.Not('src').connect(edzed.Const(True))
    edzed.FuncBlock('F', func=lambda x: x).connect('_not_src')
    edzed.FuncBlock('T', func=lambda x: x).connect('_not__not_src')
    with pytest.raises(Exception, match="not found"):
        init(circuit)
Exemple #5
0
def test_is_multiple_and_to_tuple():
    """Check _is_multiple() and _to_tuple() helpers."""
    is_multiple = edzed.block._is_multiple
    to_tuple = edzed.block._to_tuple

    # None is special case
    assert not is_multiple(None)
    assert to_tuple(None, lambda x: None) == ()

    SINGLE_VALUES = ('name', 10, {'a', 'b', 'c'}, set(), True, edzed.Const(-1))
    for arg in SINGLE_VALUES:
        assert not is_multiple(arg)
        assert to_tuple(arg, lambda x: None) == (arg, )

    MULTI_VALUES = ((1, 2, 3), [0], (), [])
    for arg in MULTI_VALUES:
        assert is_multiple(arg)
        assert to_tuple(arg, lambda x: None) == tuple(arg)

    # iterators are multiple values and are not consumed by is_multiple
    iterator = (x for x in range(4))  # a generator is always an iterator
    assert is_multiple(iterator)
    # test that the iterator is not exausted yet
    assert to_tuple(iterator, lambda x: None) == (0, 1, 2, 3)

    # check that validators are being called
    to_tuple(1, lambda x: 1 / x)
    with pytest.raises(ZeroDivisionError):
        to_tuple(0, lambda x: 1 / x)
Exemple #6
0
def test_input_by_name(circuit):
    """
    Input block may be specified by name.

    This implies that string constants require explicit Const('...')
    """
    Noop('blk_X').connect('blk_Y', edzed.Const('blk_Z'))    # blk_Z is just a string
    Noop('blk_Y').connect(a=('blk_X', None))
    init(circuit)
Exemple #7
0
def test_input_groups(circuit):
    """Input group is a sequence of input values."""
    d4 = edzed.FuncBlock(
        '4 digits', func=lambda f4: 1000*f4[0] + 100*f4[1] + 10*f4[2] + f4[3]
        ).connect(f4=[edzed.Const(3), 5, 7, 9])
    init(circuit)

    d4.eval_block()
    assert d4.output == 3579
Exemple #8
0
def test_unnamed_inputs(circuit):
    """
    Unnamed inputs are processed in order as they are connected.

    Const blocks are created on the fly.
    """
    d4 = edzed.FuncBlock(
        '4 digits', func=lambda a, b, c, d: 1000*a + 100*b + 10*c + d
        ).connect(1, 9, 8, edzed.Const(4))
    init(circuit)

    d4.eval_block()
    assert d4.output == 1984
Exemple #9
0
def test_getblocks(circuit):
    """Test getblocks() and findblock()."""
    # 1 Const, 2 CBlocks and 2 SBlocks
    edzed.Const(0)
    f1 = edzed.FuncBlock('F1', func=lambda: None)  # CBlock
    f2 = edzed.FuncBlock('F2', func=lambda: None)  # CBlock
    t1 = edzed.Timer('T1')  # SBlock
    t2 = edzed.Timer('T2')  # SBlock
    assert circuit.findblock('F1') is f1
    assert circuit.findblock('T2') is t2
    assert set(circuit.getblocks()) == {f1, f2, t1, t2}
    assert not set(circuit.getblocks(
        btype=edzed.Const))  # Const blocks are not registered
    assert set(circuit.getblocks(btype=edzed.CBlock)) == {f1, f2}
    assert set(circuit.getblocks(btype=edzed.SBlock)) == {t1, t2}
Exemple #10
0
def test_no_cross_circuit_inputs(circuit):
    """No cross circuit connections. Constants are an exception."""
    noop1 = Noop('noop')
    msg1 = edzed.Const("hello!")
    init(circuit)

    edzed.reset_circuit()
    noop2 = Noop('noop').connect(noop1)
    circuit2 = edzed.get_circuit()
    with pytest.raises(ValueError, match="not in the current circuit"):
        init(circuit2)

    # Const objects do not belong to specific circuit
    edzed.reset_circuit()
    noop3 = Noop('noop').connect(msg1)
    circuit3 = edzed.get_circuit()
    init(circuit3)
Exemple #11
0
def test_input_access(circuit):
    """Test various methods to access input values."""
    class MyBlock(edzed.CBlock):
        def calc_output(self):
            return [
                self._in['_'],       # tuple of all unnanmed inputs
                self._in['ctrl'],    # input name as a key
                self._in.ctrl,       # input name as an attr
                ]

    blk = MyBlock('test').connect(50, 51, 52, 53, 54, ctrl=edzed.Const('CTRL'))
    init(circuit)

    blk.eval_block()
    assert blk.output == [
        (50, 51, 52, 53, 54),
        'CTRL',
        'CTRL',
        ]
Exemple #12
0
def test_no_unknown_inputs(circuit):
    """Test unknown block error. """
    Noop('blk_X').connect('blk_Y', edzed.Const('blk_Z'))
    Noop('blk_Y').connect(a=('blk_X', 'blk_Z'))     # there is no blk_Z
    with pytest.raises(Exception, match="not found"):
        init(circuit)