diff --git a/cdevents-sdk/Cargo.toml b/cdevents-sdk/Cargo.toml index 9cc5395..f38f150 100644 --- a/cdevents-sdk/Cargo.toml +++ b/cdevents-sdk/Cargo.toml @@ -21,6 +21,7 @@ time = { version = "0.3", features = ["serde-human-readable"] } [dev-dependencies] assert-json-diff = "2.0" +boon = "0.5" proptest = "1" rstest = "0.18" diff --git a/cdevents-sdk/tests/specs.rs b/cdevents-sdk/tests/specs.rs index 0cd1008..be3d313 100644 --- a/cdevents-sdk/tests/specs.rs +++ b/cdevents-sdk/tests/specs.rs @@ -3,6 +3,8 @@ use cdevents_sdk::CDEvent; use rstest::rstest; use std::fs; use std::path::PathBuf; +use proptest::prelude::*; +use boon::{Schemas, Compiler}; #[rstest] fn for_each_example(#[files("../cdevents-spec/examples/*.json")] path: PathBuf) { @@ -27,3 +29,40 @@ fn for_each_example(#[files("../cdevents-spec/examples/*.json")] path: PathBuf) dbg!(&cdevent_json); assert_json_eq!(example_json, cdevent_json); } + +fn check_against_schema(json: &serde_json::Value, ty: &str) { + let (subject, predicate) = cdevents_sdk::extract_subject_predicate(ty).expect("valid type: {ty}"); + let schemapath = format!("../cdevents-spec/schemas/{subject}{predicate}.json"); + //TODO optimize to not recompile a previously read schema + let mut schemas = Schemas::new(); + let mut compiler = Compiler::new(); + let sch_index = compiler.compile(&schemapath, &mut schemas); + if let Err(err) = sch_index { + assert!(false, "{err:#}"); + return; // to allow sch_index.unwrap() + } + let sch_index = sch_index.unwrap(); + let result = schemas.validate(&json, sch_index); + if let Err(err) = result { + assert!(false, "{err}"); + return; + } +} + +#[rstest] +fn validate_example_against_schema(#[files("../cdevents-spec/examples/*.json")] path: PathBuf) { + let example_txt = fs::read_to_string(path).expect("to read file as string"); + let example_json: serde_json::Value = + serde_json::from_str(&example_txt).expect("to parse as json"); + let ty = example_json["context"]["type"].as_str().expect("valid context.type in json"); + check_against_schema(&example_json, ty); +} + +proptest! { + #[test] + #[cfg(feature = "testkit")] + fn arbitraries_check_jsonschema(s in any::()) { + let json = serde_json::to_value(&s).unwrap(); + check_against_schema(&json, s.ty()); + } +}