示例#1
0
    def test_merge_list_with_oneof(self):
        "Non-rule node in list's inner spec"

        # TODO: refactor and reformulate.
        #       This test was written for older implementation of Monk.

        int_spec = IsA(int, default=123)
        str_spec = IsA(str, default='foo')

        # no defaults

        #rule = Rule(datatype=list, inner_spec=OneOf([123, 456]))
        item_spec = Any([int_spec, str_spec])
        rule = ListOf(item_spec)
        assert rule.get_default_for([]) == []
        assert rule.get_default_for([789]) == [789]

        # with defaults
        # (same results because defaults have no effect on lists)

        #rule = Rule(datatype=list,
        #            inner_spec=OneOf([123, 456], first_is_default=True))

        item_spec = Any([int_spec, str_spec], first_is_default=True)
        rule = ListOf(item_spec)
        assert rule.get_default_for([]) == []
        assert rule.get_default_for([789]) == [789]
示例#2
0
def test_translate_list():
    assert translate(list) == IsA(list)
    assert translate([]) == IsA(list)
    assert translate([int]) == ListOf(IsA(int))
    assert translate([1]) == ListOf(IsA(int, default=1))
    with raises_regexp(StructureSpecificationError,
                       'Expected a list containing exactly 1 item; '
                       'got 3: \[1, 2, 3\]'):
        translate([1, 2, 3])
示例#3
0
def test_combinator_any():
    v = Any([ IsA(str), IsA(int) ])

    assert repr(v) == '(must be str or must be int)'

    v('foo')
    v(123)
    with raises_regexp(ValidationError, '^must be str or must be int$'):
        v(4.5)
示例#4
0
    def test_list(self):
        assert translate(list) == IsA(list)

        assert translate([]) == IsA(list)

        with pytest.raises(errors.StructureSpecificationError) as excinfo:
            translate([1, 2])
        assert (
            "StructureSpecificationError: Expected a list "
            "containing exactly 1 item; got 2: [1, 2]") in excinfo.exconly()
示例#5
0
    def test_validate_optional_one_of_in_a_list(self):
        # unset "optional" should work exactly as in a Rule
        schema = translate([IsA(str) | IsA(int)])
        with raises(ValidationError):
            schema([])

        schema = translate([optional(IsA(str) | IsA(int))])

        schema([])
        schema([123])
        schema([123, 'sss'])
        with raises(ValidationError):
            schema([123, 'sss', 999.999])
示例#6
0
    def test_merge_dictof(self):

        ## present non-empty inner spec (optional)
        spec = DictOf([
            (Equals('a'), IsA(int, default=1)),
        ]) | Equals(None)

        # optional missing dictionary with required key
        assert spec.get_default_for(None) == None

        # optional empty dictionary with required key
        assert spec.get_default_for({}) == {'a': 1}

        ## present non-empty inner spec (optional)
        spec = DictOf([
            (Equals('a'), IsA(int, default=1) | Equals(None)),
        ])

        # optional missing dictionary with optional key
        # XXX CHANGED
        #assert spec.get_default_for(None) == None
        assert spec.get_default_for(None) == {'a': None}

        # optional empty dictionary with optional key
        # XXX CHANGED
        # (if the value can be either int or None, why choose one?
        # here we set None not because of Equals(None) but because
        # we *mean* None — no value could be chosen.
        #assert spec.get_default_for({}) == {'a': 1}
        assert spec.get_default_for({}) == {'a': None}

        ## present non-empty inner spec (required)
        spec = DictOf([
            (Equals('a'), IsA(int, default=1)),
        ])

        # required missing dictionary → inner spec
        assert spec.get_default_for({}) == {'a': 1}

        # required empty dictionary → inner spec
        assert spec.get_default_for({}) == {'a': 1}

        # XXX CHANGED
        ## required non-empty dictionary → inner spec
        #fallback = lambda s, v, **kw: v
        #assert merge_defaults(rule, {'a': 2}, {}, fallback) == {'a': 2}
        #assert merge_defaults(rule, {'b': 3}, {}, fallback) == {'a': 1, 'b': 3}

        # bogus value; will not pass validation but should be preserved
        assert spec.get_default_for(123) == 123
示例#7
0
def test_translate_dict():
    assert translate(dict) == IsA(dict)
    assert translate({}) == IsA(dict)

    # literal as a key
    assert translate({'foo': 123}) == DictOf([
        (Equals('foo'), IsA(int, default=123)),
    ])
    assert translate({123: str}) == DictOf([
        (Equals(123), IsA(str)),
    ])

    # validator as a key
    assert translate({Equals('foo') | Equals('bar'): str}) == DictOf([
        (Equals('foo') | Equals('bar'), IsA(str)),
    ])

    # type as a key
    assert translate({str: int}) == DictOf([
        (IsA(str), IsA(int)),
    ])

    # function as a key
    func = lambda: 'foo'
    assert translate({func: int}) == DictOf([
        (Equals('foo'), IsA(int)),
    ])
