test_format.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """
  2. Tests for the parts of jsonschema related to the :validator:`format` property.
  3. """
  4. from unittest import TestCase
  5. from jsonschema import FormatError, ValidationError, FormatChecker
  6. from jsonschema.validators import Draft4Validator
  7. BOOM = ValueError("Boom!")
  8. BANG = ZeroDivisionError("Bang!")
  9. def boom(thing):
  10. if thing == "bang":
  11. raise BANG
  12. raise BOOM
  13. class TestFormatChecker(TestCase):
  14. def test_it_can_validate_no_formats(self):
  15. checker = FormatChecker(formats=())
  16. self.assertFalse(checker.checkers)
  17. def test_it_raises_a_key_error_for_unknown_formats(self):
  18. with self.assertRaises(KeyError):
  19. FormatChecker(formats=["o noes"])
  20. def test_it_can_register_cls_checkers(self):
  21. original = dict(FormatChecker.checkers)
  22. self.addCleanup(FormatChecker.checkers.pop, "boom")
  23. FormatChecker.cls_checks("boom")(boom)
  24. self.assertEqual(
  25. FormatChecker.checkers,
  26. dict(original, boom=(boom, ())),
  27. )
  28. def test_it_can_register_checkers(self):
  29. checker = FormatChecker()
  30. checker.checks("boom")(boom)
  31. self.assertEqual(
  32. checker.checkers,
  33. dict(FormatChecker.checkers, boom=(boom, ()))
  34. )
  35. def test_it_catches_registered_errors(self):
  36. checker = FormatChecker()
  37. checker.checks("boom", raises=type(BOOM))(boom)
  38. with self.assertRaises(FormatError) as cm:
  39. checker.check(instance=12, format="boom")
  40. self.assertIs(cm.exception.cause, BOOM)
  41. self.assertIs(cm.exception.__cause__, BOOM)
  42. # Unregistered errors should not be caught
  43. with self.assertRaises(type(BANG)):
  44. checker.check(instance="bang", format="boom")
  45. def test_format_error_causes_become_validation_error_causes(self):
  46. checker = FormatChecker()
  47. checker.checks("boom", raises=ValueError)(boom)
  48. validator = Draft4Validator({"format": "boom"}, format_checker=checker)
  49. with self.assertRaises(ValidationError) as cm:
  50. validator.validate("BOOM")
  51. self.assertIs(cm.exception.cause, BOOM)
  52. self.assertIs(cm.exception.__cause__, BOOM)
  53. def test_format_checkers_come_with_defaults(self):
  54. # This is bad :/ but relied upon.
  55. # The docs for quite awhile recommended people do things like
  56. # validate(..., format_checker=FormatChecker())
  57. # We should change that, but we can't without deprecation...
  58. checker = FormatChecker()
  59. with self.assertRaises(FormatError):
  60. checker.check(instance="not-an-ipv4", format="ipv4")
  61. def test_repr(self):
  62. checker = FormatChecker(formats=())
  63. checker.checks("foo")(lambda thing: True)
  64. checker.checks("bar")(lambda thing: True)
  65. checker.checks("baz")(lambda thing: True)
  66. self.assertEqual(
  67. repr(checker),
  68. "<FormatChecker checkers=['bar', 'baz', 'foo']>",
  69. )