コード例 #1
0
def test_allow_unknown():
    schema = {
        'a': {
            'type': 'dict',
            'items': {'x': {}}
        },
        'b': {
            'type': 'dict',
            'items': {'x': {}},
            'allow_unknown': True
        },
        'c': {
            'type': 'dict',
            'items': {'x': {}},
            'allow_unknown': False
        }
    }
    vn = Validator(schema, allow_unknown=0)
    va = Validator(schema, allow_unknown=1)

    for schema in 'abc':
        assert vn[schema]({'x': 3}) == ({'x': 3}, None)
        assert va[schema]({'x': 3}) == ({'x': 3}, None)

    assert vn['a']({'u': 5}) == (None, "Input must not contain keys {'u'}")
    assert vn['b']({'u': 5}) == ({'u': 5}, None)
    assert vn['c']({'u': 5}) == (None, "Input must not contain keys {'u'}")

    assert va['a']({'u': 5}) == ({'u': 5}, None)
    assert va['b']({'u': 5}) == ({'u': 5}, None)
    assert va['c']({'u': 5}) == (None, "Input must not contain keys {'u'}")
コード例 #2
0
def test_purge_unknown():
    schema = {
        'a': {
            'type': 'dict',
            'items': {'x': {}}
        },
        'b': {
            'type': 'dict',
            'items': {'x': {}},
            'purge_unknown': True
        },
        'c': {
            'type': 'dict',
            'items': {'x': {}},
            'purge_unknown': False
        }
        # TODO: lists
    }
    vn = Validator(schema, allow_unknown=1, purge_unknown=0)
    vp = Validator(schema, allow_unknown=1, purge_unknown=1)

    for schema in 'abc':
        assert vn[schema]({'x': 3}) == ({'x': 3}, None)
        assert vp[schema]({'x': 3}) == ({'x': 3}, None)

    d = {'x': 3, 'u': 5}
    assert vn['a'](d) == (d, None)
    assert vn['b'](d) == ({'x': 3}, None)
    assert vn['c'](d) == (d, None)

    assert vp['a'](d) == ({'x': 3}, None)
    assert vp['b'](d) == ({'x': 3}, None)
    assert vp['c'](d) == (d, None)
コード例 #3
0
def test_post_coerce():
    v = Validator({
        'a': {
            'coerce': 'int',
            'post_coerce': 'str'
        },
        'g': {
            'coerce': 'int',
            'post_coerce': 'gender'
        }
    })

    v.coerce_gender = coerce_gender

    assert v['a'](1) == ('1', None)
    assert v['a'](1.2) == ('1', None)
    assert v['a']('1') == ('1', None)
    assert v['a']({}) == (None, 'Input is not coercible to int')

    assert v['g'](1) == ('male', None)
    assert v['g'](1.2) == ('male', None)
    assert v['g']('1') == ('male', None)
    assert v['g'](2) == (None, 'Input is not coercible to gender')
    assert v['g']('2') == (None, 'Input is not coercible to gender')
    assert v['g']({}) == (None, 'Input is not coercible to int')
コード例 #4
0
def test_overwrite_default_coercion():
    v = Validator()
    v.coerce_bool = lambda val, args: {'foo': True, 'bar': False}[val]
    v['b'] = {'coerce': 'bool'}

    assert v['b']('foo') == (True, None)
    assert v['b']('bar') == (False, None)
    assert v['b']('baz') == (None, 'Input is not coercible to bool')
