Blame tools/extra/packager/jsonschema-2.3.0/jsonschema/tests/test_exceptions.py

Packit 534379
from jsonschema import Draft4Validator, exceptions
Packit 534379
from jsonschema.tests.compat import mock, unittest
Packit 534379
Packit 534379
Packit 534379
class TestBestMatch(unittest.TestCase):
Packit 534379
    def best_match(self, errors):
Packit 534379
        errors = list(errors)
Packit 534379
        best = exceptions.best_match(errors)
Packit 534379
        reversed_best = exceptions.best_match(reversed(errors))
Packit 534379
        self.assertEqual(
Packit 534379
            best,
Packit 534379
            reversed_best,
Packit 534379
            msg="Didn't return a consistent best match!\n"
Packit 534379
                "Got: {0}\n\nThen: {1}".format(best, reversed_best),
Packit 534379
        )
Packit 534379
        return best
Packit 534379
Packit 534379
    def test_shallower_errors_are_better_matches(self):
Packit 534379
        validator = Draft4Validator(
Packit 534379
            {
Packit 534379
                "properties": {
Packit 534379
                    "foo": {
Packit 534379
                        "minProperties": 2,
Packit 534379
                        "properties": {"bar": {"type": "object"}},
Packit 534379
                    }
Packit 534379
                }
Packit 534379
            }
Packit 534379
        )
Packit 534379
        best = self.best_match(validator.iter_errors({"foo": {"bar": []}}))
Packit 534379
        self.assertEqual(best.validator, "minProperties")
Packit 534379
Packit 534379
    def test_oneOf_and_anyOf_are_weak_matches(self):
Packit 534379
        """
Packit 534379
        A property you *must* match is probably better than one you have to
Packit 534379
        match a part of.
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        validator = Draft4Validator(
Packit 534379
            {
Packit 534379
                "minProperties": 2,
Packit 534379
                "anyOf": [{"type": "string"}, {"type": "number"}],
Packit 534379
                "oneOf": [{"type": "string"}, {"type": "number"}],
Packit 534379
            }
Packit 534379
        )
Packit 534379
        best = self.best_match(validator.iter_errors({}))
Packit 534379
        self.assertEqual(best.validator, "minProperties")
Packit 534379
Packit 534379
    def test_if_the_most_relevant_error_is_anyOf_it_is_traversed(self):
Packit 534379
        """
Packit 534379
        If the most relevant error is an anyOf, then we traverse its context
Packit 534379
        and select the otherwise *least* relevant error, since in this case
Packit 534379
        that means the most specific, deep, error inside the instance.
Packit 534379
Packit 534379
        I.e. since only one of the schemas must match, we look for the most
Packit 534379
        relevant one.
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        validator = Draft4Validator(
Packit 534379
            {
Packit 534379
                "properties": {
Packit 534379
                    "foo": {
Packit 534379
                        "anyOf": [
Packit 534379
                            {"type": "string"},
Packit 534379
                            {"properties": {"bar": {"type": "array"}}},
Packit 534379
                        ],
Packit 534379
                    },
Packit 534379
                },
Packit 534379
            },
Packit 534379
        )
Packit 534379
        best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
Packit 534379
        self.assertEqual(best.validator_value, "array")
Packit 534379
Packit 534379
    def test_if_the_most_relevant_error_is_oneOf_it_is_traversed(self):
Packit 534379
        """
Packit 534379
        If the most relevant error is an oneOf, then we traverse its context
Packit 534379
        and select the otherwise *least* relevant error, since in this case
Packit 534379
        that means the most specific, deep, error inside the instance.
Packit 534379
Packit 534379
        I.e. since only one of the schemas must match, we look for the most
Packit 534379
        relevant one.
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        validator = Draft4Validator(
Packit 534379
            {
Packit 534379
                "properties": {
Packit 534379
                    "foo": {
Packit 534379
                        "oneOf": [
Packit 534379
                            {"type": "string"},
Packit 534379
                            {"properties": {"bar": {"type": "array"}}},
Packit 534379
                        ],
Packit 534379
                    },
Packit 534379
                },
Packit 534379
            },
Packit 534379
        )
Packit 534379
        best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
Packit 534379
        self.assertEqual(best.validator_value, "array")
Packit 534379
Packit 534379
    def test_if_the_most_relevant_error_is_allOf_it_is_traversed(self):
Packit 534379
        """
