Skip to content

Commit

Permalink
fix: Combination of unevaluatedProperties with allOf and oneOf
Browse files Browse the repository at this point in the history
Ref: #496

Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
  • Loading branch information
Stranger6667 committed Sep 13, 2024
1 parent 3c58526 commit 7ef1155
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
### Fixed

- `uuid` format validation.
- Combination of `unevaluatedProperties` with `allOf` and `oneOf`. [#496](https://github.com/Stranger6667/jsonschema-rs/issues/496)

### Deprecated

Expand Down
1 change: 1 addition & 0 deletions crates/jsonschema-py/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Fixed

- `uuid` format validation.
- Combination of `unevaluatedProperties` with `allOf` and `oneOf`. [#496](https://github.com/Stranger6667/jsonschema-rs/issues/496)

### Performance

Expand Down
53 changes: 46 additions & 7 deletions crates/jsonschema/src/keywords/unevaluated_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ impl UnevaluatedPropertiesValidator {
})
})
.or_else(|| {
let result = self.subschemas.as_ref().and_then(|subschemas| {
self.subschemas.as_ref().and_then(|subschemas| {
subschemas.iter().find_map(|subschema| {
subschema.apply_property(
instance,
Expand All @@ -323,9 +323,7 @@ impl UnevaluatedPropertiesValidator {
property_name,
)
})
});

result
})
})
.or_else(|| {
self.additional.as_ref().and_then(|additional| {
Expand Down Expand Up @@ -649,14 +647,16 @@ impl SubschemaSubvalidator {
let results = mapped.collect::<Vec<_>>();
let all_subschemas_valid =
results.iter().all(|(_, instance_valid)| *instance_valid);
all_subschemas_valid.then(|| {
if all_subschemas_valid {
// We only need to find the first valid evaluation because we know if that
// all subschemas were valid against the instance that there can't actually
// be any subschemas where the property was evaluated but invalid.
results
.iter()
.any(|(property_result, _)| matches!(property_result, Some(true)))
})
.find_map(|(property_result, _)| *property_result)
} else {
None
}
}

// The instance must be valid against only _one_ subschema, and for that subschema, the
Expand Down Expand Up @@ -1430,4 +1430,43 @@ mod tests {
&json!({ "foo": "wee", "another": false }),
);
}

#[test]
fn test_unevaluated_properties_with_allof_oneof() {
let schema = json!({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"allOf": [{}],
"oneOf": [
{
"properties": {
"blah": true
}
}
],
"unevaluatedProperties": false
});

let valid = json!({
"blah": 1
});

let validator = crate::compile(&schema).expect("Schema should compile");

assert!(validator.validate(&valid).is_ok(), "Validation should pass");
assert!(validator.is_valid(&valid), "Instance should be valid");

let invalid = json!({
"blah": 1,
"extra": "property"
});

assert!(
!validator.is_valid(&invalid),
"Instance with extra property should be invalid"
);
assert!(
validator.validate(&invalid).is_err(),
"Validation should fail for instance with extra property"
);
}
}

0 comments on commit 7ef1155

Please sign in to comment.