コード例 #5
0
def test_required():
    schema = {
        'a': {
            'type': 'dict',
            'items': {'x': {}}
        },
        'b': {
            'type': 'dict',
            'items': {'x': {'required': True}}
        },
        'c': {
            'type': 'dict',
            'items': {'x': {}},
            'require_all': True
        },
        'd': {
            'type': 'dict',
            'items': {'x': {'required': False}},
            'require_all': True
        },
        'e': {
            'type': 'dict',
            'items': {'x': {}},
            'require_all': False
        },
        'f': {
            'type': 'dict',
            'items': {'x': {'required': True}},
            'require_all': False
        }
    }
    vn = Validator(schema, require_all=0)
    vr = Validator(schema, require_all=1)

    for schema in 'abcdef':
        assert vn[schema]({'x': 3}) == ({'x': 3}, None)
        assert vr[schema]({'x': 3}) == ({'x': 3}, None)

    assert vn['a']({}) == ({}, None)
    assert vn['b']({}) == (None, 'Input.x is required')
    assert vn['c']({}) == (None, 'Input.x is required')
    assert vn['d']({}) == ({}, None)
    assert vn['e']({}) == ({}, None)
    assert vn['f']({}) == (None, 'Input.x is required')

    assert vr['a']({}) == (None, 'Input.x is required')
    assert vr['b']({}) == (None, 'Input.x is required')
    assert vr['c']({}) == (None, 'Input.x is required')
    assert vr['d']({}) == ({}, None)
    assert vr['e']({}) == ({}, None)
    assert vr['f']({}) == (None, 'Input.x is required')
コード例 #6
0
def test_minmax_len():
    v = Validator({
        'x': {'min_len': 2, 'max_len': 3}
    })

    assert v['x']([]) == (None, 'Input length must be at least 2')
    assert v['x']([1]) == (None, 'Input length must be at least 2')
    assert v['x']([1, 2]) == ([1, 2], None)
    assert v['x']([1, 2, 3]) == ([1, 2, 3], None)
    assert v['x']([1, 2, 3, 4]) == (None, 'Input length must be at most 3')

    assert v['x']('') == (None, 'Input length must be at least 2')
    assert v['x']('a') == (None, 'Input length must be at least 2')
    assert v['x']('ab') == ('ab', None)
    assert v['x']('abc') == ('abc', None)
    assert v['x']('abcd') == (None, 'Input length must be at most 3')

    assert v['x']({}) == (None, 'Input length must be at least 2')
    assert v['x']({1: 1}) == (None, 'Input length must be at least 2')
    assert v['x']({1: 1, 2: 2}) == ({1: 1, 2: 2}, None)
    assert v['x']({1: 1, 2: 2, 3: 3}) == ({1: 1, 2: 2, 3: 3}, None)
    assert v['x']({1: 1, 2: 2, 3: 3, 4: 4}) == (None, 'Input length must be at most 3')

    assert v['x'](set()) == (None, 'Input length must be at least 2')
    assert v['x']({1}) == (None, 'Input length must be at least 2')
    assert v['x']({1, 2}) == ({1, 2}, None)
    assert v['x']({1, 2, 3}) == ({1, 2, 3}, None)
    assert v['x']({1, 2, 3, 4}) == (None, 'Input length must be at most 3')
コード例 #7
0
def test_schema_examples():
    v = Validator({
        'a': {
            'enum': [1, 2, 3],
            'examples': [2, 3],
            'negative_examples': [0, 4]
        },
        'b': {
            'type': 'dict',
            'items': {
                'x': {
                    'enum': [1, 2],
                    'examples': [1]
                }
            },
            'examples': [{'x': 2}]
        }
    })

    bad_schemas = [
        {
            'enum': [1, 2, 3],
            'examples': [1, 5]
        },
        {
            'enum': [1, 2, 3],
            'negative_examples': [1]
        },
        {
            'type': 'dict',
            'items': {
                'x': {
                    'enum': [1, 2],
                    'examples': [5]
                }
            },
            'examples': [{'x': 2}]
        },
        {
            'type': 'dict',
            'items': {
                'x': {
                    'enum': [1, 2],
                    'examples': [1]
                }
            },
            'examples': [{'x': 5}]
        }
    ]

    for schema in bad_schemas:
        try:
            v['x'] = schema
            assert 0, 'Must throw exception'
        except ValueError:
            pass
コード例 #8
0
def test_map():
    v = Validator({
        'x': {'map': {'a': 1, 'b': 2}}
    })

    assert v['x'](3) == (3, None)
    assert v['x']('a') == (1, None)
    assert v['x']('b') == (2, None)
    assert v['x']('c') == ('c', None)
    assert v['x']({}) == ({}, None)