示例#8
0
def test_magic_and_or():
    v = IsA(str) | IsA(int)
    assert isinstance(v, Any)
    assert repr(v) == '(must be str or must be int)'

    v = IsA(str) & IsA(int)    # silly but who cares
    assert isinstance(v, All)
    assert repr(v) == '(must be str and must be int)'


    v = IsA(str) & IsA(int) | IsA(float)
    assert repr(v) == '((must be str and must be int) or must be float)'

    v = IsA(str) | IsA(int) & IsA(float)
    assert repr(v) == '(must be str or (must be int and must be float))'
示例#9
0
    def test_merge_oneof(self):
        str_rule = IsA(str, default='hello')
        int_rule = IsA(int, default=123)

        schema = Any([str_rule, int_rule])
        assert schema.get_default_for(None) == None

        schema = Any([str_rule, int_rule], default=456)
        assert schema.get_default_for(None) == 456

        schema = Any([str_rule, int_rule], first_is_default=True)
        assert schema.get_default_for(None) == 'hello'

        schema = Any([int_rule, str_rule], first_is_default=True)
        assert schema.get_default_for(None) == 123
示例#10
0
def test_list_of_all():
    v = ListOfAll(IsA(str))

    assert repr(v) == 'ListOfAll(must be str)'

    with raises_regexp(ValidationError, '^must be list$'):
        v('foo')

    with raises_regexp(ValidationError, '^lacks item: must be str$'):
        v([])

    # positive

    v(['foo'])

    v(['foo', 'bar'])

    with raises_regexp(ValidationError, '^item #2: must be str$'):
        v(['foo', 'bar', 123])

    # negated

    v = ~v

    with raises_regexp(ValidationError, '^~ListOfAll\(must be str\)$'):
        v(['foo'])

    with raises_regexp(ValidationError, '^~ListOfAll\(must be str\)$'):
        v(['foo', 'bar'])

    v(['foo', 'bar', 123])
示例#11
0
def test_list_of_any():
    v = ListOfAny(IsA(str))

    assert repr(v) == 'ListOfAny(must be str)'

    with raises_regexp(ValidationError, '^must be list$'):
        v('foo')

    with raises_regexp(ValidationError, '^lacks item: must be str$'):
        v([])

    # positive

    v(['foo'])

    v(['foo', 123])

    with raises_regexp(ValidationError,
        '^item #0: must be str or item #1: must be str$'):
        v([123, 5.5])

    # negated

    v = ~v

    with raises_regexp(ValidationError, '^~ListOfAny\(must be str\)$'):
        v(['foo'])

    with raises_regexp(ValidationError, '^~ListOfAny\(must be str\)$'):
        v(['foo', 123])

    v([123, 5.5])
示例#12
0
    def test_merge_isa__dict(self):
        # TODO use a single test for all types used with IsA

        # optional missing dictionary
        assert (IsA(dict) | Equals(None)).get_default_for(None) == None

        # XXX CHANGED
        ## required missing dictionary → empty dictionary
        #assert IsA(dict).get_default_for(None) == {}
        assert IsA(dict).get_default_for(None) == None

        # required empty dictionary
        assert IsA(dict).get_default_for({}) == {}

        # required non-empty dictionary
        assert IsA(dict).get_default_for({'x': 1}) == {'x': 1}
示例#13
0
 def test_opt_key__py2_unicode(self):
     raw = {
         opt_key(unicode('foo')): int,
     }
     assert translate(raw) == DictOf([
         (Equals(unicode('foo')) | ~Exists(), IsA(int)),
     ])
示例#14
0
 def test_opt_key__str(self):
     # this also means Unicode for Py3 but it's OK
     raw = {
         opt_key('foo'): int,
     }
     assert translate(raw) == DictOf([
         (Equals('foo') | ~Exists(), IsA(int)),
     ])
示例#15
0
def test_isa():
    v = IsA(str)

    assert repr(v) == 'must be str'

    v('foo')

    with raises_regexp(ValidationError, '^must be str'):
        v(123)
示例#16
0
def test_combinator_edge_cases():
    with raises_regexp(TypeError, 'got Exists class instead of its instance'):
        IsA(str) | Exists

    # translate() is applied to the right argument
    assert IsA(str) | 'Albatross!' == IsA(str) | IsA(str, default='Albatross!')
    assert IsA(str) | None == IsA(str) | Anything()
    assert Length(min=3) & [] == Length(min=3) & IsA(list)
