diff --git a/json/tests/draft4/meta/meta.json b/json/tests/draft4/meta/meta.json new file mode 100644 index 000000000..3774bf871 --- /dev/null +++ b/json/tests/draft4/meta/meta.json @@ -0,0 +1,782 @@ +[ + { + "description": "Any type - invalid type", + "tests": [ + { + "description": "is float", + "schema": { + "type": "float" + } + }, + { + "description": "contains duplicate", + "schema": { + "type": [ + "null", + "null" + ] + } + } + ] + }, + { + "description": "Any type - invalid enum", + "tests": [ + { + "description": "not array", + "schema": { + "enum": "not_an_array" + } + }, + { + "description": "empty array", + "schema": { + "enum": [] + } + }, + { + "description": "contains duplicate", + "schema": { + "enum": [ + "not_unique", + "not_unique" + ] + } + } + ] + }, + { + "description": "Any type - invalid allOf", + "tests": [ + { + "description": "not array", + "schema": { + "allOf": "not_an_array" + } + }, + { + "description": "empty array", + "schema": { + "allOf": [] + } + }, + { + "description": "not a schema", + "schema": { + "allOf": [ + "not a schema" + ] + } + } + ] + }, + { + "description": "Any type - invalid anyOf", + "tests": [ + { + "description": "not array", + "schema": { + "anyOf": "not_an_array" + } + }, + { + "description": "empty array", + "schema": { + "anyOf": [] + } + }, + { + "description": "not a schema", + "schema": { + "anyOf": [ + "not a schema" + ] + } + } + ] + }, + { + "description": "Any type - invalid oneOf", + "tests": [ + { + "description": "not array", + "schema": { + "oneOf": "not_an_array" + } + }, + { + "description": "empty array", + "schema": { + "oneOf": [] + } + }, + { + "description": "not a schema", + "schema": { + "oneOf": [ + "not a schema" + ] + } + } + ] + }, + { + "description": "Any type - invalid not", + "tests": [ + { + "description": "not a schema", + "schema": { + "not": [ + "not a schema" + ] + } + } + ] + }, + { + "description": "Numeric - invalid multipleOf", + "tests": [ + { + "description": "is string not number", + "schema": { + "multipleOf": "one" + } + }, + { + "description": "is null not number", + "schema": { + "multipleOf": null + } + }, + { + "description": "is array not number", + "schema": { + "multipleOf": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "multipleOf": {} + } + }, + { + "description": "is not greater than zero", + "schema": { + "multipleOf": 0 + } + } + ] + }, + { + "description": "Numeric - invalid maximum", + "tests": [ + { + "description": "is string not number", + "schema": { + "maximum": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "maximum": true + } + }, + { + "description": "is array not number", + "schema": { + "maximum": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "maximum": {} + } + }, + { + "description": "is null not number", + "schema": { + "maximum": null + } + } + ] + }, + { + "description": "Numeric - invalid exclusiveMaximum", + "tests": [ + { + "description": "is string not number", + "schema": { + "exclusiveMaximum": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "exclusiveMaximum": true + } + }, + { + "description": "is array not number", + "schema": { + "exclusiveMaximum": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "exclusiveMaximum": {} + } + }, + { + "description": "is null not number", + "schema": { + "exclusiveMaximum": null + } + } + ] + }, + { + "description": "Numeric - invalid minimum", + "tests": [ + { + "description": "is string not number", + "schema": { + "minimum": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "minimum": true + } + }, + { + "description": "is array not number", + "schema": { + "minimum": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "minimum": {} + } + }, + { + "description": "is null not number", + "schema": { + "minimum": null + } + } + ] + }, + { + "description": "Numeric - invalid exclusiveMinimum", + "tests": [ + { + "description": "is string not number", + "schema": { + "exclusiveMinimum": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "exclusiveMinimum": true + } + }, + { + "description": "is array not number", + "schema": { + "exclusiveMinimum": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "exclusiveMinimum": {} + } + }, + { + "description": "is null not number", + "schema": { + "exclusiveMinimum": null + } + } + ] + }, + { + "description": "String - invalid maxLength", + "tests": [ + { + "description": "is string not number", + "schema": { + "maxLength": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "maxLength": true + } + }, + { + "description": "is array not number", + "schema": { + "maxLength": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "maxLength": {} + } + }, + { + "description": "is null not number", + "schema": { + "maxLength": null + } + }, + { + "description": "is decimal not integer", + "schema": { + "maxLength": 1.5 + } + }, + { + "description": "is negative", + "schema": { + "maxLength": -1 + } + } + ] + }, + { + "description": "String - invalid minLength", + "tests": [ + { + "description": "is string not number", + "schema": { + "minLength": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "minLength": true + } + }, + { + "description": "is array not number", + "schema": { + "minLength": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "minLength": {} + } + }, + { + "description": "is null not number", + "schema": { + "minLength": null + } + }, + { + "description": "is decimal not integer", + "schema": { + "maxLength": 1.5 + } + }, + { + "description": "is negative", + "schema": { + "maxLength": -1 + } + } + ] + }, + { + "description": "Array - invalid items", + "tests": [ + { + "description": "not a schema", + "schema": { + "items": "not a schema" + } + } + ] + }, + { + "description": "Array - invalid additionalItems", + "tests": [ + { + "description": "not a schema", + "schema": { + "additionalItems": "not a schema" + } + } + ] + }, + { + "description": "Array - invalid maxItems", + "tests": [ + { + "description": "is string not number", + "schema": { + "maxItems": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "maxItems": true + } + }, + { + "description": "is array not number", + "schema": { + "maxItems": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "maxItems": {} + } + }, + { + "description": "is null not number", + "schema": { + "maxItems": null + } + }, + { + "description": "is decimal not integer", + "schema": { + "maxItems": 1.5 + } + }, + { + "description": "is negative", + "schema": { + "maxItems": -1 + } + } + ] + }, + { + "description": "Array - invalid minItems", + "tests": [ + { + "description": "is string not number", + "schema": { + "minItems": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "minItems": true + } + }, + { + "description": "is array not number", + "schema": { + "minItems": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "minItems": {} + } + }, + { + "description": "is null not number", + "schema": { + "minItems": null + } + }, + { + "description": "is decimal not integer", + "schema": { + "minItems": 1.5 + } + }, + { + "description": "is negative", + "schema": { + "minItems": -1 + } + } + ] + }, + { + "description": "Array - invalid uniqueItems", + "tests": [ + { + "description": "is string not boolean", + "schema": { + "uniqueItems": "one" + } + }, + { + "description": "is number not boolean", + "schema": { + "uniqueItems": 1 + } + }, + { + "description": "is array not boolean", + "schema": { + "uniqueItems": [ + true + ] + } + }, + { + "description": "is object not boolean", + "schema": { + "uniqueItems": {} + } + }, + { + "description": "is null not boolean", + "schema": { + "uniqueItems": null + } + } + ] + }, + { + "description": "Object - invalid maxProperties", + "tests": [ + { + "description": "is string not number", + "schema": { + "maxProperties": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "maxProperties": true + } + }, + { + "description": "is array not number", + "schema": { + "maxProperties": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "maxProperties": {} + } + }, + { + "description": "is null not number", + "schema": { + "maxProperties": null + } + }, + { + "description": "is decimal not integer", + "schema": { + "maxProperties": 1.5 + } + }, + { + "description": "is negative", + "schema": { + "maxProperties": -1 + } + } + ] + }, + { + "description": "Object - invalid minProperties", + "tests": [ + { + "description": "is string not number", + "schema": { + "minProperties": "one" + } + }, + { + "description": "is boolean not number", + "schema": { + "minProperties": true + } + }, + { + "description": "is array not number", + "schema": { + "minProperties": [ + 1 + ] + } + }, + { + "description": "is object not number", + "schema": { + "minProperties": {} + } + }, + { + "description": "is null not number", + "schema": { + "minProperties": null + } + }, + { + "description": "is decimal not integer", + "schema": { + "minProperties": 1.5 + } + }, + { + "description": "is negative", + "schema": { + "minProperties": -1 + } + } + ] + }, + { + "description": "Object - invalid required", + "tests": [ + { + "description": "is string not array", + "schema": { + "required": "one" + } + }, + { + "description": "is empty array", + "schema": { + "required": [] + } + }, + { + "description": "array contains non-string", + "schema": { + "required": [ + 1 + ] + } + }, + { + "description": "array elements not unique", + "schema": { + "required": [ + "prop", + "prop" + ] + } + } + ] + }, + { + "description": "Object - invalid additionalProperties", + "tests": [ + { + "description": "is string not boolean", + "schema": { + "additionalProperties": "one" + } + }, + { + "description": "is number not boolean", + "schema": { + "additionalProperties": 1 + } + }, + { + "description": "is array not boolean", + "schema": { + "additionalProperties": [ + true + ] + } + }, + { + "description": "not a schema", + "schema": { + "additionalProperties": "not a schema" + } + }, + { + "description": "is null not boolean", + "schema": { + "additionalProperties": null + } + } + ] + }, + { + "description": "Object - invalid properties", + "tests": [ + { + "description": "is string not object", + "schema": { + "properties": "one" + } + }, + { + "description": "is number not object", + "schema": { + "properties": 1 + } + }, + { + "description": "is array not object", + "schema": { + "properties": [ + true + ] + } + }, + { + "description": "child not a schema", + "schema": { + "properties": {"child": "not a schema"} + } + }, + { + "description": "is null not object", + "schema": { + "properties": null + } + } + ] + } +] diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index c86ea60ca..c535a79bb 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -10,6 +10,9 @@ from decimal import Decimal import sys import unittest +import os +import json +import re from jsonschema import ( FormatError, SchemaError, ValidationError, Draft3Validator, @@ -52,6 +55,31 @@ def add_test_methods(test_class): return add_test_methods +def load_meta_cases(meta_tests_file, basedir=os.path.join(SUITE, "tests")): + def add_test_methods(test_class): + with open(os.path.join(basedir, meta_tests_file)) as test_file: + for case in json.load(test_file): + for (idx, test) in enumerate(case["tests"]): + name = "test_meta_%s_%s_%s" % ( + re.sub(r"[\W ]+", "_", case["description"]), + idx, + re.sub(r"[\W ]+", "_", test["description"]), + ) + assert not hasattr(test_class, name), name + test_method = create_meta_test(test["schema"]) + setattr(test_class, name, test_method) + return test_class + return add_test_methods + + +def create_meta_test(schema): + def test(self): + kwargs = getattr(self, "validator_kwargs", {}) + with self.assertRaises(SchemaError): + validate({}, schema, cls=self.validator_class, **kwargs) + return test + + def skip_tests_containing_descriptions(descriptions_and_reasons): def skipper(test): return next( @@ -200,21 +228,11 @@ def test_minItems_invalid_string(self): ) @load_json_cases(tests=DRAFT4.optional_tests_of(name="bignum")) @load_json_cases(tests=DRAFT4.optional_tests_of(name="zeroTerminatedFloats")) +@load_meta_cases("draft4/meta/meta.json") class TestDraft4(unittest.TestCase, TypesMixin, DecimalMixin, FormatMixin): validator_class = Draft4Validator validator_kwargs = {"format_checker": draft4_format_checker} - # TODO: we're in need of more meta schema tests - def test_invalid_properties(self): - with self.assertRaises(SchemaError): - validate({}, {"properties": {"test": True}}, - cls=self.validator_class) - - def test_minItems_invalid_string(self): - with self.assertRaises(SchemaError): - # needs to be an integer - validate([1], {"minItems": "1"}, cls=self.validator_class) - @load_json_cases(tests=DRAFT3.tests_of(name="refRemote")) class Draft3RemoteResolution(unittest.TestCase):