コード例 #9
0
def test_default():
    v = Validator({
        'a': {
            'type': 'dict',
            'items': {
                'd': {'default': 5}
            }
        }
    })

    assert v['a']({'d': 3}) == ({'d': 3}, None)
    assert v['a']({}) == ({'d': 5}, None)
コード例 #10
0
def test_default_args():
    v = Validator({
        'a': {
            'type': 'dict',
            'items': {
                'd': {'default': '{MY_PARAM}'}
            }
        }
    })

    assert v['a']({'d': 3}) == ({'d': 3}, None)
    assert v['a']({}, {'MY_PARAM': 5}) == ({'d': 5}, None)
コード例 #11
0
def test_coerce():
    v = Validator({
        'n': {'coerce': 'number'},
        's': {'coerce': 'str'},
        'b': {'coerce': 'bool'},
        'g': {'coerce': 'gender'}
    })

    v.coerce_gender = coerce_gender

    assert v['n'](1) == (1, None)
    assert v['n'](1.2) == (1.2, None)
    assert v['n']('1') == (1, None)
    assert v['n']('1.2') == (1.2, None)
    assert v['n']('que?') == (None, 'Input is not coercible to number')

    assert v['s'](1) == ('1', None)
    assert v['s'](1.2) == ('1.2', None)
    assert v['s']('1') == ('1', None)
    assert v['s']({}) == ('{}', None)
    assert v['s'](None) == ('None', None)

    assert v['b'](True) == (True, None)
    assert v['b'](1) == (True, None)
    assert v['b']('Yes') == (True, None)
    assert v['b']('1.0') == (True, None)
    assert v['b'](0) == (False, None)
    assert v['b'](False) == (False, None)
    assert v['b']('N') == (False, None)
    assert v['b']({}) == (None, 'Input is not coercible to bool')
    assert v['b'](5) == (None, 'Input is not coercible to bool')
    assert v['b']('qwe') == (None, 'Input is not coercible to bool')

    assert v['g']('female') == ('female', None)
    assert v['g'](1) == ('male', None)
    assert v['g'](False) == ('female', None)
    assert v['g'](2) == (None, 'Input is not coercible to gender')
    assert v['g']({}) == (None, 'Input is not coercible to gender')
    assert v['g'](None) == (None, 'Input is not coercible to gender')
コード例 #12
0
def test_synonyms():
    v = Validator({
        'x': {
            'type': 'dict',
            'items': {
                'a': {'type': 'int', 'synonyms': ['b', 'c']},
            }
        }
    })

    assert v['x']({'a': 1}) == ({'a': 1}, None)
    assert v['x']({'c': 1}) == ({'a': 1}, None)
    assert v['x']({'a': '1'}) == (None, 'Input.a type must be int')
    assert v['x']({'b': '1'}) == (None, 'Input.b type must be int')
コード例 #13
0
def test_nullable():
    v = Validator({
        'x': {'nullable': True, 'type': 'str'},
        'y': {'nullable': True, 'type': 'str', 'if_null': -1},
        'z': {'nullable': True, 'type': 'str', 'if_null': '{MY_PARAM}'}
    })

    assert v['x']('Hey!') == ('Hey!', None)
    assert v['x']({}) == (None, 'Input type must be str')
    assert v['x'](None) == (None, None)
    assert v['y']('Hey!') == ('Hey!', None)
    assert v['y'](None) == (-1, None)
    assert v['z']('Hey!') == ('Hey!', None)
    assert v['z'](None, {'MY_PARAM': -2}) == (-2, None)
コード例 #14
0
def test_rename():
    v = Validator({
        'x': {
            'type': 'dict',
            'items': {
                'a': {'type': 'int', 'rename': 'b'},
                'b': {'type': 'str'}
            },
            'require_all': False
        }
    })

    assert v['x']({'a': 1}) == ({'b': 1}, None)
    assert v['x']({'a': '1'}) == (None, 'Input.a type must be int')
    assert v['x']({'b': '1'}) == ({'b': '1'}, None)
    assert v['x']({'b': 1}) == (None, 'Input.b type must be str')
コード例 #15
0
def test_minmax():
    v = Validator({
        'n': {'min': -10, 'max': 15},
        'w': {'min': 'flight', 'max': 'somewhere'},
    })

    assert v['n'](-11) == (None, 'Input must be at least -10')
    assert v['n'](-10) == (-10, None)
    assert v['n'](1) == (1, None)
    assert v['n'](15) == (15, None)
    assert v['n'](16) == (None, 'Input must be at most 15')

    assert v['w']('chicken') == (None, 'Input must be at least "flight"')
    assert v['w']('flight') == ('flight', None)
    assert v['w']('potato') == ('potato', None)
    assert v['w']('somewhere') == ('somewhere', None)
    assert v['w']('space') == (None, 'Input must be at most "somewhere"')
コード例 #16
0
def test_number():
    v = Validator({
        'n': {'type': 'number'},
        'f': {'type': 'float'},
        'i': {'type': 'int'}
    })

    assert v['n'](1) == (1, None)
    assert v['n'](1.2) == (1.2, None)
    assert v['n']('1') == (None, 'Input type must be number')

    assert v['f'](1) == (None, 'Input type must be float')
    assert v['f'](1.2) == (1.2, None)
    assert v['f']('1') == (None, 'Input type must be float')

    assert v['i'](1) == (1, None)
    assert v['i'](1.2) == (None, 'Input type must be int')
    assert v['i']('1') == (None, 'Input type must be int')
コード例 #17
0
def test_one_any_of():
    v = Validator({
        'a1': {'any_of': [{'type': 'int'}, {'type': 'str'}]},
        'a2': {'any_of': [{'type': 'float'}, {'type': 'number'}]},
        'ac': {'any_of': [{'coerce': 'int'}, {'coerce': 'str'}]},
        'o1': {'one_of': [{'type': 'int'}, {'type': 'str'}]},
        'o2': {'one_of': [{'type': 'float'}, {'type': 'number'}]},
        'oc': {'one_of': [{'coerce': 'int'}, {'coerce': 'str'}]}
    })

    assert v['a1'](1) == (1, None)
    assert v['a1'](1.5) == (None, 'Input must satisfy any of 2 rules:\n'
                                  '1: ^ type must be int\n'
                                  '2: ^ type must be str')
    assert v['a1']('q') == ('q', None)
    assert v['a2'](1) == (1, None)
    assert v['a2'](1.5) == (1.5, None)
    assert v['a2']('q') == (None, 'Input must satisfy any of 2 rules:\n'
                                  '1: ^ type must be float\n'
                                  '2: ^ type must be number')
    assert v['ac'](1) == (1, None)
    assert v['ac']('1') == (1, None)
    assert v['ac']('1.5e2') == (150, None)
    assert v['ac']({}) == ('{}', None)

    assert v['o1'](1) == (1, None)
    assert v['o1'](1.5) == (None, 'Input must satisfy exactly one of 2 rules:\n'
                                  '1: ^ type must be int\n'
                                  '2: ^ type must be str')
    assert v['o1']('q') == ('q', None)
    assert v['o2'](1) == (1, None)
    assert v['o2'](1.5) == (None, 'Input must satisfy exactly one of 2 rules:\n'
                                  '1: ok\n'
                                  '2: ok')
    assert v['o2']('q') == (None, 'Input must satisfy exactly one of 2 rules:\n'
                                  '1: ^ type must be float\n'
                                  '2: ^ type must be number')
    assert v['oc'](1) == (None, 'Input must satisfy exactly one of 2 rules:\n'
                                '1: ok\n'
                                '2: ok')
    assert v['oc']('1') == (None, 'Input must satisfy exactly one of 2 rules:\n'
                                  '1: ok\n'
                                  '2: ok')
    assert v['oc']({}) == ('{}', None)