Packit 534379
        Now, if the error is allOf, we traverse but select the *most* relevant
Packit 534379
        error from the context, because all schemas here must match anyways.
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        validator = Draft4Validator(
Packit 534379
            {
Packit 534379
                "properties": {
Packit 534379
                    "foo": {
Packit 534379
                        "allOf": [
Packit 534379
                            {"type": "string"},
Packit 534379
                            {"properties": {"bar": {"type": "array"}}},
Packit 534379
                        ],
Packit 534379
                    },
Packit 534379
                },
Packit 534379
            },
Packit 534379
        )
Packit 534379
        best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
Packit 534379
        self.assertEqual(best.validator_value, "string")
Packit 534379
Packit 534379
    def test_nested_context_for_oneOf(self):
Packit 534379
        validator = Draft4Validator(
Packit 534379
            {
Packit 534379
                "properties": {
Packit 534379
                    "foo": {
Packit 534379
                        "oneOf": [
Packit 534379
                            {"type": "string"},
Packit 534379
                            {
Packit 534379
                                "oneOf": [
Packit 534379
                                    {"type": "string"},
Packit 534379
                                    {
Packit 534379
                                        "properties": {
Packit 534379
                                            "bar": {"type": "array"}
Packit 534379
                                        },
Packit 534379
                                    },
Packit 534379
                                ],
Packit 534379
                            },
Packit 534379
                        ],
Packit 534379
                    },
Packit 534379
                },
Packit 534379
            },
Packit 534379
        )
Packit 534379
        best = self.best_match(validator.iter_errors({"foo": {"bar": 12}}))
Packit 534379
        self.assertEqual(best.validator_value, "array")
Packit 534379
Packit 534379
    def test_one_error(self):
Packit 534379
        validator = Draft4Validator({"minProperties": 2})
Packit 534379
        error, = validator.iter_errors({})
Packit 534379
        self.assertEqual(
Packit 534379
            exceptions.best_match(validator.iter_errors({})).validator,
Packit 534379
            "minProperties",
Packit 534379
        )
Packit 534379
Packit 534379
    def test_no_errors(self):
Packit 534379
        validator = Draft4Validator({})
Packit 534379
        self.assertIsNone(exceptions.best_match(validator.iter_errors({})))
Packit 534379
Packit 534379
Packit 534379
class TestByRelevance(unittest.TestCase):
Packit 534379
    def test_short_paths_are_better_matches(self):
Packit 534379
        shallow = exceptions.ValidationError("Oh no!", path=["baz"])
Packit 534379
        deep = exceptions.ValidationError("Oh yes!", path=["foo", "bar"])
Packit 534379
        match = max([shallow, deep], key=exceptions.by_relevance())
Packit 534379
        self.assertIs(match, shallow)
Packit 534379
Packit 534379
        match = max([deep, shallow], key=exceptions.by_relevance())
Packit 534379
        self.assertIs(match, shallow)
Packit 534379
Packit 534379
    def test_global_errors_are_even_better_matches(self):
Packit 534379
        shallow = exceptions.ValidationError("Oh no!", path=[])
Packit 534379
        deep = exceptions.ValidationError("Oh yes!", path=["foo"])
Packit 534379
Packit 534379
        errors = sorted([shallow, deep], key=exceptions.by_relevance())
Packit 534379
        self.assertEqual(
Packit 534379
            [list(error.path) for error in errors],
Packit 534379
            [["foo"], []],
Packit 534379
        )
Packit 534379
Packit 534379
        errors = sorted([deep, shallow], key=exceptions.by_relevance())
Packit 534379
        self.assertEqual(
Packit 534379
            [list(error.path) for error in errors],
Packit 534379
            [["foo"], []],
Packit 534379
        )
Packit 534379
Packit 534379
    def test_weak_validators_are_lower_priority(self):
Packit 534379
        weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
Packit 534379
        normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
Packit 534379
Packit 534379
        best_match = exceptions.by_relevance(weak="a")
Packit 534379
Packit 534379
        match = max([weak, normal], key=best_match)
Packit 534379
        self.assertIs(match, normal)
Packit 534379
Packit 534379
        match = max([normal, weak], key=best_match)
