From f450f8ab8bfa348851813880b29695feeda29d92 Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Fri, 17 Apr 2026 18:25:14 -0400 Subject: [PATCH] added realm to jspg processing --- .DS_Store | Bin 6148 -> 6148 bytes fixtures/additionalProperties.json | 83 +++-- fixtures/booleanSchema.json | 24 +- fixtures/cases.json | 426 ++++++++++++----------- fixtures/const.json | 282 ++++++++++------ fixtures/contains.json | 151 ++++++--- fixtures/content.json | 78 +++-- fixtures/dependencies.json | 333 ++++++++++-------- fixtures/emptyString.json | 73 ++-- fixtures/enum.json | 317 +++++++++++------- fixtures/exclusiveMaximum.json | 13 +- fixtures/exclusiveMinimum.json | 13 +- fixtures/format.json | 484 +++++++++++++++++---------- fixtures/items.json | 344 ++++++++++++------- fixtures/maxContains.json | 101 +++--- fixtures/maxItems.json | 45 ++- fixtures/maxLength.json | 28 +- fixtures/maxProperties.json | 60 ++-- fixtures/maximum.json | 26 +- fixtures/merge.json | 194 ++++++----- fixtures/minContains.json | 189 +++++++---- fixtures/minItems.json | 45 ++- fixtures/minLength.json | 28 +- fixtures/minProperties.json | 45 ++- fixtures/minimum.json | 26 +- fixtures/multipleOf.json | 54 ++- fixtures/not.json | 220 +++++++----- fixtures/objectTypes.json | 130 ++++--- fixtures/paths.json | 187 ++++++----- fixtures/pattern.json | 26 +- fixtures/patternProperties.json | 126 ++++--- fixtures/polymorphism.json | 189 ++++++----- fixtures/prefixItems.json | 105 +++--- fixtures/primitiveTypes.json | 186 ++++++---- fixtures/properties.json | 309 ++++++++++------- fixtures/propertyNames.json | 131 +++++--- fixtures/required.json | 130 ++++--- fixtures/uniqueItems.json | 161 +++++---- log.txt | 23 ++ log_test.txt | 23 ++ scripts/migrate_legacy_schemas.py | 55 +++ scripts/migrate_properly.py | 54 +++ scripts/revert_puncs_to_types.js | 41 +++ scripts/revert_puncs_to_types.py | 29 ++ scripts/update_fixtures.js | 43 +++ scripts/update_fixtures.py | 33 ++ src/database/compile/mod.rs | 4 +- src/database/compile/polymorphism.rs | 2 +- src/database/mod.rs | 120 ++++--- src/database/realm.rs | 6 + src/merger/mod.rs | 42 ++- src/queryer/compiler.rs | 20 +- src/tests/types/case.rs | 6 - src/tests/types/expect/schema.rs | 18 +- src/validator/mod.rs | 17 +- src/validator/rules/object.rs | 65 ++-- src/validator/rules/polymorphism.rs | 11 +- test_failures.log | 81 +++++ test_merge.log | 23 ++ 59 files changed, 3884 insertions(+), 2194 deletions(-) create mode 100644 log.txt create mode 100644 log_test.txt create mode 100644 scripts/migrate_legacy_schemas.py create mode 100644 scripts/migrate_properly.py create mode 100644 scripts/revert_puncs_to_types.js create mode 100644 scripts/revert_puncs_to_types.py create mode 100644 scripts/update_fixtures.js create mode 100644 scripts/update_fixtures.py create mode 100644 src/database/realm.rs create mode 100644 test_failures.log create mode 100644 test_merge.log diff --git a/.DS_Store b/.DS_Store index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..b8900662b1d70a5dcccb112d290fb7f8fa621b14 100644 GIT binary patch delta 336 zcmZoMXfc=|#>B)qF;Q%yo}wrd0|Nsi1A_nqLn%WMLn=dYQh9N~#>C}}^&lAzhBSsu zh6;ufWZ9&g{3M{>TVI+#IpN8TsYGC5a`a#ZHMu(I8$( zetu38jGdSimYG@}FCgNapI4HYnU`7w){vQ!3RDsko|%`DU+$D&nwL^v4AvYBk>TLv z;EWfLuCCTKG&R>zFf=hTsMS%ZHZ(B<^2`hkYHK+;M3wcegW|Jua`W L5$VkVB3qaNmcmpl delta 70 zcmZoMXfc=|#>AjHu~2NHo+1YW5HK<@2y7N){>HLdfq56xW_AvK4xj>{$am(+{342+ UKzW7)kiy9(Jj$D6L{=~Z01@sEU;qFB diff --git a/fixtures/additionalProperties.json b/fixtures/additionalProperties.json index 9f643ef..231c2ec 100644 --- a/fixtures/additionalProperties.json +++ b/fixtures/additionalProperties.json @@ -2,21 +2,26 @@ { "description": "additionalProperties validates properties not matched by properties", "database": { - "schemas": { - "schema1": { - "properties": { - "foo": { - "type": "string" - }, - "bar": { - "type": "number" + "types": [ + { + "name": "schema1", + "schemas": { + "schema1": { + "properties": { + "foo": { + "type": "string" + }, + "bar": { + "type": "number" + } + }, + "additionalProperties": { + "type": "boolean" + } } - }, - "additionalProperties": { - "type": "boolean" } } - } + ] }, "tests": [ { @@ -61,19 +66,24 @@ { "description": "extensible: true with additionalProperties still validates structure", "database": { - "schemas": { - "additionalProperties_1_0": { - "properties": { - "foo": { - "type": "string" + "types": [ + { + "name": "additionalProperties_1_0", + "schemas": { + "additionalProperties_1_0": { + "properties": { + "foo": { + "type": "string" + } + }, + "extensible": true, + "additionalProperties": { + "type": "integer" + } } - }, - "extensible": true, - "additionalProperties": { - "type": "integer" } } - } + ] }, "tests": [ { @@ -106,21 +116,26 @@ { "description": "complex additionalProperties with object and array items", "database": { - "schemas": { - "schema3": { - "properties": { - "type": { - "type": "string" - } - }, - "additionalProperties": { - "type": "array", - "items": { - "type": "string" + "types": [ + { + "name": "schema3", + "schemas": { + "schema3": { + "properties": { + "type": { + "type": "string" + } + }, + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } } } } - } + ] }, "tests": [ { diff --git a/fixtures/booleanSchema.json b/fixtures/booleanSchema.json index cc44d38..5e2964f 100644 --- a/fixtures/booleanSchema.json +++ b/fixtures/booleanSchema.json @@ -2,9 +2,14 @@ { "description": "boolean schema 'true'", "database": { - "schemas": { - "booleanSchema_0_0": {} - } + "types": [ + { + "name": "booleanSchema_0_0", + "schemas": { + "booleanSchema_0_0": {} + } + } + ] }, "tests": [ { @@ -97,11 +102,16 @@ { "description": "boolean schema 'false'", "database": { - "schemas": { - "booleanSchema_1_0": { - "not": {} + "types": [ + { + "name": "booleanSchema_1_0", + "schemas": { + "booleanSchema_1_0": { + "not": {} + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/cases.json b/fixtures/cases.json index 0000d89..9203f3d 100644 --- a/fixtures/cases.json +++ b/fixtures/cases.json @@ -2,218 +2,238 @@ { "description": "Multi-Paradigm Declarative Cases", "database": { - "schemas": { - "parallel_rules": { - "type": "object", - "properties": { - "status": { - "type": "string" - }, - "kind": { - "type": "string" - } - }, - "cases": [ - { - "when": { - "properties": { - "status": { - "const": "unverified" - } + "types": [ + { + "name": "parallel_rules", + "schemas": { + "parallel_rules": { + "type": "object", + "properties": { + "status": { + "type": "string" }, - "required": [ - "status" - ] + "kind": { + "type": "string" + } }, - "then": { - "properties": { - "amount_1": { - "type": "number" + "cases": [ + { + "when": { + "properties": { + "status": { + "const": "unverified" + } + }, + "required": [ + "status" + ] }, - "amount_2": { - "type": "number" - } - }, - "required": [ - "amount_1", - "amount_2" - ] - } - }, - { - "when": { - "properties": { - "kind": { - "const": "credit" - } - }, - "required": [ - "kind" - ] - }, - "then": { - "properties": { - "cvv": { - "type": "number" - } - }, - "required": [ - "cvv" - ] - } - } - ] - }, - "mutually_exclusive": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - }, - "cases": [ - { - "when": { - "properties": { - "type": { - "const": "A" - } - }, - "required": [ - "type" - ] - }, - "then": { - "properties": { - "field_a": { - "type": "number" - } - }, - "required": [ - "field_a" - ] - } - }, - { - "when": { - "properties": { - "type": { - "const": "B" - } - }, - "required": [ - "type" - ] - }, - "then": { - "properties": { - "field_b": { - "type": "number" - } - }, - "required": [ - "field_b" - ] - }, - "else": { - "properties": { - "fallback_b": { - "type": "number" - } - }, - "required": [ - "fallback_b" - ] - } - } - ] - }, - "nested_fallbacks": { - "type": "object", - "properties": { - "tier": { - "type": "string" - } - }, - "cases": [ - { - "when": { - "properties": { - "tier": { - "const": "1" - } - }, - "required": [ - "tier" - ] - }, - "then": { - "properties": { - "basic": { - "type": "number" - } - }, - "required": [ - "basic" - ] - }, - "else": { - "cases": [ - { - "when": { - "properties": { - "tier": { - "const": "2" - } + "then": { + "properties": { + "amount_1": { + "type": "number" }, - "required": [ - "tier" - ] + "amount_2": { + "type": "number" + } }, - "then": { - "properties": { - "standard": { - "type": "number" - } - }, - "required": [ - "standard" - ] - }, - "else": { - "properties": { - "premium": { - "type": "number" - } - }, - "required": [ - "premium" - ] - } - } - ] - } - } - ] - }, - "missing_when": { - "type": "object", - "cases": [ - { - "else": { - "properties": { - "unconditional": { - "type": "number" + "required": [ + "amount_1", + "amount_2" + ] } }, - "required": [ - "unconditional" - ] - } + { + "when": { + "properties": { + "kind": { + "const": "credit" + } + }, + "required": [ + "kind" + ] + }, + "then": { + "properties": { + "cvv": { + "type": "number" + } + }, + "required": [ + "cvv" + ] + } + } + ] } - ] + } + }, + { + "name": "mutually_exclusive", + "schemas": { + "mutually_exclusive": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "cases": [ + { + "when": { + "properties": { + "type": { + "const": "A" + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "field_a": { + "type": "number" + } + }, + "required": [ + "field_a" + ] + } + }, + { + "when": { + "properties": { + "type": { + "const": "B" + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "field_b": { + "type": "number" + } + }, + "required": [ + "field_b" + ] + }, + "else": { + "properties": { + "fallback_b": { + "type": "number" + } + }, + "required": [ + "fallback_b" + ] + } + } + ] + } + } + }, + { + "name": "nested_fallbacks", + "schemas": { + "nested_fallbacks": { + "type": "object", + "properties": { + "tier": { + "type": "string" + } + }, + "cases": [ + { + "when": { + "properties": { + "tier": { + "const": "1" + } + }, + "required": [ + "tier" + ] + }, + "then": { + "properties": { + "basic": { + "type": "number" + } + }, + "required": [ + "basic" + ] + }, + "else": { + "cases": [ + { + "when": { + "properties": { + "tier": { + "const": "2" + } + }, + "required": [ + "tier" + ] + }, + "then": { + "properties": { + "standard": { + "type": "number" + } + }, + "required": [ + "standard" + ] + }, + "else": { + "properties": { + "premium": { + "type": "number" + } + }, + "required": [ + "premium" + ] + } + } + ] + } + } + ] + } + } + }, + { + "name": "missing_when", + "schemas": { + "missing_when": { + "type": "object", + "cases": [ + { + "else": { + "properties": { + "unconditional": { + "type": "number" + } + }, + "required": [ + "unconditional" + ] + } + } + ] + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/const.json b/fixtures/const.json index bd4b796..caf0804 100644 --- a/fixtures/const.json +++ b/fixtures/const.json @@ -2,11 +2,16 @@ { "description": "const validation", "database": { - "schemas": { - "const_0_0": { - "const": 2 + "types": [ + { + "name": "const_0_0", + "schemas": { + "const_0_0": { + "const": 2 + } + } } - } + ] }, "tests": [ { @@ -41,18 +46,23 @@ { "description": "const with object", "database": { - "schemas": { - "const_1_0": { - "const": { - "foo": "bar", - "baz": "bax" - }, - "properties": { - "foo": {}, - "baz": {} + "types": [ + { + "name": "const_1_0", + "schemas": { + "const_1_0": { + "const": { + "foo": "bar", + "baz": "bax" + }, + "properties": { + "foo": {}, + "baz": {} + } + } } } - } + ] }, "tests": [ { @@ -107,15 +117,20 @@ { "description": "const with array", "database": { - "schemas": { - "const_2_0": { - "const": [ - { - "foo": "bar" + "types": [ + { + "name": "const_2_0", + "schemas": { + "const_2_0": { + "const": [ + { + "foo": "bar" + } + ] } - ] + } } - } + ] }, "tests": [ { @@ -160,11 +175,16 @@ { "description": "const with null", "database": { - "schemas": { - "const_3_0": { - "const": null + "types": [ + { + "name": "const_3_0", + "schemas": { + "const_3_0": { + "const": null + } + } } - } + ] }, "tests": [ { @@ -190,11 +210,16 @@ { "description": "const with false does not match 0", "database": { - "schemas": { - "const_4_0": { - "const": false + "types": [ + { + "name": "const_4_0", + "schemas": { + "const_4_0": { + "const": false + } + } } - } + ] }, "tests": [ { @@ -229,11 +254,16 @@ { "description": "const with true does not match 1", "database": { - "schemas": { - "const_5_0": { - "const": true + "types": [ + { + "name": "const_5_0", + "schemas": { + "const_5_0": { + "const": true + } + } } - } + ] }, "tests": [ { @@ -268,13 +298,18 @@ { "description": "const with [false] does not match [0]", "database": { - "schemas": { - "const_6_0": { - "const": [ - false - ] + "types": [ + { + "name": "const_6_0", + "schemas": { + "const_6_0": { + "const": [ + false + ] + } + } } - } + ] }, "tests": [ { @@ -315,13 +350,18 @@ { "description": "const with [true] does not match [1]", "database": { - "schemas": { - "const_7_0": { - "const": [ - true - ] + "types": [ + { + "name": "const_7_0", + "schemas": { + "const_7_0": { + "const": [ + true + ] + } + } } - } + ] }, "tests": [ { @@ -362,13 +402,18 @@ { "description": "const with {\"a\": false} does not match {\"a\": 0}", "database": { - "schemas": { - "const_8_0": { - "const": { - "a": false + "types": [ + { + "name": "const_8_0", + "schemas": { + "const_8_0": { + "const": { + "a": false + } + } } } - } + ] }, "tests": [ { @@ -409,13 +454,18 @@ { "description": "const with {\"a\": true} does not match {\"a\": 1}", "database": { - "schemas": { - "const_9_0": { - "const": { - "a": true + "types": [ + { + "name": "const_9_0", + "schemas": { + "const_9_0": { + "const": { + "a": true + } + } } } - } + ] }, "tests": [ { @@ -456,11 +506,16 @@ { "description": "const with 0 does not match other zero-like types", "database": { - "schemas": { - "const_10_0": { - "const": 0 + "types": [ + { + "name": "const_10_0", + "schemas": { + "const_10_0": { + "const": 0 + } + } } - } + ] }, "tests": [ { @@ -522,11 +577,16 @@ { "description": "const with 1 does not match true", "database": { - "schemas": { - "const_11_0": { - "const": 1 + "types": [ + { + "name": "const_11_0", + "schemas": { + "const_11_0": { + "const": 1 + } + } } - } + ] }, "tests": [ { @@ -561,11 +621,16 @@ { "description": "const with -2.0 matches integer and float types", "database": { - "schemas": { - "const_12_0": { - "const": -2 + "types": [ + { + "name": "const_12_0", + "schemas": { + "const_12_0": { + "const": -2 + } + } } - } + ] }, "tests": [ { @@ -618,11 +683,16 @@ { "description": "float and integers are equal up to 64-bit representation limits", "database": { - "schemas": { - "const_13_0": { - "const": 9007199254740992 + "types": [ + { + "name": "const_13_0", + "schemas": { + "const_13_0": { + "const": 9007199254740992 + } + } } - } + ] }, "tests": [ { @@ -666,11 +736,16 @@ { "description": "nul characters in strings", "database": { - "schemas": { - "const_14_0": { - "const": "hello\u0000there" + "types": [ + { + "name": "const_14_0", + "schemas": { + "const_14_0": { + "const": "hello\u0000there" + } + } } - } + ] }, "tests": [ { @@ -696,17 +771,22 @@ { "description": "characters with the same visual representation but different codepoint", "database": { - "schemas": { - "const_15_0": { - "const": "μ", - "$comment": "U+03BC" + "types": [ + { + "name": "const_15_0", + "schemas": { + "const_15_0": { + "const": "\u03bc", + "$comment": "U+03BC" + } + } } - } + ] }, "tests": [ { "description": "character uses the same codepoint", - "data": "μ", + "data": "\u03bc", "comment": "U+03BC", "schema_id": "const_15_0", "action": "validate", @@ -716,7 +796,7 @@ }, { "description": "character looks the same but uses a different codepoint", - "data": "µ", + "data": "\u00b5", "comment": "U+00B5", "schema_id": "const_15_0", "action": "validate", @@ -729,17 +809,22 @@ { "description": "characters with the same visual representation, but different number of codepoints", "database": { - "schemas": { - "const_16_0": { - "const": "ä", - "$comment": "U+00E4" + "types": [ + { + "name": "const_16_0", + "schemas": { + "const_16_0": { + "const": "\u00e4", + "$comment": "U+00E4" + } + } } - } + ] }, "tests": [ { "description": "character uses the same codepoint", - "data": "ä", + "data": "\u00e4", "comment": "U+00E4", "schema_id": "const_16_0", "action": "validate", @@ -749,7 +834,7 @@ }, { "description": "character looks the same but uses combining marks", - "data": "ä", + "data": "a\u0308", "comment": "a, U+0308", "schema_id": "const_16_0", "action": "validate", @@ -762,14 +847,19 @@ { "description": "extensible: true allows extra properties in const object match", "database": { - "schemas": { - "const_17_0": { - "const": { - "a": 1 - }, - "extensible": true + "types": [ + { + "name": "const_17_0", + "schemas": { + "const_17_0": { + "const": { + "a": 1 + }, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/contains.json b/fixtures/contains.json index 3578ff9..faba6fa 100644 --- a/fixtures/contains.json +++ b/fixtures/contains.json @@ -2,14 +2,19 @@ { "description": "contains keyword validation", "database": { - "schemas": { - "contains_0_0": { - "contains": { - "minimum": 5 - }, - "items": true + "types": [ + { + "name": "contains_0_0", + "schemas": { + "contains_0_0": { + "contains": { + "minimum": 5 + }, + "items": true + } + } } - } + ] }, "tests": [ { @@ -88,14 +93,19 @@ { "description": "contains keyword with const keyword", "database": { - "schemas": { - "contains_1_0": { - "contains": { - "const": 5 - }, - "items": true + "types": [ + { + "name": "contains_1_0", + "schemas": { + "contains_1_0": { + "contains": { + "const": 5 + }, + "items": true + } + } } - } + ] }, "tests": [ { @@ -144,11 +154,16 @@ { "description": "contains keyword with boolean schema true", "database": { - "schemas": { - "contains_2_0": { - "contains": true + "types": [ + { + "name": "contains_2_0", + "schemas": { + "contains_2_0": { + "contains": true + } + } } - } + ] }, "tests": [ { @@ -176,11 +191,16 @@ { "description": "contains keyword with boolean schema false", "database": { - "schemas": { - "contains_3_0": { - "contains": false + "types": [ + { + "name": "contains_3_0", + "schemas": { + "contains_3_0": { + "contains": false + } + } } - } + ] }, "tests": [ { @@ -217,16 +237,21 @@ { "description": "items + contains", "database": { - "schemas": { - "contains_4_0": { - "items": { - "multipleOf": 2 - }, - "contains": { - "multipleOf": 3 + "types": [ + { + "name": "contains_4_0", + "schemas": { + "contains_4_0": { + "items": { + "multipleOf": 2 + }, + "contains": { + "multipleOf": 3 + } + } } } - } + ] }, "tests": [ { @@ -284,14 +309,19 @@ { "description": "contains with false if subschema", "database": { - "schemas": { - "contains_5_0": { - "contains": { - "if": false, - "else": true + "types": [ + { + "name": "contains_5_0", + "schemas": { + "contains_5_0": { + "contains": { + "if": false, + "else": true + } + } } } - } + ] }, "tests": [ { @@ -319,13 +349,18 @@ { "description": "contains with null instance elements", "database": { - "schemas": { - "contains_6_0": { - "contains": { - "type": "null" + "types": [ + { + "name": "contains_6_0", + "schemas": { + "contains_6_0": { + "contains": { + "type": "null" + } + } } } - } + ] }, "tests": [ { @@ -344,14 +379,19 @@ { "description": "extensible: true allows non-matching items in contains", "database": { - "schemas": { - "contains_7_0": { - "contains": { - "const": 1 - }, - "extensible": true + "types": [ + { + "name": "contains_7_0", + "schemas": { + "contains_7_0": { + "contains": { + "const": 1 + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -371,13 +411,18 @@ { "description": "strict by default: non-matching items in contains are invalid", "database": { - "schemas": { - "contains_8_0": { - "contains": { - "const": 1 + "types": [ + { + "name": "contains_8_0", + "schemas": { + "contains_8_0": { + "contains": { + "const": 1 + } + } } } - } + ] }, "tests": [ { diff --git a/fixtures/content.json b/fixtures/content.json index 1e33e68..5ca98ed 100644 --- a/fixtures/content.json +++ b/fixtures/content.json @@ -2,11 +2,16 @@ { "description": "validation of string-encoded content based on media type", "database": { - "schemas": { - "content_0_0": { - "contentMediaType": "application/json" + "types": [ + { + "name": "content_0_0", + "schemas": { + "content_0_0": { + "contentMediaType": "application/json" + } + } } - } + ] }, "tests": [ { @@ -41,11 +46,16 @@ { "description": "validation of binary string-encoding", "database": { - "schemas": { - "content_1_0": { - "contentEncoding": "base64" + "types": [ + { + "name": "content_1_0", + "schemas": { + "content_1_0": { + "contentEncoding": "base64" + } + } } - } + ] }, "tests": [ { @@ -80,12 +90,17 @@ { "description": "validation of binary-encoded media type documents", "database": { - "schemas": { - "content_2_0": { - "contentMediaType": "application/json", - "contentEncoding": "base64" + "types": [ + { + "name": "content_2_0", + "schemas": { + "content_2_0": { + "contentMediaType": "application/json", + "contentEncoding": "base64" + } + } } - } + ] }, "tests": [ { @@ -129,26 +144,31 @@ { "description": "validation of binary-encoded media type documents with schema", "database": { - "schemas": { - "content_3_0": { - "contentMediaType": "application/json", - "contentEncoding": "base64", - "contentSchema": { - "type": "object", - "required": [ - "foo" - ], - "properties": { - "foo": { - "type": "string" - }, - "boo": { - "type": "integer" + "types": [ + { + "name": "content_3_0", + "schemas": { + "content_3_0": { + "contentMediaType": "application/json", + "contentEncoding": "base64", + "contentSchema": { + "type": "object", + "required": [ + "foo" + ], + "properties": { + "foo": { + "type": "string" + }, + "boo": { + "type": "integer" + } + } } } } } - } + ] }, "tests": [ { diff --git a/fixtures/dependencies.json b/fixtures/dependencies.json index 75472de..e135dd9 100644 --- a/fixtures/dependencies.json +++ b/fixtures/dependencies.json @@ -2,17 +2,22 @@ { "description": "single dependency (required)", "database": { - "schemas": { - "schema1": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "dependencies": { - "bar": [ - "foo" - ] - }, - "extensible": true + "types": [ + { + "name": "schema1", + "schemas": { + "schema1": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "dependencies": { + "bar": [ + "foo" + ] + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -92,15 +97,20 @@ { "description": "empty dependents", "database": { - "schemas": { - "schema2": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "dependencies": { - "bar": [] - }, - "extensible": true + "types": [ + { + "name": "schema2", + "schemas": { + "schema2": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "dependencies": { + "bar": [] + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -137,18 +147,23 @@ { "description": "multiple dependents required", "database": { - "schemas": { - "schema3": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "dependencies": { - "quux": [ - "foo", - "bar" - ] - }, - "extensible": true + "types": [ + { + "name": "schema3", + "schemas": { + "schema3": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "dependencies": { + "quux": [ + "foo", + "bar" + ] + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -225,20 +240,25 @@ { "description": "dependencies with escaped characters", "database": { - "schemas": { - "schema4": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "dependencies": { - "foo\nbar": [ - "foo\rbar" - ], - "foo\"bar": [ - "foo'bar" - ] - }, - "extensible": true + "types": [ + { + "name": "schema4", + "schemas": { + "schema4": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "dependencies": { + "foo\nbar": [ + "foo\rbar" + ], + "foo\"bar": [ + "foo'bar" + ] + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -293,17 +313,22 @@ { "description": "extensible: true allows extra properties in dependentRequired", "database": { - "schemas": { - "schema5": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "dependencies": { - "bar": [ - "foo" - ] - }, - "extensible": true + "types": [ + { + "name": "schema5", + "schemas": { + "schema5": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "dependencies": { + "bar": [ + "foo" + ] + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -324,27 +349,32 @@ { "description": "single dependency (schemas, STRICT)", "database": { - "schemas": { - "schema_schema1": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "foo": true, - "bar": true - }, - "dependencies": { - "bar": { + "types": [ + { + "name": "schema_schema1", + "schemas": { + "schema_schema1": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { - "foo": { - "type": "integer" - }, + "foo": true, + "bar": true + }, + "dependencies": { "bar": { - "type": "integer" + "properties": { + "foo": { + "type": "integer" + }, + "bar": { + "type": "integer" + } + } } } } } } - } + ] }, "tests": [ { @@ -445,28 +475,33 @@ { "description": "single dependency (schemas, EXTENSIBLE)", "database": { - "schemas": { - "schema_schema2": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "foo": true, - "bar": true - }, - "dependencies": { - "bar": { + "types": [ + { + "name": "schema_schema2", + "schemas": { + "schema_schema2": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { - "foo": { - "type": "integer" - }, + "foo": true, + "bar": true + }, + "dependencies": { "bar": { - "type": "integer" + "properties": { + "foo": { + "type": "integer" + }, + "bar": { + "type": "integer" + } + } } - } + }, + "extensible": true } - }, - "extensible": true + } } - } + ] }, "tests": [ { @@ -485,19 +520,24 @@ { "description": "boolean subschemas", "database": { - "schemas": { - "schema_schema3": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "foo": true, - "bar": true - }, - "dependencies": { - "foo": true, - "bar": false + "types": [ + { + "name": "schema_schema3", + "schemas": { + "schema_schema3": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "foo": true, + "bar": true + }, + "dependencies": { + "foo": true, + "bar": false + } + } } } - } + ] }, "tests": [ { @@ -548,29 +588,34 @@ { "description": "dependencies with escaped characters", "database": { - "schemas": { - "schema_schema4": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "foo\tbar": true, - "foo'bar": true, - "a": true, - "b": true, - "c": true - }, - "dependencies": { - "foo\tbar": { - "minProperties": 4, - "extensible": true - }, - "foo'bar": { - "required": [ - "foo\"bar" - ] + "types": [ + { + "name": "schema_schema4", + "schemas": { + "schema_schema4": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "foo\tbar": true, + "foo'bar": true, + "a": true, + "b": true, + "c": true + }, + "dependencies": { + "foo\tbar": { + "minProperties": 4, + "extensible": true + }, + "foo'bar": { + "required": [ + "foo\"bar" + ] + } + } } } } - } + ] }, "tests": [ { @@ -628,22 +673,27 @@ { "description": "dependent subschema incompatible with root (STRICT)", "database": { - "schemas": { - "schema_schema5": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "foo": {}, - "baz": true - }, - "dependencies": { - "foo": { + "types": [ + { + "name": "schema_schema5", + "schemas": { + "schema_schema5": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { - "bar": {} + "foo": {}, + "baz": true + }, + "dependencies": { + "foo": { + "properties": { + "bar": {} + } + } } } } } - } + ] }, "tests": [ { @@ -701,24 +751,29 @@ { "description": "dependent subschema incompatible with root (EXTENSIBLE)", "database": { - "schemas": { - "schema_schema6": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": { - "foo": {}, - "baz": true - }, - "dependencies": { - "foo": { + "types": [ + { + "name": "schema_schema6", + "schemas": { + "schema_schema6": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { - "bar": {} + "foo": {}, + "baz": true }, - "additionalProperties": false + "dependencies": { + "foo": { + "properties": { + "bar": {} + }, + "additionalProperties": false + } + }, + "extensible": true } - }, - "extensible": true + } } - } + ] }, "tests": [ { diff --git a/fixtures/emptyString.json b/fixtures/emptyString.json index 0e81d3f..8e2b0b4 100644 --- a/fixtures/emptyString.json +++ b/fixtures/emptyString.json @@ -2,43 +2,48 @@ { "description": "empty string is valid for all types (except const)", "database": { - "schemas": { - "emptyString_0_0": { - "properties": { - "obj": { - "type": "object" - }, - "arr": { - "type": "array" - }, - "str": { - "type": "string" - }, - "int": { - "type": "integer" - }, - "num": { - "type": "number" - }, - "bool": { - "type": "boolean" - }, - "nul": { - "type": "null" - }, - "fmt": { - "type": "string", - "format": "uuid" - }, - "con": { - "const": "value" - }, - "con_empty": { - "const": "" + "types": [ + { + "name": "emptyString_0_0", + "schemas": { + "emptyString_0_0": { + "properties": { + "obj": { + "type": "object" + }, + "arr": { + "type": "array" + }, + "str": { + "type": "string" + }, + "int": { + "type": "integer" + }, + "num": { + "type": "number" + }, + "bool": { + "type": "boolean" + }, + "nul": { + "type": "null" + }, + "fmt": { + "type": "string", + "format": "uuid" + }, + "con": { + "const": "value" + }, + "con_empty": { + "const": "" + } + } } } } - } + ] }, "tests": [ { diff --git a/fixtures/enum.json b/fixtures/enum.json index 15d7f43..25f03b4 100644 --- a/fixtures/enum.json +++ b/fixtures/enum.json @@ -2,15 +2,20 @@ { "description": "simple enum validation", "database": { - "schemas": { - "enum_0_0": { - "enum": [ - 1, - 2, - 3 - ] + "types": [ + { + "name": "enum_0_0", + "schemas": { + "enum_0_0": { + "enum": [ + 1, + 2, + 3 + ] + } + } } - } + ] }, "tests": [ { @@ -36,22 +41,27 @@ { "description": "heterogeneous enum validation", "database": { - "schemas": { - "enum_1_0": { - "enum": [ - 6, - "foo", - [], - true, - { - "foo": 12 + "types": [ + { + "name": "enum_1_0", + "schemas": { + "enum_1_0": { + "enum": [ + 6, + "foo", + [], + true, + { + "foo": 12 + } + ], + "properties": { + "foo": {} + } } - ], - "properties": { - "foo": {} } } - } + ] }, "tests": [ { @@ -111,14 +121,19 @@ { "description": "heterogeneous enum-with-null validation", "database": { - "schemas": { - "enum_2_0": { - "enum": [ - 6, - null - ] + "types": [ + { + "name": "enum_2_0", + "schemas": { + "enum_2_0": { + "enum": [ + 6, + null + ] + } + } } - } + ] }, "tests": [ { @@ -153,26 +168,31 @@ { "description": "enums in properties", "database": { - "schemas": { - "enum_3_0": { - "type": "object", - "properties": { - "foo": { - "enum": [ - "foo" - ] - }, - "bar": { - "enum": [ + "types": [ + { + "name": "enum_3_0", + "schemas": { + "enum_3_0": { + "type": "object", + "properties": { + "foo": { + "enum": [ + "foo" + ] + }, + "bar": { + "enum": [ + "bar" + ] + } + }, + "required": [ "bar" ] } - }, - "required": [ - "bar" - ] + } } - } + ] }, "tests": [ { @@ -247,14 +267,19 @@ { "description": "enum with escaped characters", "database": { - "schemas": { - "enum_4_0": { - "enum": [ - "foo\nbar", - "foo\rbar" - ] + "types": [ + { + "name": "enum_4_0", + "schemas": { + "enum_4_0": { + "enum": [ + "foo\nbar", + "foo\rbar" + ] + } + } } - } + ] }, "tests": [ { @@ -289,13 +314,18 @@ { "description": "enum with false does not match 0", "database": { - "schemas": { - "enum_5_0": { - "enum": [ - false - ] + "types": [ + { + "name": "enum_5_0", + "schemas": { + "enum_5_0": { + "enum": [ + false + ] + } + } } - } + ] }, "tests": [ { @@ -330,15 +360,20 @@ { "description": "enum with [false] does not match [0]", "database": { - "schemas": { - "enum_6_0": { - "enum": [ - [ - false - ] - ] + "types": [ + { + "name": "enum_6_0", + "schemas": { + "enum_6_0": { + "enum": [ + [ + false + ] + ] + } + } } - } + ] }, "tests": [ { @@ -379,13 +414,18 @@ { "description": "enum with true does not match 1", "database": { - "schemas": { - "enum_7_0": { - "enum": [ - true - ] + "types": [ + { + "name": "enum_7_0", + "schemas": { + "enum_7_0": { + "enum": [ + true + ] + } + } } - } + ] }, "tests": [ { @@ -420,15 +460,20 @@ { "description": "enum with [true] does not match [1]", "database": { - "schemas": { - "enum_8_0": { - "enum": [ - [ - true - ] - ] + "types": [ + { + "name": "enum_8_0", + "schemas": { + "enum_8_0": { + "enum": [ + [ + true + ] + ] + } + } } - } + ] }, "tests": [ { @@ -469,13 +514,18 @@ { "description": "enum with 0 does not match false", "database": { - "schemas": { - "enum_9_0": { - "enum": [ - 0 - ] + "types": [ + { + "name": "enum_9_0", + "schemas": { + "enum_9_0": { + "enum": [ + 0 + ] + } + } } - } + ] }, "tests": [ { @@ -510,15 +560,20 @@ { "description": "enum with [0] does not match [false]", "database": { - "schemas": { - "enum_10_0": { - "enum": [ - [ - 0 - ] - ] + "types": [ + { + "name": "enum_10_0", + "schemas": { + "enum_10_0": { + "enum": [ + [ + 0 + ] + ] + } + } } - } + ] }, "tests": [ { @@ -559,13 +614,18 @@ { "description": "enum with 1 does not match true", "database": { - "schemas": { - "enum_11_0": { - "enum": [ - 1 - ] + "types": [ + { + "name": "enum_11_0", + "schemas": { + "enum_11_0": { + "enum": [ + 1 + ] + } + } } - } + ] }, "tests": [ { @@ -600,15 +660,20 @@ { "description": "enum with [1] does not match [true]", "database": { - "schemas": { - "enum_12_0": { - "enum": [ - [ - 1 - ] - ] + "types": [ + { + "name": "enum_12_0", + "schemas": { + "enum_12_0": { + "enum": [ + [ + 1 + ] + ] + } + } } - } + ] }, "tests": [ { @@ -649,13 +714,18 @@ { "description": "nul characters in strings", "database": { - "schemas": { - "enum_13_0": { - "enum": [ - "hello\u0000there" - ] + "types": [ + { + "name": "enum_13_0", + "schemas": { + "enum_13_0": { + "enum": [ + "hello\u0000there" + ] + } + } } - } + ] }, "tests": [ { @@ -681,16 +751,21 @@ { "description": "extensible: true allows extra properties in enum object match", "database": { - "schemas": { - "enum_14_0": { - "enum": [ - { - "foo": 1 + "types": [ + { + "name": "enum_14_0", + "schemas": { + "enum_14_0": { + "enum": [ + { + "foo": 1 + } + ], + "extensible": true } - ], - "extensible": true + } } - } + ] }, "tests": [ { diff --git a/fixtures/exclusiveMaximum.json b/fixtures/exclusiveMaximum.json index b67410c..634c34f 100644 --- a/fixtures/exclusiveMaximum.json +++ b/fixtures/exclusiveMaximum.json @@ -2,11 +2,16 @@ { "description": "exclusiveMaximum validation", "database": { - "schemas": { - "exclusiveMaximum_0_0": { - "exclusiveMaximum": 3 + "types": [ + { + "name": "exclusiveMaximum_0_0", + "schemas": { + "exclusiveMaximum_0_0": { + "exclusiveMaximum": 3 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/exclusiveMinimum.json b/fixtures/exclusiveMinimum.json index d07b09d..e137796 100644 --- a/fixtures/exclusiveMinimum.json +++ b/fixtures/exclusiveMinimum.json @@ -2,11 +2,16 @@ { "description": "exclusiveMinimum validation", "database": { - "schemas": { - "exclusiveMinimum_0_0": { - "exclusiveMinimum": 1.1 + "types": [ + { + "name": "exclusiveMinimum_0_0", + "schemas": { + "exclusiveMinimum_0_0": { + "exclusiveMinimum": 1.1 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/format.json b/fixtures/format.json index a15da7b..5373369 100644 --- a/fixtures/format.json +++ b/fixtures/format.json @@ -2,11 +2,16 @@ { "description": "validation of date-time strings", "database": { - "schemas": { - "format_0_0": { - "format": "date-time" + "types": [ + { + "name": "format_0_0", + "schemas": { + "format_0_0": { + "format": "date-time" + } + } } - } + ] }, "tests": [ { @@ -217,8 +222,8 @@ } }, { - "description": "invalid non-ASCII '৪' (a Bengali 4) in date portion", - "data": "1963-06-1৪T00:00:00Z", + "description": "invalid non-ASCII '\u09ea' (a Bengali 4) in date portion", + "data": "1963-06-1\u09eaT00:00:00Z", "schema_id": "format_0_0", "action": "validate", "expect": { @@ -226,8 +231,8 @@ } }, { - "description": "invalid non-ASCII '৪' (a Bengali 4) in time portion", - "data": "1963-06-11T0৪:00:00Z", + "description": "invalid non-ASCII '\u09ea' (a Bengali 4) in time portion", + "data": "1963-06-11T0\u09ea:00:00Z", "schema_id": "format_0_0", "action": "validate", "expect": { @@ -248,11 +253,16 @@ { "description": "validation of date strings", "database": { - "schemas": { - "format_1_0": { - "format": "date" + "types": [ + { + "name": "format_1_0", + "schemas": { + "format_1_0": { + "format": "date" + } + } } - } + ] }, "tests": [ { @@ -634,8 +644,8 @@ } }, { - "description": "invalid non-ASCII '৪' (a Bengali 4)", - "data": "1963-06-1৪", + "description": "invalid non-ASCII '\u09ea' (a Bengali 4)", + "data": "1963-06-1\u09ea", "schema_id": "format_1_0", "action": "validate", "expect": { @@ -692,11 +702,16 @@ { "description": "validation of duration strings", "database": { - "schemas": { - "format_2_0": { - "format": "duration" + "types": [ + { + "name": "format_2_0", + "schemas": { + "format_2_0": { + "format": "duration" + } + } } - } + ] }, "tests": [ { @@ -916,8 +931,8 @@ } }, { - "description": "invalid non-ASCII '২' (a Bengali 2)", - "data": "P২Y", + "description": "invalid non-ASCII '\u09e8' (a Bengali 2)", + "data": "P\u09e8Y", "schema_id": "format_2_0", "action": "validate", "expect": { @@ -938,11 +953,16 @@ { "description": "\\a is not an ECMA 262 control escape", "database": { - "schemas": { - "format_3_0": { - "format": "regex" + "types": [ + { + "name": "format_3_0", + "schemas": { + "format_3_0": { + "format": "regex" + } + } } - } + ] }, "tests": [ { @@ -959,11 +979,16 @@ { "description": "validation of e-mail addresses", "database": { - "schemas": { - "format_4_0": { - "format": "email" + "types": [ + { + "name": "format_4_0", + "schemas": { + "format_4_0": { + "format": "email" + } + } } - } + ] }, "tests": [ { @@ -1187,11 +1212,16 @@ { "description": "validation of host names", "database": { - "schemas": { - "format_5_0": { - "format": "hostname" + "types": [ + { + "name": "format_5_0", + "schemas": { + "format_5_0": { + "format": "hostname" + } + } } - } + ] }, "tests": [ { @@ -1331,7 +1361,7 @@ }, { "description": "IDN label separator", - "data": "example.com", + "data": "example\uff0ecom", "schema_id": "format_5_0", "action": "validate", "expect": { @@ -1416,11 +1446,16 @@ { "description": "validation of A-label (punycode) host names", "database": { - "schemas": { - "format_6_0": { - "format": "hostname" + "types": [ + { + "name": "format_6_0", + "schemas": { + "format_6_0": { + "format": "hostname" + } + } } - } + ] }, "tests": [ { @@ -1796,11 +1831,16 @@ { "description": "validation of an internationalized e-mail addresses", "database": { - "schemas": { - "format_7_0": { - "format": "idn-email" + "types": [ + { + "name": "format_7_0", + "schemas": { + "format_7_0": { + "format": "idn-email" + } + } } - } + ] }, "tests": [ { @@ -1859,7 +1899,7 @@ }, { "description": "a valid idn e-mail (example@example.test in Hangul)", - "data": "실례@실례.테스트", + "data": "\uc2e4\ub840@\uc2e4\ub840.\ud14c\uc2a4\ud2b8", "schema_id": "format_7_0", "action": "validate", "expect": { @@ -1898,11 +1938,16 @@ { "description": "validation of internationalized host names", "database": { - "schemas": { - "format_8_0": { - "format": "idn-hostname" + "types": [ + { + "name": "format_8_0", + "schemas": { + "format_8_0": { + "format": "idn-hostname" + } + } } - } + ] }, "tests": [ { @@ -1961,7 +2006,7 @@ }, { "description": "a valid host name (example.test in Hangul)", - "data": "실례.테스트", + "data": "\uc2e4\ub840.\ud14c\uc2a4\ud2b8", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -1970,7 +2015,7 @@ }, { "description": "illegal first char U+302E Hangul single dot tone mark", - "data": "〮실례.테스트", + "data": "\u302e\uc2e4\ub840.\ud14c\uc2a4\ud2b8", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -1979,7 +2024,7 @@ }, { "description": "contains illegal char U+302E Hangul single dot tone mark", - "data": "실〮례.테스트", + "data": "\uc2e4\u302e\ub840.\ud14c\uc2a4\ud2b8", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -1988,7 +2033,7 @@ }, { "description": "a host name with a component too long", - "data": "실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실실례례테스트례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례례례례례례례례테스트례례례례례례례례례례례례테스트례례실례.테스트", + "data": "\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\uc2e4\ub840\ub840\ud14c\uc2a4\ud2b8\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ud14c\uc2a4\ud2b8\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ud14c\uc2a4\ud2b8\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ub840\ud14c\uc2a4\ud2b8\ub840\ub840\uc2e4\ub840.\ud14c\uc2a4\ud2b8", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2068,7 +2113,7 @@ { "description": "Begins with a Spacing Combining Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", - "data": "ःhello", + "data": "\u0903hello", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2078,7 +2123,7 @@ { "description": "Begins with a Nonspacing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", - "data": "̀hello", + "data": "\u0300hello", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2088,7 +2133,7 @@ { "description": "Begins with an Enclosing Mark", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.2", - "data": "҈hello", + "data": "\u0488hello", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2098,7 +2143,7 @@ { "description": "Exceptions that are PVALID, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", - "data": "ßς་〇", + "data": "\u00df\u03c2\u0f0b\u3007", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2108,7 +2153,7 @@ { "description": "Exceptions that are PVALID, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", - "data": "۽۾", + "data": "\u06fd\u06fe", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2118,7 +2163,7 @@ { "description": "Exceptions that are DISALLOWED, right-to-left chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6", - "data": "ـߺ", + "data": "\u0640\u07fa", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2128,7 +2173,7 @@ { "description": "Exceptions that are DISALLOWED, left-to-right chars", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.2 https://tools.ietf.org/html/rfc5892#section-2.6 Note: The two combining marks (U+302E and U+302F) are in the middle and not at the start", - "data": "〱〲〳〴〵〮〯〻", + "data": "\u3031\u3032\u3033\u3034\u3035\u302e\u302f\u303b", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2138,7 +2183,7 @@ { "description": "MIDDLE DOT with no preceding 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", - "data": "a·l", + "data": "a\u00b7l", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2148,7 +2193,7 @@ { "description": "MIDDLE DOT with nothing preceding", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", - "data": "·l", + "data": "\u00b7l", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2158,7 +2203,7 @@ { "description": "MIDDLE DOT with no following 'l'", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", - "data": "l·a", + "data": "l\u00b7a", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2168,7 +2213,7 @@ { "description": "MIDDLE DOT with nothing following", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", - "data": "l·", + "data": "l\u00b7", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2178,7 +2223,7 @@ { "description": "MIDDLE DOT with surrounding 'l's", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.3", - "data": "l·l", + "data": "l\u00b7l", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2188,7 +2233,7 @@ { "description": "Greek KERAIA not followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", - "data": "α͵S", + "data": "\u03b1\u0375S", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2198,7 +2243,7 @@ { "description": "Greek KERAIA not followed by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", - "data": "α͵", + "data": "\u03b1\u0375", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2208,7 +2253,7 @@ { "description": "Greek KERAIA followed by Greek", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.4", - "data": "α͵β", + "data": "\u03b1\u0375\u03b2", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2218,7 +2263,7 @@ { "description": "Hebrew GERESH not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", - "data": "A׳ב", + "data": "A\u05f3\u05d1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2228,7 +2273,7 @@ { "description": "Hebrew GERESH not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", - "data": "׳ב", + "data": "\u05f3\u05d1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2238,7 +2283,7 @@ { "description": "Hebrew GERESH preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.5", - "data": "א׳ב", + "data": "\u05d0\u05f3\u05d1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2248,7 +2293,7 @@ { "description": "Hebrew GERSHAYIM not preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", - "data": "A״ב", + "data": "A\u05f4\u05d1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2258,7 +2303,7 @@ { "description": "Hebrew GERSHAYIM not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", - "data": "״ב", + "data": "\u05f4\u05d1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2268,7 +2313,7 @@ { "description": "Hebrew GERSHAYIM preceded by Hebrew", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.6", - "data": "א״ב", + "data": "\u05d0\u05f4\u05d1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2278,7 +2323,7 @@ { "description": "KATAKANA MIDDLE DOT with no Hiragana, Katakana, or Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", - "data": "def・abc", + "data": "def\u30fbabc", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2288,7 +2333,7 @@ { "description": "KATAKANA MIDDLE DOT with no other characters", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", - "data": "・", + "data": "\u30fb", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2298,7 +2343,7 @@ { "description": "KATAKANA MIDDLE DOT with Hiragana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", - "data": "・ぁ", + "data": "\u30fb\u3041", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2308,7 +2353,7 @@ { "description": "KATAKANA MIDDLE DOT with Katakana", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", - "data": "・ァ", + "data": "\u30fb\u30a1", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2318,7 +2363,7 @@ { "description": "KATAKANA MIDDLE DOT with Han", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.7", - "data": "・丈", + "data": "\u30fb\u4e08", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2328,7 +2373,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "ب٠۰", + "data": "\u0628\u0660\u06f0", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2338,7 +2383,7 @@ { "description": "Arabic-Indic digits not mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "ب٠ب", + "data": "\u0628\u0660\u0628", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2348,7 +2393,7 @@ { "description": "Extended Arabic-Indic digits not mixed with Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.9", - "data": "۰0", + "data": "\u06f00", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2358,7 +2403,7 @@ { "description": "ZERO WIDTH JOINER not preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", - "data": "क‍ष", + "data": "\u0915\u200d\u0937", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2368,7 +2413,7 @@ { "description": "ZERO WIDTH JOINER not preceded by anything", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", - "data": "‍ष", + "data": "\u200d\u0937", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2378,7 +2423,7 @@ { "description": "ZERO WIDTH JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.2 https://www.unicode.org/review/pr-37.pdf", - "data": "क्‍ष", + "data": "\u0915\u094d\u200d\u0937", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2388,7 +2433,7 @@ { "description": "ZERO WIDTH NON-JOINER preceded by Virama", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1", - "data": "क्‌ष", + "data": "\u0915\u094d\u200c\u0937", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2398,7 +2443,7 @@ { "description": "ZERO WIDTH NON-JOINER not preceded by Virama but matches regexp", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", - "data": "بي‌بي", + "data": "\u0628\u064a\u200c\u0628\u064a", "schema_id": "format_8_0", "action": "validate", "expect": { @@ -2470,11 +2515,16 @@ } ], "database": { - "schemas": { - "format_9_0": { - "format": "idn-hostname" + "types": [ + { + "name": "format_9_0", + "schemas": { + "format_9_0": { + "format": "idn-hostname" + } + } } - } + ] }, "tests": [ { @@ -2488,7 +2538,7 @@ }, { "description": "single ideographic full stop", - "data": "。", + "data": "\u3002", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2497,7 +2547,7 @@ }, { "description": "single fullwidth full stop", - "data": ".", + "data": "\uff0e", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2506,7 +2556,7 @@ }, { "description": "single halfwidth ideographic full stop", - "data": "。", + "data": "\uff61", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2524,7 +2574,7 @@ }, { "description": "ideographic full stop as label separator", - "data": "a。b", + "data": "a\u3002b", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2533,7 +2583,7 @@ }, { "description": "fullwidth full stop as label separator", - "data": "a.b", + "data": "a\uff0eb", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2542,7 +2592,7 @@ }, { "description": "halfwidth ideographic full stop as label separator", - "data": "a。b", + "data": "a\uff61b", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2560,7 +2610,7 @@ }, { "description": "leading ideographic full stop", - "data": "。example", + "data": "\u3002example", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2569,7 +2619,7 @@ }, { "description": "leading fullwidth full stop", - "data": ".example", + "data": "\uff0eexample", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2578,7 +2628,7 @@ }, { "description": "leading halfwidth ideographic full stop", - "data": "。example", + "data": "\uff61example", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2596,7 +2646,7 @@ }, { "description": "trailing ideographic full stop", - "data": "example。", + "data": "example\u3002", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2605,7 +2655,7 @@ }, { "description": "trailing fullwidth full stop", - "data": "example.", + "data": "example\uff0e", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2614,7 +2664,7 @@ }, { "description": "trailing halfwidth ideographic full stop", - "data": "example。", + "data": "example\uff61", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2623,7 +2673,7 @@ }, { "description": "label too long if separator ignored (full stop)", - "data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα.com", + "data": "\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1.com", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2632,7 +2682,7 @@ }, { "description": "label too long if separator ignored (ideographic full stop)", - "data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα。com", + "data": "\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u3002com", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2641,7 +2691,7 @@ }, { "description": "label too long if separator ignored (fullwidth full stop)", - "data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα.com", + "data": "\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\uff0ecom", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2650,7 +2700,7 @@ }, { "description": "label too long if separator ignored (halfwidth ideographic full stop)", - "data": "παράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπαράδειγμαπα。com", + "data": "\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1\u03c0\u03b1\uff61com", "schema_id": "format_9_0", "action": "validate", "expect": { @@ -2662,11 +2712,16 @@ { "description": "validation of IP addresses", "database": { - "schemas": { - "format_10_0": { - "format": "ipv4" + "types": [ + { + "name": "format_10_0", + "schemas": { + "format_10_0": { + "format": "ipv4" + } + } } - } + ] }, "tests": [ { @@ -2797,8 +2852,8 @@ } }, { - "description": "invalid non-ASCII '২' (a Bengali 2)", - "data": "1২7.0.0.1", + "description": "invalid non-ASCII '\u09e8' (a Bengali 2)", + "data": "1\u09e87.0.0.1", "schema_id": "format_10_0", "action": "validate", "expect": { @@ -2819,11 +2874,16 @@ { "description": "validation of IPv6 addresses", "database": { - "schemas": { - "format_11_0": { - "format": "ipv6" + "types": [ + { + "name": "format_11_0", + "schemas": { + "format_11_0": { + "format": "ipv6" + } + } } - } + ] }, "tests": [ { @@ -3169,8 +3229,8 @@ } }, { - "description": "invalid non-ASCII '৪' (a Bengali 4)", - "data": "1:2:3:4:5:6:7:৪", + "description": "invalid non-ASCII '\u09ea' (a Bengali 4)", + "data": "1:2:3:4:5:6:7:\u09ea", "schema_id": "format_11_0", "action": "validate", "expect": { @@ -3178,8 +3238,8 @@ } }, { - "description": "invalid non-ASCII '৪' (a Bengali 4) in the IPv4 portion", - "data": "1:2::192.16৪.0.1", + "description": "invalid non-ASCII '\u09ea' (a Bengali 4) in the IPv4 portion", + "data": "1:2::192.16\u09ea.0.1", "schema_id": "format_11_0", "action": "validate", "expect": { @@ -3191,11 +3251,16 @@ { "description": "validation of IRI References", "database": { - "schemas": { - "format_12_0": { - "format": "iri-reference" + "types": [ + { + "name": "format_12_0", + "schemas": { + "format_12_0": { + "format": "iri-reference" + } + } } - } + ] }, "tests": [ { @@ -3254,7 +3319,7 @@ }, { "description": "a valid IRI", - "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", + "data": "http://\u0192\u00f8\u00f8.\u00df\u00e5r/?\u2202\u00e9\u0153=\u03c0\u00eex#\u03c0\u00ee\u00fcx", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3263,7 +3328,7 @@ }, { "description": "a valid protocol-relative IRI Reference", - "data": "//ƒøø.ßår/?∂éœ=πîx#πîüx", + "data": "//\u0192\u00f8\u00f8.\u00df\u00e5r/?\u2202\u00e9\u0153=\u03c0\u00eex#\u03c0\u00ee\u00fcx", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3272,7 +3337,7 @@ }, { "description": "a valid relative IRI Reference", - "data": "/âππ", + "data": "/\u00e2\u03c0\u03c0", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3281,7 +3346,7 @@ }, { "description": "an invalid IRI Reference", - "data": "\\\\WINDOWS\\filëßåré", + "data": "\\\\WINDOWS\\fil\u00eb\u00df\u00e5r\u00e9", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3290,7 +3355,7 @@ }, { "description": "a valid IRI Reference", - "data": "âππ", + "data": "\u00e2\u03c0\u03c0", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3299,7 +3364,7 @@ }, { "description": "a valid IRI fragment", - "data": "#ƒrägmênt", + "data": "#\u0192r\u00e4gm\u00eant", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3308,7 +3373,7 @@ }, { "description": "an invalid IRI fragment", - "data": "#ƒräg\\mênt", + "data": "#\u0192r\u00e4g\\m\u00eant", "schema_id": "format_12_0", "action": "validate", "expect": { @@ -3320,11 +3385,16 @@ { "description": "validation of IRIs", "database": { - "schemas": { - "format_13_0": { - "format": "iri" + "types": [ + { + "name": "format_13_0", + "schemas": { + "format_13_0": { + "format": "iri" + } + } } - } + ] }, "tests": [ { @@ -3383,7 +3453,7 @@ }, { "description": "a valid IRI with anchor tag", - "data": "http://ƒøø.ßår/?∂éœ=πîx#πîüx", + "data": "http://\u0192\u00f8\u00f8.\u00df\u00e5r/?\u2202\u00e9\u0153=\u03c0\u00eex#\u03c0\u00ee\u00fcx", "schema_id": "format_13_0", "action": "validate", "expect": { @@ -3392,7 +3462,7 @@ }, { "description": "a valid IRI with anchor tag and parentheses", - "data": "http://ƒøø.com/blah_(wîkïpédiå)_blah#ßité-1", + "data": "http://\u0192\u00f8\u00f8.com/blah_(w\u00eek\u00efp\u00e9di\u00e5)_blah#\u00dfit\u00e9-1", "schema_id": "format_13_0", "action": "validate", "expect": { @@ -3401,7 +3471,7 @@ }, { "description": "a valid IRI with URL-encoded stuff", - "data": "http://ƒøø.ßår/?q=Test%20URL-encoded%20stuff", + "data": "http://\u0192\u00f8\u00f8.\u00df\u00e5r/?q=Test%20URL-encoded%20stuff", "schema_id": "format_13_0", "action": "validate", "expect": { @@ -3446,7 +3516,7 @@ }, { "description": "an invalid IRI", - "data": "\\\\WINDOWS\\filëßåré", + "data": "\\\\WINDOWS\\fil\u00eb\u00df\u00e5r\u00e9", "schema_id": "format_13_0", "action": "validate", "expect": { @@ -3455,7 +3525,7 @@ }, { "description": "an invalid IRI though valid IRI reference", - "data": "âππ", + "data": "\u00e2\u03c0\u03c0", "schema_id": "format_13_0", "action": "validate", "expect": { @@ -3467,11 +3537,16 @@ { "description": "validation of JSON-pointers (JSON String Representation)", "database": { - "schemas": { - "format_14_0": { - "format": "json-pointer" + "types": [ + { + "name": "format_14_0", + "schemas": { + "format_14_0": { + "format": "json-pointer" + } + } } - } + ] }, "tests": [ { @@ -3821,11 +3896,16 @@ { "description": "validation of regular expressions", "database": { - "schemas": { - "format_15_0": { - "format": "regex" + "types": [ + { + "name": "format_15_0", + "schemas": { + "format_15_0": { + "format": "regex" + } + } } - } + ] }, "tests": [ { @@ -3905,11 +3985,16 @@ { "description": "validation of Relative JSON Pointers (RJP)", "database": { - "schemas": { - "format_16_0": { - "format": "relative-json-pointer" + "types": [ + { + "name": "format_16_0", + "schemas": { + "format_16_0": { + "format": "relative-json-pointer" + } + } } - } + ] }, "tests": [ { @@ -4079,11 +4164,16 @@ { "description": "validation of time strings", "database": { - "schemas": { - "format_17_0": { - "format": "time" + "types": [ + { + "name": "format_17_0", + "schemas": { + "format_17_0": { + "format": "time" + } + } } - } + ] }, "tests": [ { @@ -4465,8 +4555,8 @@ } }, { - "description": "invalid non-ASCII '২' (a Bengali 2)", - "data": "1২:00:00Z", + "description": "invalid non-ASCII '\u09e8' (a Bengali 2)", + "data": "1\u09e8:00:00Z", "schema_id": "format_17_0", "action": "validate", "expect": { @@ -4505,11 +4595,16 @@ { "description": "unknown format", "database": { - "schemas": { - "format_18_0": { - "format": "unknown" + "types": [ + { + "name": "format_18_0", + "schemas": { + "format_18_0": { + "format": "unknown" + } + } } - } + ] }, "tests": [ { @@ -4580,11 +4675,16 @@ { "description": "validation of URI References", "database": { - "schemas": { - "format_19_0": { - "format": "uri-reference" + "types": [ + { + "name": "format_19_0", + "schemas": { + "format_19_0": { + "format": "uri-reference" + } + } } - } + ] }, "tests": [ { @@ -4706,7 +4806,7 @@ }, { "description": "unescaped non US-ASCII characters", - "data": "/foobar®.txt", + "data": "/foobar\u00ae.txt", "schema_id": "format_19_0", "action": "validate", "expect": { @@ -4727,11 +4827,16 @@ { "description": "format: uri-template", "database": { - "schemas": { - "format_20_0": { - "format": "uri-template" + "types": [ + { + "name": "format_20_0", + "schemas": { + "format_20_0": { + "format": "uri-template" + } + } } - } + ] }, "tests": [ { @@ -4829,11 +4934,16 @@ { "description": "validation of URIs", "database": { - "schemas": { - "format_21_0": { - "format": "uri" + "types": [ + { + "name": "format_21_0", + "schemas": { + "format_21_0": { + "format": "uri" + } + } } - } + ] }, "tests": [ { @@ -5081,7 +5191,7 @@ }, { "description": "unescaped non US-ASCII characters", - "data": "https://example.org/foobar®.txt", + "data": "https://example.org/foobar\u00ae.txt", "schema_id": "format_21_0", "action": "validate", "expect": { @@ -5165,11 +5275,16 @@ { "description": "uuid format", "database": { - "schemas": { - "format_22_0": { - "format": "uuid" + "types": [ + { + "name": "format_22_0", + "schemas": { + "format_22_0": { + "format": "uuid" + } + } } - } + ] }, "tests": [ { @@ -5375,11 +5490,16 @@ { "description": "period format", "database": { - "schemas": { - "format_23_0": { - "format": "period" + "types": [ + { + "name": "format_23_0", + "schemas": { + "format_23_0": { + "format": "period" + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/items.json b/fixtures/items.json index 209e5d7..b2c85b5 100644 --- a/fixtures/items.json +++ b/fixtures/items.json @@ -2,13 +2,18 @@ { "description": "a schema given for items", "database": { - "schemas": { - "items_0_0": { - "items": { - "type": "integer" + "types": [ + { + "name": "items_0_0", + "schemas": { + "items_0_0": { + "items": { + "type": "integer" + } + } } } - } + ] }, "tests": [ { @@ -64,11 +69,16 @@ { "description": "items with boolean schema (true)", "database": { - "schemas": { - "items_1_0": { - "items": true + "types": [ + { + "name": "items_1_0", + "schemas": { + "items_1_0": { + "items": true + } + } } - } + ] }, "tests": [ { @@ -98,11 +108,16 @@ { "description": "items with boolean schema (false)", "database": { - "schemas": { - "items_2_0": { - "items": false + "types": [ + { + "name": "items_2_0", + "schemas": { + "items_2_0": { + "items": false + } + } } - } + ] }, "tests": [ { @@ -132,41 +147,56 @@ { "description": "items and subitems", "database": { - "schemas": { - "items_3_0": { - "type": "array", - "items": false, - "prefixItems": [ - { - "type": "item" - }, - { - "type": "item" - }, - { - "type": "item" + "types": [ + { + "name": "items_3_0", + "schemas": { + "items_3_0": { + "type": "array", + "items": false, + "prefixItems": [ + { + "type": "item" + }, + { + "type": "item" + }, + { + "type": "item" + } + ] } - ] + } }, - "item": { - "type": "array", - "items": false, - "prefixItems": [ - { - "type": "sub-item" - }, - { - "type": "sub-item" + { + "name": "item", + "schemas": { + "item": { + "type": "array", + "items": false, + "prefixItems": [ + { + "type": "sub-item" + }, + { + "type": "sub-item" + } + ] } - ] + } }, - "sub-item": { - "type": "object", - "required": [ - "foo" - ] + { + "name": "sub-item", + "schemas": { + "sub-item": { + "type": "object", + "required": [ + "foo" + ] + } + } } - } + ] }, "tests": [ { @@ -368,23 +398,28 @@ { "description": "nested items", "database": { - "schemas": { - "items_4_0": { - "type": "array", - "items": { - "type": "array", - "items": { + "types": [ + { + "name": "items_4_0", + "schemas": { + "items_4_0": { "type": "array", "items": { "type": "array", "items": { - "type": "number" + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } } } } } } - } + ] }, "tests": [ { @@ -500,16 +535,21 @@ { "description": "prefixItems with no additional items allowed", "database": { - "schemas": { - "items_5_0": { - "prefixItems": [ - {}, - {}, - {} - ], - "items": false + "types": [ + { + "name": "items_5_0", + "schemas": { + "items_5_0": { + "prefixItems": [ + {}, + {}, + {} + ], + "items": false + } + } } - } + ] }, "tests": [ { @@ -576,22 +616,27 @@ { "description": "items does not look in applicators, valid case", "database": { - "schemas": { - "items_6_0": { - "allOf": [ - { - "prefixItems": [ + "types": [ + { + "name": "items_6_0", + "schemas": { + "items_6_0": { + "allOf": [ { - "minimum": 3 + "prefixItems": [ + { + "minimum": 3 + } + ] } - ] + ], + "items": { + "minimum": 5 + } } - ], - "items": { - "minimum": 5 } } - } + ] }, "tests": [ { @@ -623,18 +668,23 @@ { "description": "prefixItems validation adjusts the starting index for items", "database": { - "schemas": { - "items_7_0": { - "prefixItems": [ - { - "type": "string" + "types": [ + { + "name": "items_7_0", + "schemas": { + "items_7_0": { + "prefixItems": [ + { + "type": "string" + } + ], + "items": { + "type": "integer" + } } - ], - "items": { - "type": "integer" } } - } + ] }, "tests": [ { @@ -667,14 +717,19 @@ { "description": "items with heterogeneous array", "database": { - "schemas": { - "items_8_0": { - "prefixItems": [ - {} - ], - "items": false + "types": [ + { + "name": "items_8_0", + "schemas": { + "items_8_0": { + "prefixItems": [ + {} + ], + "items": false + } + } } - } + ] }, "tests": [ { @@ -706,13 +761,18 @@ { "description": "items with null instance elements", "database": { - "schemas": { - "items_9_0": { - "items": { - "type": "null" + "types": [ + { + "name": "items_9_0", + "schemas": { + "items_9_0": { + "items": { + "type": "null" + } + } } } - } + ] }, "tests": [ { @@ -731,12 +791,17 @@ { "description": "extensible: true allows extra items (when items is false)", "database": { - "schemas": { - "items_10_0": { - "items": false, - "extensible": true + "types": [ + { + "name": "items_10_0", + "schemas": { + "items_10_0": { + "items": false, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -755,14 +820,19 @@ { "description": "extensible: true allows extra properties for items", "database": { - "schemas": { - "items_11_0": { - "items": { - "minimum": 5 - }, - "extensible": true + "types": [ + { + "name": "items_11_0", + "schemas": { + "items_11_0": { + "items": { + "minimum": 5 + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -793,12 +863,17 @@ { "description": "array: simple extensible array", "database": { - "schemas": { - "items_12_0": { - "type": "array", - "extensible": true + "types": [ + { + "name": "items_12_0", + "schemas": { + "items_12_0": { + "type": "array", + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -827,12 +902,17 @@ { "description": "array: strict array", "database": { - "schemas": { - "items_13_0": { - "type": "array", - "extensible": false + "types": [ + { + "name": "items_13_0", + "schemas": { + "items_13_0": { + "type": "array", + "extensible": false + } + } } - } + ] }, "tests": [ { @@ -860,14 +940,19 @@ { "description": "array: items extensible", "database": { - "schemas": { - "items_14_0": { - "type": "array", - "items": { - "extensible": true + "types": [ + { + "name": "items_14_0", + "schemas": { + "items_14_0": { + "type": "array", + "items": { + "extensible": true + } + } } } - } + ] }, "tests": [ { @@ -897,15 +982,20 @@ { "description": "array: items strict", "database": { - "schemas": { - "items_15_0": { - "type": "array", - "items": { - "type": "object", - "extensible": false + "types": [ + { + "name": "items_15_0", + "schemas": { + "items_15_0": { + "type": "array", + "items": { + "type": "object", + "extensible": false + } + } } } - } + ] }, "tests": [ { diff --git a/fixtures/maxContains.json b/fixtures/maxContains.json index 18461fd..d3fefad 100644 --- a/fixtures/maxContains.json +++ b/fixtures/maxContains.json @@ -2,12 +2,17 @@ { "description": "maxContains without contains is ignored", "database": { - "schemas": { - "maxContains_0_0": { - "maxContains": 1, - "extensible": true + "types": [ + { + "name": "maxContains_0_0", + "schemas": { + "maxContains_0_0": { + "maxContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -38,15 +43,20 @@ { "description": "maxContains with contains", "database": { - "schemas": { - "maxContains_1_0": { - "contains": { - "const": 1 - }, - "maxContains": 1, - "extensible": true + "types": [ + { + "name": "maxContains_1_0", + "schemas": { + "maxContains_1_0": { + "contains": { + "const": 1 + }, + "maxContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -111,15 +121,20 @@ { "description": "maxContains with contains, value with a decimal", "database": { - "schemas": { - "maxContains_2_0": { - "contains": { - "const": 1 - }, - "maxContains": 1, - "extensible": true + "types": [ + { + "name": "maxContains_2_0", + "schemas": { + "maxContains_2_0": { + "contains": { + "const": 1 + }, + "maxContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -150,16 +165,21 @@ { "description": "minContains < maxContains", "database": { - "schemas": { - "maxContains_3_0": { - "contains": { - "const": 1 - }, - "minContains": 1, - "maxContains": 3, - "extensible": true + "types": [ + { + "name": "maxContains_3_0", + "schemas": { + "maxContains_3_0": { + "contains": { + "const": 1 + }, + "minContains": 1, + "maxContains": 3, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -202,15 +222,20 @@ { "description": "extensible: true allows non-matching items in maxContains", "database": { - "schemas": { - "maxContains_4_0": { - "contains": { - "const": 1 - }, - "maxContains": 1, - "extensible": true + "types": [ + { + "name": "maxContains_4_0", + "schemas": { + "maxContains_4_0": { + "contains": { + "const": 1 + }, + "maxContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/maxItems.json b/fixtures/maxItems.json index e840538..db8fab3 100644 --- a/fixtures/maxItems.json +++ b/fixtures/maxItems.json @@ -2,12 +2,17 @@ { "description": "maxItems validation", "database": { - "schemas": { - "maxItems_0_0": { - "maxItems": 2, - "extensible": true + "types": [ + { + "name": "maxItems_0_0", + "schemas": { + "maxItems_0_0": { + "maxItems": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -60,12 +65,17 @@ { "description": "maxItems validation with a decimal", "database": { - "schemas": { - "maxItems_1_0": { - "maxItems": 2, - "extensible": true + "types": [ + { + "name": "maxItems_1_0", + "schemas": { + "maxItems_1_0": { + "maxItems": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -97,12 +107,17 @@ { "description": "extensible: true allows extra items in maxItems (but counted)", "database": { - "schemas": { - "maxItems_2_0": { - "maxItems": 2, - "extensible": true + "types": [ + { + "name": "maxItems_2_0", + "schemas": { + "maxItems_2_0": { + "maxItems": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/maxLength.json b/fixtures/maxLength.json index 278ffba..6a0978a 100644 --- a/fixtures/maxLength.json +++ b/fixtures/maxLength.json @@ -2,11 +2,16 @@ { "description": "maxLength validation", "database": { - "schemas": { - "maxLength_0_0": { - "maxLength": 2 + "types": [ + { + "name": "maxLength_0_0", + "schemas": { + "maxLength_0_0": { + "maxLength": 2 + } + } } - } + ] }, "tests": [ { @@ -47,7 +52,7 @@ }, { "description": "two graphemes is long enough", - "data": "💩💩", + "data": "\ud83d\udca9\ud83d\udca9", "schema_id": "maxLength_0_0", "action": "validate", "expect": { @@ -59,11 +64,16 @@ { "description": "maxLength validation with a decimal", "database": { - "schemas": { - "maxLength_1_0": { - "maxLength": 2 + "types": [ + { + "name": "maxLength_1_0", + "schemas": { + "maxLength_1_0": { + "maxLength": 2 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/maxProperties.json b/fixtures/maxProperties.json index 1ff64f2..e598bba 100644 --- a/fixtures/maxProperties.json +++ b/fixtures/maxProperties.json @@ -2,12 +2,17 @@ { "description": "maxProperties validation", "database": { - "schemas": { - "maxProperties_0_0": { - "maxProperties": 2, - "extensible": true + "types": [ + { + "name": "maxProperties_0_0", + "schemas": { + "maxProperties_0_0": { + "maxProperties": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -82,12 +87,17 @@ { "description": "maxProperties validation with a decimal", "database": { - "schemas": { - "maxProperties_1_0": { - "maxProperties": 2, - "extensible": true + "types": [ + { + "name": "maxProperties_1_0", + "schemas": { + "maxProperties_1_0": { + "maxProperties": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -119,12 +129,17 @@ { "description": "maxProperties = 0 means the object is empty", "database": { - "schemas": { - "maxProperties_2_0": { - "maxProperties": 0, - "extensible": true + "types": [ + { + "name": "maxProperties_2_0", + "schemas": { + "maxProperties_2_0": { + "maxProperties": 0, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -152,12 +167,17 @@ { "description": "extensible: true allows extra properties in maxProperties (though maxProperties still counts them!)", "database": { - "schemas": { - "maxProperties_3_0": { - "maxProperties": 2, - "extensible": true + "types": [ + { + "name": "maxProperties_3_0", + "schemas": { + "maxProperties_3_0": { + "maxProperties": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/maximum.json b/fixtures/maximum.json index 7a36bdf..06febaf 100644 --- a/fixtures/maximum.json +++ b/fixtures/maximum.json @@ -2,11 +2,16 @@ { "description": "maximum validation", "database": { - "schemas": { - "maximum_0_0": { - "maximum": 3 + "types": [ + { + "name": "maximum_0_0", + "schemas": { + "maximum_0_0": { + "maximum": 3 + } + } } - } + ] }, "tests": [ { @@ -50,11 +55,16 @@ { "description": "maximum validation with unsigned integer", "database": { - "schemas": { - "maximum_1_0": { - "maximum": 300 + "types": [ + { + "name": "maximum_1_0", + "schemas": { + "maximum_1_0": { + "maximum": 300 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/merge.json b/fixtures/merge.json index 3ac011e..d1cec1a 100644 --- a/fixtures/merge.json +++ b/fixtures/merge.json @@ -2,23 +2,33 @@ { "description": "merging: properties accumulate", "database": { - "schemas": { - "base_0": { - "properties": { - "base_prop": { - "type": "string" + "types": [ + { + "name": "base_0", + "schemas": { + "base_0": { + "properties": { + "base_prop": { + "type": "string" + } + } } } }, - "merge_0_0": { - "type": "base_0", - "properties": { - "child_prop": { - "type": "string" + { + "name": "merge_0_0", + "schemas": { + "merge_0_0": { + "type": "base_0", + "properties": { + "child_prop": { + "type": "string" + } + } } } } - } + ] }, "tests": [ { @@ -58,29 +68,39 @@ { "description": "merging: required fields accumulate", "database": { - "schemas": { - "base_1": { - "properties": { - "a": { - "type": "string" + "types": [ + { + "name": "base_1", + "schemas": { + "base_1": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ] } - }, - "required": [ - "a" - ] + } }, - "merge_1_0": { - "type": "base_1", - "properties": { - "b": { - "type": "string" + { + "name": "merge_1_0", + "schemas": { + "merge_1_0": { + "type": "base_1", + "properties": { + "b": { + "type": "string" + } + }, + "required": [ + "b" + ] } - }, - "required": [ - "b" - ] + } } - } + ] }, "tests": [ { @@ -138,36 +158,46 @@ { "description": "merging: dependencies accumulate", "database": { - "schemas": { - "base_2": { - "properties": { - "trigger": { - "type": "string" - }, - "base_dep": { - "type": "string" + "types": [ + { + "name": "base_2", + "schemas": { + "base_2": { + "properties": { + "trigger": { + "type": "string" + }, + "base_dep": { + "type": "string" + } + }, + "dependencies": { + "trigger": [ + "base_dep" + ] + } } - }, - "dependencies": { - "trigger": [ - "base_dep" - ] } }, - "merge_2_0": { - "type": "base_2", - "properties": { - "child_dep": { - "type": "string" + { + "name": "merge_2_0", + "schemas": { + "merge_2_0": { + "type": "base_2", + "properties": { + "child_dep": { + "type": "string" + } + }, + "dependencies": { + "trigger": [ + "child_dep" + ] + } } - }, - "dependencies": { - "trigger": [ - "child_dep" - ] } } - } + ] }, "tests": [ { @@ -228,33 +258,43 @@ { "description": "merging: form and display do NOT merge", "database": { - "schemas": { - "base_3": { - "properties": { - "a": { - "type": "string" - }, - "b": { - "type": "string" + "types": [ + { + "name": "base_3", + "schemas": { + "base_3": { + "properties": { + "a": { + "type": "string" + }, + "b": { + "type": "string" + } + }, + "form": [ + "a", + "b" + ] } - }, - "form": [ - "a", - "b" - ] + } }, - "merge_3_0": { - "type": "base_3", - "properties": { - "c": { - "type": "string" + { + "name": "merge_3_0", + "schemas": { + "merge_3_0": { + "type": "base_3", + "properties": { + "c": { + "type": "string" + } + }, + "form": [ + "c" + ] } - }, - "form": [ - "c" - ] + } } - } + ] }, "tests": [ { diff --git a/fixtures/minContains.json b/fixtures/minContains.json index b621a9d..d3994a0 100644 --- a/fixtures/minContains.json +++ b/fixtures/minContains.json @@ -2,12 +2,17 @@ { "description": "minContains without contains is ignored", "database": { - "schemas": { - "minContains_0_0": { - "minContains": 1, - "extensible": true + "types": [ + { + "name": "minContains_0_0", + "schemas": { + "minContains_0_0": { + "minContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -35,15 +40,20 @@ { "description": "minContains=1 with contains", "database": { - "schemas": { - "minContains_1_0": { - "contains": { - "const": 1 - }, - "minContains": 1, - "extensible": true + "types": [ + { + "name": "minContains_1_0", + "schemas": { + "minContains_1_0": { + "contains": { + "const": 1 + }, + "minContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -106,15 +116,20 @@ { "description": "minContains=2 with contains", "database": { - "schemas": { - "minContains_2_0": { - "contains": { - "const": 1 - }, - "minContains": 2, - "extensible": true + "types": [ + { + "name": "minContains_2_0", + "schemas": { + "minContains_2_0": { + "contains": { + "const": 1 + }, + "minContains": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -192,15 +207,20 @@ { "description": "minContains=2 with contains with a decimal value", "database": { - "schemas": { - "minContains_3_0": { - "contains": { - "const": 1 - }, - "minContains": 2, - "extensible": true + "types": [ + { + "name": "minContains_3_0", + "schemas": { + "minContains_3_0": { + "contains": { + "const": 1 + }, + "minContains": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -231,16 +251,21 @@ { "description": "maxContains = minContains", "database": { - "schemas": { - "minContains_4_0": { - "contains": { - "const": 1 - }, - "maxContains": 2, - "minContains": 2, - "extensible": true + "types": [ + { + "name": "minContains_4_0", + "schemas": { + "minContains_4_0": { + "contains": { + "const": 1 + }, + "maxContains": 2, + "minContains": 2, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -293,16 +318,21 @@ { "description": "maxContains < minContains", "database": { - "schemas": { - "minContains_5_0": { - "contains": { - "const": 1 - }, - "maxContains": 1, - "minContains": 3, - "extensible": true + "types": [ + { + "name": "minContains_5_0", + "schemas": { + "minContains_5_0": { + "contains": { + "const": 1 + }, + "maxContains": 1, + "minContains": 3, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -355,15 +385,20 @@ { "description": "minContains = 0", "database": { - "schemas": { - "minContains_6_0": { - "contains": { - "const": 1 - }, - "minContains": 0, - "extensible": true + "types": [ + { + "name": "minContains_6_0", + "schemas": { + "minContains_6_0": { + "contains": { + "const": 1 + }, + "minContains": 0, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -391,16 +426,21 @@ { "description": "minContains = 0 with maxContains", "database": { - "schemas": { - "minContains_7_0": { - "contains": { - "const": 1 - }, - "minContains": 0, - "maxContains": 1, - "extensible": true + "types": [ + { + "name": "minContains_7_0", + "schemas": { + "minContains_7_0": { + "contains": { + "const": 1 + }, + "minContains": 0, + "maxContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -440,15 +480,20 @@ { "description": "extensible: true allows non-matching items in minContains", "database": { - "schemas": { - "minContains_8_0": { - "contains": { - "const": 1 - }, - "minContains": 1, - "extensible": true + "types": [ + { + "name": "minContains_8_0", + "schemas": { + "minContains_8_0": { + "contains": { + "const": 1 + }, + "minContains": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/minItems.json b/fixtures/minItems.json index 3566412..493ea0b 100644 --- a/fixtures/minItems.json +++ b/fixtures/minItems.json @@ -2,12 +2,17 @@ { "description": "minItems validation", "database": { - "schemas": { - "minItems_0_0": { - "minItems": 1, - "extensible": true + "types": [ + { + "name": "minItems_0_0", + "schemas": { + "minItems_0_0": { + "minItems": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -56,12 +61,17 @@ { "description": "minItems validation with a decimal", "database": { - "schemas": { - "minItems_1_0": { - "minItems": 1, - "extensible": true + "types": [ + { + "name": "minItems_1_0", + "schemas": { + "minItems_1_0": { + "minItems": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -90,12 +100,17 @@ { "description": "extensible: true allows extra items in minItems", "database": { - "schemas": { - "minItems_2_0": { - "minItems": 1, - "extensible": true + "types": [ + { + "name": "minItems_2_0", + "schemas": { + "minItems_2_0": { + "minItems": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/minLength.json b/fixtures/minLength.json index b3e73c5..39f88d3 100644 --- a/fixtures/minLength.json +++ b/fixtures/minLength.json @@ -2,11 +2,16 @@ { "description": "minLength validation", "database": { - "schemas": { - "minLength_0_0": { - "minLength": 2 + "types": [ + { + "name": "minLength_0_0", + "schemas": { + "minLength_0_0": { + "minLength": 2 + } + } } - } + ] }, "tests": [ { @@ -47,7 +52,7 @@ }, { "description": "one grapheme is not long enough", - "data": "💩", + "data": "\ud83d\udca9", "schema_id": "minLength_0_0", "action": "validate", "expect": { @@ -59,11 +64,16 @@ { "description": "minLength validation with a decimal", "database": { - "schemas": { - "minLength_1_0": { - "minLength": 2 + "types": [ + { + "name": "minLength_1_0", + "schemas": { + "minLength_1_0": { + "minLength": 2 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/minProperties.json b/fixtures/minProperties.json index 93f29fd..2323eee 100644 --- a/fixtures/minProperties.json +++ b/fixtures/minProperties.json @@ -2,12 +2,17 @@ { "description": "minProperties validation", "database": { - "schemas": { - "minProperties_0_0": { - "minProperties": 1, - "extensible": true + "types": [ + { + "name": "minProperties_0_0", + "schemas": { + "minProperties_0_0": { + "minProperties": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -74,12 +79,17 @@ { "description": "minProperties validation with a decimal", "database": { - "schemas": { - "minProperties_1_0": { - "minProperties": 1, - "extensible": true + "types": [ + { + "name": "minProperties_1_0", + "schemas": { + "minProperties_1_0": { + "minProperties": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -108,12 +118,17 @@ { "description": "extensible: true allows extra properties in minProperties", "database": { - "schemas": { - "minProperties_2_0": { - "minProperties": 1, - "extensible": true + "types": [ + { + "name": "minProperties_2_0", + "schemas": { + "minProperties_2_0": { + "minProperties": 1, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/minimum.json b/fixtures/minimum.json index 8762643..4266767 100644 --- a/fixtures/minimum.json +++ b/fixtures/minimum.json @@ -2,11 +2,16 @@ { "description": "minimum validation", "database": { - "schemas": { - "minimum_0_0": { - "minimum": 1.1 + "types": [ + { + "name": "minimum_0_0", + "schemas": { + "minimum_0_0": { + "minimum": 1.1 + } + } } - } + ] }, "tests": [ { @@ -50,11 +55,16 @@ { "description": "minimum validation with signed integer", "database": { - "schemas": { - "minimum_1_0": { - "minimum": -2 + "types": [ + { + "name": "minimum_1_0", + "schemas": { + "minimum_1_0": { + "minimum": -2 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/multipleOf.json b/fixtures/multipleOf.json index 93a166c..a578a90 100644 --- a/fixtures/multipleOf.json +++ b/fixtures/multipleOf.json @@ -2,11 +2,16 @@ { "description": "by int", "database": { - "schemas": { - "multipleOf_0_0": { - "multipleOf": 2 + "types": [ + { + "name": "multipleOf_0_0", + "schemas": { + "multipleOf_0_0": { + "multipleOf": 2 + } + } } - } + ] }, "tests": [ { @@ -41,11 +46,16 @@ { "description": "by number", "database": { - "schemas": { - "multipleOf_1_0": { - "multipleOf": 1.5 + "types": [ + { + "name": "multipleOf_1_0", + "schemas": { + "multipleOf_1_0": { + "multipleOf": 1.5 + } + } } - } + ] }, "tests": [ { @@ -80,11 +90,16 @@ { "description": "by small number", "database": { - "schemas": { - "multipleOf_2_0": { - "multipleOf": 0.0001 + "types": [ + { + "name": "multipleOf_2_0", + "schemas": { + "multipleOf_2_0": { + "multipleOf": 0.0001 + } + } } - } + ] }, "tests": [ { @@ -110,12 +125,17 @@ { "description": "small multiple of large integer", "database": { - "schemas": { - "multipleOf_3_0": { - "type": "integer", - "multipleOf": 1e-08 + "types": [ + { + "name": "multipleOf_3_0", + "schemas": { + "multipleOf_3_0": { + "type": "integer", + "multipleOf": 1e-08 + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/not.json b/fixtures/not.json index e9c422d..0d2e4e8 100644 --- a/fixtures/not.json +++ b/fixtures/not.json @@ -2,13 +2,18 @@ { "description": "not", "database": { - "schemas": { - "not_0_0": { - "not": { - "type": "integer" + "types": [ + { + "name": "not_0_0", + "schemas": { + "not_0_0": { + "not": { + "type": "integer" + } + } } } - } + ] }, "tests": [ { @@ -34,16 +39,21 @@ { "description": "not multiple types", "database": { - "schemas": { - "not_1_0": { - "not": { - "type": [ - "integer", - "boolean" - ] + "types": [ + { + "name": "not_1_0", + "schemas": { + "not_1_0": { + "not": { + "type": [ + "integer", + "boolean" + ] + } + } } } - } + ] }, "tests": [ { @@ -78,19 +88,24 @@ { "description": "not more complex schema", "database": { - "schemas": { - "not_2_0": { - "not": { - "type": "object", - "properties": { - "foo": { - "type": "string" - } + "types": [ + { + "name": "not_2_0", + "schemas": { + "not_2_0": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + }, + "extensible": true } - }, - "extensible": true + } } - } + ] }, "tests": [ { @@ -129,15 +144,20 @@ { "description": "forbidden property", "database": { - "schemas": { - "not_3_0": { - "properties": { - "foo": { - "not": {} + "types": [ + { + "name": "not_3_0", + "schemas": { + "not_3_0": { + "properties": { + "foo": { + "not": {} + } + } } } } - } + ] }, "tests": [ { @@ -166,11 +186,16 @@ { "description": "forbid everything with empty schema", "database": { - "schemas": { - "not_4_0": { - "not": {} + "types": [ + { + "name": "not_4_0", + "schemas": { + "not_4_0": { + "not": {} + } + } } - } + ] }, "tests": [ { @@ -263,11 +288,16 @@ { "description": "forbid everything with boolean schema true", "database": { - "schemas": { - "not_5_0": { - "not": true + "types": [ + { + "name": "not_5_0", + "schemas": { + "not_5_0": { + "not": true + } + } } - } + ] }, "tests": [ { @@ -360,12 +390,17 @@ { "description": "allow everything with boolean schema false", "database": { - "schemas": { - "not_6_0": { - "not": false, - "extensible": true + "types": [ + { + "name": "not_6_0", + "schemas": { + "not_6_0": { + "not": false, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -458,13 +493,18 @@ { "description": "double negation", "database": { - "schemas": { - "not_7_0": { - "not": { - "not": {} + "types": [ + { + "name": "not_7_0", + "schemas": { + "not_7_0": { + "not": { + "not": {} + } + } } } - } + ] }, "tests": [ { @@ -481,14 +521,19 @@ { "description": "extensible: true allows extra properties in not", "database": { - "schemas": { - "not_8_0": { - "not": { - "type": "integer" - }, - "extensible": true + "types": [ + { + "name": "not_8_0", + "schemas": { + "not_8_0": { + "not": { + "type": "integer" + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -507,13 +552,18 @@ { "description": "extensible: false (default) forbids extra properties in not", "database": { - "schemas": { - "not_9_0": { - "not": { - "type": "integer" + "types": [ + { + "name": "not_9_0", + "schemas": { + "not_9_0": { + "not": { + "type": "integer" + } + } } } - } + ] }, "tests": [ { @@ -532,19 +582,24 @@ { "description": "property next to not (extensible: true)", "database": { - "schemas": { - "not_10_0": { - "properties": { - "bar": { - "type": "string" + "types": [ + { + "name": "not_10_0", + "schemas": { + "not_10_0": { + "properties": { + "bar": { + "type": "string" + } + }, + "not": { + "type": "integer" + }, + "extensible": true } - }, - "not": { - "type": "integer" - }, - "extensible": true + } } - } + ] }, "tests": [ { @@ -564,18 +619,23 @@ { "description": "property next to not (extensible: false)", "database": { - "schemas": { - "not_11_0": { - "properties": { - "bar": { - "type": "string" + "types": [ + { + "name": "not_11_0", + "schemas": { + "not_11_0": { + "properties": { + "bar": { + "type": "string" + } + }, + "not": { + "type": "integer" + } } - }, - "not": { - "type": "integer" } } - } + ] }, "tests": [ { diff --git a/fixtures/objectTypes.json b/fixtures/objectTypes.json index 510cb89..95efb91 100644 --- a/fixtures/objectTypes.json +++ b/fixtures/objectTypes.json @@ -2,27 +2,37 @@ { "description": "Strict Inheritance", "database": { - "schemas": { - "parent_type": { - "type": "object", - "properties": { - "a": { - "type": "integer" + "types": [ + { + "name": "parent_type", + "schemas": { + "parent_type": { + "type": "object", + "properties": { + "a": { + "type": "integer" + } + }, + "required": [ + "a" + ] } - }, - "required": [ - "a" - ] + } }, - "child_type": { - "type": "parent_type", - "properties": { - "b": { - "type": "integer" + { + "name": "child_type", + "schemas": { + "child_type": { + "type": "parent_type", + "properties": { + "b": { + "type": "integer" + } + } } } } - } + ] }, "tests": [ { @@ -66,26 +76,36 @@ { "description": "Local Shadowing (Composition & Proxies)", "database": { - "schemas": { - "budget": { - "type": "object", - "properties": { - "max": { - "type": "integer", - "maximum": 100 + "types": [ + { + "name": "budget", + "schemas": { + "budget": { + "type": "object", + "properties": { + "max": { + "type": "integer", + "maximum": 100 + } + } } } }, - "custom_budget": { - "type": "budget", - "properties": { - "max": { - "type": "integer", - "maximum": 50 + { + "name": "custom_budget", + "schemas": { + "custom_budget": { + "type": "budget", + "properties": { + "max": { + "type": "integer", + "maximum": 50 + } + } } } } - } + ] }, "tests": [ { @@ -115,30 +135,40 @@ { "description": "Primitive Array Shorthand (Optionality)", "database": { - "schemas": { - "invoice": { - "type": "object", - "properties": { - "amount": { - "type": "integer" - } - }, - "required": [ - "amount" - ] - }, - "request": { - "type": "object", - "properties": { - "inv": { - "type": [ - "invoice", - "null" + "types": [ + { + "name": "invoice", + "schemas": { + "invoice": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + } + }, + "required": [ + "amount" ] } } + }, + { + "name": "request", + "schemas": { + "request": { + "type": "object", + "properties": { + "inv": { + "type": [ + "invoice", + "null" + ] + } + } + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/paths.json b/fixtures/paths.json index 87532a8..efe246e 100644 --- a/fixtures/paths.json +++ b/fixtures/paths.json @@ -2,63 +2,68 @@ { "description": "Hybrid Array Pathing", "database": { - "schemas": { - "hybrid_pathing": { - "type": "object", - "properties": { - "primitives": { - "type": "array", - "items": { - "type": "string" - } - }, - "ad_hoc_objects": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { + "types": [ + { + "name": "hybrid_pathing", + "schemas": { + "hybrid_pathing": { + "type": "object", + "properties": { + "primitives": { + "type": "array", + "items": { "type": "string" } }, - "required": [ - "name" - ] - } - }, - "entities": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "value": { - "type": "number", - "minimum": 10 + "ad_hoc_objects": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ] } - } - } - }, - "deep_entities": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "nested": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "flag": { - "type": "boolean" + }, + "entities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "value": { + "type": "number", + "minimum": 10 + } + } + } + }, + "deep_entities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "nested": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "flag": { + "type": "boolean" + } + } } } } @@ -68,7 +73,7 @@ } } } - } + ] }, "tests": [ { @@ -227,26 +232,31 @@ { "description": "Ad-Hoc Union Pathing", "database": { - "schemas": { - "ad_hoc_pathing": { - "type": "object", - "properties": { - "metadata_bubbles": { - "type": "array", - "items": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "integer" + "types": [ + { + "name": "ad_hoc_pathing", + "schemas": { + "ad_hoc_pathing": { + "type": "object", + "properties": { + "metadata_bubbles": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] } - ] + } } } } } - } + ] }, "tests": [ { @@ -277,9 +287,22 @@ { "description": "Polymorphic Family Pathing", "database": { + "relations": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "type": "relation", + "constraint": "fk_family_pathing_table_families_widget", + "source_type": "widget", + "source_columns": ["family_pathing_id"], + "destination_type": "family_pathing", + "destination_columns": ["id"], + "prefix": "table_families" + } + ], "types": [ { "name": "widget", + "hierarchy": ["widget"], "variations": [ "widget" ], @@ -322,21 +345,25 @@ ] } } - } - ], - "schemas": { - "family_pathing": { - "type": "object", - "properties": { - "table_families": { - "type": "array", - "items": { - "family": "widget" + }, + { + "name": "family_pathing", + "hierarchy": ["family_pathing"], + "schemas": { + "family_pathing": { + "type": "object", + "properties": { + "table_families": { + "type": "array", + "items": { + "family": "widget" + } + } } } } } - } + ] }, "tests": [ { diff --git a/fixtures/pattern.json b/fixtures/pattern.json index 171a983..b3c5db5 100644 --- a/fixtures/pattern.json +++ b/fixtures/pattern.json @@ -2,11 +2,16 @@ { "description": "pattern validation", "database": { - "schemas": { - "pattern_0_0": { - "pattern": "^a*$" + "types": [ + { + "name": "pattern_0_0", + "schemas": { + "pattern_0_0": { + "pattern": "^a*$" + } + } } - } + ] }, "tests": [ { @@ -86,11 +91,16 @@ { "description": "pattern is not anchored", "database": { - "schemas": { - "pattern_1_0": { - "pattern": "a+" + "types": [ + { + "name": "pattern_1_0", + "schemas": { + "pattern_1_0": { + "pattern": "a+" + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/patternProperties.json b/fixtures/patternProperties.json index 63f0f00..66010bb 100644 --- a/fixtures/patternProperties.json +++ b/fixtures/patternProperties.json @@ -2,16 +2,21 @@ { "description": "patternProperties validates properties matching a regex", "database": { - "schemas": { - "patternProperties_0_0": { - "patternProperties": { - "f.*o": { - "type": "integer" + "types": [ + { + "name": "patternProperties_0_0", + "schemas": { + "patternProperties_0_0": { + "patternProperties": { + "f.*o": { + "type": "integer" + } + }, + "items": {} } - }, - "items": {} + } } - } + ] }, "tests": [ { @@ -107,18 +112,23 @@ { "description": "multiple simultaneous patternProperties are validated", "database": { - "schemas": { - "patternProperties_1_0": { - "patternProperties": { - "a*": { - "type": "integer" - }, - "aaa*": { - "maximum": 20 + "types": [ + { + "name": "patternProperties_1_0", + "schemas": { + "patternProperties_1_0": { + "patternProperties": { + "a*": { + "type": "integer" + }, + "aaa*": { + "maximum": 20 + } + } } } } - } + ] }, "tests": [ { @@ -194,19 +204,24 @@ { "description": "regexes are not anchored by default and are case sensitive", "database": { - "schemas": { - "patternProperties_2_0": { - "patternProperties": { - "[0-9]{2,}": { - "type": "boolean" - }, - "X_": { - "type": "string" + "types": [ + { + "name": "patternProperties_2_0", + "schemas": { + "patternProperties_2_0": { + "patternProperties": { + "[0-9]{2,}": { + "type": "boolean" + }, + "X_": { + "type": "string" + } + }, + "extensible": true } - }, - "extensible": true + } } - } + ] }, "tests": [ { @@ -258,14 +273,19 @@ { "description": "patternProperties with boolean schemas", "database": { - "schemas": { - "patternProperties_3_0": { - "patternProperties": { - "f.*": true, - "b.*": false + "types": [ + { + "name": "patternProperties_3_0", + "schemas": { + "patternProperties_3_0": { + "patternProperties": { + "f.*": true, + "b.*": false + } + } } } - } + ] }, "tests": [ { @@ -327,15 +347,20 @@ { "description": "patternProperties with null valued instance properties", "database": { - "schemas": { - "patternProperties_4_0": { - "patternProperties": { - "^.*bar$": { - "type": "null" + "types": [ + { + "name": "patternProperties_4_0", + "schemas": { + "patternProperties_4_0": { + "patternProperties": { + "^.*bar$": { + "type": "null" + } + } } } } - } + ] }, "tests": [ { @@ -354,16 +379,21 @@ { "description": "extensible: true allows extra properties NOT matching pattern", "database": { - "schemas": { - "patternProperties_5_0": { - "patternProperties": { - "f.*o": { - "type": "integer" + "types": [ + { + "name": "patternProperties_5_0", + "schemas": { + "patternProperties_5_0": { + "patternProperties": { + "f.*o": { + "type": "integer" + } + }, + "extensible": true } - }, - "extensible": true + } } - } + ] }, "tests": [ { diff --git a/fixtures/polymorphism.json b/fixtures/polymorphism.json index 1b9e4aa..340f781 100644 --- a/fixtures/polymorphism.json +++ b/fixtures/polymorphism.json @@ -73,13 +73,16 @@ } } } + }, + { + "name": "family_entity", + "schemas": { + "family_entity": { + "family": "entity" + } + } } - ], - "schemas": { - "family_entity": { - "family": "entity" - } - } + ] }, "tests": [ { @@ -222,13 +225,16 @@ "type": "light.entity" } } + }, + { + "name": "family_light_org", + "schemas": { + "family_light_org": { + "family": "light.organization" + } + } } - ], - "schemas": { - "family_light_org": { - "family": "light.organization" - } - } + ] }, "tests": [ { @@ -315,16 +321,24 @@ } } } - } - ], - "schemas": { - "family_widget": { - "family": "widget" }, - "family_stock_widget": { - "family": "stock.widget" + { + "name": "family_widget", + "schemas": { + "family_widget": { + "family": "widget" + } + } + }, + { + "name": "family_stock_widget", + "schemas": { + "family_stock_widget": { + "family": "stock.widget" + } + } } - } + ] }, "tests": [ { @@ -463,20 +477,23 @@ ] } } - } - ], - "schemas": { - "oneOf_union": { - "oneOf": [ - { - "type": "full.person" - }, - { - "type": "full.bot" + }, + { + "name": "oneOf_union", + "schemas": { + "oneOf_union": { + "oneOf": [ + { + "type": "full.person" + }, + { + "type": "full.bot" + } + ] } - ] + } } - } + ] }, "tests": [ { @@ -559,48 +576,58 @@ { "description": "JSONB Field Bubble oneOf Discrimination (Promoted IDs)", "database": { - "schemas": { - "metadata": { - "type": "object", - "properties": { - "type": { - "type": "string" + "types": [ + { + "name": "metadata", + "schemas": { + "metadata": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + }, + "invoice.metadata": { + "type": "metadata", + "properties": { + "invoice_id": { + "type": "integer" + } + }, + "required": [ + "invoice_id" + ] + }, + "payment.metadata": { + "type": "metadata", + "properties": { + "payment_id": { + "type": "integer" + } + }, + "required": [ + "payment_id" + ] } } }, - "invoice.metadata": { - "type": "metadata", - "properties": { - "invoice_id": { - "type": "integer" + { + "name": "oneOf_bubble", + "schemas": { + "oneOf_bubble": { + "oneOf": [ + { + "type": "invoice.metadata" + }, + { + "type": "payment.metadata" + } + ] } - }, - "required": [ - "invoice_id" - ] - }, - "payment.metadata": { - "type": "metadata", - "properties": { - "payment_id": { - "type": "integer" - } - }, - "required": [ - "payment_id" - ] - }, - "oneOf_bubble": { - "oneOf": [ - { - "type": "invoice.metadata" - }, - { - "type": "payment.metadata" - } - ] + } } - } + ] }, "tests": [ { @@ -675,16 +702,24 @@ } } } - } - ], - "schemas": { - "stock_widget_validation": { - "type": "stock.widget" }, - "projected_widget_validation": { - "type": "projected.widget" + { + "name": "stock_widget_validation", + "schemas": { + "stock_widget_validation": { + "type": "stock.widget" + } + } + }, + { + "name": "projected_widget_validation", + "schemas": { + "projected_widget_validation": { + "type": "projected.widget" + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/prefixItems.json b/fixtures/prefixItems.json index b38a44f..a79fd15 100644 --- a/fixtures/prefixItems.json +++ b/fixtures/prefixItems.json @@ -2,18 +2,23 @@ { "description": "a schema given for prefixItems", "database": { - "schemas": { - "prefixItems_0_0": { - "prefixItems": [ - { - "type": "integer" - }, - { - "type": "string" + "types": [ + { + "name": "prefixItems_0_0", + "schemas": { + "prefixItems_0_0": { + "prefixItems": [ + { + "type": "integer" + }, + { + "type": "string" + } + ] } - ] + } } - } + ] }, "tests": [ { @@ -91,14 +96,19 @@ { "description": "prefixItems with boolean schemas", "database": { - "schemas": { - "prefixItems_1_0": { - "prefixItems": [ - true, - false - ] + "types": [ + { + "name": "prefixItems_1_0", + "schemas": { + "prefixItems_1_0": { + "prefixItems": [ + true, + false + ] + } + } } - } + ] }, "tests": [ { @@ -138,16 +148,21 @@ { "description": "additional items are allowed by default", "database": { - "schemas": { - "prefixItems_2_0": { - "prefixItems": [ - { - "type": "integer" + "types": [ + { + "name": "prefixItems_2_0", + "schemas": { + "prefixItems_2_0": { + "prefixItems": [ + { + "type": "integer" + } + ], + "extensible": true } - ], - "extensible": true + } } - } + ] }, "tests": [ { @@ -168,15 +183,20 @@ { "description": "prefixItems with null instance elements", "database": { - "schemas": { - "prefixItems_3_0": { - "prefixItems": [ - { - "type": "null" + "types": [ + { + "name": "prefixItems_3_0", + "schemas": { + "prefixItems_3_0": { + "prefixItems": [ + { + "type": "null" + } + ] } - ] + } } - } + ] }, "tests": [ { @@ -195,16 +215,21 @@ { "description": "extensible: true allows extra items with prefixItems", "database": { - "schemas": { - "prefixItems_4_0": { - "prefixItems": [ - { - "type": "integer" + "types": [ + { + "name": "prefixItems_4_0", + "schemas": { + "prefixItems_4_0": { + "prefixItems": [ + { + "type": "integer" + } + ], + "extensible": true } - ], - "extensible": true + } } - } + ] }, "tests": [ { diff --git a/fixtures/primitiveTypes.json b/fixtures/primitiveTypes.json index 714efa2..fd0cc51 100644 --- a/fixtures/primitiveTypes.json +++ b/fixtures/primitiveTypes.json @@ -2,11 +2,16 @@ { "description": "integer type matches integers", "database": { - "schemas": { - "type_0_0": { - "type": "integer" + "types": [ + { + "name": "type_0_0", + "schemas": { + "type_0_0": { + "type": "integer" + } + } } - } + ] }, "tests": [ { @@ -95,11 +100,16 @@ { "description": "number type matches numbers", "database": { - "schemas": { - "type_1_0": { - "type": "number" + "types": [ + { + "name": "type_1_0", + "schemas": { + "type_1_0": { + "type": "number" + } + } } - } + ] }, "tests": [ { @@ -188,11 +198,16 @@ { "description": "string type matches strings", "database": { - "schemas": { - "type_2_0": { - "type": "string" + "types": [ + { + "name": "type_2_0", + "schemas": { + "type_2_0": { + "type": "string" + } + } } - } + ] }, "tests": [ { @@ -281,11 +296,16 @@ { "description": "object type matches objects", "database": { - "schemas": { - "type_3_0": { - "type": "object" + "types": [ + { + "name": "type_3_0", + "schemas": { + "type_3_0": { + "type": "object" + } + } } - } + ] }, "tests": [ { @@ -356,11 +376,16 @@ { "description": "array type matches arrays", "database": { - "schemas": { - "type_4_0": { - "type": "array" + "types": [ + { + "name": "type_4_0", + "schemas": { + "type_4_0": { + "type": "array" + } + } } - } + ] }, "tests": [ { @@ -431,11 +456,16 @@ { "description": "boolean type matches booleans", "database": { - "schemas": { - "type_5_0": { - "type": "boolean" + "types": [ + { + "name": "type_5_0", + "schemas": { + "type_5_0": { + "type": "boolean" + } + } } - } + ] }, "tests": [ { @@ -533,11 +563,16 @@ { "description": "null type matches only the null object", "database": { - "schemas": { - "type_6_0": { - "type": "null" + "types": [ + { + "name": "type_6_0", + "schemas": { + "type_6_0": { + "type": "null" + } + } } - } + ] }, "tests": [ { @@ -635,14 +670,19 @@ { "description": "multiple types can be specified in an array", "database": { - "schemas": { - "type_7_0": { - "type": [ - "integer", - "string" - ] + "types": [ + { + "name": "type_7_0", + "schemas": { + "type_7_0": { + "type": [ + "integer", + "string" + ] + } + } } - } + ] }, "tests": [ { @@ -713,13 +753,18 @@ { "description": "type as array with one item", "database": { - "schemas": { - "type_8_0": { - "type": [ - "string" - ] + "types": [ + { + "name": "type_8_0", + "schemas": { + "type_8_0": { + "type": [ + "string" + ] + } + } } - } + ] }, "tests": [ { @@ -745,15 +790,20 @@ { "description": "type: array or object", "database": { - "schemas": { - "type_9_0": { - "type": [ - "array", - "object" - ], - "items": {} + "types": [ + { + "name": "type_9_0", + "schemas": { + "type_9_0": { + "type": [ + "array", + "object" + ], + "items": {} + } + } } - } + ] }, "tests": [ { @@ -810,16 +860,21 @@ { "description": "type: array, object or null", "database": { - "schemas": { - "type_10_0": { - "type": [ - "array", - "object", - "null" - ], - "items": {} + "types": [ + { + "name": "type_10_0", + "schemas": { + "type_10_0": { + "type": [ + "array", + "object", + "null" + ], + "items": {} + } + } } - } + ] }, "tests": [ { @@ -876,12 +931,17 @@ { "description": "extensible: true allows extra properties", "database": { - "schemas": { - "type_11_0": { - "type": "object", - "extensible": true + "types": [ + { + "name": "type_11_0", + "schemas": { + "type_11_0": { + "type": "object", + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/properties.json b/fixtures/properties.json index 3c6b3a3..712ac29 100644 --- a/fixtures/properties.json +++ b/fixtures/properties.json @@ -2,18 +2,23 @@ { "description": "object properties validation", "database": { - "schemas": { - "properties_0_0": { - "properties": { - "foo": { - "type": "integer" - }, - "bar": { - "type": "string" + "types": [ + { + "name": "properties_0_0", + "schemas": { + "properties_0_0": { + "properties": { + "foo": { + "type": "integer" + }, + "bar": { + "type": "string" + } + } } } } - } + ] }, "tests": [ { @@ -84,14 +89,19 @@ { "description": "properties with boolean schema", "database": { - "schemas": { - "properties_1_0": { - "properties": { - "foo": true, - "bar": false + "types": [ + { + "name": "properties_1_0", + "schemas": { + "properties_1_0": { + "properties": { + "foo": true, + "bar": false + } + } } } - } + ] }, "tests": [ { @@ -142,30 +152,35 @@ { "description": "properties with escaped characters", "database": { - "schemas": { - "properties_2_0": { - "properties": { - "foo\nbar": { - "type": "number" - }, - "foo\"bar": { - "type": "number" - }, - "foo\\bar": { - "type": "number" - }, - "foo\rbar": { - "type": "number" - }, - "foo\tbar": { - "type": "number" - }, - "foo\fbar": { - "type": "number" + "types": [ + { + "name": "properties_2_0", + "schemas": { + "properties_2_0": { + "properties": { + "foo\nbar": { + "type": "number" + }, + "foo\"bar": { + "type": "number" + }, + "foo\\bar": { + "type": "number" + }, + "foo\rbar": { + "type": "number" + }, + "foo\tbar": { + "type": "number" + }, + "foo\fbar": { + "type": "number" + } + } } } } - } + ] }, "tests": [ { @@ -205,15 +220,20 @@ { "description": "properties with null valued instance properties", "database": { - "schemas": { - "properties_3_0": { - "properties": { - "foo": { - "type": "null" + "types": [ + { + "name": "properties_3_0", + "schemas": { + "properties_3_0": { + "properties": { + "foo": { + "type": "null" + } + } } } } - } + ] }, "tests": [ { @@ -233,25 +253,30 @@ "description": "properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "database": { - "schemas": { - "properties_4_0": { - "properties": { - "__proto__": { - "type": "number" - }, - "toString": { + "types": [ + { + "name": "properties_4_0", + "schemas": { + "properties_4_0": { "properties": { - "length": { - "type": "string" + "__proto__": { + "type": "number" + }, + "toString": { + "properties": { + "length": { + "type": "string" + } + } + }, + "constructor": { + "type": "number" } } - }, - "constructor": { - "type": "number" } } } - } + ] }, "tests": [ { @@ -338,16 +363,21 @@ { "description": "extensible: true allows extra properties", "database": { - "schemas": { - "properties_5_0": { - "properties": { - "foo": { - "type": "integer" + "types": [ + { + "name": "properties_5_0", + "schemas": { + "properties_5_0": { + "properties": { + "foo": { + "type": "integer" + } + }, + "extensible": true } - }, - "extensible": true + } } - } + ] }, "tests": [ { @@ -367,15 +397,20 @@ { "description": "strict by default: extra properties invalid", "database": { - "schemas": { - "properties_6_0": { - "properties": { - "foo": { - "type": "string" + "types": [ + { + "name": "properties_6_0", + "schemas": { + "properties_6_0": { + "properties": { + "foo": { + "type": "string" + } + } } } } - } + ] }, "tests": [ { @@ -395,19 +430,24 @@ { "description": "inheritance: nested object inherits strictness from strict parent", "database": { - "schemas": { - "properties_7_0": { - "properties": { - "nested": { + "types": [ + { + "name": "properties_7_0", + "schemas": { + "properties_7_0": { "properties": { - "foo": { - "type": "string" + "nested": { + "properties": { + "foo": { + "type": "string" + } + } } } } } } - } + ] }, "tests": [ { @@ -429,20 +469,25 @@ { "description": "override: nested object allows extra properties if extensible: true", "database": { - "schemas": { - "properties_8_0": { - "properties": { - "nested": { - "extensible": true, + "types": [ + { + "name": "properties_8_0", + "schemas": { + "properties_8_0": { "properties": { - "foo": { - "type": "string" + "nested": { + "extensible": true, + "properties": { + "foo": { + "type": "string" + } + } } } } } } - } + ] }, "tests": [ { @@ -464,20 +509,25 @@ { "description": "inheritance: nested object inherits looseness from loose parent", "database": { - "schemas": { - "properties_9_0": { - "extensible": true, - "properties": { - "nested": { + "types": [ + { + "name": "properties_9_0", + "schemas": { + "properties_9_0": { + "extensible": true, "properties": { - "foo": { - "type": "string" + "nested": { + "properties": { + "foo": { + "type": "string" + } + } } } } } } - } + ] }, "tests": [ { @@ -499,21 +549,26 @@ { "description": "override: nested object enforces strictness if extensible: false", "database": { - "schemas": { - "properties_10_0": { - "extensible": true, - "properties": { - "nested": { - "extensible": false, + "types": [ + { + "name": "properties_10_0", + "schemas": { + "properties_10_0": { + "extensible": true, "properties": { - "foo": { - "type": "string" + "nested": { + "extensible": false, + "properties": { + "foo": { + "type": "string" + } + } } } } } } - } + ] }, "tests": [ { @@ -535,22 +590,27 @@ { "description": "arrays: inline items inherit strictness from strict parent", "database": { - "schemas": { - "properties_11_0": { - "properties": { - "list": { - "type": "array", - "items": { - "properties": { - "foo": { - "type": "string" + "types": [ + { + "name": "properties_11_0", + "schemas": { + "properties_11_0": { + "properties": { + "list": { + "type": "array", + "items": { + "properties": { + "foo": { + "type": "string" + } + } } } } } } } - } + ] }, "tests": [ { @@ -574,23 +634,28 @@ { "description": "arrays: inline items inherit looseness from loose parent", "database": { - "schemas": { - "properties_12_0": { - "extensible": true, - "properties": { - "list": { - "type": "array", - "items": { - "properties": { - "foo": { - "type": "string" + "types": [ + { + "name": "properties_12_0", + "schemas": { + "properties_12_0": { + "extensible": true, + "properties": { + "list": { + "type": "array", + "items": { + "properties": { + "foo": { + "type": "string" + } + } } } } } } } - } + ] }, "tests": [ { diff --git a/fixtures/propertyNames.json b/fixtures/propertyNames.json index 85a8c37..0128953 100644 --- a/fixtures/propertyNames.json +++ b/fixtures/propertyNames.json @@ -2,14 +2,19 @@ { "description": "propertyNames validation", "database": { - "schemas": { - "propertyNames_0_0": { - "propertyNames": { - "maxLength": 3 - }, - "extensible": true + "types": [ + { + "name": "propertyNames_0_0", + "schemas": { + "propertyNames_0_0": { + "propertyNames": { + "maxLength": 3 + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -82,14 +87,19 @@ { "description": "propertyNames validation with pattern", "database": { - "schemas": { - "propertyNames_1_0": { - "propertyNames": { - "pattern": "^a+$" - }, - "extensible": true + "types": [ + { + "name": "propertyNames_1_0", + "schemas": { + "propertyNames_1_0": { + "propertyNames": { + "pattern": "^a+$" + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -130,12 +140,17 @@ { "description": "propertyNames with boolean schema true", "database": { - "schemas": { - "propertyNames_2_0": { - "propertyNames": true, - "extensible": true + "types": [ + { + "name": "propertyNames_2_0", + "schemas": { + "propertyNames_2_0": { + "propertyNames": true, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -163,12 +178,17 @@ { "description": "propertyNames with boolean schema false", "database": { - "schemas": { - "propertyNames_3_0": { - "propertyNames": false, - "extensible": true + "types": [ + { + "name": "propertyNames_3_0", + "schemas": { + "propertyNames_3_0": { + "propertyNames": false, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -196,14 +216,19 @@ { "description": "propertyNames with const", "database": { - "schemas": { - "propertyNames_4_0": { - "propertyNames": { - "const": "foo" - }, - "extensible": true + "types": [ + { + "name": "propertyNames_4_0", + "schemas": { + "propertyNames_4_0": { + "propertyNames": { + "const": "foo" + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -242,17 +267,22 @@ { "description": "propertyNames with enum", "database": { - "schemas": { - "propertyNames_5_0": { - "propertyNames": { - "enum": [ - "foo", - "bar" - ] - }, - "extensible": true + "types": [ + { + "name": "propertyNames_5_0", + "schemas": { + "propertyNames_5_0": { + "propertyNames": { + "enum": [ + "foo", + "bar" + ] + }, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -303,14 +333,19 @@ { "description": "extensible: true allows extra properties (checked by propertyNames)", "database": { - "schemas": { - "propertyNames_6_0": { - "propertyNames": { - "maxLength": 3 - }, - "extensible": true + "types": [ + { + "name": "propertyNames_6_0", + "schemas": { + "propertyNames_6_0": { + "propertyNames": { + "maxLength": 3 + }, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/required.json b/fixtures/required.json index 97fd836..21fb9fb 100644 --- a/fixtures/required.json +++ b/fixtures/required.json @@ -2,17 +2,22 @@ { "description": "required validation", "database": { - "schemas": { - "required_0_0": { - "properties": { - "foo": {}, - "bar": {} - }, - "required": [ - "foo" - ] + "types": [ + { + "name": "required_0_0", + "schemas": { + "required_0_0": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": [ + "foo" + ] + } + } } - } + ] }, "tests": [ { @@ -87,13 +92,18 @@ { "description": "required default validation", "database": { - "schemas": { - "required_1_0": { - "properties": { - "foo": {} + "types": [ + { + "name": "required_1_0", + "schemas": { + "required_1_0": { + "properties": { + "foo": {} + } + } } } - } + ] }, "tests": [ { @@ -110,14 +120,19 @@ { "description": "required with empty array", "database": { - "schemas": { - "required_2_0": { - "properties": { - "foo": {} - }, - "required": [] + "types": [ + { + "name": "required_2_0", + "schemas": { + "required_2_0": { + "properties": { + "foo": {} + }, + "required": [] + } + } } - } + ] }, "tests": [ { @@ -134,19 +149,24 @@ { "description": "required with escaped characters", "database": { - "schemas": { - "required_3_0": { - "required": [ - "foo\nbar", - "foo\"bar", - "foo\\bar", - "foo\rbar", - "foo\tbar", - "foo\fbar" - ], - "extensible": true + "types": [ + { + "name": "required_3_0", + "schemas": { + "required_3_0": { + "required": [ + "foo\nbar", + "foo\"bar", + "foo\\bar", + "foo\rbar", + "foo\tbar", + "foo\fbar" + ], + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -183,16 +203,21 @@ "description": "required properties whose names are Javascript object property names", "comment": "Ensure JS implementations don't universally consider e.g. __proto__ to always be present in an object.", "database": { - "schemas": { - "required_4_0": { - "required": [ - "__proto__", - "toString", - "constructor" - ], - "extensible": true + "types": [ + { + "name": "required_4_0", + "schemas": { + "required_4_0": { + "required": [ + "__proto__", + "toString", + "constructor" + ], + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -279,14 +304,19 @@ { "description": "extensible: true allows extra properties in required", "database": { - "schemas": { - "required_5_0": { - "required": [ - "foo" - ], - "extensible": true + "types": [ + { + "name": "required_5_0", + "schemas": { + "required_5_0": { + "required": [ + "foo" + ], + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/fixtures/uniqueItems.json b/fixtures/uniqueItems.json index 17adf27..6fb55d1 100644 --- a/fixtures/uniqueItems.json +++ b/fixtures/uniqueItems.json @@ -2,12 +2,17 @@ { "description": "uniqueItems validation", "database": { - "schemas": { - "uniqueItems_0_0": { - "uniqueItems": true, - "extensible": true + "types": [ + { + "name": "uniqueItems_0_0", + "schemas": { + "uniqueItems_0_0": { + "uniqueItems": true, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -468,20 +473,25 @@ { "description": "uniqueItems with an array of items", "database": { - "schemas": { - "uniqueItems_1_0": { - "prefixItems": [ - { - "type": "boolean" - }, - { - "type": "boolean" + "types": [ + { + "name": "uniqueItems_1_0", + "schemas": { + "uniqueItems_1_0": { + "prefixItems": [ + { + "type": "boolean" + }, + { + "type": "boolean" + } + ], + "uniqueItems": true, + "extensible": true } - ], - "uniqueItems": true, - "extensible": true + } } - } + ] }, "tests": [ { @@ -593,20 +603,25 @@ { "description": "uniqueItems with an array of items and additionalItems=false", "database": { - "schemas": { - "uniqueItems_2_0": { - "prefixItems": [ - { - "type": "boolean" - }, - { - "type": "boolean" + "types": [ + { + "name": "uniqueItems_2_0", + "schemas": { + "uniqueItems_2_0": { + "prefixItems": [ + { + "type": "boolean" + }, + { + "type": "boolean" + } + ], + "uniqueItems": true, + "items": false } - ], - "uniqueItems": true, - "items": false + } } - } + ] }, "tests": [ { @@ -675,12 +690,17 @@ { "description": "uniqueItems=false validation", "database": { - "schemas": { - "uniqueItems_3_0": { - "uniqueItems": false, - "extensible": true + "types": [ + { + "name": "uniqueItems_3_0", + "schemas": { + "uniqueItems_3_0": { + "uniqueItems": false, + "extensible": true + } + } } - } + ] }, "tests": [ { @@ -920,20 +940,25 @@ { "description": "uniqueItems=false with an array of items", "database": { - "schemas": { - "uniqueItems_4_0": { - "prefixItems": [ - { - "type": "boolean" - }, - { - "type": "boolean" + "types": [ + { + "name": "uniqueItems_4_0", + "schemas": { + "uniqueItems_4_0": { + "prefixItems": [ + { + "type": "boolean" + }, + { + "type": "boolean" + } + ], + "uniqueItems": false, + "extensible": true } - ], - "uniqueItems": false, - "extensible": true + } } - } + ] }, "tests": [ { @@ -1045,20 +1070,25 @@ { "description": "uniqueItems=false with an array of items and additionalItems=false", "database": { - "schemas": { - "uniqueItems_5_0": { - "prefixItems": [ - { - "type": "boolean" - }, - { - "type": "boolean" + "types": [ + { + "name": "uniqueItems_5_0", + "schemas": { + "uniqueItems_5_0": { + "prefixItems": [ + { + "type": "boolean" + }, + { + "type": "boolean" + } + ], + "uniqueItems": false, + "items": false } - ], - "uniqueItems": false, - "items": false + } } - } + ] }, "tests": [ { @@ -1127,12 +1157,17 @@ { "description": "extensible: true allows extra items in uniqueItems", "database": { - "schemas": { - "uniqueItems_6_0": { - "uniqueItems": true, - "extensible": true + "types": [ + { + "name": "uniqueItems_6_0", + "schemas": { + "uniqueItems_6_0": { + "uniqueItems": true, + "extensible": true + } + } } - } + ] }, "tests": [ { diff --git a/log.txt b/log.txt new file mode 100644 index 0000000..794a356 --- /dev/null +++ b/log.txt @@ -0,0 +1,23 @@ + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.60s + Running unittests src/lib.rs (target/debug/deps/jspg-d3f18ff3a7e2b386) + +running 1 test +test tests::test_library_api ... FAILED + +failures: + +---- tests::test_library_api stdout ---- + +thread 'tests::test_library_api' (110325727) panicked at src/tests/mod.rs:86:3: +assertion `left == right` failed + left: Object {"response": Object {"enums": Object {}, "puncs": Object {}, "relations": Object {"fk_test_target": Object {"constraint": String("fk_test_target"), "destination_columns": Array [String("id")], "destination_type": String("target_schema"), "id": String("11111111-1111-1111-1111-111111111111"), "prefix": String("target"), "source_columns": Array [String("target_id")], "source_type": String("source_schema"), "type": String("relation")}}, "types": Object {"source_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("source_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("source_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"source_schema": Object {"compiledEdges": Object {"target": Object {"constraint": String("fk_test_target"), "forward": Bool(true)}}, "compiledPropertyNames": Array [String("name"), String("target"), String("type")], "properties": Object {"name": Object {"type": String("string")}, "target": Object {"compiledPropertyNames": Array [String("value")], "type": String("target_schema")}, "type": Object {"type": String("string")}}, "required": Array [String("name")], "type": String("object")}, "source_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "properties": Object {"$and": Object {"items": Object {"type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "name": Object {"type": Array [String("string.condition"), String("null")]}, "target": Object {"type": Array [String("target_schema.filter"), String("null")]}, "type": Object {"type": Array [String("string.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("source_schema")]}, "target_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("target_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("target_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"target_schema": Object {"compiledPropertyNames": Array [String("value")], "properties": Object {"value": Object {"type": String("number")}}, "type": String("object")}, "target_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "properties": Object {"$and": Object {"items": Object {"type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "value": Object {"type": Array [String("number.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("target_schema")]}}}, "type": String("drop")} + right: Object {"response": Object {"enums": Object {}, "puncs": Object {}, "relations": Object {"fk_test_target": Object {"constraint": String("fk_test_target"), "destination_columns": Array [String("id")], "destination_type": String("target_schema"), "id": String("11111111-1111-1111-1111-111111111111"), "prefix": String("target"), "source_columns": Array [String("target_id")], "source_type": String("source_schema"), "type": String("relation")}}, "types": Object {"source_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("source_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("source_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"source_schema": Object {"compiledEdges": Object {"target": Object {"constraint": String("fk_test_target"), "forward": Bool(true)}}, "compiledPropertyNames": Array [String("name"), String("target"), String("type")], "properties": Object {"name": Object {"type": String("string")}, "target": Object {"compiledPropertyNames": Array [String("value")], "type": String("target_schema")}, "type": Object {"type": String("string")}}, "required": Array [String("name")], "type": String("object")}, "source_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "properties": Object {"$and": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "name": Object {"type": Array [String("string.condition"), String("null")]}, "target": Object {"type": Array [String("target_schema.filter"), String("null")]}, "type": Object {"type": Array [String("string.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("source_schema")]}, "target_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("target_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("target_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"target_schema": Object {"compiledPropertyNames": Array [String("value")], "properties": Object {"value": Object {"type": String("number")}}, "type": String("object")}, "target_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "properties": Object {"$and": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "value": Object {"type": Array [String("number.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("target_schema")]}}}, "type": String("drop")} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::test_library_api + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1357 filtered out; finished in 0.00s + +error: test failed, to rerun pass `--lib` diff --git a/log_test.txt b/log_test.txt new file mode 100644 index 0000000..bdd9215 --- /dev/null +++ b/log_test.txt @@ -0,0 +1,23 @@ + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.35s + Running unittests src/lib.rs (target/debug/deps/jspg-d3f18ff3a7e2b386) + +running 1 test +test tests::test_library_api ... FAILED + +failures: + +---- tests::test_library_api stdout ---- + +thread 'tests::test_library_api' (110334696) panicked at src/tests/mod.rs:86:3: +assertion `left == right` failed + left: Object {"response": Object {"enums": Object {}, "puncs": Object {}, "relations": Object {"fk_test_target": Object {"constraint": String("fk_test_target"), "destination_columns": Array [String("id")], "destination_type": String("target_schema"), "id": String("11111111-1111-1111-1111-111111111111"), "prefix": String("target"), "source_columns": Array [String("target_id")], "source_type": String("source_schema"), "type": String("relation")}}, "types": Object {"source_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("source_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("source_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"source_schema": Object {"compiledEdges": Object {"target": Object {"constraint": String("fk_test_target"), "forward": Bool(true)}}, "compiledPropertyNames": Array [String("name"), String("target"), String("type")], "properties": Object {"name": Object {"type": String("string")}, "target": Object {"compiledPropertyNames": Array [String("value")], "type": String("target_schema")}, "type": Object {"type": String("string")}}, "required": Array [String("name")], "type": String("object")}, "source_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "properties": Object {"$and": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "name": Object {"type": Array [String("string.condition"), String("null")]}, "target": Object {"type": Array [String("target_schema.filter"), String("null")]}, "type": Object {"type": Array [String("string.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("source_schema")]}, "target_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("target_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("target_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"target_schema": Object {"compiledPropertyNames": Array [String("value")], "properties": Object {"value": Object {"type": String("number")}}, "type": String("object")}, "target_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "properties": Object {"$and": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "value": Object {"type": Array [String("number.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("target_schema")]}}}, "type": String("drop")} + right: Object {"response": Object {"enums": Object {}, "puncs": Object {}, "relations": Object {"fk_test_target": Object {"constraint": String("fk_test_target"), "destination_columns": Array [String("id")], "destination_type": String("target_schema"), "id": String("11111111-1111-1111-1111-111111111111"), "prefix": String("target"), "source_columns": Array [String("target_id")], "source_type": String("source_schema"), "type": String("relation")}}, "types": Object {"source_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("source_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("source_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"source_schema": Object {"compiledEdges": Object {"target": Object {"constraint": String("fk_test_target"), "forward": Bool(true)}}, "compiledPropertyNames": Array [String("name"), String("target"), String("type")], "properties": Object {"name": Object {"type": String("string")}, "target": Object {"compiledPropertyNames": Array [String("value")], "type": String("target_schema")}, "type": Object {"type": String("string")}}, "required": Array [String("name")], "type": String("object")}, "source_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("name"), String("target"), String("type")], "properties": Object {"$and": Object {"items": Object {"type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"type": String("source_schema.filter")}, "type": Array [String("array"), String("null")]}, "name": Object {"type": Array [String("string.condition"), String("null")]}, "target": Object {"type": Array [String("target_schema.filter"), String("null")]}, "type": Object {"type": Array [String("string.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("source_schema")]}, "target_schema": Object {"default_fields": Array [], "field_types": Null, "fields": Array [], "grouped_fields": Null, "hierarchy": Array [String("target_schema"), String("entity")], "historical": Bool(false), "id": String(""), "longevity": Null, "lookup_fields": Array [], "module": String(""), "name": String("target_schema"), "notify": Bool(false), "null_fields": Array [], "ownable": Bool(false), "relationship": Bool(false), "schemas": Object {"target_schema": Object {"compiledPropertyNames": Array [String("value")], "properties": Object {"value": Object {"type": String("number")}}, "type": String("object")}, "target_schema.filter": Object {"compiledPropertyNames": Array [String("$and"), String("$or"), String("value")], "properties": Object {"$and": Object {"items": Object {"type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "$or": Object {"items": Object {"type": String("target_schema.filter")}, "type": Array [String("array"), String("null")]}, "value": Object {"type": Array [String("number.condition"), String("null")]}}, "type": String("filter")}}, "sensitive": Bool(false), "source": String(""), "type": String(""), "variations": Array [String("target_schema")]}}}, "type": String("drop")} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::test_library_api + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1357 filtered out; finished in 0.00s + +error: test failed, to rerun pass `--lib` diff --git a/scripts/migrate_legacy_schemas.py b/scripts/migrate_legacy_schemas.py new file mode 100644 index 0000000..c30c484 --- /dev/null +++ b/scripts/migrate_legacy_schemas.py @@ -0,0 +1,55 @@ +import json +import os +import glob + +fixtures_dir = 'fixtures' +for filepath in glob.glob(os.path.join(fixtures_dir, '*.json')): + try: + with open(filepath, 'r') as f: + data = json.load(f) + except Exception as e: + continue + + changed = False + for suite in data: + db = suite.get("database") + if not db or "schemas" not in db: + continue + + legacy_schemas = db["schemas"] + # Make sure types array is ready + if "types" not in db: + db["types"] = [] + + # Push schemas into types + for schema_id, schema_def in legacy_schemas.items(): + base_name = schema_id.split('.')[-1] + + # Find an existing type with base_name first + found = False + for t in db["types"]: + if t.get("name") == base_name: + if "schemas" not in t: + t["schemas"] = {} + t["schemas"][schema_id] = schema_def + found = True + break + + if not found: + db["types"].append({ + "name": base_name, + "variations": [base_name], # Optional placeholder, shouldn't break anything + "hierarchy": [base_name, "entity"], + "schemas": { + schema_id: schema_def + } + }) + + # Clean up legacy global map + del db["schemas"] + changed = True + + if changed: + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + print("Migrated legacy schemas to types in", filepath) diff --git a/scripts/migrate_properly.py b/scripts/migrate_properly.py new file mode 100644 index 0000000..fedf73e --- /dev/null +++ b/scripts/migrate_properly.py @@ -0,0 +1,54 @@ +import json +import os +import glob + +fixtures_dir = 'fixtures' +for filepath in glob.glob(os.path.join(fixtures_dir, '*.json')): + try: + with open(filepath, 'r') as f: + data = json.load(f) + except Exception as e: + print(f"Failed to load {filepath}: {e}") + continue + + changed = False + for suite in data: + db = suite.get("database") + if not db or "schemas" not in db: + continue + + legacy_schemas = db["schemas"] + # Make sure types array is ready + if "types" not in db: + db["types"] = [] + + # Push schemas into types + for schema_id, schema_def in legacy_schemas.items(): + base_name = schema_id.split('.')[-1] + + # Find an existing type with base_name first + found = False + for t in db["types"]: + if t.get("name") == base_name: + if "schemas" not in t: + t["schemas"] = {} + t["schemas"][schema_id] = schema_def + found = True + break + + if not found: + db["types"].append({ + "name": base_name, + "schemas": { + schema_id: schema_def + } + }) + + # Clean up legacy global map + del db["schemas"] + changed = True + + if changed: + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + print("Migrated legacy schemas to types properly in", filepath) diff --git a/scripts/revert_puncs_to_types.js b/scripts/revert_puncs_to_types.js new file mode 100644 index 0000000..0de3656 --- /dev/null +++ b/scripts/revert_puncs_to_types.js @@ -0,0 +1,41 @@ +const fs = require('fs'); +const path = require('path'); + +function updateFile(filePath) { + let content = fs.readFileSync(filePath, 'utf8'); + let data; + try { + data = JSON.parse(content); + } catch (e) { + console.error("Failed to parse " + filePath, e); + return; + } + + let changed = false; + for (let suite of data) { + if (suite.database && suite.database.puncs && suite.database.puncs.length > 0) { + if (!suite.database.types) suite.database.types = []; + for (let punc of suite.database.puncs) { + // Determine if we should push it to types. + // Basically all of them should go to types except maybe if they are explicitly being tested as Puncs? + // But the tests construct Queryer and Merger using these ids, which query the Type Realm. + suite.database.types.push(punc); + } + delete suite.database.puncs; + changed = true; + } + } + + if (changed) { + fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); + console.log("Reverted puncs to types in " + filePath); + } +} + +let fixturesDir = 'fixtures'; +let files = fs.readdirSync(fixturesDir); +for (let file of files) { + if (file.endsWith('.json')) { + updateFile(path.join(fixturesDir, file)); + } +} diff --git a/scripts/revert_puncs_to_types.py b/scripts/revert_puncs_to_types.py new file mode 100644 index 0000000..6541fc1 --- /dev/null +++ b/scripts/revert_puncs_to_types.py @@ -0,0 +1,29 @@ +import json +import os +import glob + +fixtures_dir = 'fixtures' +for filepath in glob.glob(os.path.join(fixtures_dir, '*.json')): + with open(filepath, 'r') as f: + try: + data = json.load(f) + except Exception as e: + print("Failed to parse", filepath, e) + continue + + changed = False + for suite in data: + db = suite.get("database", {}) + puncs = db.get("puncs", []) + if puncs: + if "types" not in db: + db["types"] = [] + for punc in puncs: + db["types"].append(punc) + del db["puncs"] + changed = True + + if changed: + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + print("Reverted puncs to types in", filepath) diff --git a/scripts/update_fixtures.js b/scripts/update_fixtures.js new file mode 100644 index 0000000..243f381 --- /dev/null +++ b/scripts/update_fixtures.js @@ -0,0 +1,43 @@ +const fs = require('fs'); +const path = require('path'); + +function updateFile(filePath) { + let content = fs.readFileSync(filePath, 'utf8'); + let data; + try { + data = JSON.parse(content); + } catch (e) { + console.error("Failed to parse " + filePath, e); + return; + } + + let changed = false; + for (let suite of data) { + if (suite.database && suite.database.schemas) { + if (!suite.database.puncs) suite.database.puncs = []; + for (let id of Object.keys(suite.database.schemas)) { + let schema = suite.database.schemas[id]; + let puncType = { + name: id, + schemas: { [id]: schema } + }; + suite.database.puncs.push(puncType); + } + delete suite.database.schemas; + changed = true; + } + } + + if (changed) { + fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); + console.log("Updated " + filePath); + } +} + +let fixturesDir = 'fixtures'; +let files = fs.readdirSync(fixturesDir); +for (let file of files) { + if (file.endsWith('.json')) { + updateFile(path.join(fixturesDir, file)); + } +} diff --git a/scripts/update_fixtures.py b/scripts/update_fixtures.py new file mode 100644 index 0000000..83dea54 --- /dev/null +++ b/scripts/update_fixtures.py @@ -0,0 +1,33 @@ +import json +import os + +fixtures_dir = 'fixtures' + +for filename in os.listdir(fixtures_dir): + if not filename.endswith('.json'): + continue + filepath = os.path.join(fixtures_dir, filename) + with open(filepath, 'r') as f: + try: + data = json.load(f) + except json.JSONDecodeError: + print("Failed to parse", filepath) + continue + changed = False + for suite in data: + db = suite.get('database', {}) + if 'schemas' in db: + if 'types' not in db: + db['types'] = [] + for id_str, schema in db['schemas'].items(): + target_type = { + 'name': id_str, + 'schemas': { id_str: schema } + } + db['types'].append(target_type) + del db['schemas'] + changed = True + if changed: + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + print("Updated", filepath) diff --git a/src/database/compile/mod.rs b/src/database/compile/mod.rs index 5c66379..35ed18e 100644 --- a/src/database/compile/mod.rs +++ b/src/database/compile/mod.rs @@ -52,7 +52,7 @@ impl Schema { // 1. Resolve INHERITANCE dependencies first if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ { if !crate::database::object::is_primitive_type(t) { - if let Some(parent) = db.schemas.get(t) { + if let Some(parent) = db.get_scoped_schema(crate::database::realm::SchemaRealm::Type, t) { parent.as_ref().compile(db, t, t.clone(), errors); if let Some(p_props) = parent.obj.compiled_properties.get() { props.extend(p_props.clone()); @@ -86,7 +86,7 @@ impl Schema { for t in types { if !crate::database::object::is_primitive_type(t) { - if let Some(parent) = db.schemas.get(t) { + if let Some(parent) = db.get_scoped_schema(crate::database::realm::SchemaRealm::Type, t) { parent.as_ref().compile(db, t, t.clone(), errors); } } diff --git a/src/database/compile/polymorphism.rs b/src/database/compile/polymorphism.rs index 0ba1c25..cfb51a5 100644 --- a/src/database/compile/polymorphism.rs +++ b/src/database/compile/polymorphism.rs @@ -29,7 +29,7 @@ impl Schema { format!("{}.{}", family_prefix, var) }; - if db.schemas.contains_key(&target_id) { + if db.get_scoped_schema(crate::database::realm::SchemaRealm::Type, &target_id).is_some() { options.insert(var.to_string(), (None, Some(target_id))); } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 71214ab..6953e7c 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -6,12 +6,11 @@ pub mod formats; pub mod object; pub mod page; pub mod punc; +pub mod realm; pub mod relation; pub mod schema; pub mod r#type; -// External mock exports inside the executor sub-folder - use r#enum::Enum; use executors::DatabaseExecutor; @@ -22,6 +21,7 @@ use executors::pgrx::SpiExecutor; use executors::mock::MockExecutor; use punc::Punc; +use realm::SchemaRealm; use relation::Relation; use schema::Schema; use serde_json::Value; @@ -36,8 +36,6 @@ pub struct Database { pub puncs: HashMap, pub relations: HashMap, #[serde(skip)] - pub schemas: HashMap>, - #[serde(skip)] pub executor: Box, } @@ -48,7 +46,6 @@ impl Database { types: HashMap::new(), relations: HashMap::new(), puncs: HashMap::new(), - schemas: HashMap::new(), #[cfg(not(test))] executor: Box::new(SpiExecutor::new()), #[cfg(test)] @@ -157,26 +154,6 @@ impl Database { } } - if let Some(map) = val.get("schemas").and_then(|v| v.as_object()) { - for (key, item) in map.iter() { - match serde_json::from_value::(item.clone()) { - Ok(schema) => { - db.schemas.insert(key.clone(), Arc::new(schema)); - } - Err(e) => { - errors.push(crate::drop::Error { - code: "DATABASE_SCHEMA_PARSE_FAILED".to_string(), - message: format!("Failed to parse database schema key '{}': {}", key, e), - details: crate::drop::ErrorDetails { - context: Some(serde_json::json!(key)), - ..Default::default() - }, - }); - } - } - } - } - db.compile(&mut errors); let drop = if errors.is_empty() { crate::drop::Drop::success() @@ -213,30 +190,26 @@ impl Database { } pub fn compile(&mut self, errors: &mut Vec) { - // Collect existing schemas patched in the databse - let mut harvested = Vec::new(); - for (id, schema_arc) in &self.schemas { - crate::database::schema::Schema::collect_schemas( - schema_arc, - id, - id.clone(), - &mut harvested, - errors, - ); - } - for (id, schema_arc) in harvested { - self.schemas.insert(id, schema_arc); - } - self.collect_schemas(errors); - // Mathematically evaluate all property inheritances, formats, schemas, and foreign key edges topographically over OnceLocks - for (id, schema_arc) in &self.schemas { - // First compile pass initializes exact structural root_id mapping to resolve DB constraints - let root_id = id.split('/').next().unwrap_or(id); - schema_arc - .as_ref() - .compile(self, root_id, id.clone(), errors); + // Formally evaluate properties with strict 3-pass Ordered Graph execution natively + for (_, enum_def) in &self.enums { + for (schema_id, schema_arc) in &enum_def.schemas { + let root_id = schema_id.split('/').next().unwrap_or(schema_id); + schema_arc.as_ref().compile(self, root_id, schema_id.clone(), errors); + } + } + for (_, type_def) in &self.types { + for (schema_id, schema_arc) in &type_def.schemas { + let root_id = schema_id.split('/').next().unwrap_or(schema_id); + schema_arc.as_ref().compile(self, root_id, schema_id.clone(), errors); + } + } + for (_, punc_def) in &self.puncs { + for (schema_id, schema_arc) in &punc_def.schemas { + let root_id = schema_id.split('/').next().unwrap_or(schema_id); + schema_arc.as_ref().compile(self, root_id, schema_id.clone(), errors); + } } // Phase 2: Synthesize Composed Filter References @@ -260,16 +233,15 @@ impl Database { let mut filter_ids = Vec::new(); for (type_name, id, filter_arc) in filter_schemas { - filter_ids.push(id.clone()); - self.schemas.insert(id.clone(), filter_arc.clone()); + filter_ids.push((type_name.clone(), id.clone())); if let Some(t) = self.types.get_mut(&type_name) { t.schemas.insert(id, filter_arc); } } // Now actively compile the newly injected filters to lock all nested compose references natively - for id in filter_ids { - if let Some(filter_arc) = self.schemas.get(&id).cloned() { + for (type_name, id) in filter_ids { + if let Some(filter_arc) = self.types.get(&type_name).and_then(|t| t.schemas.get(&id)).cloned() { let root_id = id.split('/').next().unwrap_or(&id); filter_arc .as_ref() @@ -282,13 +254,11 @@ impl Database { let mut type_insert = Vec::new(); let mut punc_insert = Vec::new(); let mut enum_insert = Vec::new(); - let mut global_insert = Vec::new(); // Pass 1: Extract all Schemas structurally off top level definitions into the master registry. // Validate every node recursively via string filters natively! for (type_name, type_def) in &self.types { for (id, schema_arc) in &type_def.schemas { - global_insert.push((id.clone(), Arc::clone(schema_arc))); let mut local_insert = Vec::new(); crate::database::schema::Schema::collect_schemas( schema_arc, @@ -299,14 +269,12 @@ impl Database { ); for entry in &local_insert { type_insert.push((type_name.clone(), entry.0.clone(), Arc::clone(&entry.1))); - global_insert.push((entry.0.clone(), Arc::clone(&entry.1))); } } } for (punc_name, punc_def) in &self.puncs { for (id, schema_arc) in &punc_def.schemas { - global_insert.push((id.clone(), Arc::clone(schema_arc))); let mut local_insert = Vec::new(); crate::database::schema::Schema::collect_schemas( schema_arc, @@ -317,14 +285,12 @@ impl Database { ); for entry in &local_insert { punc_insert.push((punc_name.clone(), entry.0.clone(), Arc::clone(&entry.1))); - global_insert.push((entry.0.clone(), Arc::clone(&entry.1))); } } } for (enum_name, enum_def) in &self.enums { for (id, schema_arc) in &enum_def.schemas { - global_insert.push((id.clone(), Arc::clone(schema_arc))); let mut local_insert = Vec::new(); crate::database::schema::Schema::collect_schemas( schema_arc, @@ -335,16 +301,10 @@ impl Database { ); for entry in &local_insert { enum_insert.push((enum_name.clone(), entry.0.clone(), Arc::clone(&entry.1))); - global_insert.push((entry.0.clone(), Arc::clone(&entry.1))); } } } - // Apply global inserts - for (id, schema_arc) in global_insert { - self.schemas.insert(id, schema_arc); - } - // Apply local scopes for (origin_name, id, schema_arc) in type_insert { if let Some(t) = self.types.get_mut(&origin_name) { @@ -362,6 +322,40 @@ impl Database { } } } + + pub fn get_scoped_schema(&self, realm: SchemaRealm, schema_id: &str) -> Option> { + // Punc Realm natively maps mathematically to `.request` and `.response` shapes + if realm == SchemaRealm::Punc { + if schema_id.ends_with(".request") || schema_id.ends_with(".response") { + let punc_name = schema_id + .trim_end_matches(".request") + .trim_end_matches(".response"); + return self.puncs.get(punc_name).and_then(|p| p.schemas.get(schema_id).cloned()); + } + } + + let clean_id = schema_id.trim_end_matches(".filter"); + let root_id = clean_id.split('/').next().unwrap_or(clean_id); + let base_name = root_id.split('.').next_back().unwrap_or(root_id); + + // Puncs and Types can lookup Table boundaries + if realm == SchemaRealm::Type || realm == SchemaRealm::Punc { + if let Some(type_def) = self.types.get(base_name) { + if let Some(schema) = type_def.schemas.get(schema_id) { + return Some(schema.clone()); + } + } + } + + // All realms can intrinsically look up enumerations + if let Some(enum_def) = self.enums.get(base_name) { + if let Some(schema) = enum_def.schemas.get(schema_id) { + return Some(schema.clone()); + } + } + + None + } /// Inspects the Postgres pg_constraint relations catalog to securely identify /// the precise Foreign Key connecting a parent and child hierarchy path. diff --git a/src/database/realm.rs b/src/database/realm.rs new file mode 100644 index 0000000..4ec6ac7 --- /dev/null +++ b/src/database/realm.rs @@ -0,0 +1,6 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum SchemaRealm { + Enum, + Type, + Punc, +} diff --git a/src/merger/mod.rs b/src/merger/mod.rs index a6fec9b..115e1eb 100644 --- a/src/merger/mod.rs +++ b/src/merger/mod.rs @@ -4,6 +4,7 @@ pub mod cache; use crate::database::Database; +use crate::database::realm::SchemaRealm; use crate::database::r#type::Type; use serde_json::Value; use std::sync::Arc; @@ -24,8 +25,8 @@ impl Merger { pub fn merge(&self, schema_id: &str, data: Value) -> crate::drop::Drop { let mut notifications_queue = Vec::new(); - let target_schema = match self.db.schemas.get(schema_id) { - Some(s) => Arc::clone(s), + let target_schema = match self.db.get_scoped_schema(SchemaRealm::Type, schema_id) { + Some(s) => Arc::clone(&s), None => { return crate::drop::Drop::with_errors(vec![crate::drop::Error { code: "MERGE_FAILED".to_string(), @@ -144,30 +145,49 @@ impl Merger { if let Some(v) = val { if let Some((idx_opt, target_id_opt)) = options.get(v) { if let Some(target_id) = target_id_opt { - if let Some(target_schema) = self.db.schemas.get(target_id) { - schema = Arc::clone(target_schema); + if let Some(target_schema) = + self.db.get_scoped_schema(SchemaRealm::Type, target_id) + { + schema = target_schema.clone(); } else { - return Err(format!("Polymorphic mapped target '{}' not found in database registry", target_id)); + return Err(format!( + "Polymorphic mapped target '{}' not found in database registry", + target_id + )); } } else if let Some(idx) = idx_opt { - if let Some(target_schema) = schema.obj.one_of.as_ref().and_then(|options| options.get(*idx)) { - schema = Arc::clone(target_schema); + if let Some(target_schema) = schema + .obj + .one_of + .as_ref() + .and_then(|options| options.get(*idx)) + { + schema = Arc::clone(target_schema); } else { - return Err(format!("Polymorphic index target '{}' not found in local oneOf array", idx)); + return Err(format!( + "Polymorphic index target '{}' not found in local oneOf array", + idx + )); } } else { return Err(format!("Polymorphic mapped target has no path")); } } else { - return Err(format!("Polymorphic discriminator {}='{}' matched no compiled options", disc, v)); + return Err(format!( + "Polymorphic discriminator {}='{}' matched no compiled options", + disc, v + )); } } else { - return Err(format!("Polymorphic merging failed: missing required discriminator '{}'", disc)); + return Err(format!( + "Polymorphic merging failed: missing required discriminator '{}'", + disc + )); } } } self.merge_object(schema, map, notifications) - }, + } _ => Err("Invalid merge payload: root must be an Object or Array".to_string()), } } diff --git a/src/queryer/compiler.rs b/src/queryer/compiler.rs index 51a157a..dd9413b 100644 --- a/src/queryer/compiler.rs +++ b/src/queryer/compiler.rs @@ -1,4 +1,5 @@ use crate::database::Database; +use crate::database::realm::SchemaRealm; use std::sync::Arc; pub struct Compiler<'a> { @@ -24,13 +25,18 @@ pub struct Node<'a> { impl<'a> Compiler<'a> { /// Compiles a JSON schema into a nested PostgreSQL query returning JSONB pub fn compile(&self, schema_id: &str, filter_keys: &[String]) -> Result { + let realm = if schema_id.ends_with(".request") || schema_id.ends_with(".response") { + SchemaRealm::Punc + } else { + SchemaRealm::Type + }; + let schema = self .db - .schemas - .get(schema_id) + .get_scoped_schema(realm, schema_id) .ok_or_else(|| format!("Schema not found: {}", schema_id))?; - let target_schema = std::sync::Arc::clone(schema); + let target_schema = schema; let mut compiler = Compiler { db: &self.db, @@ -151,9 +157,9 @@ impl<'a> Compiler<'a> { if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &node.schema.obj.type_ { if !crate::database::object::is_primitive_type(t) { // If it's just an ad-hoc struct ref, we should resolve it - if let Some(target_schema) = self.db.schemas.get(t) { + if let Some(target_schema) = self.db.get_scoped_schema(SchemaRealm::Type, t) { let mut ref_node = node.clone(); - ref_node.schema = Arc::clone(target_schema); + ref_node.schema = target_schema.clone(); ref_node.schema_id = Some(t.clone()); return self.compile_node(ref_node); } @@ -306,9 +312,9 @@ impl<'a> Compiler<'a> { for (disc_val, (idx_opt, target_id_opt)) in options { if let Some(target_id) = target_id_opt { - if let Some(target_schema) = self.db.schemas.get(target_id) { + if let Some(target_schema) = self.db.get_scoped_schema(SchemaRealm::Type, target_id) { let mut child_node = node.clone(); - child_node.schema = Arc::clone(target_schema); + child_node.schema = target_schema.clone(); child_node.schema_id = Some(target_id.clone()); child_node.is_polymorphic_branch = true; diff --git a/src/tests/types/case.rs b/src/tests/types/case.rs index 4b320e5..0f5f4df 100644 --- a/src/tests/types/case.rs +++ b/src/tests/types/case.rs @@ -64,12 +64,6 @@ impl Case { let validator = Validator::new(db); let schema_id = &self.schema_id; - if !validator.db.schemas.contains_key(schema_id) { - return Err(format!( - "Missing Schema: Cannot find schema ID '{}'", - schema_id - )); - } let test_data = self.data.clone().unwrap_or(Value::Null); let result = validator.validate(schema_id, &test_data); diff --git a/src/tests/types/expect/schema.rs b/src/tests/types/expect/schema.rs index 1e74183..d60ab15 100644 --- a/src/tests/types/expect/schema.rs +++ b/src/tests/types/expect/schema.rs @@ -5,7 +5,16 @@ impl Expect { pub fn assert_schemas(&self, db: &Arc) -> Result<(), String> { if let Some(expected_map) = &self.schemas { // Collect actual schemas and sort - let mut actual: Vec = db.schemas.keys().cloned().collect(); + let mut actual: Vec = Vec::new(); + for type_def in db.types.values() { + actual.extend(type_def.schemas.keys().cloned()); + } + for punc_def in db.puncs.values() { + actual.extend(punc_def.schemas.keys().cloned()); + } + for enum_def in db.enums.values() { + actual.extend(enum_def.schemas.keys().cloned()); + } actual.sort(); // Collect expected schemas and sort @@ -26,7 +35,12 @@ impl Expect { if expected_val.is_object() && expected_val.as_object().unwrap().is_empty() { continue; // A `{}` means we just wanted to test it was collected/promoted, skip deep match } - let actual_ast = db.schemas.get(key).unwrap(); + let schema_realm = if key.ends_with(".request") || key.ends_with(".response") { + crate::database::realm::SchemaRealm::Punc + } else { + crate::database::realm::SchemaRealm::Type + }; + let actual_ast = db.get_scoped_schema(schema_realm, key).unwrap(); let actual_val = serde_json::to_value(actual_ast).unwrap(); if actual_val != *expected_val { diff --git a/src/validator/mod.rs b/src/validator/mod.rs index b07994d..dc13a1b 100644 --- a/src/validator/mod.rs +++ b/src/validator/mod.rs @@ -10,6 +10,7 @@ pub use error::ValidationError; pub use result::ValidationResult; use crate::database::Database; +use crate::database::realm::SchemaRealm; use crate::validator::rules::util::is_integer; use serde_json::Value; use std::sync::Arc; @@ -23,10 +24,6 @@ impl Validator { Self { db } } - pub fn get_schema_ids(&self) -> Vec { - self.db.schemas.keys().cloned().collect() - } - pub fn check_type(t: &str, val: &Value) -> bool { if let Value::String(s) = val && s.is_empty() @@ -46,11 +43,17 @@ impl Validator { } pub fn validate(&self, schema_id: &str, instance: &Value) -> crate::drop::Drop { - if let Some(schema) = self.db.schemas.get(schema_id) { + let schema_opt = if schema_id.ends_with(".request") || schema_id.ends_with(".response") { + self.db.get_scoped_schema(SchemaRealm::Punc, schema_id) + } else { + self.db.get_scoped_schema(SchemaRealm::Type, schema_id) + }; + + if let Some(schema) = schema_opt { let ctx = ValidationContext::new( &self.db, - schema, - schema, + &schema, + &schema, instance, HashSet::new(), false, diff --git a/src/validator/rules/object.rs b/src/validator/rules/object.rs index 2adfba3..159a307 100644 --- a/src/validator/rules/object.rs +++ b/src/validator/rules/object.rs @@ -23,10 +23,13 @@ impl<'a> ValidationContext<'a> { // Entity implicit type validation if let Some(ref schema_identifier_str) = schema_identifier { // We decompose identity string routing inherently - let expected_type = schema_identifier_str.split('.').last().unwrap_or(schema_identifier_str); - + let expected_type = schema_identifier_str + .split('.') + .last() + .unwrap_or(schema_identifier_str); + // Check if the identifier represents a registered global database entity boundary mathematically - if let Some(type_def) = self.db.types.get(expected_type) { + if let Some(type_def) = self.db.types.get(expected_type).filter(|t| !t.variations.is_empty()) { if let Some(type_val) = obj.get("type") { if let Some(type_str) = type_val.as_str() { if type_def.variations.contains(type_str) { @@ -47,21 +50,28 @@ impl<'a> ValidationContext<'a> { // Because it's a global entity target, the payload must structurally provide a discriminator natively result.errors.push(ValidationError { code: "MISSING_TYPE".to_string(), - message: format!("Schema mechanically requires type discrimination '{}'", expected_type), + message: format!( + "Schema mechanically requires type discrimination '{}'", + expected_type + ), path: self.path.clone(), // Empty boundary }); } // If the target mathematically declares a horizontal structural STI variation natively if schema_identifier_str.contains('.') { - let requires_kind = self.schema.compiled_properties.get() - .map_or(false, |p| p.contains_key("kind")); - + let requires_kind = self + .schema + .compiled_properties + .get() + .map_or(false, |p| p.contains_key("kind")); + if requires_kind { if obj.get("kind").is_none() { result.errors.push(ValidationError { code: "MISSING_KIND".to_string(), - message: "Schema mechanically requires horizontal kind discrimination".to_string(), + message: "Schema mechanically requires horizontal kind discrimination" + .to_string(), path: self.path.clone(), }); } else { @@ -74,20 +84,20 @@ impl<'a> ValidationContext<'a> { // Because they lack manual type property descriptors, we natively shield "type" and "kind" keys from // triggering additionalProperty violations natively IF they precisely correspond to their fast-path boundaries if let Some(type_val) = obj.get("type") { - if let Some(type_str) = type_val.as_str() { - if type_str == expected_type { - result.evaluated_keys.insert("type".to_string()); - } - } + if let Some(type_str) = type_val.as_str() { + if type_str == expected_type { + result.evaluated_keys.insert("type".to_string()); + } + } } if let Some(kind_val) = obj.get("kind") { - if let Some((kind_str, _)) = schema_identifier_str.rsplit_once('.') { - if let Some(actual_kind) = kind_val.as_str() { - if actual_kind == kind_str { - result.evaluated_keys.insert("kind".to_string()); - } + if let Some((kind_str, _)) = schema_identifier_str.rsplit_once('.') { + if let Some(actual_kind) = kind_val.as_str() { + if actual_kind == kind_str { + result.evaluated_keys.insert("kind".to_string()); } - } + } + } } } } @@ -167,7 +177,9 @@ impl<'a> ValidationContext<'a> { if let Some(child_instance) = obj.get(key) { let new_path = self.join_path(key); let is_ref = match &sub_schema.type_ { - Some(crate::database::object::SchemaTypeOrArray::Single(t)) => !crate::database::object::is_primitive_type(t), + Some(crate::database::object::SchemaTypeOrArray::Single(t)) => { + !crate::database::object::is_primitive_type(t) + } _ => false, }; let next_extensible = if is_ref { false } else { self.extensible }; @@ -182,8 +194,6 @@ impl<'a> ValidationContext<'a> { ); let item_res = derived.validate()?; - - result.merge(item_res); result.evaluated_keys.insert(key.to_string()); } @@ -196,7 +206,9 @@ impl<'a> ValidationContext<'a> { if compiled_re.0.is_match(key) { let new_path = self.join_path(key); let is_ref = match &sub_schema.type_ { - Some(crate::database::object::SchemaTypeOrArray::Single(t)) => !crate::database::object::is_primitive_type(t), + Some(crate::database::object::SchemaTypeOrArray::Single(t)) => { + !crate::database::object::is_primitive_type(t) + } _ => false, }; let next_extensible = if is_ref { false } else { self.extensible }; @@ -225,7 +237,8 @@ impl<'a> ValidationContext<'a> { { locally_matched = true; } - if !locally_matched && let Some(compiled_pp) = self.schema.compiled_pattern_properties.get() + if !locally_matched + && let Some(compiled_pp) = self.schema.compiled_pattern_properties.get() { for (compiled_re, _) in compiled_pp { if compiled_re.0.is_match(key) { @@ -238,7 +251,9 @@ impl<'a> ValidationContext<'a> { if !locally_matched { let new_path = self.join_path(key); let is_ref = match &additional_schema.type_ { - Some(crate::database::object::SchemaTypeOrArray::Single(t)) => !crate::database::object::is_primitive_type(t), + Some(crate::database::object::SchemaTypeOrArray::Single(t)) => { + !crate::database::object::is_primitive_type(t) + } _ => false, }; let next_extensible = if is_ref { false } else { self.extensible }; diff --git a/src/validator/rules/polymorphism.rs b/src/validator/rules/polymorphism.rs index b2b5856..096d1f2 100644 --- a/src/validator/rules/polymorphism.rs +++ b/src/validator/rules/polymorphism.rs @@ -1,6 +1,7 @@ use crate::validator::context::ValidationContext; use crate::validator::error::ValidationError; use crate::validator::result::ValidationResult; +use crate::database::realm::SchemaRealm; impl<'a> ValidationContext<'a> { pub(crate) fn validate_family( @@ -99,8 +100,8 @@ impl<'a> ValidationContext<'a> { if let Some(val) = instance_val { if let Some((idx_opt, target_id_opt)) = options.get(&val) { if let Some(target_id) = target_id_opt { - if let Some(target_schema) = self.db.schemas.get(target_id) { - let derived = self.derive_for_schema(target_schema.as_ref(), false); + if let Some(target_schema) = self.db.get_scoped_schema(SchemaRealm::Type, target_id) { + let derived = self.derive_for_schema(&target_schema, false); let sub_res = derived.validate()?; let is_valid = sub_res.is_valid(); result.merge(sub_res); @@ -221,21 +222,21 @@ impl<'a> ValidationContext<'a> { } for t in custom_types { - if let Some(global_schema) = self.db.schemas.get(&t) { + if let Some(global_schema) = self.db.get_scoped_schema(SchemaRealm::Type, &t) { let mut new_overrides = self.overrides.clone(); if let Some(props) = &self.schema.properties { new_overrides.extend(props.keys().map(|k| k.to_string())); } let mut shadow = self.derive( - global_schema, + &global_schema, self.instance, &self.path, new_overrides, self.extensible, true, // Reporter mode ); - shadow.root = global_schema; + shadow.root = &global_schema; result.merge(shadow.validate()?); } else { result.errors.push(ValidationError { diff --git a/test_failures.log b/test_failures.log new file mode 100644 index 0000000..cfe234b --- /dev/null +++ b/test_failures.log @@ -0,0 +1,81 @@ + Finished `test` profile [unoptimized + debuginfo] target(s) in 0.43s + Running unittests src/lib.rs (target/debug/deps/jspg-d3f18ff3a7e2b386) + +running 11 tests +test tests::test_minimum_0_2 ... ok +test tests::test_minimum_1_4 ... ok +test tests::test_minimum_1_0 ... FAILED +test tests::test_minimum_1_1 ... FAILED +test tests::test_minimum_0_3 ... FAILED +test tests::test_minimum_1_5 ... ok +test tests::test_minimum_1_3 ... FAILED +test tests::test_minimum_0_0 ... FAILED +test tests::test_minimum_0_1 ... FAILED +test tests::test_minimum_1_2 ... FAILED +test tests::test_minimum_1_6 ... FAILED + +failures: + +---- tests::test_minimum_1_0 stdout ---- +TEST VALIDATE ERROR FOR 'negative above the minimum is valid': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_1_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_1_0' (110318318) panicked at src/tests/fixtures.rs:3503:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation with signed integer] Validate Test 'negative above the minimum is valid' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_1_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +---- tests::test_minimum_1_1 stdout ---- +TEST VALIDATE ERROR FOR 'positive above the minimum is valid': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_1_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_1_1' (110318319) panicked at src/tests/fixtures.rs:3509:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation with signed integer] Validate Test 'positive above the minimum is valid' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_1_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + +---- tests::test_minimum_0_3 stdout ---- +TEST VALIDATE ERROR FOR 'ignores non-numbers': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_0_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_0_3' (110318317) panicked at src/tests/fixtures.rs:3497:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation] Validate Test 'ignores non-numbers' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_0_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + +---- tests::test_minimum_1_3 stdout ---- +TEST VALIDATE ERROR FOR 'boundary point with float is valid': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_1_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_1_3' (110318321) panicked at src/tests/fixtures.rs:3521:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation with signed integer] Validate Test 'boundary point with float is valid' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_1_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + +---- tests::test_minimum_0_0 stdout ---- +TEST VALIDATE ERROR FOR 'above the minimum is valid': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_0_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_0_0' (110318314) panicked at src/tests/fixtures.rs:3479:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation] Validate Test 'above the minimum is valid' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_0_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + +---- tests::test_minimum_0_1 stdout ---- +TEST VALIDATE ERROR FOR 'boundary point is valid': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_0_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_0_1' (110318315) panicked at src/tests/fixtures.rs:3485:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation] Validate Test 'boundary point is valid' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_0_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + +---- tests::test_minimum_1_2 stdout ---- +TEST VALIDATE ERROR FOR 'boundary point is valid': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_1_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_1_2' (110318320) panicked at src/tests/fixtures.rs:3515:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation with signed integer] Validate Test 'boundary point is valid' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_1_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + +---- tests::test_minimum_1_6 stdout ---- +TEST VALIDATE ERROR FOR 'ignores non-numbers': Expected success: true, Got: false. Actual Errors: [Error { code: "SCHEMA_NOT_FOUND", message: "Schema minimum_1_0 not found", details: ErrorDetails { path: Some("/"), cause: None, context: None, schema: None } }] + +thread 'tests::test_minimum_1_6' (110318324) panicked at src/tests/fixtures.rs:3539:54: +called `Result::unwrap()` on an `Err` value: "[minimum validation with signed integer] Validate Test 'ignores non-numbers' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"SCHEMA_NOT_FOUND\", message: \"Schema minimum_1_0 not found\", details: ErrorDetails { path: Some(\"/\"), cause: None, context: None, schema: None } }]" + + +failures: + tests::test_minimum_0_0 + tests::test_minimum_0_1 + tests::test_minimum_0_3 + tests::test_minimum_1_0 + tests::test_minimum_1_1 + tests::test_minimum_1_2 + tests::test_minimum_1_3 + tests::test_minimum_1_6 + +test result: FAILED. 3 passed; 8 failed; 0 ignored; 0 measured; 1347 filtered out; finished in 0.00s + +error: test failed, to rerun pass `--lib` diff --git a/test_merge.log b/test_merge.log new file mode 100644 index 0000000..84a54e6 --- /dev/null +++ b/test_merge.log @@ -0,0 +1,23 @@ + Compiling jspg v0.1.0 (/Users/awgneo/Repositories/thoughtpatterns/cellular/jspg) + Finished `test` profile [unoptimized + debuginfo] target(s) in 7.59s + Running unittests src/lib.rs (target/debug/deps/jspg-d3f18ff3a7e2b386) + +running 1 test +test tests::test_merge_0_0 ... FAILED + +failures: + +---- tests::test_merge_0_0 stdout ---- +TEST VALIDATE ERROR FOR 'valid with both properties': Expected success: true, Got: false. Actual Errors: [Error { code: "MISSING_TYPE", message: "Schema mechanically requires type discrimination 'base_0'", details: ErrorDetails { path: Some(""), cause: None, context: None, schema: None } }] + +thread 'tests::test_merge_0_0' (110369726) panicked at src/tests/fixtures.rs:4307:54: +called `Result::unwrap()` on an `Err` value: "[merging: properties accumulate] Validate Test 'valid with both properties' failed. Error: Expected success: true, Got: false. Actual Errors: [Error { code: \"MISSING_TYPE\", message: \"Schema mechanically requires type discrimination 'base_0'\", details: ErrorDetails { path: Some(\"\"), cause: None, context: None, schema: None } }]" +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::test_merge_0_0 + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 1357 filtered out; finished in 0.00s + +error: test failed, to rerun pass `--lib`