def test_valid_document(self): "a complex document" spec = { 'text': text_type, 'tags': [text_type], 'views': int, 'comments': [ { 'time': datetime.datetime, 'text': text_type, }, ] } data = { 'text': text_type('Hello world!'), 'tags': [text_type('hello'), text_type('world')], 'views': 2, 'comments': [ { 'time': datetime.datetime(2000,1,1), 'text': text_type('Is there anybody out there?') }, { 'time': datetime.datetime.utcnow(), 'text': text_type('Yes, I am, why?') }, ], } validate(spec, data)
def test_valid_document(self): "a complex document" spec = { 'text': text_type, 'tags': [text_type], 'views': int, 'comments': [ { 'time': datetime.datetime, 'text': text_type, }, ] } data = { 'text': text_type('Hello world!'), 'tags': [text_type('hello'), text_type('world')], 'views': 2, 'comments': [ { 'time': datetime.datetime(2000, 1, 1), 'text': text_type('Is there anybody out there?') }, { 'time': datetime.datetime.utcnow(), 'text': text_type('Yes, I am, why?') }, ], } validate(spec, data)
def validate(self): try: validate(self.schema, self._data) except ValidationError as e: import pprint pprint.pprint(self.schema) pprint.pprint(self._data) raise e from None
def __init__(self, conf=None, extra=None): if not conf: conf = {} if extra: conf.update(extra) if self.needs is NotImplemented: raise NotImplementedError('{}.needs'.format(self.__class__.__name__)) merged = merge_defaults(self.needs, conf) validate(self.needs, merged) self.update(merged) self.init()
def _get_config(): conf_file_path = os.getenv(ENV_CONFIG_VAR, 'conf.yaml') with open(conf_file_path) as f: conf = yaml.load(f, Loader=yaml.Loader) validate({ 'database': dict, 'etl': dict, 'web': dict, }, conf) return conf
def _get_config(): conf_file_path = os.getenv(ENV_CONFIG_VAR, 'conf.yaml') with open(conf_file_path) as f: conf = yaml.load(f) validate({ 'storage': dict, 'etl': dict, 'web': dict, }, conf) return conf
def test_dict_in_dict(self): "A required dict nested in another required dict" spec = translate({'foo': dict}) # key is missing with raises_regexp(MissingKeys, "must have keys: 'foo'"): spec({}) # key is present, value is missing with raises_regexp(ValidationError, "'foo' value must be dict"): spec({'foo': None}) # value is present validate(spec, {'foo': {}})
def test_unknown_keys(self): # special behaviour: missing/empty inner_spec means "a dict of anything" validate(dict, {'x': 123}) # inner_spec not empty, value matches it validate({'x': None}, {'x': 123}) with raises(InvalidKeys): validate({'x': None}, {'y': 123}) with raises(InvalidKeys): validate({'x': None}, {'x': 123, 'y': 456})
def _load_object_list(self, path, model): with open(path) as f: try: items = yaml.load(f) except: print('FAILED to load', model, 'from', path) raise if not items: return for data in items: obj = model(data) try: validate(model, obj) except (ValidationError, TypeError) as e: raise type(e)('{path}: {e}'.format(path=path, e=e)) yield obj
def _dump_to_file(self, file_path, facts, create=False): if not os.path.exists(file_path): # make sure the year and month dirs are created month_dir = os.path.dirname(file_path) if not os.path.exists(month_dir): os.makedirs(month_dir) fact_ods = [] for fact in facts: # insert defaults monk.merge_defaults(models.Fact.structure, fact) # validate structure and types monk.validate(models.Fact.structure, fact) # ensure field order and stuff fact_od = _prepare_fact_for_yaml(fact) fact_ods.append(fact_od) with open(file_path, 'w') as f: yaml.dump(fact_ods, f, allow_unicode=True, default_flow_style=False)
def load_card(path, model): with open(path) as f: raw_card = yaml.load(f) card = compat.fix_strings_to_unicode(raw_card) if not card: return # populate defaults card = merge_defaults(model, card) card = DotExpandedDict(card) try: # XXX HACK card.concerns = [models.Concern(**x) for x in card.get('concerns') or []] validate(model, card) except (ValidationError, TypeError) as e: safe_path = compat.encode(path) raise type(e)('{path}: {e}'.format(path=safe_path, e=e)) return card
def test_multi_datatypes_to_datatype(self): schema = { str: int, int: int, } with raises(MissingKeys): validate(schema, {'a': 1}) with raises(MissingKeys): validate(schema, {123: 1}) validate(schema, {'a': 1, 'b': 2, 123: 4, 456: 5})
def test_datetime_instance(self): validate({'a': datetime.datetime(1900, 1, 1)}, {'a': datetime.datetime.utcnow()}) with raises(ValidationError): validate({'a': datetime.datetime}, {'a': 123})
def test_unicode_instance(self): validate({'a': text_type('foo')}, {'a': text_type('hello')}) with raises(ValidationError): validate({'a': text_type('foo')}, {'a': 123})
def test_list(self): validate({'a': list}, {'a': []}) validate({'a': list}, {'a': ['b', 123]})
def test_int(self): validate({'a': int}, {'a': 123})
def test_float(self): validate({'a': float}, {'a': .5})
def test_empty(self): # (pre-v0.13 "missing value", now None != MISSING) validate({'a': optional(text_type)}, {'a': text_type('')}) with raises(ValidationError): validate({'a': text_type}, {'a': None}) validate({'a': optional(dict)}, {'a': {}}) with raises(ValidationError): validate({'a': dict}, {'a': None}) validate({'a': optional(list)}, {'a': []}) with raises(ValidationError): validate({'a': list}, {'a': None}) validate({'a': bool}, {'a': True}) validate({'a': bool}, {'a': False}) with raises(ValidationError): validate({'a': optional(bool)}, {'a': None}) with raises(ValidationError): validate({'a': bool}, {'a': None}) # (pre-v0.13 TypeError, now everything has ValidationError as base) with raises(ValidationError): validate({'a': text_type}, {'a': False}) with raises(ValidationError): validate({'a': text_type}, {'a': 0}) with raises(ValidationError): validate({'a': bool}, {'a': ''})
def test_missing_key(self): with raises(MissingKeys): validate({str: int}, {})
def test_invalid_key(self): with raises(InvalidKeys): validate({str: int}, {'a': 1, 1: 2}) with raises(InvalidKeys): # special handling of rule.default in dict keys validate({'a': int}, {'a': 1, 'b': 5})
def test_type_error(self): #with raises(TypeError): with raises(InvalidKeys): validate({str: int}, {'a': 1, NotImplemented: 5})
def test_dbref(self): validate({'a': bson.DBRef}, {'a': bson.DBRef('a', 'b')})
def test_any_value_as_key(self): validate({None: 1}, {2: 3})
def test_nonsense(self): with raises(InvalidKeys): validate({int: str}, {int: 'foo'})
def test_dict_instance(self): validate({'a': {}}, {'a': {}}) validate({'a': {}}, {'a': {'b': 123}})
def test_objectid(self): validate({'a': bson.ObjectId}, {'a': bson.ObjectId()})
def test_float_instance(self): validate({'a': .2}, {'a': .5})
def test_int_instance(self): validate({'a': 1}, {'a': 123})
def test_list_instance(self): validate({'a': []}, {'a': []}) validate({'a': []}, {'a': ['b', 123]}) with raises_regexp(ValidationError, "'a' value lacks item: must be int"): validate({'a': [int]}, {'a': []}) validate({'a': [int]}, {'a': [123]}) validate({'a': [int]}, {'a': [123, 456]}) with raises(ValidationError): validate({'a': [int]}, {'a': ['b', 123]}) with raises(ValidationError): validate({'a': [text_type]}, {'a': [{'b': 'c'}]})
def test_datetime(self): validate({'a': datetime.datetime}, {'a': datetime.datetime.utcnow()}) with raises(ValidationError): validate({'a': datetime.datetime}, {'a': 123})
def test_callable(self): def func(): return 1 class Obj: @staticmethod def smeth(): return 1 @classmethod def cmeth(cls): return 1 def ometh(self): return 1 validate({'a': func}, {'a': 2}) validate({'a': Obj.smeth}, {'a': 2}) validate({'a': Obj.cmeth}, {'a': 2}) validate({'a': Obj().ometh}, {'a': 2}) with raises(ValidationError): validate({'a': func}, {'a': 'foo'}) with raises(ValidationError): validate({'a': Obj.smeth}, {'a': 'foo'}) with raises(ValidationError): validate({'a': Obj.cmeth}, {'a': 'foo'}) with raises(ValidationError): validate({'a': Obj().ometh}, {'a': 'foo'})
def test_bool_instance(self): validate({'a': True}, {'a': True}) validate({'a': True}, {'a': False})
def test_dict(self): validate({'a': dict}, {'a': {}}) validate({'a': dict}, {'a': {'b': 'c'}})
def test_bool(self): validate({'a': bool}, {'a': True}) validate({'a': bool}, {'a': False})
def test_unknown_keys_encoding(self): with raises(InvalidKeys): validate({'a': text_type}, {'привет': 1}) with raises(InvalidKeys): validate({'a': text_type}, {safe_unicode('привет'): 1})