Ejemplo n.º 1
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
Ejemplo n.º 2
0
def test_invert_combinator():
    hello_or_bye = Equals('hello') | Equals('bye')
    hello_or_bye('hello')
    hello_or_bye('bye')
    with raises_regexp(ValidationError, "^must equal 'hello' or must equal 'bye'$"):
        hello_or_bye('albatross!')

    neither_hello_nor_bye = ~hello_or_bye
    with raises_regexp(ValidationError,
        "^not \(must equal 'hello' or must equal 'bye'\)$"):
        neither_hello_nor_bye('hello')
    with raises_regexp(ValidationError,
        "^not \(must equal 'hello' or must equal 'bye'\)$"):
        neither_hello_nor_bye('bye')
    neither_hello_nor_bye('albatross!')
Ejemplo n.º 3
0
 def test_opt_key__py2_unicode(self):
     raw = {
         opt_key(unicode('foo')): int,
     }
     assert translate(raw) == DictOf([
         (Equals(unicode('foo')) | ~Exists(), IsA(int)),
     ])
Ejemplo n.º 4
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)),
     ])
Ejemplo n.º 5
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)),
    ])
Ejemplo n.º 6
0
def test_equals():
    v = Equals('foo')

    assert repr(v) == "must equal 'foo'"

    v('foo')

    with raises_regexp(ValidationError, "^must equal 'foo'"):
        v('bar')
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
def test_regression_22():
    ~Anything()
    ~IsA(str)
    ~Equals(5)
    ~Contains('x')
    ~InRange(5)
    ~Length(5)
    ~ListOf(str)
    ~DictOf([])
    ~Exists()
Ejemplo n.º 9
0
def test_invert_requirement():
    says_hello = Equals('hello')
    says_hello('hello')
    with raises_regexp(ValidationError, "^must equal 'hello'$"):
        says_hello('bye')

    says_not_hello = ~says_hello
    with raises_regexp(ValidationError, "^not \(must equal 'hello'\)$"):
        says_not_hello('hello')
    says_not_hello('bye')
Ejemplo n.º 10
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)
Ejemplo n.º 11
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({})
Ejemplo n.º 12
0
def test_double_invert_requirement():
    a = Equals('hello')
    a('hello')
    with raises_regexp(ValidationError, "^must equal 'hello'$"):
        a('bye')

    b = ~a
    with raises_regexp(ValidationError, "^not \(must equal 'hello'\)$"):
        b('hello')
    b('bye')

    c = ~b
    c('hello')
    with raises_regexp(ValidationError, "^must equal 'hello'$"):
        c('bye')
Ejemplo n.º 13
0
    def test_one_of(self):
        # literals (behaviour implicitly turned on)

        assert one_of(['foo', 'bar']) == Equals('foo') | Equals('bar')

        v = one_of(['foo', 'bar'])
        v('foo')
        with pytest.raises(errors.ValidationError) as excinfo:
            v('quux')
        assert "AllFailed: must equal 'foo' or must equal 'bar'" in excinfo.exconly(
        )

        # non-literals → rules (behaviour explicitly turned on)

        shortcut_rule = one_of(['foo', 'bar'], as_rules=True)
        verbose_rule = Any(['foo', 'bar'])
        assert shortcut_rule == verbose_rule

        v = one_of(['foo', 123], as_rules=True)
        v('hello')
        v(456)
        with pytest.raises(errors.ValidationError) as excinfo:
            v(5.5)
        assert "AllFailed: must be str or must be int" in excinfo.exconly()
Ejemplo n.º 14
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}
Ejemplo n.º 15
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)
Ejemplo n.º 16
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})
Ejemplo n.º 17
0
def test_magic_eq():
    assert IsA(str) == IsA(str)
    assert IsA(str) != IsA(str, default='foo')
    assert IsA(str) != IsA(int)
    assert IsA(str) != Equals(int)

    # nested
    v1 = ListOf([DictOf([ (Equals('foo'), IsA(str)) ])])
    v2 = ListOf([DictOf([ (Equals('foo'), IsA(str)) ])])
    v3 = ListOf([DictOf([ (Equals('bar'), IsA(str)) ])])
    v4 = ListOf([DictOf([ (Equals('foo'), IsA(int)) ])])
    v5 = ListOf([DictOf([ (Equals('foo'), IsA(str, default='x')) ])])
    assert v1 == v1
    assert v1 == v2
    assert v1 != v3
    assert v1 != v4
    assert v1 != v5
Ejemplo n.º 18
0
    def test_int_in_optional_dict(self):
        "A required int nested in an optional dict"

        spec = translate({'foo': int}) | Equals(None)

        # outer optional value is missing

        spec(None)

        # outer optional value is present, inner key is missing

        with raises_regexp(AllFailed,
                           "must have keys: 'foo' or must equal None"):
            spec({})

        # inner key is present, inner value is missing

        with raises_regexp(AllFailed,
                           "'foo' value must be int or must equal None"):
            spec({'foo': None})

        # inner value is present

        spec({'foo': 123})
Ejemplo n.º 19
0
 def test_dict(self):
     assert translate(dict) == IsA(dict)
     assert translate({'foo': 123}) == DictOf([
         (Equals('foo'), IsA(int, default=123)),
     ])
Ejemplo n.º 20
0
    def test_merge_list(self):

        ## present but empty inner spec (optional)
        rule = ListOf([]) | Equals(None)

        # optional missing list
        assert rule.get_default_for(None) == None

        ## present but empty inner spec (required)
        rule = ListOf([])

        # required missing list → empty list
        assert rule.get_default_for(None) == []

        ## present non-empty inner spec (optional)
        rule = ListOf(IsA(int, default=123)) | Equals(None)

        # optional missing list with required item(s)
        assert rule.get_default_for(None) == None

        # optional empty list with required item(s)
        assert rule.get_default_for([]) == []

        ## present non-empty inner spec (optional)
        elem_spec = IsA(int, default=123) | Equals(None)
        rule = ListOf(elem_spec) | Equals(None)

        # optional missing list with optional item(s)
        assert rule.get_default_for(None) == None

        # optional empty list with optional item
        assert rule.get_default_for([]) == []

        ## present non-empty inner spec (required)
        rule = ListOf(IsA(int, default=123))

        # required missing list → inner spec
        assert rule.get_default_for(None) == []

        # required empty list → inner spec
        assert rule.get_default_for([]) == []

        # required non-empty list → inner spec
        #        fallback = lambda s, v, **kw: v
        assert rule.get_default_for([None]) == [None]
        assert rule.get_default_for([456]) == [456]

        ## present inner spec with empty item spec
        rule = ListOf(Anything())
        assert rule.get_default_for([456]) == [456]

        ## present inner spec with item spec that has an inner spec
        #rule = Rule(datatype=list, inner_spec=[123])
        rule = ListOf(ListOf(IsA(int, default=123)))

        # XXX CHANGED    WTF was it before!?
        ##assert rule.get_default_for([None]) == [123]
        #assert rule.get_default_for([[]]) == [[123]]

        # bogus value; will not pass validation but should be preserved
        assert rule.get_default_for(123) == 123