diff --git a/fastjsonschema/draft04.py b/fastjsonschema/draft04.py index 7dd097e..c5c7752 100644 --- a/fastjsonschema/draft04.py +++ b/fastjsonschema/draft04.py @@ -158,7 +158,7 @@ def generate_any_of(self): self.l('except JsonSchemaValueException: pass') with self.l('if not {variable}_any_of_count{count}:', count=count, optimize=False): - self.exc('{name} must be valid by one of anyOf definition', rule='anyOf') + self.exc('{name} cannot be validated by any definition', rule='anyOf') def generate_one_of(self): """ @@ -188,7 +188,8 @@ def generate_one_of(self): self.l('except JsonSchemaValueException: pass') with self.l('if {variable}_one_of_count{count} != 1:', count=count): - self.exc('{name} must be valid exactly by one of oneOf definition', rule='oneOf') + dynamic = '" (" + str({variable}_one_of_count{}) + " matches found)"' + self.exc('{name} must be valid exactly by one definition', count, append_to_msg=dynamic, rule='oneOf') def generate_not(self): """ diff --git a/fastjsonschema/generator.py b/fastjsonschema/generator.py index 5e08030..331fb51 100644 --- a/fastjsonschema/generator.py +++ b/fastjsonschema/generator.py @@ -247,11 +247,14 @@ def e(self, string): """ return str(string).replace('"', '\\"') - def exc(self, msg, *args, rule=None): + def exc(self, msg, *args, append_to_msg=None, rule=None): """ Short-cut for creating raising exception in the code. """ - msg = 'raise JsonSchemaValueException("'+msg+'", value={variable}, name="{name}", definition={definition}, rule={rule})' + arg = '"'+msg+'"' + if append_to_msg: + arg += ' + (' + append_to_msg + ')' + msg = 'raise JsonSchemaValueException('+arg+', value={variable}, name="{name}", definition={definition}, rule={rule})' definition = self._expand_refs(self._definition) definition_rule = self.e(definition.get(rule) if isinstance(definition, dict) else None) self.l(msg, *args, definition=repr(definition), rule=repr(rule), definition_rule=definition_rule) diff --git a/tests/test_common.py b/tests/test_common.py index faca524..4134345 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -39,7 +39,7 @@ def test_all_of(asserter, value, expected): ]}, value, expected) -exc = JsonSchemaValueException('data must be valid by one of anyOf definition', value='{data}', name='data', definition='{definition}', rule='anyOf') +exc = JsonSchemaValueException('data cannot be validated by any definition', value='{data}', name='data', definition='{definition}', rule='anyOf') @pytest.mark.parametrize('value, expected', [ (0, 0), (None, exc), @@ -55,13 +55,16 @@ def test_any_of(asserter, value, expected): ]}, value, expected) -exc = JsonSchemaValueException('data must be valid exactly by one of oneOf definition', value='{data}', name='data', definition='{definition}', rule='oneOf') +def exc(n): + suffix = " ({} matches found)".format(n) + return JsonSchemaValueException('data must be valid exactly by one definition' + suffix, value='{data}', name='data', definition='{definition}', rule='oneOf') + @pytest.mark.parametrize('value, expected', [ - (0, exc), - (2, exc), + (0, exc(2)), + (2, exc(0)), (9, 9), (10, 10), - (15, exc), + (15, exc(2)), ]) def test_one_of(asserter, value, expected): asserter({'oneOf': [ @@ -70,13 +73,12 @@ def test_one_of(asserter, value, expected): ]}, value, expected) -exc = JsonSchemaValueException('data must be valid exactly by one of oneOf definition', value='{data}', name='data', definition='{definition}', rule='oneOf') @pytest.mark.parametrize('value, expected', [ - (0, exc), - (2, exc), + (0, exc(2)), + (2, exc(0)), (9, 9), (10, 10), - (15, exc), + (15, exc(2)), ]) def test_one_of_factorized(asserter, value, expected): asserter({ diff --git a/tests/test_integration.py b/tests/test_integration.py index 8145fd6..c95923d 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -98,7 +98,7 @@ ), ( [9, 'hello', [1], {'a': 'a', 'b': 'b', 'x': 'x'}, 42, 15], - JsonSchemaValueException('data[5] must be valid exactly by one of oneOf definition', value=15, name='data[5]', definition=definition['items'][5], rule='oneOf'), + JsonSchemaValueException('data[5] must be valid exactly by one definition (2 matches found)', value=15, name='data[5]', definition=definition['items'][5], rule='oneOf'), ), ]) def test_integration(asserter, value, expected):