Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ec06b81cc | |||
| c4e8e0309f |
@ -142,7 +142,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "CONST_VIOLATED",
|
"code": "CONST_VIOLATED",
|
||||||
"path": "/con"
|
"path": "con"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "TYPE_MISMATCH",
|
"code": "TYPE_MISMATCH",
|
||||||
"path": "/base_prop"
|
"path": "base_prop"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "REQUIRED_FIELD_MISSING",
|
"code": "REQUIRED_FIELD_MISSING",
|
||||||
"path": "/a"
|
"path": "a"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "REQUIRED_FIELD_MISSING",
|
"code": "REQUIRED_FIELD_MISSING",
|
||||||
"path": "/b"
|
"path": "b"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "DEPENDENCY_FAILED",
|
"code": "DEPENDENCY_FAILED",
|
||||||
"path": "/base_dep"
|
"path": "base_dep"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "DEPENDENCY_FAILED",
|
"code": "DEPENDENCY_FAILED",
|
||||||
"path": "/child_dep"
|
"path": "child_dep"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,13 +75,30 @@
|
|||||||
{
|
{
|
||||||
"description": "happy path passes structural validation",
|
"description": "happy path passes structural validation",
|
||||||
"data": {
|
"data": {
|
||||||
"primitives": ["a", "b"],
|
"primitives": [
|
||||||
"ad_hoc_objects": [{"name": "obj1"}],
|
"a",
|
||||||
"entities": [{"id": "entity-1", "value": 15}],
|
"b"
|
||||||
|
],
|
||||||
|
"ad_hoc_objects": [
|
||||||
|
{
|
||||||
|
"name": "obj1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"id": "entity-1",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
],
|
||||||
"deep_entities": [
|
"deep_entities": [
|
||||||
{
|
{
|
||||||
"id": "parent-1",
|
"id": "parent-1",
|
||||||
"nested": [{"id": "child-1", "flag": true}]
|
"nested": [
|
||||||
|
{
|
||||||
|
"id": "child-1",
|
||||||
|
"flag": true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -94,7 +111,10 @@
|
|||||||
{
|
{
|
||||||
"description": "primitive arrays use numeric indexing",
|
"description": "primitive arrays use numeric indexing",
|
||||||
"data": {
|
"data": {
|
||||||
"primitives": ["a", 123]
|
"primitives": [
|
||||||
|
"a",
|
||||||
|
123
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"schema_id": "hybrid_pathing",
|
"schema_id": "hybrid_pathing",
|
||||||
"action": "validate",
|
"action": "validate",
|
||||||
@ -103,7 +123,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "INVALID_TYPE",
|
"code": "INVALID_TYPE",
|
||||||
"path": "/primitives/1"
|
"path": "primitives/1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -112,8 +132,12 @@
|
|||||||
"description": "ad-hoc objects without ids use numeric indexing",
|
"description": "ad-hoc objects without ids use numeric indexing",
|
||||||
"data": {
|
"data": {
|
||||||
"ad_hoc_objects": [
|
"ad_hoc_objects": [
|
||||||
{"name": "valid"},
|
{
|
||||||
{"age": 30}
|
"name": "valid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"age": 30
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"schema_id": "hybrid_pathing",
|
"schema_id": "hybrid_pathing",
|
||||||
@ -123,7 +147,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "REQUIRED_FIELD_MISSING",
|
"code": "REQUIRED_FIELD_MISSING",
|
||||||
"path": "/ad_hoc_objects/1/name"
|
"path": "ad_hoc_objects/1/name"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -132,8 +156,14 @@
|
|||||||
"description": "arrays of objects with ids use topological uuid indexing",
|
"description": "arrays of objects with ids use topological uuid indexing",
|
||||||
"data": {
|
"data": {
|
||||||
"entities": [
|
"entities": [
|
||||||
{"id": "entity-alpha", "value": 20},
|
{
|
||||||
{"id": "entity-beta", "value": 5}
|
"id": "entity-alpha",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "entity-beta",
|
||||||
|
"value": 5
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"schema_id": "hybrid_pathing",
|
"schema_id": "hybrid_pathing",
|
||||||
@ -143,7 +173,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "MINIMUM_VIOLATED",
|
"code": "MINIMUM_VIOLATED",
|
||||||
"path": "/entities/entity-beta/value"
|
"path": "entities/entity-beta/value"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -155,8 +185,14 @@
|
|||||||
{
|
{
|
||||||
"id": "parent-omega",
|
"id": "parent-omega",
|
||||||
"nested": [
|
"nested": [
|
||||||
{"id": "child-alpha", "flag": true},
|
{
|
||||||
{"id": "child-beta", "flag": "invalid-string"}
|
"id": "child-alpha",
|
||||||
|
"flag": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "child-beta",
|
||||||
|
"flag": "invalid-string"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -168,7 +204,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "INVALID_TYPE",
|
"code": "INVALID_TYPE",
|
||||||
"path": "/deep_entities/parent-omega/nested/child-beta/flag"
|
"path": "deep_entities/parent-omega/nested/child-beta/flag"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -677,7 +677,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "TYPE_MISMATCH",
|
"code": "TYPE_MISMATCH",
|
||||||
"path": "/type"
|
"path": "type"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -782,7 +782,7 @@
|
|||||||
"errors": [
|
"errors": [
|
||||||
{
|
{
|
||||||
"code": "TYPE_MISMATCH",
|
"code": "TYPE_MISMATCH",
|
||||||
"path": "/type"
|
"path": "type"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,12 +134,12 @@ fn test_library_api() {
|
|||||||
{
|
{
|
||||||
"code": "REQUIRED_FIELD_MISSING",
|
"code": "REQUIRED_FIELD_MISSING",
|
||||||
"message": "Missing name",
|
"message": "Missing name",
|
||||||
"details": { "path": "/name" }
|
"details": { "path": "name" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "STRICT_PROPERTY_VIOLATION",
|
"code": "STRICT_PROPERTY_VIOLATION",
|
||||||
"message": "Unexpected property 'wrong'",
|
"message": "Unexpected property 'wrong'",
|
||||||
"details": { "path": "/wrong" }
|
"details": { "path": "wrong" }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
@ -41,6 +41,14 @@ impl<'a> ValidationContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn join_path(&self, key: &str) -> String {
|
||||||
|
if self.path.is_empty() {
|
||||||
|
key.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{}/{}", self.path, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn derive(
|
pub fn derive(
|
||||||
&self,
|
&self,
|
||||||
schema: &'a Schema,
|
schema: &'a Schema,
|
||||||
|
|||||||
@ -92,10 +92,10 @@ impl<'a> ValidationContext<'a> {
|
|||||||
for (i, sub_schema) in prefix.iter().enumerate() {
|
for (i, sub_schema) in prefix.iter().enumerate() {
|
||||||
if i < len {
|
if i < len {
|
||||||
if let Some(child_instance) = arr.get(i) {
|
if let Some(child_instance) = arr.get(i) {
|
||||||
let mut item_path = format!("{}/{}", self.path, i);
|
let mut item_path = self.join_path(&i.to_string());
|
||||||
if let Some(obj) = child_instance.as_object() {
|
if let Some(obj) = child_instance.as_object() {
|
||||||
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
||||||
item_path = format!("{}/{}", self.path, id_str);
|
item_path = self.join_path(id_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let derived = self.derive(
|
let derived = self.derive(
|
||||||
@ -118,10 +118,10 @@ impl<'a> ValidationContext<'a> {
|
|||||||
if let Some(ref items_schema) = self.schema.items {
|
if let Some(ref items_schema) = self.schema.items {
|
||||||
for i in validation_index..len {
|
for i in validation_index..len {
|
||||||
if let Some(child_instance) = arr.get(i) {
|
if let Some(child_instance) = arr.get(i) {
|
||||||
let mut item_path = format!("{}/{}", self.path, i);
|
let mut item_path = self.join_path(&i.to_string());
|
||||||
if let Some(obj) = child_instance.as_object() {
|
if let Some(obj) = child_instance.as_object() {
|
||||||
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
||||||
item_path = format!("{}/{}", self.path, id_str);
|
item_path = self.join_path(id_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let derived = self.derive(
|
let derived = self.derive(
|
||||||
|
|||||||
@ -44,7 +44,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
result.errors.push(ValidationError {
|
result.errors.push(ValidationError {
|
||||||
code: "STRICT_PROPERTY_VIOLATION".to_string(),
|
code: "STRICT_PROPERTY_VIOLATION".to_string(),
|
||||||
message: format!("Unexpected property '{}'", key),
|
message: format!("Unexpected property '{}'", key),
|
||||||
path: format!("{}/{}", self.path, key),
|
path: self.join_path(key),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,11 +53,11 @@ impl<'a> ValidationContext<'a> {
|
|||||||
if let Some(arr) = self.instance.as_array() {
|
if let Some(arr) = self.instance.as_array() {
|
||||||
for i in 0..arr.len() {
|
for i in 0..arr.len() {
|
||||||
if !result.evaluated_indices.contains(&i) {
|
if !result.evaluated_indices.contains(&i) {
|
||||||
let mut item_path = format!("{}/{}", self.path, i);
|
let mut item_path = self.join_path(&i.to_string());
|
||||||
if let Some(child_instance) = arr.get(i) {
|
if let Some(child_instance) = arr.get(i) {
|
||||||
if let Some(obj) = child_instance.as_object() {
|
if let Some(obj) = child_instance.as_object() {
|
||||||
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
if let Some(id_str) = obj.get("id").and_then(|v| v.as_str()) {
|
||||||
item_path = format!("{}/{}", self.path, id_str);
|
item_path = self.join_path(id_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
"Type '{}' is not a valid descendant for this entity bound schema",
|
"Type '{}' is not a valid descendant for this entity bound schema",
|
||||||
type_str
|
type_str
|
||||||
),
|
),
|
||||||
path: format!("{}/type", self.path),
|
path: self.join_path("type"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -70,7 +70,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
result.errors.push(ValidationError {
|
result.errors.push(ValidationError {
|
||||||
code: "REQUIRED_FIELD_MISSING".to_string(),
|
code: "REQUIRED_FIELD_MISSING".to_string(),
|
||||||
message: format!("Missing {}", field),
|
message: format!("Missing {}", field),
|
||||||
path: format!("{}/{}", self.path, field),
|
path: self.join_path(field),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(child_instance) = obj.get(key) {
|
if let Some(child_instance) = obj.get(key) {
|
||||||
let new_path = format!("{}/{}", self.path, key);
|
let new_path = self.join_path(key);
|
||||||
let is_ref = sub_schema.r#ref.is_some();
|
let is_ref = sub_schema.r#ref.is_some();
|
||||||
let next_extensible = if is_ref { false } else { self.extensible };
|
let next_extensible = if is_ref { false } else { self.extensible };
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
for (compiled_re, sub_schema) in compiled_pp {
|
for (compiled_re, sub_schema) in compiled_pp {
|
||||||
for (key, child_instance) in obj {
|
for (key, child_instance) in obj {
|
||||||
if compiled_re.0.is_match(key) {
|
if compiled_re.0.is_match(key) {
|
||||||
let new_path = format!("{}/{}", self.path, key);
|
let new_path = self.join_path(key);
|
||||||
let is_ref = sub_schema.r#ref.is_some();
|
let is_ref = sub_schema.r#ref.is_some();
|
||||||
let next_extensible = if is_ref { false } else { self.extensible };
|
let next_extensible = if is_ref { false } else { self.extensible };
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !locally_matched {
|
if !locally_matched {
|
||||||
let new_path = format!("{}/{}", self.path, key);
|
let new_path = self.join_path(key);
|
||||||
let is_ref = additional_schema.r#ref.is_some();
|
let is_ref = additional_schema.r#ref.is_some();
|
||||||
let next_extensible = if is_ref { false } else { self.extensible };
|
let next_extensible = if is_ref { false } else { self.extensible };
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ impl<'a> ValidationContext<'a> {
|
|||||||
|
|
||||||
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() {
|
||||||
let _new_path = format!("{}/propertyNames/{}", self.path, key);
|
let _new_path = self.join_path(&format!("propertyNames/{}", key));
|
||||||
let val_str = Value::String(key.to_string());
|
let val_str = Value::String(key.to_string());
|
||||||
|
|
||||||
let ctx = ValidationContext::new(
|
let ctx = ValidationContext::new(
|
||||||
|
|||||||
Reference in New Issue
Block a user