def test_istype(x):
    """
    Given a value and its correct type, calling istype() with the type returns
    a function that returns the value it is called with.
    """
    v, t = x
    validator = mod.istype(t)
    assert validator(v) == v
def test_istype(x):
    """
    Given a value and its correct type, calling istype() with the type returns
    a function that returns the value it is called with.
    """
    v, t = x
    validator = mod.istype(t)
    assert validator(v) == v
def test_istype_wrong_type(x):
    """
    Given a value and type that doesn't match the value, calling istype() with
    the type returns a function that raises ValueError when called with the
    value.
    """
    v, t = x
    validator = mod.istype(t)
    with pytest.raises(ValueError):
        validator(v)
def test_istype_wrong_type(x):
    """
    Given a value and type that doesn't match the value, calling istype() with
    the type returns a function that raises ValueError when called with the
    value.
    """
    v, t = x
    validator = mod.istype(t)
    with pytest.raises(ValueError):
        validator(v)
@pytest.mark.parametrize('x', [
    fail(('2015-04-29', '%Y-%m-%d')),
    fail(('2015-04-29 17:00:01', '%Y-%m-%d %H:%M:%S')),
    ('2015-29-04', '%Y-%m-%d'),
    ('2015-04-29', '%H:%M:%S'),
])
def test_timestamp_reverse(x):
    s, fmt = x
    validator = mod.timestamp(fmt)
    with pytest.raises(ValueError):
        validator(s)


@pytest.mark.parametrize('x', [
    ([1, 2], mod.istype(int)),
    (["a", "bb"], mod.istype(str)),
])
def test_listof_valid(x):
    (value, item_validator) = x
    validator = mod.listof(item_validator)
    assert validator(value) == value


@pytest.mark.parametrize('x', [(None, None), ({}, None), (1, None),
                               ("test", None), ([1, 2], mod.istype(str))])
def test_listof_invalid(x):
    (value, item_validator) = x
    validator = mod.listof(item_validator)
    with pytest.raises(ValueError):
        validator(value)