massively improves the jspg validator by removing mathmatical functions like allOf, anyOf, ref, etc to effectively use discriminators and OOP with types to determine valid pathing an nno intersections, unions, or guesswork; added cases to replace the former conditionals
This commit is contained in:
@ -1,677 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "allOf",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "allOf_0_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "allOf",
|
||||
"data": {
|
||||
"foo": "baz",
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "allOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch second",
|
||||
"data": {
|
||||
"foo": "baz"
|
||||
},
|
||||
"schema_id": "allOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch first",
|
||||
"data": {
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "allOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "wrong type",
|
||||
"data": {
|
||||
"foo": "baz",
|
||||
"bar": "quux"
|
||||
},
|
||||
"schema_id": "allOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with base schema",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer"
|
||||
},
|
||||
"baz": {},
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"baz": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"baz"
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "allOf_1_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": {
|
||||
"foo": "quux",
|
||||
"bar": 2,
|
||||
"baz": null
|
||||
},
|
||||
"schema_id": "allOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch base schema",
|
||||
"data": {
|
||||
"foo": "quux",
|
||||
"baz": null
|
||||
},
|
||||
"schema_id": "allOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch first allOf",
|
||||
"data": {
|
||||
"bar": 2,
|
||||
"baz": null
|
||||
},
|
||||
"schema_id": "allOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch second allOf",
|
||||
"data": {
|
||||
"foo": "quux",
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "allOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch both",
|
||||
"data": {
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "allOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf simple types",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"maximum": 30
|
||||
},
|
||||
{
|
||||
"minimum": 20
|
||||
}
|
||||
],
|
||||
"$id": "allOf_2_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid",
|
||||
"data": 25,
|
||||
"schema_id": "allOf_2_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "mismatch one",
|
||||
"data": 35,
|
||||
"schema_id": "allOf_2_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, all true",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
true,
|
||||
true
|
||||
],
|
||||
"$id": "allOf_3_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"schema_id": "allOf_3_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, some false",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
true,
|
||||
false
|
||||
],
|
||||
"$id": "allOf_4_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "allOf_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with boolean schemas, all false",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"$id": "allOf_5_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "allOf_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with one empty schema",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{}
|
||||
],
|
||||
"$id": "allOf_6_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any data is valid",
|
||||
"data": 1,
|
||||
"schema_id": "allOf_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with two empty schemas",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{},
|
||||
{}
|
||||
],
|
||||
"$id": "allOf_7_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any data is valid",
|
||||
"data": 1,
|
||||
"schema_id": "allOf_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with the first empty schema",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{},
|
||||
{
|
||||
"type": "number"
|
||||
}
|
||||
],
|
||||
"$id": "allOf_8_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"schema_id": "allOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "allOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with the last empty schema",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
],
|
||||
"$id": "allOf_9_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "number is valid",
|
||||
"data": 1,
|
||||
"schema_id": "allOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "string is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "allOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested allOf, to check validation semantics",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "allOf_10_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"schema_id": "allOf_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"schema_id": "allOf_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "extensible: true allows extra properties in allOf",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
],
|
||||
"extensible": true,
|
||||
"$id": "allOf_12_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "extra property is valid",
|
||||
"data": {
|
||||
"foo": "baz",
|
||||
"bar": 2,
|
||||
"qux": 3
|
||||
},
|
||||
"schema_id": "allOf_12_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "strict by default with allOf properties",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"const": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"bar": {
|
||||
"const": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"$id": "allOf_13_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "validates merged properties",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "allOf_13_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "fails on extra property z explicitly",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"z": 3
|
||||
},
|
||||
"schema_id": "allOf_13_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "allOf with nested extensible: true (partial looseness)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"const": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"extensible": true,
|
||||
"properties": {
|
||||
"bar": {
|
||||
"const": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"$id": "allOf_14_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "extensible subschema doesn't make root extensible if root is strict",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"z": 3
|
||||
},
|
||||
"schema_id": "allOf_14_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "strictness: allOf composition with strict refs",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "partA"
|
||||
},
|
||||
{
|
||||
"$ref": "partB"
|
||||
}
|
||||
],
|
||||
"$id": "allOf_15_0"
|
||||
},
|
||||
{
|
||||
"$id": "partA",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "partB",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "merged instance is valid",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"name": "Me"
|
||||
},
|
||||
"schema_id": "allOf_15_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "extra property is invalid (root is strict)",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"name": "Me",
|
||||
"extra": 1
|
||||
},
|
||||
"schema_id": "allOf_15_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "partA mismatch is invalid",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "Me"
|
||||
},
|
||||
"schema_id": "allOf_15_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
183
fixtures/cases.json
Normal file
183
fixtures/cases.json
Normal file
@ -0,0 +1,183 @@
|
||||
[
|
||||
{
|
||||
"description": "Multi-Paradigm Declarative Cases",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "parallel_rules",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": { "type": "string" },
|
||||
"kind": { "type": "string" }
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"when": { "properties": { "status": {"const": "unverified"} }, "required": ["status"] },
|
||||
"then": {
|
||||
"properties": {
|
||||
"amount_1": {"type": "number"},
|
||||
"amount_2": {"type": "number"}
|
||||
},
|
||||
"required": ["amount_1", "amount_2"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": { "properties": { "kind": {"const": "credit"} }, "required": ["kind"] },
|
||||
"then": {
|
||||
"properties": {
|
||||
"cvv": {"type": "number"}
|
||||
},
|
||||
"required": ["cvv"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"$id": "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"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"$id": "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"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"$id": "missing_when",
|
||||
"type": "object",
|
||||
"cases": [
|
||||
{
|
||||
"else": {
|
||||
"properties": { "unconditional": {"type": "number"} },
|
||||
"required": ["unconditional"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Fires only the first rule successfully",
|
||||
"data": { "status": "unverified", "amount_1": 1, "amount_2": 2 },
|
||||
"schema_id": "parallel_rules",
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Fires both independent parallel rules flawlessly",
|
||||
"data": { "status": "unverified", "kind": "credit", "amount_1": 1, "amount_2": 2, "cvv": 123 },
|
||||
"schema_id": "parallel_rules",
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Catches errors triggered concurrently by multiple independent blocked rules",
|
||||
"data": { "status": "unverified", "kind": "credit" },
|
||||
"schema_id": "parallel_rules",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{ "code": "REQUIRED_FIELD_MISSING", "details": { "path": "amount_1" } },
|
||||
{ "code": "REQUIRED_FIELD_MISSING", "details": { "path": "amount_2" } },
|
||||
{ "code": "REQUIRED_FIELD_MISSING", "details": { "path": "cvv" } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "STRICT_PROPERTY_VIOLATION throws if an un-triggered then property is submitted",
|
||||
"data": { "status": "verified", "cvv": 123 },
|
||||
"schema_id": "parallel_rules",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{ "code": "STRICT_PROPERTY_VIOLATION", "details": { "path": "cvv" } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Successfully routes mutually exclusive properties seamlessly",
|
||||
"data": { "type": "A", "field_a": 1, "fallback_b": 2 },
|
||||
"schema_id": "mutually_exclusive",
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Nested fallbacks execute seamlessly",
|
||||
"data": { "tier": "3", "premium": 1 },
|
||||
"schema_id": "nested_fallbacks",
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "A case without a when executes its else indiscriminately",
|
||||
"data": { "unconditional": 1 },
|
||||
"schema_id": "missing_when",
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "A case without a when throws if else unconditionally requires field",
|
||||
"data": { },
|
||||
"schema_id": "missing_when",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{ "code": "REQUIRED_FIELD_MISSING", "details": { "path": "unconditional" } }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -23,7 +23,7 @@
|
||||
"missing_users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "full.user"
|
||||
"type": "full.user"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,7 +92,7 @@
|
||||
"children": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "full.child"
|
||||
"type": "full.child"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,7 +175,7 @@
|
||||
"activities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "full.activity"
|
||||
"type": "full.activity"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,7 +282,7 @@
|
||||
"ambiguous_edge": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "empty.junction"
|
||||
"type": "empty.junction"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,217 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "Entity families via pure $ref graph",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "entity",
|
||||
"variations": [
|
||||
"entity",
|
||||
"organization",
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "light.entity",
|
||||
"$ref": "entity"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "organization",
|
||||
"variations": [
|
||||
"organization",
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "organization",
|
||||
"$ref": "entity",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "person",
|
||||
"variations": [
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"$ref": "organization",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "light.person",
|
||||
"$ref": "light.entity"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"puncs": [
|
||||
{
|
||||
"name": "get_entities",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "get_entities.response",
|
||||
"$family": "entity"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_light_entities",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "get_light_entities.response",
|
||||
"$family": "light.entity"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Family matches base entity",
|
||||
"schema_id": "get_entities.response",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"type": "entity"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Family matches descendant person",
|
||||
"schema_id": "get_entities.response",
|
||||
"data": {
|
||||
"id": "2",
|
||||
"type": "person",
|
||||
"name": "ACME",
|
||||
"first_name": "John"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Graph family matches light.entity",
|
||||
"schema_id": "get_light_entities.response",
|
||||
"data": {
|
||||
"id": "3",
|
||||
"type": "entity"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Graph family matches light.person (because it $refs light.entity)",
|
||||
"schema_id": "get_light_entities.response",
|
||||
"data": {
|
||||
"id": "4",
|
||||
"type": "person"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Graph family excludes organization (missing light. schema that $refs light.entity)",
|
||||
"schema_id": "get_light_entities.response",
|
||||
"data": {
|
||||
"id": "5",
|
||||
"type": "organization",
|
||||
"name": "ACME"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{
|
||||
"code": "NO_FAMILY_MATCH",
|
||||
"details": { "path": "" }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Ad-hoc non-entity families (using normal json-schema object structures)",
|
||||
"database": {
|
||||
"puncs": [
|
||||
{
|
||||
"name": "get_widgets",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "widget",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"widget_type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "special_widget",
|
||||
"$ref": "widget",
|
||||
"properties": {
|
||||
"special_feature": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "get_widgets.response",
|
||||
"$family": "widget"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Ad-hoc family matches strictly by shape (no magic variations for base schemas)",
|
||||
"schema_id": "get_widgets.response",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"widget_type": "special",
|
||||
"special_feature": "yes"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -1,594 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "ignore if without then or else",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"const": 0
|
||||
},
|
||||
"$id": "if-then-else_0_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when valid against lone if",
|
||||
"data": 0,
|
||||
"schema_id": "if-then-else_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid when invalid against lone if",
|
||||
"data": "hello",
|
||||
"schema_id": "if-then-else_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ignore then without if",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"then": {
|
||||
"const": 0
|
||||
},
|
||||
"$id": "if-then-else_1_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when valid against lone then",
|
||||
"data": 0,
|
||||
"schema_id": "if-then-else_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid when invalid against lone then",
|
||||
"data": "hello",
|
||||
"schema_id": "if-then-else_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ignore else without if",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"else": {
|
||||
"const": 0
|
||||
},
|
||||
"$id": "if-then-else_2_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when valid against lone else",
|
||||
"data": 0,
|
||||
"schema_id": "if-then-else_2_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid when invalid against lone else",
|
||||
"data": "hello",
|
||||
"schema_id": "if-then-else_2_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if and then without else",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
},
|
||||
"then": {
|
||||
"minimum": -10
|
||||
},
|
||||
"$id": "if-then-else_3_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid through then",
|
||||
"data": -1,
|
||||
"schema_id": "if-then-else_3_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "invalid through then",
|
||||
"data": -100,
|
||||
"schema_id": "if-then-else_3_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid when if test fails",
|
||||
"data": 3,
|
||||
"schema_id": "if-then-else_3_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if and else without then",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
},
|
||||
"else": {
|
||||
"multipleOf": 2
|
||||
},
|
||||
"$id": "if-then-else_4_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid when if test passes",
|
||||
"data": -1,
|
||||
"schema_id": "if-then-else_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid through else",
|
||||
"data": 4,
|
||||
"schema_id": "if-then-else_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "invalid through else",
|
||||
"data": 3,
|
||||
"schema_id": "if-then-else_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "validate against correct branch, then vs else",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
},
|
||||
"then": {
|
||||
"minimum": -10
|
||||
},
|
||||
"else": {
|
||||
"multipleOf": 2
|
||||
},
|
||||
"$id": "if-then-else_5_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid through then",
|
||||
"data": -1,
|
||||
"schema_id": "if-then-else_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "invalid through then",
|
||||
"data": -100,
|
||||
"schema_id": "if-then-else_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid through else",
|
||||
"data": 4,
|
||||
"schema_id": "if-then-else_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "invalid through else",
|
||||
"data": 3,
|
||||
"schema_id": "if-then-else_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "non-interference across combined schemas",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"exclusiveMaximum": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"then": {
|
||||
"minimum": -10
|
||||
}
|
||||
},
|
||||
{
|
||||
"else": {
|
||||
"multipleOf": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"$id": "if-then-else_6_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid, but would have been invalid through then",
|
||||
"data": -100,
|
||||
"schema_id": "if-then-else_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "valid, but would have been invalid through else",
|
||||
"data": 3,
|
||||
"schema_id": "if-then-else_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if with boolean schema true",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": true,
|
||||
"then": {
|
||||
"const": "then"
|
||||
},
|
||||
"else": {
|
||||
"const": "else"
|
||||
},
|
||||
"$id": "if-then-else_7_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "boolean schema true in if always chooses the then path (valid)",
|
||||
"data": "then",
|
||||
"schema_id": "if-then-else_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "boolean schema true in if always chooses the then path (invalid)",
|
||||
"data": "else",
|
||||
"schema_id": "if-then-else_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if with boolean schema false",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": false,
|
||||
"then": {
|
||||
"const": "then"
|
||||
},
|
||||
"else": {
|
||||
"const": "else"
|
||||
},
|
||||
"$id": "if-then-else_8_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "boolean schema false in if always chooses the else path (invalid)",
|
||||
"data": "then",
|
||||
"schema_id": "if-then-else_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "boolean schema false in if always chooses the else path (valid)",
|
||||
"data": "else",
|
||||
"schema_id": "if-then-else_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "if appears at the end when serialized (keyword processing sequence)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"then": {
|
||||
"const": "yes"
|
||||
},
|
||||
"else": {
|
||||
"const": "other"
|
||||
},
|
||||
"if": {
|
||||
"maxLength": 4
|
||||
},
|
||||
"$id": "if-then-else_9_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "yes redirects to then and passes",
|
||||
"data": "yes",
|
||||
"schema_id": "if-then-else_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "other redirects to else and passes",
|
||||
"data": "other",
|
||||
"schema_id": "if-then-else_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "no redirects to then and fails",
|
||||
"data": "no",
|
||||
"schema_id": "if-then-else_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "invalid redirects to else and fails",
|
||||
"data": "invalid",
|
||||
"schema_id": "if-then-else_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "then: false fails when condition matches",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"const": 1
|
||||
},
|
||||
"then": false,
|
||||
"$id": "if-then-else_10_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches if → then=false → invalid",
|
||||
"data": 1,
|
||||
"schema_id": "if-then-else_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "does not match if → then ignored → valid",
|
||||
"data": 2,
|
||||
"schema_id": "if-then-else_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "else: false fails when condition does not match",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"const": 1
|
||||
},
|
||||
"else": false,
|
||||
"$id": "if-then-else_11_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "matches if → else ignored → valid",
|
||||
"data": 1,
|
||||
"schema_id": "if-then-else_11_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "does not match if → else executes → invalid",
|
||||
"data": 2,
|
||||
"schema_id": "if-then-else_11_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "extensible: true allows extra properties in if-then-else",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"foo": {
|
||||
"const": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"bar": {
|
||||
"const": 2
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
"extensible": true,
|
||||
"$id": "if-then-else_12_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "extra property is valid (matches if and then)",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"extra": "prop"
|
||||
},
|
||||
"schema_id": "if-then-else_12_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "strict by default with if-then properties",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"foo": {
|
||||
"const": 1
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"bar": {
|
||||
"const": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"$id": "if-then-else_13_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid match (foo + bar)",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "if-then-else_13_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "fails on extra property z explicitly",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"z": 3
|
||||
},
|
||||
"schema_id": "if-then-else_13_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -9,7 +9,7 @@
|
||||
{
|
||||
"$id": "get_invoice.response",
|
||||
"oneOf": [
|
||||
{ "$ref": "invoice" },
|
||||
{ "type": "invoice" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
}
|
||||
@ -66,7 +66,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "activity",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"start_date": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
@ -96,12 +96,12 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "invoice",
|
||||
"$ref": "activity",
|
||||
"type": "activity",
|
||||
"properties": {
|
||||
"status": { "type": "string" },
|
||||
"attachments": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "attachment" }
|
||||
"items": { "type": "attachment" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,7 +132,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "attachment",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"attachable_id": { "type": "string", "format": "uuid" },
|
||||
@ -194,7 +194,6 @@
|
||||
"type": "invoice",
|
||||
"archived": false,
|
||||
"created_at": "2023-01-01T00:00:00Z",
|
||||
"start_date": null,
|
||||
"status": "draft",
|
||||
"attachments": [
|
||||
{
|
||||
|
||||
@ -141,13 +141,13 @@
|
||||
"items": false,
|
||||
"prefixItems": [
|
||||
{
|
||||
"$ref": "item"
|
||||
"type": "item"
|
||||
},
|
||||
{
|
||||
"$ref": "item"
|
||||
"type": "item"
|
||||
},
|
||||
{
|
||||
"$ref": "item"
|
||||
"type": "item"
|
||||
}
|
||||
],
|
||||
"$id": "items_3_0"
|
||||
@ -158,10 +158,10 @@
|
||||
"items": false,
|
||||
"prefixItems": [
|
||||
{
|
||||
"$ref": "sub-item"
|
||||
"type": "sub-item"
|
||||
},
|
||||
{
|
||||
"$ref": "sub-item"
|
||||
"type": "sub-item"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "base_0",
|
||||
"type": "base_0",
|
||||
"properties": {
|
||||
"child_prop": {
|
||||
"type": "string"
|
||||
@ -71,7 +71,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"$ref": "base_1",
|
||||
"type": "base_1",
|
||||
"properties": {
|
||||
"b": {
|
||||
"type": "string"
|
||||
@ -154,7 +154,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "base_2",
|
||||
"type": "base_2",
|
||||
"properties": {
|
||||
"child_dep": {
|
||||
"type": "string"
|
||||
@ -241,7 +241,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"$ref": "base_3",
|
||||
"type": "base_3",
|
||||
"properties": {
|
||||
"c": {
|
||||
"type": "string"
|
||||
|
||||
@ -165,7 +165,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "organization",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
@ -213,7 +213,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "user",
|
||||
"$ref": "organization",
|
||||
"type": "organization",
|
||||
"properties": {}
|
||||
}
|
||||
],
|
||||
@ -262,7 +262,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"$ref": "user",
|
||||
"type": "user",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
@ -282,15 +282,15 @@
|
||||
"contacts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "contact",
|
||||
"type": "contact",
|
||||
"properties": {
|
||||
"target": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "phone_number"
|
||||
"type": "phone_number"
|
||||
},
|
||||
{
|
||||
"$ref": "email_address"
|
||||
"type": "email_address"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -300,10 +300,10 @@
|
||||
"email_addresses": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "contact",
|
||||
"type": "contact",
|
||||
"properties": {
|
||||
"target": {
|
||||
"$ref": "email_address"
|
||||
"type": "email_address"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,7 +376,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "order",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "number"
|
||||
@ -385,12 +385,12 @@
|
||||
"type": "string"
|
||||
},
|
||||
"customer": {
|
||||
"$ref": "person"
|
||||
"type": "person"
|
||||
},
|
||||
"lines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "order_line"
|
||||
"type": "order_line"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -440,7 +440,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "order_line",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
@ -549,7 +549,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "relationship",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {}
|
||||
}
|
||||
],
|
||||
@ -619,7 +619,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "contact",
|
||||
"$ref": "relationship",
|
||||
"type": "relationship",
|
||||
"properties": {
|
||||
"is_primary": {
|
||||
"type": "boolean"
|
||||
@ -677,7 +677,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "phone_number",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"number": {
|
||||
"type": "string"
|
||||
@ -736,7 +736,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "email_address",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
@ -772,7 +772,7 @@
|
||||
},
|
||||
{
|
||||
"$id": "attachment",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"flags": {
|
||||
"type": "array",
|
||||
@ -781,10 +781,10 @@
|
||||
}
|
||||
},
|
||||
"type_metadata": {
|
||||
"$ref": "type_metadata"
|
||||
"type": "type_metadata"
|
||||
},
|
||||
"other_metadata": {
|
||||
"$ref": "other_metadata"
|
||||
"type": "other_metadata"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
167
fixtures/objectTypes.json
Normal file
167
fixtures/objectTypes.json
Normal file
@ -0,0 +1,167 @@
|
||||
[
|
||||
{
|
||||
"description": "Strict Inheritance",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "parent_type",
|
||||
"type": "object",
|
||||
"properties": {"a": {"type": "integer"}},
|
||||
"required": ["a"]
|
||||
},
|
||||
{
|
||||
"$id": "child_type",
|
||||
"type": "parent_type",
|
||||
"properties": {"b": {"type": "integer"}}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid child inherits properties and strictness",
|
||||
"schema_id": "child_type",
|
||||
"data": {"a": 1, "b": 2},
|
||||
"action": "validate",
|
||||
"expect": {"success": true}
|
||||
},
|
||||
{
|
||||
"description": "missing inherited required property fails",
|
||||
"schema_id": "child_type",
|
||||
"data": {"b": 2},
|
||||
"action": "validate",
|
||||
"expect": {"success": false}
|
||||
},
|
||||
{
|
||||
"description": "additional properties fail due to inherited strictness",
|
||||
"schema_id": "child_type",
|
||||
"data": {"a": 1, "b": 2, "c": 3},
|
||||
"action": "validate",
|
||||
"expect": {"success": false}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Local Shadowing (Composition & Proxies)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "budget",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"max": {"type": "integer", "maximum": 100}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "custom_budget",
|
||||
"type": "budget",
|
||||
"properties": {
|
||||
"max": {"type": "integer", "maximum": 50}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "shadowing override applies (50 is locally allowed)",
|
||||
"schema_id": "custom_budget",
|
||||
"data": {"max": 40},
|
||||
"action": "validate",
|
||||
"expect": {"success": true}
|
||||
},
|
||||
{
|
||||
"description": "shadowing override applies natively, rejecting 60 even though parent allowed 100",
|
||||
"schema_id": "custom_budget",
|
||||
"data": {"max": 60},
|
||||
"action": "validate",
|
||||
"expect": {"success": false}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Inline id Resolution",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "api.request",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"inline_obj": {
|
||||
"$id": "inline_nested",
|
||||
"type": "object",
|
||||
"properties": {"foo": {"type": "string"}},
|
||||
"required": ["foo"]
|
||||
},
|
||||
"proxy_obj": {
|
||||
"type": "inline_nested"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "proxy resolves and validates to the inline component",
|
||||
"schema_id": "api.request",
|
||||
"data": {
|
||||
"inline_obj": {"foo": "bar"},
|
||||
"proxy_obj": {"foo": "baz"}
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {"success": true}
|
||||
},
|
||||
{
|
||||
"description": "proxy resolves and catches violation targeting inline component constraints",
|
||||
"schema_id": "api.request",
|
||||
"data": {
|
||||
"inline_obj": {"foo": "bar"},
|
||||
"proxy_obj": {}
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {"success": false}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Primitive Array Shorthand (Optionality)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "invoice",
|
||||
"type": "object",
|
||||
"properties": {"amount": {"type": "integer"}},
|
||||
"required": ["amount"]
|
||||
},
|
||||
{
|
||||
"$id": "request",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"inv": {"type": ["invoice", "null"]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid object passes shorthand inheritance check",
|
||||
"schema_id": "request",
|
||||
"data": {"inv": {"amount": 5}},
|
||||
"action": "validate",
|
||||
"expect": {"success": true}
|
||||
},
|
||||
{
|
||||
"description": "null passes shorthand inheritance check",
|
||||
"schema_id": "request",
|
||||
"data": {"inv": null},
|
||||
"action": "validate",
|
||||
"expect": {"success": true}
|
||||
},
|
||||
{
|
||||
"description": "invalid object fails inner constraints safely",
|
||||
"schema_id": "request",
|
||||
"data": {"inv": {"amount": "string"}},
|
||||
"action": "validate",
|
||||
"expect": {"success": false}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -1,670 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "oneOf",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"minimum": 2
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_0_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first oneOf valid",
|
||||
"data": 1,
|
||||
"schema_id": "oneOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "second oneOf valid",
|
||||
"data": 2.5,
|
||||
"schema_id": "oneOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid",
|
||||
"data": 3,
|
||||
"schema_id": "oneOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "neither oneOf valid",
|
||||
"data": 1.5,
|
||||
"schema_id": "oneOf_0_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with base schema",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{
|
||||
"minLength": 2
|
||||
},
|
||||
{
|
||||
"maxLength": 4
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_1_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "mismatch base schema",
|
||||
"data": 3,
|
||||
"schema_id": "oneOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "one oneOf valid",
|
||||
"data": "foobar",
|
||||
"schema_id": "oneOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid",
|
||||
"data": "foo",
|
||||
"schema_id": "oneOf_1_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, all true",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
true,
|
||||
true,
|
||||
true
|
||||
],
|
||||
"$id": "oneOf_2_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "oneOf_2_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, one true",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
true,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"$id": "oneOf_3_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"schema_id": "oneOf_3_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, more than one true",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
true,
|
||||
true,
|
||||
false
|
||||
],
|
||||
"$id": "oneOf_4_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "oneOf_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with boolean schemas, all false",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"$id": "oneOf_5_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "oneOf_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf complex types",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_6_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first oneOf valid (complex)",
|
||||
"data": {
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "oneOf_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "second oneOf valid (complex)",
|
||||
"data": {
|
||||
"foo": "baz"
|
||||
},
|
||||
"schema_id": "oneOf_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid (complex)",
|
||||
"data": {
|
||||
"foo": "baz",
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "oneOf_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "neither oneOf valid (complex)",
|
||||
"data": {
|
||||
"foo": 2,
|
||||
"bar": "quux"
|
||||
},
|
||||
"schema_id": "oneOf_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with empty schema",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{}
|
||||
],
|
||||
"$id": "oneOf_7_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "one valid - valid",
|
||||
"data": "foo",
|
||||
"schema_id": "oneOf_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both valid - invalid",
|
||||
"data": 123,
|
||||
"schema_id": "oneOf_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with required",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": true,
|
||||
"bar": true,
|
||||
"baz": true
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"required": [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"foo",
|
||||
"baz"
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_8_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "both invalid - invalid",
|
||||
"data": {
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "oneOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "first valid - valid",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "oneOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "second valid - valid",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"baz": 3
|
||||
},
|
||||
"schema_id": "oneOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both valid - invalid",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"baz": 3
|
||||
},
|
||||
"schema_id": "oneOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "extra property invalid (strict)",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"extra": 3
|
||||
},
|
||||
"schema_id": "oneOf_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with required (extensible)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"type": "object",
|
||||
"extensible": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"required": [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"foo",
|
||||
"baz"
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_9_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "both invalid - invalid",
|
||||
"data": {
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "oneOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "first valid - valid",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2
|
||||
},
|
||||
"schema_id": "oneOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "second valid - valid",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"baz": 3
|
||||
},
|
||||
"schema_id": "oneOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both valid - invalid",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"baz": 3
|
||||
},
|
||||
"schema_id": "oneOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "extra properties are valid (extensible)",
|
||||
"data": {
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"extra": "value"
|
||||
},
|
||||
"schema_id": "oneOf_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "oneOf with missing optional property",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": true,
|
||||
"baz": true
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": true
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_10_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "first oneOf valid",
|
||||
"data": {
|
||||
"bar": 8
|
||||
},
|
||||
"schema_id": "oneOf_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "second oneOf valid",
|
||||
"data": {
|
||||
"foo": "foo"
|
||||
},
|
||||
"schema_id": "oneOf_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "both oneOf valid",
|
||||
"data": {
|
||||
"foo": "foo",
|
||||
"bar": 8
|
||||
},
|
||||
"schema_id": "oneOf_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "neither oneOf valid",
|
||||
"data": {
|
||||
"baz": "quux"
|
||||
},
|
||||
"schema_id": "oneOf_10_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "nested oneOf, to check validation semantics",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"$id": "oneOf_11_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "null is valid",
|
||||
"data": null,
|
||||
"schema_id": "oneOf_11_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "anything non-null is invalid",
|
||||
"data": 123,
|
||||
"schema_id": "oneOf_11_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "extensible: true allows extra properties in oneOf",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"foo"
|
||||
]
|
||||
}
|
||||
],
|
||||
"extensible": true,
|
||||
"$id": "oneOf_12_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "extra property is valid (matches first option)",
|
||||
"data": {
|
||||
"bar": 2,
|
||||
"extra": "prop"
|
||||
},
|
||||
"schema_id": "oneOf_12_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -148,6 +148,10 @@
|
||||
{
|
||||
"code": "REQUIRED_FIELD_MISSING",
|
||||
"details": { "path": "ad_hoc_objects/1/name" }
|
||||
},
|
||||
{
|
||||
"code": "STRICT_PROPERTY_VIOLATION",
|
||||
"details": { "path": "ad_hoc_objects/1/age" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -210,5 +214,154 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Polymorphic Structure Pathing",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "widget",
|
||||
"variations": ["widget"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "widget",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "string" },
|
||||
"type": { "type": "string" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "stock.widget",
|
||||
"type": "widget",
|
||||
"properties": {
|
||||
"kind": { "type": "string" },
|
||||
"amount": { "type": "integer" },
|
||||
"details": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nested_metric": { "type": "number" }
|
||||
},
|
||||
"required": ["nested_metric"]
|
||||
}
|
||||
},
|
||||
"required": ["amount", "details"]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "polymorphic_pathing",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"metadata_bubbles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$id": "contact_metadata",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "const": "contact" },
|
||||
"phone": { "type": "string" }
|
||||
},
|
||||
"required": ["phone"]
|
||||
},
|
||||
{
|
||||
"$id": "invoice_metadata",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "const": "invoice" },
|
||||
"invoice_id": { "type": "integer" }
|
||||
},
|
||||
"required": ["invoice_id"]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"table_families": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$family": "widget"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "oneOf tags natively bubble specific schema paths into deep array roots",
|
||||
"data": {
|
||||
"metadata_bubbles": [
|
||||
{ "type": "invoice", "invoice_id": 100 },
|
||||
{ "type": "contact", "phone": 12345, "rogue_field": "x" }
|
||||
]
|
||||
},
|
||||
"schema_id": "polymorphic_pathing",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{
|
||||
"code": "INVALID_TYPE",
|
||||
"details": { "path": "metadata_bubbles/1/phone" }
|
||||
},
|
||||
{
|
||||
"code": "STRICT_PROPERTY_VIOLATION",
|
||||
"details": { "path": "metadata_bubbles/1/rogue_field" }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "families mechanically map physical variants directly onto topological uuid array paths",
|
||||
"data": {
|
||||
"table_families": [
|
||||
{
|
||||
"id": "widget-1",
|
||||
"type": "widget",
|
||||
"kind": "stock",
|
||||
"amount": 500,
|
||||
"details": { "nested_metric": 42.0 }
|
||||
},
|
||||
{
|
||||
"id": "widget-2",
|
||||
"type": "widget",
|
||||
"kind": "stock",
|
||||
"amount": "not_an_int",
|
||||
"details": {
|
||||
"stray_child": true
|
||||
},
|
||||
"unexpected_root_prop": "hi"
|
||||
}
|
||||
]
|
||||
},
|
||||
"schema_id": "polymorphic_pathing",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{
|
||||
"code": "INVALID_TYPE",
|
||||
"details": { "path": "table_families/widget-2/amount" }
|
||||
},
|
||||
{
|
||||
"code": "REQUIRED_FIELD_MISSING",
|
||||
"details": { "path": "table_families/widget-2/details/nested_metric" }
|
||||
},
|
||||
{
|
||||
"code": "STRICT_PROPERTY_VIOLATION",
|
||||
"details": { "path": "table_families/widget-2/details/stray_child" }
|
||||
},
|
||||
{
|
||||
"code": "STRICT_PROPERTY_VIOLATION",
|
||||
"details": { "path": "table_families/widget-2/unexpected_root_prop" }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
479
fixtures/polymorphism.json
Normal file
479
fixtures/polymorphism.json
Normal file
@ -0,0 +1,479 @@
|
||||
[
|
||||
{
|
||||
"description": "Vertical $family Routing (Across Tables)",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "entity",
|
||||
"variations": ["entity", "organization", "person", "bot"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "type": "string" },
|
||||
"id": { "type": "string" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "organization",
|
||||
"variations": ["organization", "person"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "organization",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"name": { "type": "string" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "person",
|
||||
"variations": ["person"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"type": "organization",
|
||||
"properties": {
|
||||
"first_name": { "type": "string" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bot",
|
||||
"variations": ["bot"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "bot",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"model": { "type": "string" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "family_entity",
|
||||
"$family": "entity"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Matches base entity",
|
||||
"schema_id": "family_entity",
|
||||
"data": { "type": "entity", "id": "1" },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Matches descendant person natively",
|
||||
"schema_id": "family_entity",
|
||||
"data": { "type": "person", "id": "2", "first_name": "Bob" },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Missing type fails out immediately",
|
||||
"schema_id": "family_entity",
|
||||
"data": { "id": "3", "first_name": "Bob" },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "MISSING_TYPE", "details": { "path": "" } } ] }
|
||||
},
|
||||
{
|
||||
"description": "Alias matching failure",
|
||||
"schema_id": "family_entity",
|
||||
"data": { "type": "alien", "id": "4" },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "NO_FAMILY_MATCH", "details": { "path": "" } } ] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Matrix $family Routing (Vertical + Horizontal Intersections)",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "entity",
|
||||
"variations": ["entity", "organization", "person", "bot"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "type": "string" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "light.entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"kind": { "type": "string" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "organization",
|
||||
"variations": ["organization", "person"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "organization",
|
||||
"type": "entity"
|
||||
},
|
||||
{
|
||||
"$id": "light.organization",
|
||||
"type": "light.entity"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "person",
|
||||
"variations": ["person"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"type": "organization"
|
||||
},
|
||||
{
|
||||
"$id": "light.person",
|
||||
"type": "light.organization"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bot",
|
||||
"variations": ["bot"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "bot",
|
||||
"type": "entity"
|
||||
},
|
||||
{
|
||||
"$id": "light.bot",
|
||||
"type": "light.entity"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "family_light_org",
|
||||
"$family": "light.organization"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Matches light.organization exact matrix target",
|
||||
"schema_id": "family_light_org",
|
||||
"data": { "type": "organization", "kind": "light" },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Matches descendant light.person through matrix evaluation",
|
||||
"schema_id": "family_light_org",
|
||||
"data": { "type": "person", "kind": "light" },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Structurally fails to route bot (bot is not descendant of organization)",
|
||||
"schema_id": "family_light_org",
|
||||
"data": { "type": "bot", "kind": "light" },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "NO_FAMILY_MATCH", "details": { "path": "" } } ] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Horizontal $family Routing (Virtual Variations)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "widget",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "type": "string" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "stock.widget",
|
||||
"type": "widget",
|
||||
"properties": {
|
||||
"kind": { "type": "string" },
|
||||
"amount": { "type": "integer" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "super_stock.widget",
|
||||
"type": "stock.widget",
|
||||
"properties": {
|
||||
"super_amount": { "type": "integer" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "family_widget",
|
||||
"$family": "widget"
|
||||
},
|
||||
{
|
||||
"$id": "family_stock_widget",
|
||||
"$family": "stock.widget"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Base widget resolves stock widget horizontally",
|
||||
"schema_id": "family_widget",
|
||||
"data": { "type": "widget", "kind": "stock", "amount": 5 },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Base widget resolves nested super stock widget natively via descendants crawl",
|
||||
"schema_id": "family_widget",
|
||||
"data": { "type": "widget", "kind": "super_stock", "amount": 5, "super_amount": 10 },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "stock.widget explicit family resolves nested super stock via fast path",
|
||||
"schema_id": "family_stock_widget",
|
||||
"data": { "type": "widget", "kind": "super_stock", "amount": 5, "super_amount": 10 },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "stock.widget fails when presented an invalid payload constraint",
|
||||
"schema_id": "family_stock_widget",
|
||||
"data": { "type": "widget", "kind": "super_stock", "amount": 5, "super_amount": "not_an_int" },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "INVALID_TYPE", "details": { "path": "super_amount" } } ] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Strict oneOf Punc Pointers (Tagged Unions)",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "entity",
|
||||
"variations": ["entity", "person", "bot"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "type": "string" }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "person",
|
||||
"variations": ["person"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"type": "entity"
|
||||
},
|
||||
{
|
||||
"$id": "full.person",
|
||||
"type": "person",
|
||||
"properties": {
|
||||
"kind": { "type": "string" },
|
||||
"age": { "type": "integer" }
|
||||
},
|
||||
"required": ["age"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bot",
|
||||
"variations": ["bot"],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "bot",
|
||||
"type": "entity"
|
||||
},
|
||||
{
|
||||
"$id": "full.bot",
|
||||
"type": "bot",
|
||||
"properties": {
|
||||
"kind": { "type": "string" },
|
||||
"version": { "type": "string" }
|
||||
},
|
||||
"required": ["version"]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "oneOf_union",
|
||||
"oneOf": [
|
||||
{ "type": "full.person" },
|
||||
{ "type": "full.bot" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Throws MISSING_TYPE if discriminator matches neither",
|
||||
"schema_id": "oneOf_union",
|
||||
"data": { "kind": "full", "age": 5 },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "MISSING_TYPE", "details": { "path": "" } } ] }
|
||||
},
|
||||
{
|
||||
"description": "Golden match throws pure structural error exclusively on person",
|
||||
"schema_id": "oneOf_union",
|
||||
"data": { "type": "person", "kind": "full", "age": "five" },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "INVALID_TYPE", "details": { "path": "age" } } ] }
|
||||
},
|
||||
{
|
||||
"description": "Golden matches perfectly",
|
||||
"schema_id": "oneOf_union",
|
||||
"data": { "type": "person", "kind": "full", "age": 5 },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Fails nicely with NO_ONEOF_MATCH",
|
||||
"schema_id": "oneOf_union",
|
||||
"data": { "type": "alien", "kind": "full", "age": 5 },
|
||||
"action": "validate",
|
||||
"expect": { "success": false, "errors": [ { "code": "NO_ONEOF_MATCH", "details": { "path": "" } } ] }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "JSONB Field Bubble oneOf Discrimination (Promoted IDs)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "metadata",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "type": "string" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "invoice.metadata",
|
||||
"type": "metadata",
|
||||
"properties": {
|
||||
"invoice_id": { "type": "integer" }
|
||||
},
|
||||
"required": ["invoice_id"]
|
||||
},
|
||||
{
|
||||
"$id": "payment.metadata",
|
||||
"type": "metadata",
|
||||
"properties": {
|
||||
"payment_id": { "type": "integer" }
|
||||
},
|
||||
"required": ["payment_id"]
|
||||
},
|
||||
{
|
||||
"$id": "oneOf_bubble",
|
||||
"oneOf": [
|
||||
{ "type": "invoice.metadata" },
|
||||
{ "type": "payment.metadata" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Extracts golden match natively from explicit JSONB type discriminator",
|
||||
"schema_id": "oneOf_bubble",
|
||||
"data": { "type": "invoice.metadata", "invoice_id": "nan" },
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [ { "code": "INVALID_TYPE", "details": { "path": "invoice_id" } } ]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Valid payload succeeds perfectly in JSONB universe",
|
||||
"schema_id": "oneOf_bubble",
|
||||
"data": { "type": "payment.metadata", "payment_id": 123 },
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Standard JSON Schema oneOf",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "oneOf_scalars",
|
||||
"oneOf": [
|
||||
{ "type": "integer" },
|
||||
{ "minimum": 2 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"$id": "oneOf_dedupe",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shared": { "type": "integer" }
|
||||
},
|
||||
"required": ["shared"]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shared": { "type": "integer" },
|
||||
"extra": { "type": "string" }
|
||||
},
|
||||
"required": ["shared", "extra"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Valid exclusively against first scalar choice",
|
||||
"schema_id": "oneOf_scalars",
|
||||
"data": 1,
|
||||
"action": "validate",
|
||||
"expect": { "success": true }
|
||||
},
|
||||
{
|
||||
"description": "Fails mathematically if matches both schemas natively",
|
||||
"schema_id": "oneOf_scalars",
|
||||
"data": 3,
|
||||
"action": "validate",
|
||||
"expect": { "success": false }
|
||||
},
|
||||
{
|
||||
"description": "Deduper merges shared errors dynamically exactly like JSON Schema",
|
||||
"schema_id": "oneOf_dedupe",
|
||||
"data": { "shared": "nan" },
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{ "code": "NO_ONEOF_MATCH", "details": { "path": "" } },
|
||||
{ "code": "INVALID_TYPE", "details": { "path": "shared" } }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -8,7 +8,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "get_organization.response",
|
||||
"$ref": "organization"
|
||||
"type": "organization"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -40,7 +40,7 @@
|
||||
"$id": "get_orders.response",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "light.order"
|
||||
"type": "light.order"
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -238,7 +238,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "organization",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
@ -287,7 +287,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "bot",
|
||||
"$ref": "organization",
|
||||
"type": "organization",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string"
|
||||
@ -345,7 +345,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"$ref": "organization",
|
||||
"type": "organization",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
@ -360,20 +360,20 @@
|
||||
},
|
||||
{
|
||||
"$id": "light.person",
|
||||
"$ref": "person",
|
||||
"type": "person",
|
||||
"properties": {}
|
||||
},
|
||||
{
|
||||
"$id": "full.person",
|
||||
"$ref": "person",
|
||||
"type": "person",
|
||||
"properties": {
|
||||
"phone_numbers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "contact",
|
||||
"type": "contact",
|
||||
"properties": {
|
||||
"target": {
|
||||
"$ref": "phone_number"
|
||||
"type": "phone_number"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -381,10 +381,10 @@
|
||||
"email_addresses": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "contact",
|
||||
"type": "contact",
|
||||
"properties": {
|
||||
"target": {
|
||||
"$ref": "email_address"
|
||||
"type": "email_address"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,10 +392,10 @@
|
||||
"addresses": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "contact",
|
||||
"type": "contact",
|
||||
"properties": {
|
||||
"target": {
|
||||
"$ref": "address"
|
||||
"type": "address"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -403,18 +403,18 @@
|
||||
"contacts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "contact",
|
||||
"type": "contact",
|
||||
"properties": {
|
||||
"target": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "phone_number"
|
||||
"type": "phone_number"
|
||||
},
|
||||
{
|
||||
"$ref": "email_address"
|
||||
"type": "email_address"
|
||||
},
|
||||
{
|
||||
"$ref": "address"
|
||||
"type": "address"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -472,7 +472,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "relationship",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {}
|
||||
}
|
||||
],
|
||||
@ -531,7 +531,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "contact",
|
||||
"$ref": "relationship",
|
||||
"type": "relationship",
|
||||
"properties": {
|
||||
"is_primary": {
|
||||
"type": "boolean"
|
||||
@ -577,7 +577,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "phone_number",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"number": {
|
||||
"type": "string"
|
||||
@ -623,7 +623,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "email_address",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
@ -669,7 +669,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "address",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
@ -686,7 +686,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "order",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "number"
|
||||
@ -698,24 +698,24 @@
|
||||
},
|
||||
{
|
||||
"$id": "light.order",
|
||||
"$ref": "order",
|
||||
"type": "order",
|
||||
"properties": {
|
||||
"customer": {
|
||||
"$ref": "person"
|
||||
"type": "person"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "full.order",
|
||||
"$ref": "order",
|
||||
"type": "order",
|
||||
"properties": {
|
||||
"customer": {
|
||||
"$ref": "person"
|
||||
"type": "person"
|
||||
},
|
||||
"lines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "order_line"
|
||||
"type": "order_line"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -784,7 +784,7 @@
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "order_line",
|
||||
"$ref": "entity",
|
||||
"type": "entity",
|
||||
"properties": {
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
@ -862,13 +862,13 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'archived', entity_1.archived,",
|
||||
" 'created_at', entity_1.created_at,",
|
||||
" 'id', entity_1.id,",
|
||||
" 'type', entity_1.type)",
|
||||
"FROM agreego.entity entity_1",
|
||||
"WHERE NOT entity_1.archived)"
|
||||
"WHERE NOT entity_1.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -905,7 +905,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'archived', entity_1.archived,",
|
||||
" 'created_at', entity_1.created_at,",
|
||||
" 'id', entity_1.id,",
|
||||
@ -926,7 +926,7 @@
|
||||
" AND entity_1.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($10#>>'{}')::jsonb))",
|
||||
" AND entity_1.id != ($11#>>'{}')::uuid",
|
||||
" AND entity_1.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($12#>>'{}')::jsonb))",
|
||||
")"
|
||||
")))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -939,7 +939,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'age', person_1.age,",
|
||||
" 'archived', entity_3.archived,",
|
||||
" 'created_at', entity_3.created_at,",
|
||||
@ -951,7 +951,7 @@
|
||||
"FROM agreego.person person_1",
|
||||
"JOIN agreego.organization organization_2 ON organization_2.id = person_1.id",
|
||||
"JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id",
|
||||
"WHERE NOT entity_3.archived)"
|
||||
"WHERE NOT entity_3.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -964,7 +964,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'addresses',",
|
||||
" (SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'archived', entity_6.archived,",
|
||||
@ -1116,7 +1116,7 @@
|
||||
"FROM agreego.person person_1",
|
||||
"JOIN agreego.organization organization_2 ON organization_2.id = person_1.id",
|
||||
"JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id",
|
||||
"WHERE NOT entity_3.archived)"
|
||||
"WHERE NOT entity_3.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1200,7 +1200,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'addresses',",
|
||||
" (SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'archived', entity_6.archived,",
|
||||
@ -1385,7 +1385,7 @@
|
||||
" AND entity_3.id != ($28#>>'{}')::uuid",
|
||||
" AND entity_3.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($29#>>'{}')::jsonb))",
|
||||
" AND person_1.last_name ILIKE $30#>>'{}'",
|
||||
" AND person_1.last_name NOT ILIKE $31#>>'{}')"
|
||||
" AND person_1.last_name NOT ILIKE $31#>>'{}')))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1398,7 +1398,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'archived', entity_3.archived,",
|
||||
" 'created_at', entity_3.created_at,",
|
||||
" 'id', entity_3.id,",
|
||||
@ -1423,7 +1423,7 @@
|
||||
"JOIN agreego.entity entity_3 ON entity_3.id = relationship_2.id",
|
||||
"WHERE",
|
||||
" NOT entity_3.archived",
|
||||
" AND relationship_2.target_type = 'email_address')"
|
||||
" AND relationship_2.target_type = 'email_address')))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1436,7 +1436,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'archived', entity_2.archived,",
|
||||
" 'created_at', entity_2.created_at,",
|
||||
" 'customer',",
|
||||
@ -1478,7 +1478,7 @@
|
||||
")",
|
||||
"FROM agreego.order order_1",
|
||||
"JOIN agreego.entity entity_2 ON entity_2.id = order_1.id",
|
||||
"WHERE NOT entity_2.archived)"
|
||||
"WHERE NOT entity_2.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1491,7 +1491,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'archived', entity_2.archived,",
|
||||
" 'created_at', entity_2.created_at,",
|
||||
" 'id', entity_2.id,",
|
||||
@ -1500,7 +1500,7 @@
|
||||
")",
|
||||
"FROM agreego.organization organization_1",
|
||||
"JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id",
|
||||
"WHERE NOT entity_2.archived)"
|
||||
"WHERE NOT entity_2.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1513,7 +1513,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', organization_1.id,",
|
||||
" 'type', CASE",
|
||||
" WHEN organization_1.type = 'bot' THEN",
|
||||
@ -1559,7 +1559,7 @@
|
||||
")), '[]'::jsonb)",
|
||||
"FROM agreego.organization organization_1",
|
||||
"JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id",
|
||||
"WHERE NOT entity_2.archived)"
|
||||
"WHERE NOT entity_2.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1572,7 +1572,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(",
|
||||
" 'age', person_1.age,",
|
||||
" 'archived', entity_3.archived,",
|
||||
" 'created_at', entity_3.created_at,",
|
||||
@ -1585,7 +1585,7 @@
|
||||
"FROM agreego.person person_1",
|
||||
"JOIN agreego.organization organization_2 ON organization_2.id = person_1.id",
|
||||
"JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id",
|
||||
"WHERE NOT entity_3.archived)"
|
||||
"WHERE NOT entity_3.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1598,7 +1598,7 @@
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"(SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
"(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'archived', entity_2.archived,",
|
||||
" 'created_at', entity_2.created_at,",
|
||||
" 'customer',",
|
||||
@ -1625,7 +1625,7 @@
|
||||
")), '[]'::jsonb)",
|
||||
"FROM agreego.order order_1",
|
||||
"JOIN agreego.entity entity_2 ON entity_2.id = order_1.id",
|
||||
"WHERE NOT entity_2.archived)"
|
||||
"WHERE NOT entity_2.archived)))"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,929 +0,0 @@
|
||||
[
|
||||
{
|
||||
"description": "nested refs",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$ref": "c_212",
|
||||
"$id": "ref_4_0"
|
||||
},
|
||||
{
|
||||
"$id": "a_212",
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"$id": "b_212",
|
||||
"$ref": "a_212"
|
||||
},
|
||||
{
|
||||
"$id": "c_212",
|
||||
"$ref": "b_212"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "nested ref valid",
|
||||
"data": 5,
|
||||
"schema_id": "ref_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "nested ref invalid",
|
||||
"data": "a",
|
||||
"schema_id": "ref_4_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ref applies alongside sibling keywords",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"properties": {
|
||||
"foo": {
|
||||
"$ref": "reffed_248",
|
||||
"maxItems": 2
|
||||
}
|
||||
},
|
||||
"$id": "ref_5_0"
|
||||
},
|
||||
{
|
||||
"$id": "reffed_248",
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ref valid, maxItems valid",
|
||||
"data": {
|
||||
"foo": []
|
||||
},
|
||||
"schema_id": "ref_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ref valid, maxItems invalid",
|
||||
"data": {
|
||||
"foo": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
},
|
||||
"schema_id": "ref_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ref invalid",
|
||||
"data": {
|
||||
"foo": "string"
|
||||
},
|
||||
"schema_id": "ref_5_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "property named $ref that is not a reference",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"$id": "ref_6_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property named $ref valid",
|
||||
"data": {
|
||||
"$ref": "a"
|
||||
},
|
||||
"schema_id": "ref_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "property named $ref invalid",
|
||||
"data": {
|
||||
"$ref": 2
|
||||
},
|
||||
"schema_id": "ref_6_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "property named $ref, containing an actual $ref",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"$ref": "is-string_344"
|
||||
}
|
||||
},
|
||||
"$id": "ref_7_0"
|
||||
},
|
||||
{
|
||||
"$id": "is-string_344",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "property named $ref valid",
|
||||
"data": {
|
||||
"$ref": "a"
|
||||
},
|
||||
"schema_id": "ref_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "property named $ref invalid",
|
||||
"data": {
|
||||
"$ref": 2
|
||||
},
|
||||
"schema_id": "ref_7_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref to boolean schema true",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$ref": "bool_378",
|
||||
"$id": "ref_8_0"
|
||||
},
|
||||
{
|
||||
"$id": "bool_378",
|
||||
"extensible": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is valid",
|
||||
"data": "foo",
|
||||
"schema_id": "ref_8_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref to boolean schema false",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$ref": "bool_400",
|
||||
"$id": "ref_9_0"
|
||||
},
|
||||
{
|
||||
"$id": "bool_400",
|
||||
"extensible": false,
|
||||
"not": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "any value is invalid",
|
||||
"data": "foo",
|
||||
"schema_id": "ref_9_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "refs with quote",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"properties": {
|
||||
"foo\"bar": {
|
||||
"$ref": "foo%22bar_550"
|
||||
}
|
||||
},
|
||||
"$id": "ref_11_0"
|
||||
},
|
||||
{
|
||||
"$id": "foo%22bar_550",
|
||||
"type": "number"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "object with numbers is valid",
|
||||
"data": {
|
||||
"foo\"bar": 1
|
||||
},
|
||||
"schema_id": "ref_11_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "object with strings is invalid",
|
||||
"data": {
|
||||
"foo\"bar": "1"
|
||||
},
|
||||
"schema_id": "ref_11_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref boundary resets to loose",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$ref": "target_1465",
|
||||
"$id": "ref_35_0"
|
||||
},
|
||||
{
|
||||
"$id": "target_1465",
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "extra property in ref target is invalid (strict by default)",
|
||||
"data": {
|
||||
"foo": "bar",
|
||||
"extra": 1
|
||||
},
|
||||
"schema_id": "ref_35_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "$ref target can enforce strictness",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$ref": "target_1496",
|
||||
"$id": "ref_36_0"
|
||||
},
|
||||
{
|
||||
"$id": "target_1496",
|
||||
"extensible": false,
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "extra property in ref target is invalid",
|
||||
"data": {
|
||||
"foo": "bar",
|
||||
"extra": 1
|
||||
},
|
||||
"schema_id": "ref_36_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "strictness: boundary reset at $ref",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"extensible": true,
|
||||
"properties": {
|
||||
"inline_child": {
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ref_child": {
|
||||
"$ref": "strict_node_1544"
|
||||
},
|
||||
"extensible_ref_child": {
|
||||
"$ref": "extensible_node_1551"
|
||||
}
|
||||
},
|
||||
"$id": "ref_37_0"
|
||||
},
|
||||
{
|
||||
"$id": "strict_node_1544",
|
||||
"properties": {
|
||||
"b": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "extensible_node_1551",
|
||||
"extensible": true,
|
||||
"properties": {
|
||||
"c": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "inline child inherits looseness",
|
||||
"data": {
|
||||
"inline_child": {
|
||||
"a": 1,
|
||||
"extra": 2
|
||||
}
|
||||
},
|
||||
"schema_id": "ref_37_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ref child resets to strict (default)",
|
||||
"data": {
|
||||
"ref_child": {
|
||||
"b": 1,
|
||||
"extra": 2
|
||||
}
|
||||
},
|
||||
"schema_id": "ref_37_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "ref child with explicit extensible=true is loose",
|
||||
"data": {
|
||||
"extensible_ref_child": {
|
||||
"c": 1,
|
||||
"extra": 2
|
||||
}
|
||||
},
|
||||
"schema_id": "ref_37_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "arrays: ref items inherit strictness (reset at boundary)",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"properties": {
|
||||
"list": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "strict_node_1614"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$id": "ref_38_0"
|
||||
},
|
||||
{
|
||||
"$id": "strict_node_1614",
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "ref item with extra property is invalid (strict by default)",
|
||||
"data": {
|
||||
"list": [
|
||||
{
|
||||
"a": 1,
|
||||
"extra": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"schema_id": "ref_38_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "implicit keyword shadowing",
|
||||
"database": {
|
||||
"schemas": [
|
||||
{
|
||||
"$ref": "parent_1648",
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "child"
|
||||
},
|
||||
"age": {
|
||||
"minimum": 15
|
||||
}
|
||||
},
|
||||
"$id": "ref_39_0"
|
||||
},
|
||||
{
|
||||
"$id": "parent_1648",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "parent"
|
||||
},
|
||||
"age": {
|
||||
"minimum": 10,
|
||||
"maximum": 20
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"age"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "child type overrides parent type",
|
||||
"data": {
|
||||
"type": "child",
|
||||
"age": 15
|
||||
},
|
||||
"schema_id": "ref_39_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "parent type is now invalid (shadowed)",
|
||||
"data": {
|
||||
"type": "parent",
|
||||
"age": 15
|
||||
},
|
||||
"schema_id": "ref_39_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "child min age (15) is enforced",
|
||||
"data": {
|
||||
"type": "child",
|
||||
"age": 12
|
||||
},
|
||||
"schema_id": "ref_39_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "parent max age (20) is shadowed (replaced) by child definition",
|
||||
"data": {
|
||||
"type": "child",
|
||||
"age": 21
|
||||
},
|
||||
"schema_id": "ref_39_0",
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Entities extending entities (Physical Birth)",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "entity",
|
||||
"variations": [
|
||||
"entity",
|
||||
"organization",
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "organization",
|
||||
"variations": [
|
||||
"organization",
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "organization",
|
||||
"$ref": "entity",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "person",
|
||||
"variations": [
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"$ref": "organization",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"puncs": [
|
||||
{
|
||||
"name": "save_org",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "save_org.request",
|
||||
"$ref": "organization"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Valid person against organization schema (implicit type allowance from physical hierarchy)",
|
||||
"schema_id": "save_org.request",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"type": "person",
|
||||
"name": "ACME"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Valid organization against organization schema",
|
||||
"schema_id": "save_org.request",
|
||||
"data": {
|
||||
"id": "2",
|
||||
"type": "organization",
|
||||
"name": "ACME"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Invalid entity against organization schema (ancestor not allowed)",
|
||||
"schema_id": "save_org.request",
|
||||
"data": {
|
||||
"id": "3",
|
||||
"type": "entity"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{
|
||||
"code": "CONST_VIOLATED",
|
||||
"details": { "path": "type" }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Viral Infection: Ad-hocs inheriting entity boundaries via $ref",
|
||||
"database": {
|
||||
"types": [
|
||||
{
|
||||
"name": "entity",
|
||||
"variations": [
|
||||
"entity",
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "person",
|
||||
"variations": [
|
||||
"person"
|
||||
],
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "person",
|
||||
"$ref": "entity",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "light.person",
|
||||
"$ref": "entity",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"puncs": [
|
||||
{
|
||||
"name": "save_person_light",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "save_person_light.request",
|
||||
"$ref": "light.person",
|
||||
"properties": {
|
||||
"extra_request_field": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Valid person against ad-hoc request schema (request virally inherited person variations)",
|
||||
"schema_id": "save_person_light.request",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"type": "person",
|
||||
"first_name": "John",
|
||||
"extra_request_field": "test"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Invalid entity against ad-hoc request schema (viral inheritance enforces person boundary)",
|
||||
"schema_id": "save_person_light.request",
|
||||
"data": {
|
||||
"id": "1",
|
||||
"type": "entity",
|
||||
"first_name": "John"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false,
|
||||
"errors": [
|
||||
{
|
||||
"code": "CONST_VIOLATED",
|
||||
"details": { "path": "type" }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Ad-hocs extending ad-hocs (No type property)",
|
||||
"database": {
|
||||
"puncs": [
|
||||
{
|
||||
"name": "save_address",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "address",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"street": {
|
||||
"type": "string"
|
||||
},
|
||||
"city": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "us_address",
|
||||
"$ref": "address",
|
||||
"properties": {
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"zip": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "save_address.request",
|
||||
"$ref": "us_address"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Valid us_address",
|
||||
"schema_id": "save_address.request",
|
||||
"data": {
|
||||
"street": "123 Main",
|
||||
"city": "Anytown",
|
||||
"state": "CA",
|
||||
"zip": "12345"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Invalid base address against us_address",
|
||||
"schema_id": "save_address.request",
|
||||
"data": {
|
||||
"street": "123 Main",
|
||||
"city": "Anytown"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Ad-hocs extending ad-hocs (with string type property, no magic)",
|
||||
"database": {
|
||||
"puncs": [
|
||||
{
|
||||
"name": "save_config",
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "config_base",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "config_base"
|
||||
},
|
||||
"setting": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "config_advanced",
|
||||
"$ref": "config_base",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "config_advanced"
|
||||
},
|
||||
"advanced_setting": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$id": "save_config.request",
|
||||
"$ref": "config_base"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "Valid config_base against config_base",
|
||||
"schema_id": "save_config.request",
|
||||
"data": {
|
||||
"type": "config_base",
|
||||
"setting": "on"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Invalid config_advanced against config_base (no type magic, const is strictly 'config_base')",
|
||||
"schema_id": "save_config.request",
|
||||
"data": {
|
||||
"type": "config_advanced",
|
||||
"setting": "on",
|
||||
"advanced_setting": "off"
|
||||
},
|
||||
"action": "validate",
|
||||
"expect": {
|
||||
"success": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user