示例#17
0
def test_regression_22():
    ~Anything()
    ~IsA(str)
    ~Equals(5)
    ~Contains('x')
    ~InRange(5)
    ~Length(5)
    ~ListOf(str)
    ~DictOf([])
    ~Exists()
示例#18
0
    def test_missing(self):

        # MISSING KEY

        dict_with_opt_key = translate({IsA(text_type) | ~Exists(): text_type})
        dict_with_opt_key({})

        dict_with_req_key_opt_value = translate(
            {'a': IsA(text_type) | Equals(None)})
        with raises(MissingKeys):
            dict_with_req_key_opt_value({})

        dict_with_req_key_req_value = translate({'a': IsA(text_type)})
        with raises(MissingKeys):
            dict_with_req_key_req_value({})

        dict_with_req_keys_req_values = translate({'a': text_type, 'b': int})
        with raises(MissingKeys):
            dict_with_req_keys_req_values({'b': 1})
示例#19
0
    def test_typed_optional_dict(self):
        "A value of given type (dict) or no value"

        spec = IsA(dict) | Equals(None)

        # value is present
        spec({})

        # value is missing
        spec(None)
示例#20
0
    def test_typed_optional_list(self):
        "A value of given type (list) or no value"

        spec = IsA(list) | Equals(None)

        # value is present
        spec([])

        # value is missing
        spec(None)
示例#21
0
    def test_typed_required_dict(self):
        "A value of given type (dict)"

        spec = IsA(dict)

        # value is present
        spec({})

        # value is missing
        with raises_regexp(ValidationError, 'must be dict'):
            spec(None)
示例#22
0
def test_dictof():
    # key may be missing
    dict_of_str_to_int_optional_keys = DictOf([
        (IsA(str) | ~Exists(), IsA(int)),
    ])
    dict_of_str_to_int_optional_keys({})
    dict_of_str_to_int_optional_keys({'foo': 123})
    with raises_regexp(InvalidKeys, '123'):
        dict_of_str_to_int_optional_keys({123: 456})

    # key must be present, exact literals not specified
    dict_of_str_to_int = DictOf([
        (IsA(str), IsA(int)),
    ])
    with raises_regexp(MissingKeys, 'must have keys: must be str'):
        dict_of_str_to_int({})
    dict_of_str_to_int({'foo': 123})
    dict_of_str_to_int({'foo': 123, 'bar': 456})

    with raises_regexp(InvalidKeys, '123'):
        dict_of_str_to_int({'foo': 123, 'bar': 456, 123: 'quux'})
    with raises_regexp(ValidationError, "'quux' value must be int"):
        dict_of_str_to_int({'foo': 123, 'bar': 456, 'quux': 4.2})
示例#23
0
    def test_typed_required(self):
        "A value of given type"

        spec = IsA(int)

        # value is present and matches datatype
        spec(1)

        # value is present but does not match datatype
        with raises_regexp(ValidationError, 'must be int'):
            spec('bogus')

        # value is missing
        with raises_regexp(ValidationError, 'must be int'):
            spec(None)
示例#24
0
    def test_typed_required_list(self):
        "A value of given type (list)"

        spec = IsA(list)

        # value is present

        spec([])

        with raises_regexp(ValidationError, 'must be list'):
            spec('bogus')

        # value is missing
        with raises_regexp(ValidationError, 'must be list'):
            spec(None)
示例#25
0
    def test_typed_optional(self):
        "A value of given type or no value"

        spec = IsA(int) | Equals(None)

        # value is present and matches datatype
        spec(1)

        # value is present and equals None
        spec(None)

        # value is present but does not match datatype
        with raises_regexp(AllFailed, "must be int or must equal None"):
            spec('bogus')

        # value is missing
        spec(None)
示例#26
0
    def test_merge_dictof_dictof_isa(self):
        raw_spec = {
            'content': {
                'text': t('hello'),
            },
        }

        spec = translate(raw_spec)

        # make sure translation went as expected
        assert spec == DictOf([
            (Equals('content'),
             DictOf([
                 (Equals('text'), IsA(t, default=t('hello'))),
             ])),
        ])

        # make sure merging works as expected for nested dict
        assert raw_spec == spec.get_default_for({'content': {}})

        # make sure merging works as expected for nested *and* root dicts
        assert raw_spec == spec.get_default_for({})
示例#27
0
 def test_rule(self):
     rule = IsA(str, default='abc') | IsA(int)
     assert rule == translate(rule)
示例#28
0
 def test_string(self):
     assert translate(str) == IsA(str)
     assert translate('foo') == IsA(str, default='foo')
示例#29
0
 def test_int(self):
     assert translate(int) == IsA(int)
     assert translate(5) == IsA(int, default=5)
示例#30
0
 def test_float(self):
     assert translate(float) == IsA(float)
     assert translate(.5) == IsA(float, default=.5)