From 4221a55ab7d701fdb4391d18d6a7041c841b829b Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 29 Jan 2024 10:34:50 -0500 Subject: [PATCH] Add tests for not: {} schemas for all values. One would think these would be quite trivial tests... but not all implementations pass them surprisingly! This was noticed as part of tweaking Bowtie's smoke test for implementations (https://github.com/bowtie-json-schema/bowtie/commit/3984ef624e33f1992bca9e036354afc5732e7207#diff-dc32c0287345ff144e16658c5c157495f1c3c3f46c71dd3a58b2414663dcd08aR450-R458) -- which it uses to make sure JSON Schema implementations are running correctly -- in what I thought was a non-functionally meaningful way. But it turns out one implementation fails one of these tests :) -- namely it incorrectly considers `null` valid under `not: {}`. The actual contents here match what we use in other places (e.g. in boolean-schemas.json). While we're here, this also adds a test for not: not, i.e. double negation, with just one value to check. --- tests/draft2019-09/not.json | 154 +++++++++++++++++++++++++++++++++++- tests/draft2020-12/not.json | 154 +++++++++++++++++++++++++++++++++++- tests/draft4/not.json | 63 ++++++++++++++- tests/draft6/not.json | 152 +++++++++++++++++++++++++++++++++-- tests/draft7/not.json | 152 +++++++++++++++++++++++++++++++++-- 5 files changed, 658 insertions(+), 17 deletions(-) diff --git a/tests/draft2019-09/not.json b/tests/draft2019-09/not.json index 62c9af9d..d90728c7 100644 --- a/tests/draft2019-09/not.json +++ b/tests/draft2019-09/not.json @@ -97,25 +97,173 @@ ] }, { - "description": "not with boolean schema true", + "description": "forbid everything with empty schema", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "not": {} + }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": true }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false } ] }, { - "description": "not with boolean schema false", + "description": "allow everything with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "double negation", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "not": { "not": {} } + }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft2020-12/not.json b/tests/draft2020-12/not.json index 57e45ba3..d0f2b6e8 100644 --- a/tests/draft2020-12/not.json +++ b/tests/draft2020-12/not.json @@ -97,25 +97,173 @@ ] }, { - "description": "not with boolean schema true", + "description": "forbid everything with empty schema", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "not": {} + }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": true }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false } ] }, { - "description": "not with boolean schema false", + "description": "allow everything with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "double negation", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "not": { "not": {} } + }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft4/not.json b/tests/draft4/not.json index cbb7f46b..525219cf 100644 --- a/tests/draft4/not.json +++ b/tests/draft4/not.json @@ -91,6 +91,67 @@ "valid": true } ] + }, + { + "description": "forbid everything with empty schema", + "schema": { "not": {} }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "double negation", + "schema": { "not": { "not": {} } }, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] } - ] diff --git a/tests/draft6/not.json b/tests/draft6/not.json index 98de0eda..b46c4ed0 100644 --- a/tests/draft6/not.json +++ b/tests/draft6/not.json @@ -93,19 +93,161 @@ ] }, { - "description": "not with boolean schema true", - "schema": {"not": true}, + "description": "forbid everything with empty schema", + "schema": { "not": {} }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", + "schema": { "not": true }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "allow everything with boolean schema false", + "schema": { "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true } ] }, { - "description": "not with boolean schema false", - "schema": {"not": false}, + "description": "double negation", + "schema": { "not": { "not": {} } }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft7/not.json b/tests/draft7/not.json index 98de0eda..b46c4ed0 100644 --- a/tests/draft7/not.json +++ b/tests/draft7/not.json @@ -93,19 +93,161 @@ ] }, { - "description": "not with boolean schema true", - "schema": {"not": true}, + "description": "forbid everything with empty schema", + "schema": { "not": {} }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", + "schema": { "not": true }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "allow everything with boolean schema false", + "schema": { "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true } ] }, { - "description": "not with boolean schema false", - "schema": {"not": false}, + "description": "double negation", + "schema": { "not": { "not": {} } }, "tests": [ { "description": "any value is valid",