Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: allOf schemas seem to ignore conditional branches when used with .apply().basic() #318

Closed
GabrielSimonetto opened this issue Nov 12, 2021 · 4 comments · Fixed by #327

Comments

@GabrielSimonetto
Copy link

GabrielSimonetto commented Nov 12, 2021

Context

There seems to be something wrong with the new .apply() feature when using in conjunction with the pattern of using allOf as a iterator for if then else conditionals, as recommended by the documentation on: https://json-schema.org/understanding-json-schema/reference/conditionals.html

Unfortunately, this approach above doesn’t scale to more than two countries. You can, however, wrap pairs of if and then inside an allOf to create something that would scale.

For brevity sake I won't paste the same schema and examples here again, but it is exactly the ones used below the quote on the link,

Or, if you prefer, you can also find the same schema example and a valid input on this link

The problem

All correct inputs are being denied, which seems to point that the program is trying to validate all schemas on allOf, when it should evaluate conditionally to only one of them.

Below I will provide the code used to test these and dependency versions.

Output Example:

Input: {"country":"Canada","postal_code":"K1M 1M4","street_address":"24 Sussex Drive"}

result.is_ok(): true

is_valid(): true

apply result: {"errors":[{"error":"\"Canada\" was expected","instanceLocation":"/country","keywordLocation":"/allOf/1/if/properties/country/const"},{"error":"\"Netherlands\" was expected","instanceLocation":"/country","keywordLocation":"/allOf/2/if/properties/country/const"}],"valid":false}

(notice the "valid":false at the end of the result)

src/main.rs

use std::{fs::File, io::BufReader, path::PathBuf};

use jsonschema::{output::BasicOutput, Draft, JSONSchema};
use serde_json::Value;

fn read(path: PathBuf) -> Result<Value, String> {
    let file = File::open(path).expect("Could not open");
    Ok(serde_json::from_reader(BufReader::new(file)).expect("could not read"))
}

fn main() {
    // I couldn't make json!() work here, but inserting these on the project root works.
    let schema = read(PathBuf::from("all_of_schema.json")).expect("a valid schema");
    let instance =
        read(PathBuf::from("example_should_work.json")).expect("a valid instance");

    let compiled = JSONSchema::options()
        .with_draft(Draft::Draft7)
        .compile(&schema)
        .expect("A valid schema");

    let result = compiled.validate(&instance);

    println!("Input: {}\n", &instance);
    println!("result.is_ok(): {}\n", result.is_ok());

    let is_valid = compiled.is_valid(&instance);
    println!("is_valid(): {:?}\n", is_valid);

    let output: BasicOutput = compiled.apply(&instance).basic();

    let output_json = serde_json::to_value(output).unwrap();
    println!("apply result: {}", output_json);
}

Cargo.toml

[package]
name = "jsonschema_playground"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
jsonschema = "0.13.2"
serde_json = "1.0.69"
@Stranger6667
Copy link
Owner

Hi @GabrielSimonetto,

Sorry for the late answer! Thank you so much for such a detailed bug report :) I will take a look at it soon

@Stranger6667
Copy link
Owner

I fixed the error in my local branch, will work on a few other things and release a new version :) Thanks once again for reporting

Stranger6667 added a commit that referenced this issue Dec 8, 2021
… schemas with `if` and `then` (without `else`) keywords

Ref: #318
@Stranger6667 Stranger6667 mentioned this issue Dec 8, 2021
Stranger6667 added a commit that referenced this issue Dec 8, 2021
… schemas with `if` and `then` (without `else`) keywords

Ref: #318
@Stranger6667
Copy link
Owner

The fix is released in 0.13.3

@GabrielSimonetto
Copy link
Author

Nice, thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants