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)), ])
def test_opt_key__py2_unicode(self): raw = { opt_key(unicode('foo')): int, } assert translate(raw) == DictOf([ (Equals(unicode('foo')) | ~Exists(), IsA(int)), ])
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)), ])
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
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
def test_regression_22(): ~Anything() ~IsA(str) ~Equals(5) ~Contains('x') ~InRange(5) ~Length(5) ~ListOf(str) ~DictOf([]) ~Exists()
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({})
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})
def test_dict(self): assert translate(dict) == IsA(dict) assert translate({'foo': 123}) == DictOf([ (Equals('foo'), IsA(int, default=123)), ])
def test_rule_as_key(self): spec_a = DictOf([(IsA(str), IsA(int))]) spec_b = DictOf([(IsA(str) | ~Exists(), IsA(int))]) assert spec_a.get_default_for({}) == {} assert spec_b.get_default_for({}) == {}
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