Packit 534379
        self.assertIs(match, normal)
Packit 534379
Packit 534379
    def test_strong_validators_are_higher_priority(self):
Packit 534379
        weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
Packit 534379
        normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
Packit 534379
        strong = exceptions.ValidationError("Oh fine!", path=[], validator="c")
Packit 534379
Packit 534379
        best_match = exceptions.by_relevance(weak="a", strong="c")
Packit 534379
Packit 534379
        match = max([weak, normal, strong], key=best_match)
Packit 534379
        self.assertIs(match, strong)
Packit 534379
Packit 534379
        match = max([strong, normal, weak], key=best_match)
Packit 534379
        self.assertIs(match, strong)
Packit 534379
Packit 534379
Packit 534379
class TestErrorTree(unittest.TestCase):
Packit 534379
    def test_it_knows_how_many_total_errors_it_contains(self):
Packit 534379
        errors = [mock.MagicMock() for _ in range(8)]
Packit 534379
        tree = exceptions.ErrorTree(errors)
Packit 534379
        self.assertEqual(tree.total_errors, 8)
Packit 534379
Packit 534379
    def test_it_contains_an_item_if_the_item_had_an_error(self):
Packit 534379
        errors = [exceptions.ValidationError("a message", path=["bar"])]
Packit 534379
        tree = exceptions.ErrorTree(errors)
Packit 534379
        self.assertIn("bar", tree)
Packit 534379
Packit 534379
    def test_it_does_not_contain_an_item_if_the_item_had_no_error(self):
Packit 534379
        errors = [exceptions.ValidationError("a message", path=["bar"])]
Packit 534379
        tree = exceptions.ErrorTree(errors)
Packit 534379
        self.assertNotIn("foo", tree)
Packit 534379
Packit 534379
    def test_validators_that_failed_appear_in_errors_dict(self):
Packit 534379
        error = exceptions.ValidationError("a message", validator="foo")
Packit 534379
        tree = exceptions.ErrorTree([error])
Packit 534379
        self.assertEqual(tree.errors, {"foo": error})
Packit 534379
Packit 534379
    def test_it_creates_a_child_tree_for_each_nested_path(self):
Packit 534379
        errors = [
Packit 534379
            exceptions.ValidationError("a bar message", path=["bar"]),
Packit 534379
            exceptions.ValidationError("a bar -> 0 message", path=["bar", 0]),
Packit 534379
        ]
Packit 534379
        tree = exceptions.ErrorTree(errors)
Packit 534379
        self.assertIn(0, tree["bar"])
Packit 534379
        self.assertNotIn(1, tree["bar"])
Packit 534379
Packit 534379
    def test_children_have_their_errors_dicts_built(self):
Packit 534379
        e1, e2 = (
Packit 534379
            exceptions.ValidationError("1", validator="foo", path=["bar", 0]),
Packit 534379
            exceptions.ValidationError("2", validator="quux", path=["bar", 0]),
Packit 534379
        )
Packit 534379
        tree = exceptions.ErrorTree([e1, e2])
Packit 534379
        self.assertEqual(tree["bar"][0].errors, {"foo": e1, "quux": e2})
Packit 534379
Packit 534379
    def test_it_does_not_contain_subtrees_that_are_not_in_the_instance(self):
Packit 534379
        error = exceptions.ValidationError("123", validator="foo", instance=[])
Packit 534379
        tree = exceptions.ErrorTree([error])
Packit 534379
Packit 534379
        with self.assertRaises(IndexError):
Packit 534379
            tree[0]
Packit 534379
Packit 534379
    def test_if_its_in_the_tree_anyhow_it_does_not_raise_an_error(self):
Packit 534379
        """
Packit 534379
        If a validator is dumb (like:validator:`required` in draft 3) and
Packit 534379
        refers to a path that isn't in the instance, the tree still properly
Packit 534379
        returns a subtree for that path.
Packit 534379
Packit 534379
        """
Packit 534379
Packit 534379
        error = exceptions.ValidationError(
Packit 534379
            "a message", validator="foo", instance={}, path=["foo"],
Packit 534379
        )
Packit 534379
        tree = exceptions.ErrorTree([error])
Packit 534379
        self.assertIsInstance(tree["foo"], exceptions.ErrorTree)