test_errors.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. # -*- coding: utf-8 -*-
  2. from cerberus import Validator, errors
  3. from cerberus.tests import assert_fail
  4. ValidationError = errors.ValidationError
  5. def test__error_1():
  6. v = Validator(schema={'foo': {'type': 'string'}})
  7. v.document = {'foo': 42}
  8. v._error('foo', errors.BAD_TYPE, 'string')
  9. error = v._errors[0]
  10. assert error.document_path == ('foo',)
  11. assert error.schema_path == ('foo', 'type')
  12. assert error.code == 0x24
  13. assert error.rule == 'type'
  14. assert error.constraint == 'string'
  15. assert error.value == 42
  16. assert error.info == ('string',)
  17. assert not error.is_group_error
  18. assert not error.is_logic_error
  19. def test__error_2():
  20. v = Validator(schema={'foo': {'keyschema': {'type': 'integer'}}})
  21. v.document = {'foo': {'0': 'bar'}}
  22. v._error('foo', errors.KEYSCHEMA, ())
  23. error = v._errors[0]
  24. assert error.document_path == ('foo',)
  25. assert error.schema_path == ('foo', 'keyschema')
  26. assert error.code == 0x83
  27. assert error.rule == 'keyschema'
  28. assert error.constraint == {'type': 'integer'}
  29. assert error.value == {'0': 'bar'}
  30. assert error.info == ((),)
  31. assert error.is_group_error
  32. assert not error.is_logic_error
  33. def test__error_3():
  34. valids = [{'type': 'string', 'regex': '0x[0-9a-f]{2}'},
  35. {'type': 'integer', 'min': 0, 'max': 255}]
  36. v = Validator(schema={'foo': {'oneof': valids}})
  37. v.document = {'foo': '0x100'}
  38. v._error('foo', errors.ONEOF, (), 0, 2)
  39. error = v._errors[0]
  40. assert error.document_path == ('foo',)
  41. assert error.schema_path == ('foo', 'oneof')
  42. assert error.code == 0x92
  43. assert error.rule == 'oneof'
  44. assert error.constraint == valids
  45. assert error.value == '0x100'
  46. assert error.info == ((), 0, 2)
  47. assert error.is_group_error
  48. assert error.is_logic_error
  49. def test_error_tree_from_subschema(validator):
  50. schema = {'foo': {'schema': {'bar': {'type': 'string'}}}}
  51. document = {'foo': {'bar': 0}}
  52. assert_fail(document, schema, validator=validator)
  53. d_error_tree = validator.document_error_tree
  54. s_error_tree = validator.schema_error_tree
  55. assert 'foo' in d_error_tree
  56. assert len(d_error_tree['foo'].errors) == 1, d_error_tree['foo']
  57. assert d_error_tree['foo'].errors[0].code == errors.MAPPING_SCHEMA.code
  58. assert 'bar' in d_error_tree['foo']
  59. assert d_error_tree['foo']['bar'].errors[0].value == 0
  60. assert d_error_tree.fetch_errors_from(('foo', 'bar'))[0].value == 0
  61. assert 'foo' in s_error_tree
  62. assert 'schema' in s_error_tree['foo']
  63. assert 'bar' in s_error_tree['foo']['schema']
  64. assert 'type' in s_error_tree['foo']['schema']['bar']
  65. assert s_error_tree['foo']['schema']['bar']['type'].errors[0].value == 0
  66. assert s_error_tree.fetch_errors_from(
  67. ('foo', 'schema', 'bar', 'type'))[0].value == 0
  68. def test_error_tree_from_anyof(validator):
  69. schema = {'foo': {'anyof': [{'type': 'string'}, {'type': 'integer'}]}}
  70. document = {'foo': []}
  71. assert_fail(document, schema, validator=validator)
  72. d_error_tree = validator.document_error_tree
  73. s_error_tree = validator.schema_error_tree
  74. assert 'foo' in d_error_tree
  75. assert d_error_tree['foo'].errors[0].value == []
  76. assert 'foo' in s_error_tree
  77. assert 'anyof' in s_error_tree['foo']
  78. assert 0 in s_error_tree['foo']['anyof']
  79. assert 1 in s_error_tree['foo']['anyof']
  80. assert 'type' in s_error_tree['foo']['anyof'][0]
  81. assert s_error_tree['foo']['anyof'][0]['type'].errors[0].value == []
  82. def test_nested_error_paths(validator):
  83. schema = {'a_dict': {'keyschema': {'type': 'integer'},
  84. 'valueschema': {'regex': '[a-z]*'}},
  85. 'a_list': {'schema': {'type': 'string',
  86. 'oneof_regex': ['[a-z]*$', '[A-Z]*']}}}
  87. document = {'a_dict': {0: 'abc', 'one': 'abc', 2: 'aBc', 'three': 'abC'},
  88. 'a_list': [0, 'abc', 'abC']}
  89. assert_fail(document, schema, validator=validator)
  90. _det = validator.document_error_tree
  91. _set = validator.schema_error_tree
  92. assert len(_det.errors) == 0
  93. assert len(_set.errors) == 0
  94. assert len(_det['a_dict'].errors) == 2
  95. assert len(_set['a_dict'].errors) == 0
  96. assert _det['a_dict'][0] is None
  97. assert len(_det['a_dict']['one'].errors) == 1
  98. assert len(_det['a_dict'][2].errors) == 1
  99. assert len(_det['a_dict']['three'].errors) == 2
  100. assert len(_set['a_dict']['keyschema'].errors) == 1
  101. assert len(_set['a_dict']['valueschema'].errors) == 1
  102. assert len(_set['a_dict']['keyschema']['type'].errors) == 2
  103. assert len(_set['a_dict']['valueschema']['regex'].errors) == 2
  104. _ref_err = ValidationError(
  105. ('a_dict', 'one'), ('a_dict', 'keyschema', 'type'),
  106. errors.BAD_TYPE.code, 'type', 'integer', 'one', ())
  107. assert _det['a_dict']['one'].errors[0] == _ref_err
  108. assert _set['a_dict']['keyschema']['type'].errors[0] == _ref_err
  109. _ref_err = ValidationError(
  110. ('a_dict', 2), ('a_dict', 'valueschema', 'regex'),
  111. errors.REGEX_MISMATCH.code, 'regex', '[a-z]*$', 'aBc', ())
  112. assert _det['a_dict'][2].errors[0] == _ref_err
  113. assert _set['a_dict']['valueschema']['regex'].errors[0] == _ref_err
  114. _ref_err = ValidationError(
  115. ('a_dict', 'three'), ('a_dict', 'keyschema', 'type'),
  116. errors.BAD_TYPE.code, 'type', 'integer', 'three', ())
  117. assert _det['a_dict']['three'].errors[0] == _ref_err
  118. assert _set['a_dict']['keyschema']['type'].errors[1] == _ref_err
  119. _ref_err = ValidationError(
  120. ('a_dict', 'three'), ('a_dict', 'valueschema', 'regex'),
  121. errors.REGEX_MISMATCH.code, 'regex', '[a-z]*$', 'abC', ())
  122. assert _det['a_dict']['three'].errors[1] == _ref_err
  123. assert _set['a_dict']['valueschema']['regex'].errors[1] == _ref_err
  124. assert len(_det['a_list'].errors) == 1
  125. assert len(_det['a_list'][0].errors) == 1
  126. assert _det['a_list'][1] is None
  127. assert len(_det['a_list'][2].errors) == 3
  128. assert len(_set['a_list'].errors) == 0
  129. assert len(_set['a_list']['schema'].errors) == 1
  130. assert len(_set['a_list']['schema']['type'].errors) == 1
  131. assert len(_set['a_list']['schema']['oneof'][0]['regex'].errors) == 1
  132. assert len(_set['a_list']['schema']['oneof'][1]['regex'].errors) == 1
  133. _ref_err = ValidationError(
  134. ('a_list', 0), ('a_list', 'schema', 'type'), errors.BAD_TYPE.code,
  135. 'type', 'string', 0, ())
  136. assert _det['a_list'][0].errors[0] == _ref_err
  137. assert _set['a_list']['schema']['type'].errors[0] == _ref_err
  138. _ref_err = ValidationError(
  139. ('a_list', 2), ('a_list', 'schema', 'oneof'), errors.ONEOF.code,
  140. 'oneof', 'irrelevant_at_this_point', 'abC', ())
  141. assert _det['a_list'][2].errors[0] == _ref_err
  142. assert _set['a_list']['schema']['oneof'].errors[0] == _ref_err
  143. _ref_err = ValidationError(
  144. ('a_list', 2), ('a_list', 'schema', 'oneof', 0, 'regex'),
  145. errors.REGEX_MISMATCH.code, 'regex', '[a-z]*$', 'abC', ())
  146. assert _det['a_list'][2].errors[1] == _ref_err
  147. assert _set['a_list']['schema']['oneof'][0]['regex'].errors[0] == _ref_err
  148. _ref_err = ValidationError(
  149. ('a_list', 2), ('a_list', 'schema', 'oneof', 1, 'regex'),
  150. errors.REGEX_MISMATCH.code, 'regex', '[a-z]*$', 'abC', ())
  151. assert _det['a_list'][2].errors[2] == _ref_err
  152. assert _set['a_list']['schema']['oneof'][1]['regex'].errors[0] == _ref_err
  153. def test_queries():
  154. schema = {'foo': {'type': 'dict',
  155. 'schema':
  156. {'bar': {'type': 'number'}}}}
  157. document = {'foo': {'bar': 'zero'}}
  158. validator = Validator(schema)
  159. validator(document)
  160. assert 'foo' in validator.document_error_tree
  161. assert 'bar' in validator.document_error_tree['foo']
  162. assert 'foo' in validator.schema_error_tree
  163. assert 'schema' in validator.schema_error_tree['foo']
  164. assert errors.MAPPING_SCHEMA in validator.document_error_tree['foo'].errors
  165. assert errors.MAPPING_SCHEMA in validator.document_error_tree['foo']
  166. assert errors.BAD_TYPE in validator.document_error_tree['foo']['bar']
  167. assert errors.MAPPING_SCHEMA in validator.schema_error_tree['foo']['schema']
  168. assert errors.BAD_TYPE in \
  169. validator.schema_error_tree['foo']['schema']['bar']['type']
  170. assert (validator.document_error_tree['foo'][errors.MAPPING_SCHEMA]
  171. .child_errors[0].code == errors.BAD_TYPE.code)
  172. def test_basic_error_handler():
  173. handler = errors.BasicErrorHandler()
  174. _errors, ref = [], {}
  175. _errors.append(ValidationError(
  176. ['foo'], ['foo'], 0x63, 'readonly', True, None, ()))
  177. ref.update({'foo': [handler.messages[0x63]]})
  178. assert handler(_errors) == ref
  179. _errors.append(ValidationError(
  180. ['bar'], ['foo'], 0x42, 'min', 1, 2, ()))
  181. ref.update({'bar': [handler.messages[0x42].format(constraint=1)]})
  182. assert handler(_errors) == ref
  183. _errors.append(ValidationError(
  184. ['zap', 'foo'], ['zap', 'schema', 'foo'], 0x24, 'type', 'string',
  185. True, ()))
  186. ref.update({'zap': [{'foo': [handler.messages[0x24].format(
  187. constraint='string')]}]})
  188. assert handler(_errors) == ref
  189. _errors.append(ValidationError(
  190. ['zap', 'foo'], ['zap', 'schema', 'foo'], 0x41, 'regex',
  191. '^p[äe]ng$', 'boom', ()))
  192. ref['zap'][0]['foo'].append(
  193. handler.messages[0x41].format(constraint='^p[äe]ng$'))
  194. assert handler(_errors) == ref
  195. def test_basic_error_of_errors(validator):
  196. schema = {'foo': {'oneof': [
  197. {'type': 'integer'},
  198. {'type': 'string'}
  199. ]}}
  200. document = {'foo': 23.42}
  201. error = ('foo', ('foo', 'oneof'), errors.ONEOF,
  202. schema['foo']['oneof'], ())
  203. child_errors = [
  204. (error[0], error[1] + (0, 'type'), errors.BAD_TYPE, 'integer'),
  205. (error[0], error[1] + (1, 'type'), errors.BAD_TYPE, 'string')
  206. ]
  207. assert_fail(document, schema, validator=validator,
  208. error=error, child_errors=child_errors)
  209. assert validator.errors == {
  210. 'foo': [errors.BasicErrorHandler.messages[0x92],
  211. {'oneof definition 0': ['must be of integer type'],
  212. 'oneof definition 1': ['must be of string type']}
  213. ]
  214. }