コード例 #18
0
def test_values():
    v = Validator({
        'd': {
            'type': 'dict',
            'values': {'type': 'int'}
        },
        'l': {
            'type': 'list',
            'values': {'type': 'int'}
        }
    })

    assert v['d']({}) == ({}, None)
    assert v['d']({'x': 1, 'y': 2}) == ({'x': 1, 'y': 2}, None)
    assert v['d']({'x': 1, 'y': 's'}) == (None, 'Input.y type must be int')

    assert v['l']([]) == ([], None)
    assert v['l']([1, 2]) == ([1, 2], None)
    assert v['l']([1, 's']) == (None, 'Input[1] type must be int')
コード例 #19
0
def test_enum():
    v = Validator({
        'x': {'enum': [1, '2']},
        'y': {'enum': [1.0, '2', {}, None]}
    })

    assert v['x'](1) == (1, None)
    assert v['x']('1') == (None, "Input must be one of [1, '2']")
    assert v['x'](2) == (None, "Input must be one of [1, '2']")
    assert v['x']('2') == ('2', None)
    assert v['x']({}) == (None, "Input must be one of [1, '2']")
    assert v['x'](None) == (None, "Input must be one of [1, '2']")

    assert v['y'](1) == (1, None)
    assert v['y'](1.0) == (1, None)
    assert v['y']('1') == (None, "Input must be one of [1.0, '2', {}, None]")
    assert v['y'](2) == (None, "Input must be one of [1.0, '2', {}, None]")
    assert v['y']('2') == ('2', None)
    assert v['y']({}) == ({}, None)
    assert v['y'](None) == (None, None)
コード例 #20
0
def test_regex():
    v = Validator({
        'a': {'regex': '.*'},
        'b': {'regex': 'b+'},
        'c': {'regex': r'c\\+'},
        'q1': {'regex': '"+'},
        'q2': {'regex': "'+"}
    })

    assert v['a']('qwe') == ('qwe', None)

    assert v['b']('bbbb') == ('bbbb', None)
    assert v['b']('') == (None, 'Input must match regex: b+')
    assert v['b']('abc') == (None, 'Input must match regex: b+')

    assert v['c']('c\\') == ('c\\', None)
    assert v['c']('c') == (None, r'Input must match regex: c\\+')

    assert v['q1']('"""') == ('"""', None)
    assert v['q1']("''") == (None, 'Input must match regex: "+')
    assert v['q2']("'''") == ("'''", None)
    assert v['q2']('""') == (None, "Input must match regex: '+")
