jspg checkpoint
This commit is contained in:
27
GEMINI.md
27
GEMINI.md
@ -47,7 +47,22 @@ The core execution engines natively enforce these boundaries:
|
|||||||
* **Merger**: Strictly bounded to the `Type` Realm. It is philosophically impossible and mathematically illegal to attempt to UPSERT an API endpoint.
|
* **Merger**: Strictly bounded to the `Type` Realm. It is philosophically impossible and mathematically illegal to attempt to UPSERT an API endpoint.
|
||||||
* **Queryer**: Routes recursively. Safely evaluates API boundary inputs directly from the `Punc` realm, while tracing underlying table targets back through the `Type` realm to physically compile SQL `SELECT` statements.
|
* **Queryer**: Routes recursively. Safely evaluates API boundary inputs directly from the `Punc` realm, while tracing underlying table targets back through the `Type` realm to physically compile SQL `SELECT` statements.
|
||||||
|
|
||||||
### Types of Types
|
### Basic and Structural Types
|
||||||
|
JSPG models data using a simplified subset of standard JSON Schema types, categorized into primitives and structural types:
|
||||||
|
|
||||||
|
* **Primitives**:
|
||||||
|
* `string`: Standard string, supporting standard keywords (e.g., `pattern`, `minLength`, `maxLength`) and custom formats (`uuid`, `date-time`, `email`). Empty strings (`""`) are leniently treated as "present but unset".
|
||||||
|
* `number` & `integer`: Numeric and integer values (e.g., supporting `minimum`, `maximum`).
|
||||||
|
* `boolean`: Boolean `true` or `false` values.
|
||||||
|
* `null`: Represents database `NULL` or unset fields.
|
||||||
|
* **Structural Types**:
|
||||||
|
* `object`: Represents a structured object with a fixed list of static `properties`. Objects are **strict by default** (raising `STRICT_PROPERTY_VIOLATION` for properties not defined in the schema) unless marked with `"extensible": true`.
|
||||||
|
* `array`: A homogeneous, one-dimensional collection where every element is validated against the `items` schema. Positional/tuple array validation is not supported, and array strictness checks do not apply.
|
||||||
|
* `dict`: A dynamic key-value map. It utilizes the `keys` keyword to validate key strings (typically via `pattern`) and the `items` keyword to validate the values. It completely replaces the legacy `additionalProperties` and `patternProperties` keywords. Extensibility is implicitly managed via dynamic keys, so strictness checking does not apply.
|
||||||
|
|
||||||
|
### Types of Types (Complex & Referential Types)
|
||||||
|
Beyond basic primitives and structures, JSPG maps schemas to their storage and database-referential boundaries:
|
||||||
|
|
||||||
* **Table-Backed (Entity Types)**: Primarily defined in root `types` schemas. These represent physical Postgres tables.
|
* **Table-Backed (Entity Types)**: Primarily defined in root `types` schemas. These represent physical Postgres tables.
|
||||||
* They are implicitly registered in the Global Registry using their precise key name mapped from the database compilation phase.
|
* They are implicitly registered in the Global Registry using their precise key name mapped from the database compilation phase.
|
||||||
* The schema conceptually requires a `type` discriminator at runtime so the engine knows what physical variation to interact with.
|
* The schema conceptually requires a `type` discriminator at runtime so the engine knows what physical variation to interact with.
|
||||||
@ -162,9 +177,11 @@ It evaluates as an **Independent Declarative Rules Engine**. Every `Case` block
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Strict by Default & Extensibility
|
### Strict by Default & Extensibility
|
||||||
* **Strictness**: By default, any property not explicitly defined in the schema causes a validation error (effectively enforcing `additionalProperties: false` globally).
|
* **Strictness**: Strictness is a first-class feature for object schemas. By default, any property present in the JSON instance that is not explicitly defined in the schema's `properties` (or inherited, etc.) causes a `STRICT_PROPERTY_VIOLATION` validation error.
|
||||||
* **Extensibility (`extensible: true`)**: To allow a free-for-all of undefined properties, schemas must explicitly declare `"extensible": true`.
|
* **Extensibility (`extensible: true`)**: This keyword is valid **only** at the `type: "object"` level. By setting `"extensible": true`, you bypass the strictness checking on the object, allowing arbitrary undefined properties to pass.
|
||||||
* **Structured Additional Properties**: If `additionalProperties: {...}` is defined as a schema, arbitrary keys are allowed so long as their values match the defined type constraint.
|
* **Type: dict and type: array**: These types are dynamic/homogeneous:
|
||||||
|
* **`dict`**: Defined with `keys` and `items` schemas. Its keys and values are dynamic, so strictness checking does not apply. `"extensible"` is not applicable at the `dict` level.
|
||||||
|
* **`array`**: Homogeneous collection of items matching the `items` schema. Validation is homogeneous, so strictness checking does not apply. `"extensible"` is not applicable at the `array` level (tuple-like `prefixItems` are removed).
|
||||||
* **Inheritance Boundaries**: Strictness resets when crossing non-primitive `type` boundaries. A schema extending a strict parent remains strict unless it explicitly overrides with `"extensible": true`.
|
* **Inheritance Boundaries**: Strictness resets when crossing non-primitive `type` boundaries. A schema extending a strict parent remains strict unless it explicitly overrides with `"extensible": true`.
|
||||||
|
|
||||||
### Format Leniency for Empty Strings
|
### Format Leniency for Empty Strings
|
||||||
@ -206,7 +223,7 @@ Traits are reusable, non-generating schema fragments used to share properties an
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
* **Resolution and Merging**: During `Database::new()`, includes are resolved and merged at the raw JSON level:
|
* **Resolution and Merging**: During `Database::new()`, includes are resolved and merged at the raw JSON level:
|
||||||
* **`properties` / `patternProperties`**: Map keys from the host schema override/shadow included traits.
|
* **`properties`**: Map keys from the host schema override/shadow included traits.
|
||||||
* **`required` / `display`**: Lists are merged and deduped.
|
* **`required` / `display`**: Lists are merged and deduped.
|
||||||
* **`dependencies`**: Merged by combining and deduping lists.
|
* **`dependencies`**: Merged by combining and deduping lists.
|
||||||
* **Scalars / Arrays / Items**: Host definitions completely override included traits.
|
* **Scalars / Arrays / Items**: Host definitions completely override included traits.
|
||||||
|
|||||||
@ -1,246 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"description": "additionalProperties validates properties not matched by properties",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "schema1",
|
|
||||||
"schemas": {
|
|
||||||
"schema1": {
|
|
||||||
"properties": {
|
|
||||||
"foo": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"bar": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "defined properties are valid",
|
|
||||||
"data": {
|
|
||||||
"foo": "value",
|
|
||||||
"bar": 123
|
|
||||||
},
|
|
||||||
"schema_id": "schema1",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "additional property matching schema is valid",
|
|
||||||
"data": {
|
|
||||||
"foo": "value",
|
|
||||||
"is_active": true,
|
|
||||||
"hidden": false
|
|
||||||
},
|
|
||||||
"schema_id": "schema1",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "additional property not matching schema is invalid",
|
|
||||||
"data": {
|
|
||||||
"foo": "value",
|
|
||||||
"is_active": 1
|
|
||||||
},
|
|
||||||
"schema_id": "schema1",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "boolean"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "is_active",
|
|
||||||
"schema": "schema1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "extensible: true with additionalProperties still validates structure",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "additionalProperties_1_0",
|
|
||||||
"schemas": {
|
|
||||||
"additionalProperties_1_0": {
|
|
||||||
"properties": {
|
|
||||||
"foo": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extensible": true,
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "additional property matching schema is valid",
|
|
||||||
"data": {
|
|
||||||
"foo": "hello",
|
|
||||||
"count": 5,
|
|
||||||
"age": 42
|
|
||||||
},
|
|
||||||
"schema_id": "additionalProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "additional property not matching schema is invalid despite extensible: true",
|
|
||||||
"data": {
|
|
||||||
"foo": "hello",
|
|
||||||
"count": "five"
|
|
||||||
},
|
|
||||||
"schema_id": "additionalProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "count",
|
|
||||||
"schema": "additionalProperties_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "complex additionalProperties with object and array items",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "schema3",
|
|
||||||
"schemas": {
|
|
||||||
"schema3": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "valid array of strings",
|
|
||||||
"data": {
|
|
||||||
"type": "my_type",
|
|
||||||
"group_a": [
|
|
||||||
"field1",
|
|
||||||
"field2"
|
|
||||||
],
|
|
||||||
"group_b": [
|
|
||||||
"field3"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"schema_id": "schema3",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "invalid array of integers",
|
|
||||||
"data": {
|
|
||||||
"type": "my_type",
|
|
||||||
"group_a": [
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"schema_id": "schema3",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "string"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "group_a/0",
|
|
||||||
"schema": "schema3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "string"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "group_a/1",
|
|
||||||
"schema": "schema3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "invalid non-array type",
|
|
||||||
"data": {
|
|
||||||
"type": "my_type",
|
|
||||||
"group_a": "field1"
|
|
||||||
},
|
|
||||||
"schema_id": "schema3",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "array"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "group_a",
|
|
||||||
"schema": "schema3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -579,19 +579,7 @@
|
|||||||
"schema_id": "schema_schema1",
|
"schema_id": "schema_schema1",
|
||||||
"action": "validate",
|
"action": "validate",
|
||||||
"expect": {
|
"expect": {
|
||||||
"success": false,
|
"success": true
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_ITEM_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"index": "0"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0",
|
|
||||||
"schema": "schema_schema1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
284
fixtures/dict.json
Normal file
284
fixtures/dict.json
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"description": "basic dict type validation",
|
||||||
|
"database": {
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"name": "dict_basic",
|
||||||
|
"schemas": {
|
||||||
|
"dict_basic": {
|
||||||
|
"type": "dict"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "valid empty dict",
|
||||||
|
"data": {},
|
||||||
|
"schema_id": "dict_basic",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "valid simple dict",
|
||||||
|
"data": {
|
||||||
|
"key1": "value1",
|
||||||
|
"key2": 123,
|
||||||
|
"key3": true
|
||||||
|
},
|
||||||
|
"schema_id": "dict_basic",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "invalid type - array is not dict",
|
||||||
|
"data": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
],
|
||||||
|
"schema_id": "dict_basic",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": false,
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "INVALID_TYPE",
|
||||||
|
"values": {
|
||||||
|
"expected": "dict"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"path": "",
|
||||||
|
"schema": "dict_basic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "invalid type - string is not dict",
|
||||||
|
"data": "not a dict",
|
||||||
|
"schema_id": "dict_basic",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": false,
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "INVALID_TYPE",
|
||||||
|
"values": {
|
||||||
|
"expected": "dict"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"path": "",
|
||||||
|
"schema": "dict_basic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "dict keys validation",
|
||||||
|
"database": {
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"name": "dict_keys",
|
||||||
|
"schemas": {
|
||||||
|
"dict_keys": {
|
||||||
|
"type": "dict",
|
||||||
|
"keys": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[a-z]{3}$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "valid 3-letter lowercase keys",
|
||||||
|
"data": {
|
||||||
|
"abc": 1,
|
||||||
|
"xyz": "test"
|
||||||
|
},
|
||||||
|
"schema_id": "dict_keys",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "invalid key format",
|
||||||
|
"data": {
|
||||||
|
"abc": 1,
|
||||||
|
"abcd": 2
|
||||||
|
},
|
||||||
|
"schema_id": "dict_keys",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": false,
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "PATTERN_VIOLATED",
|
||||||
|
"values": {
|
||||||
|
"value": "abcd",
|
||||||
|
"pattern": "^[a-z]{3}$"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"path": "keys/abcd",
|
||||||
|
"schema": "dict_keys"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "dict items (values) validation",
|
||||||
|
"database": {
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"name": "dict_items",
|
||||||
|
"schemas": {
|
||||||
|
"dict_items": {
|
||||||
|
"type": "dict",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "valid integer values",
|
||||||
|
"data": {
|
||||||
|
"a": 1,
|
||||||
|
"b": 100
|
||||||
|
},
|
||||||
|
"schema_id": "dict_items",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "invalid value type",
|
||||||
|
"data": {
|
||||||
|
"a": 1,
|
||||||
|
"b": "string value"
|
||||||
|
},
|
||||||
|
"schema_id": "dict_items",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": false,
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "INVALID_TYPE",
|
||||||
|
"values": {
|
||||||
|
"expected": "integer"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"path": "b",
|
||||||
|
"schema": "dict_items"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "dict keys and items validation combined",
|
||||||
|
"database": {
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"name": "dict_combined",
|
||||||
|
"schemas": {
|
||||||
|
"dict_combined": {
|
||||||
|
"type": "dict",
|
||||||
|
"keys": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]+$"
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"description": "valid numeric keys and boolean values",
|
||||||
|
"data": {
|
||||||
|
"123": true,
|
||||||
|
"456": false
|
||||||
|
},
|
||||||
|
"schema_id": "dict_combined",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "invalid key and valid value",
|
||||||
|
"data": {
|
||||||
|
"123": true,
|
||||||
|
"abc": false
|
||||||
|
},
|
||||||
|
"schema_id": "dict_combined",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": false,
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "PATTERN_VIOLATED",
|
||||||
|
"values": {
|
||||||
|
"pattern": "^[0-9]+$",
|
||||||
|
"value": "abc"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"path": "keys/abc",
|
||||||
|
"schema": "dict_combined"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "valid key and invalid value",
|
||||||
|
"data": {
|
||||||
|
"123": "not a boolean"
|
||||||
|
},
|
||||||
|
"schema_id": "dict_combined",
|
||||||
|
"action": "validate",
|
||||||
|
"expect": {
|
||||||
|
"success": false,
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"code": "INVALID_TYPE",
|
||||||
|
"values": {
|
||||||
|
"expected": "boolean"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"path": "123",
|
||||||
|
"schema": "dict_combined"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -213,603 +213,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "items and subitems",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "items_3_0",
|
|
||||||
"schemas": {
|
|
||||||
"items_3_0": {
|
|
||||||
"type": "array",
|
|
||||||
"items": false,
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "item"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "item"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "item"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "item",
|
|
||||||
"schemas": {
|
|
||||||
"item": {
|
|
||||||
"type": "array",
|
|
||||||
"items": false,
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "sub-item"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "sub-item"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sub-item",
|
|
||||||
"schemas": {
|
|
||||||
"sub-item": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"foo"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "valid items",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "items_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "too many items",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "items_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "3",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "too many sub-items",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "items_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "0/2",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "wrong item",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "items_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "array"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "wrong sub-item",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "items_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "REQUIRED_FIELD_MISSING",
|
|
||||||
"values": {
|
|
||||||
"field_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2/1/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "fewer items is invalid",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"foo": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "items_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "foo"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1/0/foo",
|
|
||||||
"schema": "items_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "nested items",
|
"description": "nested items",
|
||||||
"database": {
|
"database": {
|
||||||
@ -1021,282 +424,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "prefixItems with no additional items allowed",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "items_5_0",
|
|
||||||
"schemas": {
|
|
||||||
"items_5_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
],
|
|
||||||
"items": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "empty array",
|
|
||||||
"data": [],
|
|
||||||
"schema_id": "items_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "fewer number of items present (1)",
|
|
||||||
"data": [
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"schema_id": "items_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "fewer number of items present (2)",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
],
|
|
||||||
"schema_id": "items_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "equal number of items present",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3
|
|
||||||
],
|
|
||||||
"schema_id": "items_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "additional items are not permitted",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
4
|
|
||||||
],
|
|
||||||
"schema_id": "items_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "3",
|
|
||||||
"schema": "items_5_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "items does not look in applicators, valid case",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "items_6_0",
|
|
||||||
"schemas": {
|
|
||||||
"items_6_0": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"minimum": 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"minimum": 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "prefixItems in allOf does not constrain items, invalid case",
|
|
||||||
"data": [
|
|
||||||
3,
|
|
||||||
5
|
|
||||||
],
|
|
||||||
"schema_id": "items_6_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "MINIMUM_VIOLATED",
|
|
||||||
"values": {
|
|
||||||
"limit": "5",
|
|
||||||
"value": "3"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0",
|
|
||||||
"schema": "items_6_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "prefixItems in allOf does not constrain items, valid case",
|
|
||||||
"data": [
|
|
||||||
5,
|
|
||||||
5
|
|
||||||
],
|
|
||||||
"schema_id": "items_6_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "prefixItems validation adjusts the starting index for items",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "items_7_0",
|
|
||||||
"schemas": {
|
|
||||||
"items_7_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"items": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "valid items",
|
|
||||||
"data": [
|
|
||||||
"x",
|
|
||||||
2,
|
|
||||||
3
|
|
||||||
],
|
|
||||||
"schema_id": "items_7_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "wrong type of second item",
|
|
||||||
"data": [
|
|
||||||
"x",
|
|
||||||
"y"
|
|
||||||
],
|
|
||||||
"schema_id": "items_7_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1",
|
|
||||||
"schema": "items_7_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "items with heterogeneous array",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "items_8_0",
|
|
||||||
"schemas": {
|
|
||||||
"items_8_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{}
|
|
||||||
],
|
|
||||||
"items": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "heterogeneous invalid instance",
|
|
||||||
"data": [
|
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
37
|
|
||||||
],
|
|
||||||
"schema_id": "items_8_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "1",
|
|
||||||
"schema": "items_8_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "2",
|
|
||||||
"schema": "items_8_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "valid instance",
|
|
||||||
"data": [
|
|
||||||
null
|
|
||||||
],
|
|
||||||
"schema_id": "items_8_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "items with null instance elements",
|
"description": "items with null instance elements",
|
||||||
"database": {
|
"database": {
|
||||||
@ -1460,56 +587,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "array: strict array",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "items_13_0",
|
|
||||||
"schemas": {
|
|
||||||
"items_13_0": {
|
|
||||||
"type": "array",
|
|
||||||
"extensible": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "empty array is valid",
|
|
||||||
"data": [],
|
|
||||||
"schema_id": "items_13_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "array with items is invalid (strict)",
|
|
||||||
"data": [
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"schema_id": "items_13_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_ITEM_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"index": "0"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0",
|
|
||||||
"schema": "items_13_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "array: items extensible",
|
"description": "array: items extensible",
|
||||||
"database": {
|
"database": {
|
||||||
|
|||||||
@ -7,8 +7,7 @@
|
|||||||
"name": "maxItems_0_0",
|
"name": "maxItems_0_0",
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"maxItems_0_0": {
|
"maxItems_0_0": {
|
||||||
"maxItems": 2,
|
"maxItems": 2
|
||||||
"extensible": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,8 +82,7 @@
|
|||||||
"name": "maxItems_1_0",
|
"name": "maxItems_1_0",
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"maxItems_1_0": {
|
"maxItems_1_0": {
|
||||||
"maxItems": 2,
|
"maxItems": 2
|
||||||
"extensible": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,8 +136,7 @@
|
|||||||
"name": "maxItems_2_0",
|
"name": "maxItems_2_0",
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"maxItems_2_0": {
|
"maxItems_2_0": {
|
||||||
"maxItems": 2,
|
"maxItems": 2
|
||||||
"extensible": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,7 @@
|
|||||||
"name": "minItems_0_0",
|
"name": "minItems_0_0",
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"minItems_0_0": {
|
"minItems_0_0": {
|
||||||
"minItems": 1,
|
"minItems": 1
|
||||||
"extensible": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,8 +78,7 @@
|
|||||||
"name": "minItems_1_0",
|
"name": "minItems_1_0",
|
||||||
"schemas": {
|
"schemas": {
|
||||||
"minItems_1_0": {
|
"minItems_1_0": {
|
||||||
"minItems": 1,
|
"minItems": 1
|
||||||
"extensible": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,580 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"description": "patternProperties validates properties matching a regex",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "patternProperties_0_0",
|
|
||||||
"schemas": {
|
|
||||||
"patternProperties_0_0": {
|
|
||||||
"patternProperties": {
|
|
||||||
"f.*o": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"items": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "a single valid match is valid",
|
|
||||||
"data": {
|
|
||||||
"foo": 1
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "multiple valid matches is valid",
|
|
||||||
"data": {
|
|
||||||
"foo": 1,
|
|
||||||
"foooooo": 2
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "a single invalid match is invalid",
|
|
||||||
"data": {
|
|
||||||
"foo": "bar",
|
|
||||||
"fooooo": 2
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "foo",
|
|
||||||
"schema": "patternProperties_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "multiple invalid matches is invalid",
|
|
||||||
"data": {
|
|
||||||
"foo": "bar",
|
|
||||||
"foooooo": "baz"
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "foo",
|
|
||||||
"schema": "patternProperties_0_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "foooooo",
|
|
||||||
"schema": "patternProperties_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "ignores arrays",
|
|
||||||
"data": [
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "ignores strings",
|
|
||||||
"data": "foo",
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "ignores other non-objects",
|
|
||||||
"data": 12,
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "extra property not matching pattern is INVALID (strict by default)",
|
|
||||||
"data": {
|
|
||||||
"foo": 1,
|
|
||||||
"extra": 2
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "extra"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "extra",
|
|
||||||
"schema": "patternProperties_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "multiple simultaneous patternProperties are validated",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "patternProperties_1_0",
|
|
||||||
"schemas": {
|
|
||||||
"patternProperties_1_0": {
|
|
||||||
"patternProperties": {
|
|
||||||
"a*": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"aaa*": {
|
|
||||||
"maximum": 20
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "a single valid match is valid",
|
|
||||||
"data": {
|
|
||||||
"a": 21
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "a simultaneous match is valid",
|
|
||||||
"data": {
|
|
||||||
"aaaa": 18
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "multiple matches is valid",
|
|
||||||
"data": {
|
|
||||||
"a": 21,
|
|
||||||
"aaaa": 18
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "an invalid due to one is invalid",
|
|
||||||
"data": {
|
|
||||||
"a": "bar"
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "a",
|
|
||||||
"schema": "patternProperties_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "an invalid due to the other is invalid",
|
|
||||||
"data": {
|
|
||||||
"aaaa": 31
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "MAXIMUM_VIOLATED",
|
|
||||||
"values": {
|
|
||||||
"value": "31",
|
|
||||||
"limit": "20"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "aaaa",
|
|
||||||
"schema": "patternProperties_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "an invalid due to both is invalid",
|
|
||||||
"data": {
|
|
||||||
"aaa": "foo",
|
|
||||||
"aaaa": 31
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "aaa",
|
|
||||||
"schema": "patternProperties_1_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "MAXIMUM_VIOLATED",
|
|
||||||
"values": {
|
|
||||||
"limit": "20",
|
|
||||||
"value": "31"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "aaaa",
|
|
||||||
"schema": "patternProperties_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "regexes are not anchored by default and are case sensitive",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "patternProperties_2_0",
|
|
||||||
"schemas": {
|
|
||||||
"patternProperties_2_0": {
|
|
||||||
"patternProperties": {
|
|
||||||
"[0-9]{2,}": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"X_": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extensible": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "non recognized members are ignored",
|
|
||||||
"data": {
|
|
||||||
"answer 1": "42"
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "recognized members are accounted for",
|
|
||||||
"data": {
|
|
||||||
"a31b": null
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "boolean"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "a31b",
|
|
||||||
"schema": "patternProperties_2_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "regexes are case sensitive",
|
|
||||||
"data": {
|
|
||||||
"a_x_3": 3
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "regexes are case sensitive, 2",
|
|
||||||
"data": {
|
|
||||||
"a_X_3": 3
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "string"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "a_X_3",
|
|
||||||
"schema": "patternProperties_2_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "patternProperties with boolean schemas",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "patternProperties_3_0",
|
|
||||||
"schemas": {
|
|
||||||
"patternProperties_3_0": {
|
|
||||||
"patternProperties": {
|
|
||||||
"f.*": true,
|
|
||||||
"b.*": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "object with property matching schema true is valid",
|
|
||||||
"data": {
|
|
||||||
"foo": 1
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "object with property matching schema false is invalid",
|
|
||||||
"data": {
|
|
||||||
"bar": 2
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "bar",
|
|
||||||
"schema": "patternProperties_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "object with both properties is invalid",
|
|
||||||
"data": {
|
|
||||||
"foo": 1,
|
|
||||||
"bar": 2
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "bar",
|
|
||||||
"schema": "patternProperties_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "object with a property matching both true and false is invalid",
|
|
||||||
"data": {
|
|
||||||
"foobar": 1
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "foobar",
|
|
||||||
"schema": "patternProperties_3_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "empty object is valid",
|
|
||||||
"data": {},
|
|
||||||
"schema_id": "patternProperties_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "patternProperties with null valued instance properties",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "patternProperties_4_0",
|
|
||||||
"schemas": {
|
|
||||||
"patternProperties_4_0": {
|
|
||||||
"patternProperties": {
|
|
||||||
"^.*bar$": {
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "allows null values",
|
|
||||||
"data": {
|
|
||||||
"foobar": null
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "extensible: true allows extra properties NOT matching pattern",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "patternProperties_5_0",
|
|
||||||
"schemas": {
|
|
||||||
"patternProperties_5_0": {
|
|
||||||
"patternProperties": {
|
|
||||||
"f.*o": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extensible": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "extra property not matching pattern is valid",
|
|
||||||
"data": {
|
|
||||||
"bar": 1
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "property matching pattern MUST still be valid",
|
|
||||||
"data": {
|
|
||||||
"foo": "invalid string"
|
|
||||||
},
|
|
||||||
"schema_id": "patternProperties_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "foo",
|
|
||||||
"schema": "patternProperties_5_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,324 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"description": "a schema given for prefixItems",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "prefixItems_0_0",
|
|
||||||
"schemas": {
|
|
||||||
"prefixItems_0_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "correct types",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "wrong types",
|
|
||||||
"data": [
|
|
||||||
"foo",
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "integer"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0",
|
|
||||||
"schema": "prefixItems_0_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "INVALID_TYPE",
|
|
||||||
"values": {
|
|
||||||
"expected": "string"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1",
|
|
||||||
"schema": "prefixItems_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "incomplete array of items",
|
|
||||||
"data": [
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "array with additional items (invalid due to strictness)",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
"foo",
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_ITEM_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"index": "2"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "2",
|
|
||||||
"schema": "prefixItems_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "empty array",
|
|
||||||
"data": [],
|
|
||||||
"schema_id": "prefixItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "JavaScript pseudo-array is valid (invalid due to strict object validation)",
|
|
||||||
"data": {
|
|
||||||
"0": "invalid",
|
|
||||||
"1": "valid",
|
|
||||||
"length": 2
|
|
||||||
},
|
|
||||||
"schema_id": "prefixItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "0"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "0",
|
|
||||||
"schema": "prefixItems_0_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "1"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "1",
|
|
||||||
"schema": "prefixItems_0_0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
|
||||||
"values": {
|
|
||||||
"property_name": "length"
|
|
||||||
},
|
|
||||||
"details": {
|
|
||||||
"path": "length",
|
|
||||||
"schema": "prefixItems_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "prefixItems with boolean schemas",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "prefixItems_1_0",
|
|
||||||
"schemas": {
|
|
||||||
"prefixItems_1_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "array with one item is valid",
|
|
||||||
"data": [
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "array with two items is invalid",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "1",
|
|
||||||
"schema": "prefixItems_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "empty array is valid",
|
|
||||||
"data": [],
|
|
||||||
"schema_id": "prefixItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "additional items are allowed by default",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "prefixItems_2_0",
|
|
||||||
"schemas": {
|
|
||||||
"prefixItems_2_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extensible": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "only the first item is validated",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
"foo",
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "prefixItems with null instance elements",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "prefixItems_3_0",
|
|
||||||
"schemas": {
|
|
||||||
"prefixItems_3_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "allows null elements",
|
|
||||||
"data": [
|
|
||||||
null
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_3_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "extensible: true allows extra items with prefixItems",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "prefixItems_4_0",
|
|
||||||
"schemas": {
|
|
||||||
"prefixItems_4_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"extensible": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "extra item is valid",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "prefixItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -316,536 +316,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "non-unique array of more than two arrays is invalid",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"bar"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"foo"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "1 and true are unique",
|
|
||||||
"data": [
|
|
||||||
1,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "0 and false are unique",
|
|
||||||
"data": [
|
|
||||||
0,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[1] and [true] are unique",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
1
|
|
||||||
],
|
|
||||||
[
|
|
||||||
true
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[0] and [false] are unique",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
0
|
|
||||||
],
|
|
||||||
[
|
|
||||||
false
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "nested [1] and [true] are unique",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
[
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"foo"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "nested [0] and [false] are unique",
|
|
||||||
"data": [
|
|
||||||
[
|
|
||||||
[
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"foo"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "unique heterogeneous types are valid",
|
|
||||||
"data": [
|
|
||||||
{},
|
|
||||||
[
|
|
||||||
1
|
|
||||||
],
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
1,
|
|
||||||
"{}"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "non-unique heterogeneous types are invalid",
|
|
||||||
"data": [
|
|
||||||
{},
|
|
||||||
[
|
|
||||||
1
|
|
||||||
],
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
{},
|
|
||||||
1
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "different objects are unique",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"a": 2,
|
|
||||||
"b": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "objects are non-unique despite key order",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"a": 1,
|
|
||||||
"b": 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"b": 2,
|
|
||||||
"a": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "{\"a\": false} and {\"a\": 0} are unique",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"a": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"a": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "{\"a\": true} and {\"a\": 1} are unique",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"a": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"a": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_0_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "uniqueItems with an array of items",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "uniqueItems_1_0",
|
|
||||||
"schemas": {
|
|
||||||
"uniqueItems_1_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"uniqueItems": true,
|
|
||||||
"extensible": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "[false, true] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, false] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[false, false] from items array is not valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, true] from items array is not valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "unique array extended from [false, true] is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
"foo",
|
|
||||||
"bar"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "unique array extended from [true, false] is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
"foo",
|
|
||||||
"bar"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "non-unique array extended from [false, true] is not valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
"foo",
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "non-unique array extended from [true, false] is not valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
"foo",
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_1_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_1_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "uniqueItems with an array of items and additionalItems=false",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "uniqueItems_2_0",
|
|
||||||
"schemas": {
|
|
||||||
"uniqueItems_2_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"uniqueItems": true,
|
|
||||||
"items": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "[false, true] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, false] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[false, false] from items array is not valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_2_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, true] from items array is not valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "UNIQUE_ITEMS_VIOLATED",
|
|
||||||
"details": {
|
|
||||||
"path": "",
|
|
||||||
"schema": "uniqueItems_2_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "extra items are invalid even if unique",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
null
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_2_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "2",
|
|
||||||
"schema": "uniqueItems_2_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -1099,232 +569,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "uniqueItems=false with an array of items",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "uniqueItems_4_0",
|
|
||||||
"schemas": {
|
|
||||||
"uniqueItems_4_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"uniqueItems": false,
|
|
||||||
"extensible": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "[false, true] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, false] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[false, false] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, true] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "unique array extended from [false, true] is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
"foo",
|
|
||||||
"bar"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "unique array extended from [true, false] is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
"foo",
|
|
||||||
"bar"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "non-unique array extended from [false, true] is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
"foo",
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "non-unique array extended from [true, false] is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
"foo",
|
|
||||||
"foo"
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_4_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "uniqueItems=false with an array of items and additionalItems=false",
|
|
||||||
"database": {
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"name": "uniqueItems_5_0",
|
|
||||||
"schemas": {
|
|
||||||
"uniqueItems_5_0": {
|
|
||||||
"prefixItems": [
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"uniqueItems": false,
|
|
||||||
"items": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"description": "[false, true] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, false] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[false, false] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "[true, true] from items array is valid",
|
|
||||||
"data": [
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "extra items are invalid even if unique",
|
|
||||||
"data": [
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
null
|
|
||||||
],
|
|
||||||
"schema_id": "uniqueItems_5_0",
|
|
||||||
"action": "validate",
|
|
||||||
"expect": {
|
|
||||||
"success": false,
|
|
||||||
"errors": [
|
|
||||||
{
|
|
||||||
"code": "FALSE_SCHEMA",
|
|
||||||
"details": {
|
|
||||||
"path": "2",
|
|
||||||
"schema": "uniqueItems_5_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "extensible: true allows extra items in uniqueItems",
|
"description": "extensible: true allows extra items in uniqueItems",
|
||||||
"database": {
|
"database": {
|
||||||
|
|||||||
@ -25,9 +25,9 @@ impl Schema {
|
|||||||
("identifier".to_string(), id.to_string()),
|
("identifier".to_string(), id.to_string()),
|
||||||
])),
|
])),
|
||||||
details: ErrorDetails {
|
details: ErrorDetails {
|
||||||
path: Some(path.to_string()),
|
path: Some(path.to_string()),
|
||||||
schema: Some(root_id.to_string()),
|
schema: Some(root_id.to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -84,13 +84,6 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pattern_props) = &schema_arc.obj.pattern_properties {
|
|
||||||
for (k, v) in pattern_props.iter() {
|
|
||||||
let next_path = format!("{}/{}", path, k);
|
|
||||||
Self::collect_schemas(v, root_id, next_path, to_insert, errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut map_arr = |arr: &Vec<Arc<Schema>>, sub: &str| {
|
let mut map_arr = |arr: &Vec<Arc<Schema>>, sub: &str| {
|
||||||
for (i, v) in arr.iter().enumerate() {
|
for (i, v) in arr.iter().enumerate() {
|
||||||
Self::collect_schemas(
|
Self::collect_schemas(
|
||||||
@ -103,10 +96,6 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(arr) = &schema_arc.obj.prefix_items {
|
|
||||||
map_arr(arr, "prefixItems");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arr) = &schema_arc.obj.one_of {
|
if let Some(arr) = &schema_arc.obj.one_of {
|
||||||
map_arr(arr, "oneOf");
|
map_arr(arr, "oneOf");
|
||||||
}
|
}
|
||||||
@ -123,11 +112,6 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
map_opt(
|
|
||||||
&schema_arc.obj.additional_properties,
|
|
||||||
false,
|
|
||||||
"additionalProperties",
|
|
||||||
);
|
|
||||||
map_opt(&schema_arc.obj.items, true, "items");
|
map_opt(&schema_arc.obj.items, true, "items");
|
||||||
map_opt(&schema_arc.obj.not, false, "not");
|
map_opt(&schema_arc.obj.not, false, "not");
|
||||||
map_opt(&schema_arc.obj.contains, false, "contains");
|
map_opt(&schema_arc.obj.contains, false, "contains");
|
||||||
|
|||||||
@ -39,18 +39,6 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pattern_props) = &self.obj.pattern_properties {
|
|
||||||
let mut compiled = Vec::new();
|
|
||||||
for (k, v) in pattern_props {
|
|
||||||
if let Ok(re) = regex::Regex::new(k) {
|
|
||||||
compiled.push((crate::database::object::CompiledRegex(re), v.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !compiled.is_empty() {
|
|
||||||
let _ = self.obj.compiled_pattern_properties.set(compiled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut props = IndexMap::new();
|
let mut props = IndexMap::new();
|
||||||
|
|
||||||
// 1. Resolve INHERITANCE dependencies first
|
// 1. Resolve INHERITANCE dependencies first
|
||||||
@ -78,10 +66,10 @@ impl Schema {
|
|||||||
code: "MULTIPLE_INHERITANCE_PROHIBITED".to_string(),
|
code: "MULTIPLE_INHERITANCE_PROHIBITED".to_string(),
|
||||||
values: Some(HashMap::from([("types".to_string(), types.join(", "))])),
|
values: Some(HashMap::from([("types".to_string(), types.join(", "))])),
|
||||||
details: ErrorDetails {
|
details: ErrorDetails {
|
||||||
path: Some(path.clone()),
|
path: Some(path.clone()),
|
||||||
schema: Some(root_id.to_string()),
|
schema: Some(root_id.to_string()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,29 +128,13 @@ impl Schema {
|
|||||||
if let Some(items) = &self.obj.items {
|
if let Some(items) = &self.obj.items {
|
||||||
items.compile(db, root_id, format!("{}/items", path), errors);
|
items.compile(db, root_id, format!("{}/items", path), errors);
|
||||||
}
|
}
|
||||||
if let Some(pattern_props) = &self.obj.pattern_properties {
|
|
||||||
for (k, child) in pattern_props {
|
|
||||||
child.compile(db, root_id, format!("{}/{}", path, k), errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(additional_props) = &self.obj.additional_properties {
|
|
||||||
additional_props.compile(
|
|
||||||
db,
|
|
||||||
root_id,
|
|
||||||
format!("{}/additionalProperties", path),
|
|
||||||
errors,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some(one_of) = &self.obj.one_of {
|
if let Some(one_of) = &self.obj.one_of {
|
||||||
for (i, child) in one_of.iter().enumerate() {
|
for (i, child) in one_of.iter().enumerate() {
|
||||||
child.compile(db, root_id, format!("{}/oneOf/{}", path, i), errors);
|
child.compile(db, root_id, format!("{}/oneOf/{}", path, i), errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(arr) = &self.obj.prefix_items {
|
|
||||||
for (i, child) in arr.iter().enumerate() {
|
|
||||||
child.compile(db, root_id, format!("{}/prefixItems/{}", path, i), errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(child) = &self.obj.not {
|
if let Some(child) = &self.obj.not {
|
||||||
child.compile(db, root_id, format!("{}/not", path), errors);
|
child.compile(db, root_id, format!("{}/not", path), errors);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,7 +81,6 @@ fn resolve_in_place(
|
|||||||
let mut merged_required = HashSet::new();
|
let mut merged_required = HashSet::new();
|
||||||
let mut merged_display = HashSet::new();
|
let mut merged_display = HashSet::new();
|
||||||
let mut merged_dependencies = serde_json::Map::new();
|
let mut merged_dependencies = serde_json::Map::new();
|
||||||
let mut merged_pattern_props = serde_json::Map::new();
|
|
||||||
|
|
||||||
// Read current values first to let host override included properties
|
// Read current values first to let host override included properties
|
||||||
if let Some(req) = current.get("required").and_then(|v| v.as_array()) {
|
if let Some(req) = current.get("required").and_then(|v| v.as_array()) {
|
||||||
@ -103,11 +102,7 @@ fn resolve_in_place(
|
|||||||
merged_dependencies.insert(k.clone(), v.clone());
|
merged_dependencies.insert(k.clone(), v.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(pat_props) = current.get("patternProperties").and_then(|v| v.as_object()) {
|
|
||||||
for (k, v) in pat_props {
|
|
||||||
merged_pattern_props.insert(k.clone(), v.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(props) = current.get("properties").and_then(|v| v.as_object()) {
|
if let Some(props) = current.get("properties").and_then(|v| v.as_object()) {
|
||||||
for (k, v) in props {
|
for (k, v) in props {
|
||||||
merged_props.insert(k.clone(), v.clone());
|
merged_props.insert(k.clone(), v.clone());
|
||||||
@ -119,7 +114,10 @@ fn resolve_in_place(
|
|||||||
if visited.contains(inc_name) {
|
if visited.contains(inc_name) {
|
||||||
errors.push(Error {
|
errors.push(Error {
|
||||||
code: "CIRCULAR_INCLUDE_DETECTED".to_string(),
|
code: "CIRCULAR_INCLUDE_DETECTED".to_string(),
|
||||||
values: Some(HashMap::from([("include".to_string(), inc_name.to_string())])),
|
values: Some(HashMap::from([(
|
||||||
|
"include".to_string(),
|
||||||
|
inc_name.to_string(),
|
||||||
|
)])),
|
||||||
details: ErrorDetails {
|
details: ErrorDetails {
|
||||||
schema: Some(schema_id.to_string()),
|
schema: Some(schema_id.to_string()),
|
||||||
path: Some(path.to_string()),
|
path: Some(path.to_string()),
|
||||||
@ -156,18 +154,6 @@ fn resolve_in_place(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge patternProperties (host overrides trait)
|
|
||||||
if let Some(target_pat_props) = resolved_target
|
|
||||||
.get("patternProperties")
|
|
||||||
.and_then(|v| v.as_object())
|
|
||||||
{
|
|
||||||
for (k, v) in target_pat_props {
|
|
||||||
if !merged_pattern_props.contains_key(k) {
|
|
||||||
merged_pattern_props.insert(k.clone(), v.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge required
|
// Merge required
|
||||||
if let Some(target_req) = resolved_target.get("required").and_then(|v| v.as_array()) {
|
if let Some(target_req) = resolved_target.get("required").and_then(|v| v.as_array()) {
|
||||||
for r in target_req {
|
for r in target_req {
|
||||||
@ -218,7 +204,6 @@ fn resolve_in_place(
|
|||||||
if let Some(obj) = current.as_object_mut() {
|
if let Some(obj) = current.as_object_mut() {
|
||||||
for (k, v) in resolved_target.as_object().unwrap() {
|
for (k, v) in resolved_target.as_object().unwrap() {
|
||||||
if k != "properties"
|
if k != "properties"
|
||||||
&& k != "patternProperties"
|
|
||||||
&& k != "required"
|
&& k != "required"
|
||||||
&& k != "display"
|
&& k != "display"
|
||||||
&& k != "dependencies"
|
&& k != "dependencies"
|
||||||
@ -233,7 +218,10 @@ fn resolve_in_place(
|
|||||||
} else {
|
} else {
|
||||||
errors.push(Error {
|
errors.push(Error {
|
||||||
code: "TRAIT_NOT_FOUND".to_string(),
|
code: "TRAIT_NOT_FOUND".to_string(),
|
||||||
values: Some(HashMap::from([("include".to_string(), inc_name.to_string())])),
|
values: Some(HashMap::from([(
|
||||||
|
"include".to_string(),
|
||||||
|
inc_name.to_string(),
|
||||||
|
)])),
|
||||||
details: ErrorDetails {
|
details: ErrorDetails {
|
||||||
schema: Some(schema_id.to_string()),
|
schema: Some(schema_id.to_string()),
|
||||||
path: Some(path.to_string()),
|
path: Some(path.to_string()),
|
||||||
@ -248,12 +236,7 @@ fn resolve_in_place(
|
|||||||
if !merged_props.is_empty() {
|
if !merged_props.is_empty() {
|
||||||
obj.insert("properties".to_string(), Value::Object(merged_props));
|
obj.insert("properties".to_string(), Value::Object(merged_props));
|
||||||
}
|
}
|
||||||
if !merged_pattern_props.is_empty() {
|
|
||||||
obj.insert(
|
|
||||||
"patternProperties".to_string(),
|
|
||||||
Value::Object(merged_pattern_props),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if !merged_required.is_empty() {
|
if !merged_required.is_empty() {
|
||||||
let mut req_vec: Vec<Value> = merged_required.into_iter().map(Value::String).collect();
|
let mut req_vec: Vec<Value> = merged_required.into_iter().map(Value::String).collect();
|
||||||
req_vec.sort_by(|a, b| a.as_str().unwrap().cmp(b.as_str().unwrap()));
|
req_vec.sort_by(|a, b| a.as_str().unwrap().cmp(b.as_str().unwrap()));
|
||||||
@ -289,22 +272,7 @@ fn resolve_in_place(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(pat_props) = obj
|
|
||||||
.get_mut("patternProperties")
|
|
||||||
.and_then(|v| v.as_object_mut())
|
|
||||||
{
|
|
||||||
for (k, v) in pat_props {
|
|
||||||
resolve_in_place(
|
|
||||||
v,
|
|
||||||
traits,
|
|
||||||
schemas,
|
|
||||||
errors,
|
|
||||||
schema_id,
|
|
||||||
&format!("{}/{}", path, k),
|
|
||||||
visited,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(items) = obj.get_mut("items") {
|
if let Some(items) = obj.get_mut("items") {
|
||||||
resolve_in_place(
|
resolve_in_place(
|
||||||
items,
|
items,
|
||||||
@ -316,30 +284,6 @@ fn resolve_in_place(
|
|||||||
visited,
|
visited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if let Some(prefix_items) = obj.get_mut("prefixItems").and_then(|v| v.as_array_mut()) {
|
|
||||||
for (i, v) in prefix_items.iter_mut().enumerate() {
|
|
||||||
resolve_in_place(
|
|
||||||
v,
|
|
||||||
traits,
|
|
||||||
schemas,
|
|
||||||
errors,
|
|
||||||
schema_id,
|
|
||||||
&format!("{}/prefixItems/{}", path, i),
|
|
||||||
visited,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(additional_props) = obj.get_mut("additionalProperties") {
|
|
||||||
resolve_in_place(
|
|
||||||
additional_props,
|
|
||||||
traits,
|
|
||||||
schemas,
|
|
||||||
errors,
|
|
||||||
schema_id,
|
|
||||||
&format!("{}/additionalProperties", path),
|
|
||||||
visited,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if let Some(one_of) = obj.get_mut("oneOf").and_then(|v| v.as_array_mut()) {
|
if let Some(one_of) = obj.get_mut("oneOf").and_then(|v| v.as_array_mut()) {
|
||||||
for (i, v) in one_of.iter_mut().enumerate() {
|
for (i, v) in one_of.iter_mut().enumerate() {
|
||||||
resolve_in_place(
|
resolve_in_place(
|
||||||
|
|||||||
@ -32,12 +32,10 @@ pub struct SchemaObject {
|
|||||||
// Object Keywords
|
// Object Keywords
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub properties: Option<IndexMap<String, Arc<Schema>>>,
|
pub properties: Option<IndexMap<String, Arc<Schema>>>,
|
||||||
#[serde(rename = "patternProperties")]
|
#[serde(rename = "keys")]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub pattern_properties: Option<IndexMap<String, Arc<Schema>>>,
|
pub keys: Option<Arc<Schema>>,
|
||||||
#[serde(rename = "additionalProperties")]
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub additional_properties: Option<Arc<Schema>>,
|
|
||||||
#[serde(rename = "family")]
|
#[serde(rename = "family")]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub family: Option<String>,
|
pub family: Option<String>,
|
||||||
@ -53,9 +51,6 @@ pub struct SchemaObject {
|
|||||||
#[serde(rename = "items")]
|
#[serde(rename = "items")]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub items: Option<Arc<Schema>>,
|
pub items: Option<Arc<Schema>>,
|
||||||
#[serde(rename = "prefixItems")]
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub prefix_items: Option<Vec<Arc<Schema>>>,
|
|
||||||
|
|
||||||
// String Validation
|
// String Validation
|
||||||
#[serde(rename = "minLength")]
|
#[serde(rename = "minLength")]
|
||||||
@ -189,8 +184,6 @@ pub struct SchemaObject {
|
|||||||
pub compiled_format: OnceLock<CompiledFormat>,
|
pub compiled_format: OnceLock<CompiledFormat>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub compiled_pattern: OnceLock<CompiledRegex>,
|
pub compiled_pattern: OnceLock<CompiledRegex>,
|
||||||
#[serde(skip)]
|
|
||||||
pub compiled_pattern_properties: OnceLock<Vec<(CompiledRegex, Arc<Schema>)>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a compiled format validator
|
/// Represents a compiled format validator
|
||||||
@ -263,7 +256,7 @@ where
|
|||||||
pub fn is_primitive_type(t: &str) -> bool {
|
pub fn is_primitive_type(t: &str) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
t,
|
t,
|
||||||
"string" | "number" | "integer" | "boolean" | "object" | "array" | "null"
|
"string" | "number" | "integer" | "boolean" | "object" | "array" | "null" | "dict"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,12 +26,10 @@ impl Schema {
|
|||||||
/// Returns true if the schema acts purely as a type pointer (composition without overriding constraints)
|
/// Returns true if the schema acts purely as a type pointer (composition without overriding constraints)
|
||||||
pub fn is_proxy(&self) -> bool {
|
pub fn is_proxy(&self) -> bool {
|
||||||
self.obj.properties.is_none()
|
self.obj.properties.is_none()
|
||||||
&& self.obj.pattern_properties.is_none()
|
&& self.obj.keys.is_none()
|
||||||
&& self.obj.additional_properties.is_none()
|
|
||||||
&& self.obj.required.is_none()
|
&& self.obj.required.is_none()
|
||||||
&& self.obj.dependencies.is_none()
|
&& self.obj.dependencies.is_none()
|
||||||
&& self.obj.items.is_none()
|
&& self.obj.items.is_none()
|
||||||
&& self.obj.prefix_items.is_none()
|
|
||||||
&& self.obj.contains.is_none()
|
&& self.obj.contains.is_none()
|
||||||
&& self.obj.format.is_none()
|
&& self.obj.format.is_none()
|
||||||
&& self.obj.enum_.is_none()
|
&& self.obj.enum_.is_none()
|
||||||
@ -68,12 +66,10 @@ impl<'de> Deserialize<'de> for Schema {
|
|||||||
// restrict additional properties natively
|
// restrict additional properties natively
|
||||||
let is_empty = obj.type_.is_none()
|
let is_empty = obj.type_.is_none()
|
||||||
&& obj.properties.is_none()
|
&& obj.properties.is_none()
|
||||||
&& obj.pattern_properties.is_none()
|
&& obj.keys.is_none()
|
||||||
&& obj.additional_properties.is_none()
|
|
||||||
&& obj.required.is_none()
|
&& obj.required.is_none()
|
||||||
&& obj.dependencies.is_none()
|
&& obj.dependencies.is_none()
|
||||||
&& obj.items.is_none()
|
&& obj.items.is_none()
|
||||||
&& obj.prefix_items.is_none()
|
|
||||||
&& obj.contains.is_none()
|
&& obj.contains.is_none()
|
||||||
&& obj.format.is_none()
|
&& obj.format.is_none()
|
||||||
&& obj.enum_.is_none()
|
&& obj.enum_.is_none()
|
||||||
|
|||||||
@ -197,84 +197,6 @@ fn test_unique_items_0_14() {
|
|||||||
crate::tests::runner::run_test_case(&path, 0, 14).unwrap();
|
crate::tests::runner::run_test_case(&path, 0, 14).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_15() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 15).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_16() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 16).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_17() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 17).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_18() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 18).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_19() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 19).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_20() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 20).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_21() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 21).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_22() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 22).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_23() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 23).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_24() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 24).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_25() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 25).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_26() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 26).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_0_27() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 27).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unique_items_1_0() {
|
fn test_unique_items_1_0() {
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -323,6 +245,48 @@ fn test_unique_items_1_7() {
|
|||||||
crate::tests::runner::run_test_case(&path, 1, 7).unwrap();
|
crate::tests::runner::run_test_case(&path, 1, 7).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_8() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 8).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_9() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 9).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_10() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 10).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_11() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 11).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_12() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 12).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_13() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 13).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_items_1_14() {
|
||||||
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 14).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unique_items_2_0() {
|
fn test_unique_items_2_0() {
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -335,204 +299,6 @@ fn test_unique_items_2_1() {
|
|||||||
crate::tests::runner::run_test_case(&path, 2, 1).unwrap();
|
crate::tests::runner::run_test_case(&path, 2, 1).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_2_2() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_2_3() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_2_4() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_0() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_1() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_2() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_3() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_4() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_5() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 5).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_6() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 6).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_7() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 7).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_8() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 8).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_9() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 9).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_10() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 10).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_11() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 11).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_12() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 12).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_13() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 13).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_3_14() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 14).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_0() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_1() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_2() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_3() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_4() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_5() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 5).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_6() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 6).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_4_7() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 7).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_5_0() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_5_1() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_5_2() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_5_3() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_5_4() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_6_0() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 6, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_unique_items_6_1() {
|
|
||||||
let path = format!("{}/fixtures/uniqueItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 6, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_filter_0_0() {
|
fn test_filter_0_0() {
|
||||||
let path = format!("{}/fixtures/filter.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/filter.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -581,54 +347,6 @@ fn test_min_items_2_0() {
|
|||||||
crate::tests::runner::run_test_case(&path, 2, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 2, 0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_0_0() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_0_1() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_0_2() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_1_0() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_1_1() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_2_0() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_2_1() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_additional_properties_2_2() {
|
|
||||||
let path = format!("{}/fixtures/additionalProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dependencies_0_0() {
|
fn test_dependencies_0_0() {
|
||||||
let path = format!("{}/fixtures/dependencies.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/dependencies.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -887,6 +605,72 @@ fn test_dependencies_10_0() {
|
|||||||
crate::tests::runner::run_test_case(&path, 10, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 10, 0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_0_0() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 0, 0).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_0_1() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 0, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_0_2() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 0, 2).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_0_3() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 0, 3).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_1_0() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 0).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_1_1() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 1, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_2_0() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 2, 0).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_2_1() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 2, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_3_0() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 3, 0).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_3_1() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 3, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_3_2() {
|
||||||
|
let path = format!("{}/fixtures/dict.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
crate::tests::runner::run_test_case(&path, 3, 2).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_exclusive_minimum_0_0() {
|
fn test_exclusive_minimum_0_0() {
|
||||||
let path = format!("{}/fixtures/exclusiveMinimum.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/exclusiveMinimum.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -1979,72 +1763,18 @@ fn test_items_3_2() {
|
|||||||
crate::tests::runner::run_test_case(&path, 3, 2).unwrap();
|
crate::tests::runner::run_test_case(&path, 3, 2).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_3_3() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_3_4() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_3_5() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 5).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_items_4_0() {
|
fn test_items_4_0() {
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
crate::tests::runner::run_test_case(&path, 4, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 4, 0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_4_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_4_2() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_items_5_0() {
|
fn test_items_5_0() {
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
crate::tests::runner::run_test_case(&path, 5, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 5, 0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_5_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_5_2() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_5_3() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_5_4() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_items_6_0() {
|
fn test_items_6_0() {
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -2088,75 +1818,15 @@ fn test_items_9_0() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_items_10_0() {
|
fn test_items_9_1() {
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
crate::tests::runner::run_test_case(&path, 10, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 9, 1).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_items_11_0() {
|
fn test_items_9_2() {
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
crate::tests::runner::run_test_case(&path, 11, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 9, 2).unwrap();
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_11_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 11, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_12_0() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 12, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_12_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 12, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_13_0() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 13, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_13_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 13, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_14_0() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 14, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_14_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 14, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_15_0() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 15, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_15_1() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 15, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_items_15_2() {
|
|
||||||
let path = format!("{}/fixtures/items.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 15, 2).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -3011,78 +2681,6 @@ fn test_exclusive_maximum_0_3() {
|
|||||||
crate::tests::runner::run_test_case(&path, 0, 3).unwrap();
|
crate::tests::runner::run_test_case(&path, 0, 3).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_0_0() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_0_1() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_0_2() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_0_3() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_0_4() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_0_5() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 5).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_1_0() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_1_1() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_1_2() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_2_0() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_3_0() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_prefix_items_4_0() {
|
|
||||||
let path = format!("{}/fixtures/prefixItems.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitive_types_0_0() {
|
fn test_primitive_types_0_0() {
|
||||||
let path = format!("{}/fixtures/primitiveTypes.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/primitiveTypes.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
@ -4241,162 +3839,6 @@ fn test_multiple_of_3_0() {
|
|||||||
crate::tests::runner::run_test_case(&path, 3, 0).unwrap();
|
crate::tests::runner::run_test_case(&path, 3, 0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_0() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_1() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_2() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_3() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_4() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_5() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 5).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_6() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 6).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_0_7() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 0, 7).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_1_0() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_1_1() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_1_2() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_1_3() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_1_4() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_1_5() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 1, 5).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_2_0() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_2_1() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_2_2() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_2_3() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 2, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_3_0() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_3_1() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_3_2() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 2).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_3_3() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 3).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_3_4() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 3, 4).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_4_0() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 4, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_5_0() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 0).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_pattern_properties_5_1() {
|
|
||||||
let path = format!("{}/fixtures/patternProperties.json", env!("CARGO_MANIFEST_DIR"));
|
|
||||||
crate::tests::runner::run_test_case(&path, 5, 1).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merge_0_0() {
|
fn test_merge_0_0() {
|
||||||
let path = format!("{}/fixtures/merge.json", env!("CARGO_MANIFEST_DIR"));
|
let path = format!("{}/fixtures/merge.json", env!("CARGO_MANIFEST_DIR"));
|
||||||
|
|||||||
@ -37,6 +37,7 @@ impl Validator {
|
|||||||
"number" => val.is_number(),
|
"number" => val.is_number(),
|
||||||
"integer" => is_integer(val),
|
"integer" => is_integer(val),
|
||||||
"object" => val.is_object(),
|
"object" => val.is_object(),
|
||||||
|
"dict" => val.is_object(),
|
||||||
"array" => val.is_array(),
|
"array" => val.is_array(),
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,42 +99,10 @@ impl<'a> ValidationContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let len = arr.len();
|
let len = arr.len();
|
||||||
let mut validation_index = 0;
|
|
||||||
|
|
||||||
if let Some(ref prefix) = self.schema.prefix_items {
|
|
||||||
for (i, sub_schema) in prefix.iter().enumerate() {
|
|
||||||
if i < len {
|
|
||||||
if let Some(child_instance) = arr.get(i) {
|
|
||||||
let mut item_path = self.join_path(&i.to_string());
|
|
||||||
let is_topological = sub_schema.obj.requires_uuid_path(self.db);
|
|
||||||
if is_topological {
|
|
||||||
if let Some(obj) = child_instance.as_object() {
|
|
||||||
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
|
||||||
item_path = self.join_path(id_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let derived = self.derive(
|
|
||||||
sub_schema,
|
|
||||||
child_instance,
|
|
||||||
&item_path,
|
|
||||||
HashSet::new(),
|
|
||||||
self.extensible,
|
|
||||||
false,
|
|
||||||
Some(self.instance),
|
|
||||||
);
|
|
||||||
let item_res = derived.validate()?;
|
|
||||||
result.merge(item_res);
|
|
||||||
result.evaluated_indices.insert(i);
|
|
||||||
validation_index += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref items_schema) = self.schema.items {
|
if let Some(ref items_schema) = self.schema.items {
|
||||||
let is_topological = items_schema.obj.requires_uuid_path(self.db);
|
let is_topological = items_schema.obj.requires_uuid_path(self.db);
|
||||||
for i in validation_index..len {
|
for i in 0..len {
|
||||||
if let Some(child_instance) = arr.get(i) {
|
if let Some(child_instance) = arr.get(i) {
|
||||||
let mut item_path = self.join_path(&i.to_string());
|
let mut item_path = self.join_path(&i.to_string());
|
||||||
if is_topological {
|
if is_topological {
|
||||||
|
|||||||
76
src/validator/rules/dict.rs
Normal file
76
src/validator/rules/dict.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::validator::context::ValidationContext;
|
||||||
|
use crate::validator::error::ValidationError;
|
||||||
|
use crate::validator::result::ValidationResult;
|
||||||
|
|
||||||
|
impl<'a> ValidationContext<'a> {
|
||||||
|
pub(crate) fn validate_dict(
|
||||||
|
&self,
|
||||||
|
result: &mut ValidationResult,
|
||||||
|
) -> Result<bool, ValidationError> {
|
||||||
|
let current = self.instance;
|
||||||
|
if let Some(obj) = current.as_object() {
|
||||||
|
let is_dict = match &self.schema.type_ {
|
||||||
|
Some(crate::database::object::SchemaTypeOrArray::Single(t)) => t == "dict",
|
||||||
|
Some(crate::database::object::SchemaTypeOrArray::Multiple(types)) => types.contains(&"dict".to_string()),
|
||||||
|
None => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if is_dict {
|
||||||
|
// Mark all keys as evaluated since a dictionary's keys are all dynamic parameters, not structured properties
|
||||||
|
result.evaluated_keys.extend(obj.keys().cloned());
|
||||||
|
|
||||||
|
// Validate keys
|
||||||
|
if let Some(ref keys_schema) = self.schema.keys {
|
||||||
|
for key in obj.keys() {
|
||||||
|
let _new_path = self.join_path(&format!("keys/{}", key));
|
||||||
|
let val_str = Value::String(key.to_string());
|
||||||
|
|
||||||
|
let ctx = self.derive(
|
||||||
|
keys_schema,
|
||||||
|
&val_str,
|
||||||
|
&_new_path,
|
||||||
|
HashSet::new(),
|
||||||
|
self.extensible,
|
||||||
|
self.reporter,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
result.merge(ctx.validate()?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate items (values)
|
||||||
|
if let Some(ref items_schema) = self.schema.items {
|
||||||
|
for (key, child_instance) in obj {
|
||||||
|
let new_path = self.join_path(key);
|
||||||
|
let is_ref = match &items_schema.type_ {
|
||||||
|
Some(crate::database::object::SchemaTypeOrArray::Single(ref_t)) => {
|
||||||
|
!crate::database::object::is_primitive_type(ref_t)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
let next_extensible = if is_ref { false } else { self.extensible };
|
||||||
|
|
||||||
|
let derived = self.derive(
|
||||||
|
items_schema,
|
||||||
|
child_instance,
|
||||||
|
&new_path,
|
||||||
|
HashSet::new(),
|
||||||
|
next_extensible,
|
||||||
|
false,
|
||||||
|
Some(self.instance),
|
||||||
|
);
|
||||||
|
let item_res = derived.validate()?;
|
||||||
|
result.merge(item_res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::database::object::{is_primitive_type, SchemaTypeOrArray};
|
||||||
|
use crate::database::schema::Schema;
|
||||||
use crate::validator::context::ValidationContext;
|
use crate::validator::context::ValidationContext;
|
||||||
use crate::validator::error::ValidationError;
|
use crate::validator::error::ValidationError;
|
||||||
use crate::validator::result::ValidationResult;
|
use crate::validator::result::ValidationResult;
|
||||||
@ -16,6 +18,49 @@ impl<'a> ValidationContext<'a> {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn schema_expects_primitive(&self, schema: &Schema, primitive: &str) -> bool {
|
||||||
|
match &schema.type_ {
|
||||||
|
None => true, // Any type is allowed
|
||||||
|
Some(SchemaTypeOrArray::Single(t)) => {
|
||||||
|
if t == primitive {
|
||||||
|
true
|
||||||
|
} else if !is_primitive_type(t) {
|
||||||
|
if primitive == "object" {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
// Custom type - resolve recursively
|
||||||
|
if let Some(parent) = self.db.schemas.get(t) {
|
||||||
|
self.schema_expects_primitive(parent, primitive)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(SchemaTypeOrArray::Multiple(types)) => {
|
||||||
|
types.iter().any(|t| {
|
||||||
|
if t == primitive {
|
||||||
|
true
|
||||||
|
} else if !is_primitive_type(t) {
|
||||||
|
if primitive == "object" {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
if let Some(parent) = self.db.schemas.get(t) {
|
||||||
|
self.schema_expects_primitive(parent, primitive)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn validate_strictness(
|
pub(crate) fn validate_strictness(
|
||||||
&self,
|
&self,
|
||||||
result: &mut ValidationResult,
|
result: &mut ValidationResult,
|
||||||
@ -24,38 +69,18 @@ impl<'a> ValidationContext<'a> {
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(obj) = self.instance.as_object() {
|
if self.schema_expects_primitive(self.schema, "object") || self.schema_expects_primitive(self.schema, "dict") {
|
||||||
for key in obj.keys() {
|
if let Some(obj) = self.instance.as_object() {
|
||||||
if !result.evaluated_keys.contains(key) && !self.overrides.contains(key) {
|
for key in obj.keys() {
|
||||||
result.errors.push(ValidationError {
|
if !result.evaluated_keys.contains(key) && !self.overrides.contains(key) {
|
||||||
code: "STRICT_PROPERTY_VIOLATION".to_string(),
|
result.errors.push(ValidationError {
|
||||||
values: Some(HashMap::from([
|
code: "STRICT_PROPERTY_VIOLATION".to_string(),
|
||||||
("property_name".to_string(), key.to_string()),
|
values: Some(HashMap::from([
|
||||||
])),
|
("property_name".to_string(), key.to_string()),
|
||||||
path: self.join_path(key),
|
])),
|
||||||
});
|
path: self.join_path(key),
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(arr) = self.instance.as_array() {
|
|
||||||
for i in 0..arr.len() {
|
|
||||||
if !result.evaluated_indices.contains(&i) {
|
|
||||||
let mut item_path = self.join_path(&i.to_string());
|
|
||||||
if let Some(child_instance) = arr.get(i) {
|
|
||||||
if let Some(obj) = child_instance.as_object() {
|
|
||||||
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
|
||||||
item_path = self.join_path(id_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result.errors.push(ValidationError {
|
|
||||||
code: "STRICT_ITEM_VIOLATION".to_string(),
|
|
||||||
values: Some(HashMap::from([
|
|
||||||
("index".to_string(), i.to_string()),
|
|
||||||
])),
|
|
||||||
path: item_path,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use std::collections::HashMap;
|
|||||||
pub mod array;
|
pub mod array;
|
||||||
pub mod cases;
|
pub mod cases;
|
||||||
pub mod core;
|
pub mod core;
|
||||||
|
pub mod dict;
|
||||||
pub mod extensible;
|
pub mod extensible;
|
||||||
pub mod format;
|
pub mod format;
|
||||||
pub mod not;
|
pub mod not;
|
||||||
@ -43,6 +44,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
// Complex Structures
|
// Complex Structures
|
||||||
self.validate_object(&mut result)?;
|
self.validate_object(&mut result)?;
|
||||||
self.validate_array(&mut result)?;
|
self.validate_array(&mut result)?;
|
||||||
|
self.validate_dict(&mut result)?;
|
||||||
|
|
||||||
// Multipliers & Conditionals
|
// Multipliers & Conditionals
|
||||||
if !self.validate_one_of(&mut result)? {
|
if !self.validate_one_of(&mut result)? {
|
||||||
|
|||||||
@ -211,80 +211,8 @@ impl<'a> ValidationContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(compiled_pp) = self.schema.compiled_pattern_properties.get() {
|
|
||||||
for (compiled_re, sub_schema) in compiled_pp {
|
|
||||||
for (key, child_instance) in obj {
|
|
||||||
if compiled_re.0.is_match(key) {
|
|
||||||
let new_path = self.join_path(key);
|
|
||||||
let is_ref = match &sub_schema.type_ {
|
|
||||||
Some(crate::database::object::SchemaTypeOrArray::Single(t)) => {
|
|
||||||
!crate::database::object::is_primitive_type(t)
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
let next_extensible = if is_ref { false } else { self.extensible };
|
|
||||||
|
|
||||||
let derived = self.derive(
|
|
||||||
sub_schema,
|
|
||||||
child_instance,
|
|
||||||
&new_path,
|
|
||||||
HashSet::new(),
|
|
||||||
next_extensible,
|
|
||||||
false,
|
|
||||||
Some(self.instance),
|
|
||||||
);
|
|
||||||
let item_res = derived.validate()?;
|
|
||||||
result.merge(item_res);
|
|
||||||
result.evaluated_keys.insert(key.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref additional_schema) = self.schema.additional_properties {
|
|
||||||
for (key, child_instance) in obj {
|
|
||||||
let mut locally_matched = false;
|
|
||||||
if let Some(props) = &self.schema.properties
|
|
||||||
&& props.contains_key(&key.to_string())
|
|
||||||
{
|
|
||||||
locally_matched = true;
|
|
||||||
}
|
|
||||||
if !locally_matched
|
|
||||||
&& let Some(compiled_pp) = self.schema.compiled_pattern_properties.get()
|
|
||||||
{
|
|
||||||
for (compiled_re, _) in compiled_pp {
|
|
||||||
if compiled_re.0.is_match(key) {
|
|
||||||
locally_matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !locally_matched {
|
|
||||||
let new_path = self.join_path(key);
|
|
||||||
let is_ref = match &additional_schema.type_ {
|
|
||||||
Some(crate::database::object::SchemaTypeOrArray::Single(t)) => {
|
|
||||||
!crate::database::object::is_primitive_type(t)
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
let next_extensible = if is_ref { false } else { self.extensible };
|
|
||||||
|
|
||||||
let derived = self.derive(
|
|
||||||
additional_schema,
|
|
||||||
child_instance,
|
|
||||||
&new_path,
|
|
||||||
HashSet::new(),
|
|
||||||
next_extensible,
|
|
||||||
false,
|
|
||||||
Some(self.instance),
|
|
||||||
);
|
|
||||||
let item_res = derived.validate()?;
|
|
||||||
result.merge(item_res);
|
|
||||||
result.evaluated_keys.insert(key.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref property_names) = self.schema.property_names {
|
if let Some(ref property_names) = self.schema.property_names {
|
||||||
for key in obj.keys() {
|
for key in obj.keys() {
|
||||||
|
|||||||
@ -14,7 +14,6 @@ impl<'a> ValidationContext<'a> {
|
|||||||
let conflicts = self.schema.type_.is_some()
|
let conflicts = self.schema.type_.is_some()
|
||||||
|| self.schema.properties.is_some()
|
|| self.schema.properties.is_some()
|
||||||
|| self.schema.required.is_some()
|
|| self.schema.required.is_some()
|
||||||
|| self.schema.additional_properties.is_some()
|
|
||||||
|| self.schema.items.is_some()
|
|| self.schema.items.is_some()
|
||||||
|| self.schema.cases.is_some()
|
|| self.schema.cases.is_some()
|
||||||
|| self.schema.one_of.is_some()
|
|| self.schema.one_of.is_some()
|
||||||
|
|||||||
@ -42,6 +42,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
code: "PATTERN_VIOLATED".to_string(),
|
code: "PATTERN_VIOLATED".to_string(),
|
||||||
values: Some(HashMap::from([
|
values: Some(HashMap::from([
|
||||||
("pattern".to_string(), self.schema.pattern.clone().unwrap_or_default()),
|
("pattern".to_string(), self.schema.pattern.clone().unwrap_or_default()),
|
||||||
|
("value".to_string(), s.to_string()),
|
||||||
])),
|
])),
|
||||||
path: self.path.to_string(),
|
path: self.path.to_string(),
|
||||||
});
|
});
|
||||||
@ -54,6 +55,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
code: "PATTERN_VIOLATED".to_string(),
|
code: "PATTERN_VIOLATED".to_string(),
|
||||||
values: Some(HashMap::from([
|
values: Some(HashMap::from([
|
||||||
("pattern".to_string(), pattern.to_string()),
|
("pattern".to_string(), pattern.to_string()),
|
||||||
|
("value".to_string(), s.to_string()),
|
||||||
])),
|
])),
|
||||||
path: self.path.to_string(),
|
path: self.path.to_string(),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user