コード例 #21
0
def test_general():
    schemas = {
     'str': {'type': 'str'},
     'numbers': {'minlength': 2, 'type': 'list', 'values': {'type': 'int'}},

     'user': {
      'type': 'dict',
      'schema': {
        'id': {
         'type': 'int',
         'enum': [1, 2, 3, 4, 5],
         'min': 1,
         'max': 4},
       'name': {'type': 'str', 'regex': '\\S+'},
       'addr': {
        'type': 'dict',
        'schema': {
         'city': {'type': 'str'},
         'street': {'type': 'str'},
         'bld': {'type': 'str'}},
        'minlength': 2},
       'children': {
        'type': 'list',
        'values': {
          'type': 'dict',
          'schema': {'id': {'type': 'int'}}}},
       'favourite_numbers': 'numbers'
      }
     },

     'a': {'type': 'dict', 'schema': {'next': 'b'}},
     'b': {'type': 'dict', 'schema': {'next': 'a'}},

     'recursive': {'type': 'dict',
      'schema': {'id': {'type': 'int'}, 'v': 'recursive'}},
     'recursive_ptr': {'type': 'dict',
      'schema': {'id': {'type': 'int'}, 'v': {...}}},

     'universe_answer': {'coerce': 'int', 'default': 42},
     'universe_dict': {'type': 'dict',
      'schema': {'val': {'coerce': 'int', 'default': 123}}},
     'universe_dict_2': {'type': 'dict', 'schema': {'val': 'universe_answer'}},

     'rename': {'type': 'dict',
      'schema': {'val': {'coerce': 'int', 'default': 42, 'rename': 'qwe'}}},
     'anyof_validate': {'anyof': [{'type': 'int'},
       {'type': 'dict', 'allow_unknown': True},
       'str']},
     'oneof_validate': {'oneof': [{'type': 'int'},
       {'type': 'dict', 'allow_unknown': True},
       'str']},

     'valuesrules': {'type': 'dict',
      'valuesrules': {'type': 'str'},
      'allow_unknown': True},
     'valuesrules2': {
       'type': 'dict', 'valuesrules': 'str', 'allow_unknown': True}
    }

    schemas['recursive_ptr']['schema']['v'] = schemas['recursive_ptr']

    v = Validator(schemas)

    assert v['numbers']([1, 2, 3]) == ([1, 2, 3], None)
    assert v['numbers']([2, 'a']) == (None, 'Input[1] type must be int')
    assert v['numbers']([3]) == (None, 'Input length must be at least 2')

    assert v['user']({'id': 3,
                      'name': 'John',
                      'addr': {'city': '17'},
                      'children': [{'id': '5'}],
                      'favourite_numbers': [1]}) == (None, 'Input.addr length must be at least 2')
    assert v['user']({'id': 2,
                      'name': 'John',
                      'addr': {'city': 17, 'street': '5', 'bld': '6/2'},
                      'children': [{'id': '5'}],
                      'favourite_numbers': [1]}) == (None, 'Input.addr.city type must be str')

    d1 = d1['v'] = {'id': 1, 'v': {...}}
    d2 = d2['v'] = {'id': 's', 'v': {...}}
    assert v['recursive'](d1) == (d1, None)
    assert v['recursive'](d2) == (None, 'Input.id type must be int')
    assert v['recursive_ptr'](d1) == (d1, None)
    assert v['recursive_ptr'](d2) == (None, 'Input.id type must be int')

    assert v['universe_answer'](13) == (13, None)
    assert v['universe_answer'](13.1) == (13, None)
    assert v['universe_answer'](13.1) == (13, None)
    assert v['universe_dict']({'val': 13.1}) == ({'val': 13}, None)
    assert v['universe_dict']({}) == ({'val': 123}, None)
    assert v['universe_dict_2']({'val': 13.1}) == ({'val': 13}, None)
    assert v['universe_dict_2']({}) == ({'val': 42}, None)

    assert v['rename']({}) == ({'qwe': 42}, None)
    assert v['rename']({'val': 13.1}) == ({'qwe': 13}, None)

    assert v['anyof_validate'](42) == (42, None)
    assert v['anyof_validate']({'a': 1}) == ({'a': 1}, None)
    assert v['anyof_validate']('qwe') == ('qwe', None)
    assert v['anyof_validate'](None) == (None,
            'Input must satisfy any of 3 rules:\n'
            '1: ^ type must be int\n'
            '2: ^ type must be dict\n'
            '3: ^ type must be str')
    assert v['anyof_validate']([]) == (None,
            'Input must satisfy any of 3 rules:\n'
            '1: ^ type must be int\n'
            '2: ^ type must be dict\n'
            '3: ^ type must be str')

    assert v['oneof_validate'](42) == (42, None)
    assert v['oneof_validate']({'a': 1}) == ({'a': 1}, None)
    assert v['oneof_validate']('qwe') == ('qwe', None)
    assert v['oneof_validate'](None) == (None,
            'Input must satisfy exactly one of 3 rules:\n'
            '1: ^ type must be int\n'
            '2: ^ type must be dict\n'
            '3: ^ type must be str')
    assert v['oneof_validate']([]) == (None,
            'Input must satisfy exactly one of 3 rules:\n'
            '1: ^ type must be int\n'
            '2: ^ type must be dict\n'
            '3: ^ type must be str')

    assert v['valuesrules']({'a': 'b'}) == ({'a': 'b'}, None)
    assert v['valuesrules']({'a': 1}) == (None, 'Input.a type must be str')
    assert v['valuesrules2']({'a': 'b'}) == ({'a': 'b'}, None)
    assert v['valuesrules2']({'a': 1}) == (None, 'Input.a type must be str')
コード例 #22
0
def test_self_validate():
    v = Validator(pycoercer_schema)
    assert v['obj_dict'](pycoercer_schema) == (pycoercer_schema, None)