diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs index 1ca5451..25b4dfa 100644 --- a/src/compiler/mod.rs +++ b/src/compiler/mod.rs @@ -50,6 +50,18 @@ pub fn from_str(str: &str) -> Result> { Ok(compiler) } +pub fn from_strings(strings: &[&str]) -> Result> { + let mut compiler = spec_compiler(); + for str in strings { + let schema: Value = serde_json::from_str(str)?; + let id = &schema["$id"] + .as_str() + .ok_or(super::valid::ValidationError::UnknownID)?; + compiler.add_resource(id, schema.to_owned())?; + } + Ok(compiler) +} + /// Creates a new boon::compiler with format assertions enabled and validation /// for the custom `path` and `license` formats. fn spec_compiler() -> Compiler { @@ -223,4 +235,27 @@ mod tests { Ok(()) } + + #[test] + fn test_from_strings() -> Result<(), Box> { + let schema_v1 = include_str!(concat!(env!("OUT_DIR"), "/pgxn-meta-v1.schema.json")); + let schema_v2 = include_str!(concat!(env!("OUT_DIR"), "/pgxn-meta-v2.schema.json")); + let mut compiler = from_strings(&[schema_v1, schema_v2])?; + + for tc in [("v1", "widget.json"), ("v2", "typical-sql.json")] { + let mut schemas = Schemas::new(); + let id = format!("https://pgxn.org/meta/{}/distribution.schema.json", tc.0); + let idx = compiler.compile(&id, &mut schemas)?; + + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("corpus") + .join(tc.0) + .join(tc.1); + let meta: Value = serde_json::from_reader(File::open(path)?)?; + assert!(schemas.validate(&meta, idx).is_ok()); + } + + Ok(()) + } } diff --git a/src/lib.rs b/src/lib.rs index 93cf3f1..30e71bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,8 +42,8 @@ assert!(validator.validate(&meta).is_ok()); */ -mod valid; -pub use valid::{ValidationError, Validator}; - #[doc(hidden)] pub mod compiler; + +mod valid; +pub use valid::{ValidationError, Validator}; diff --git a/src/valid/mod.rs b/src/valid/mod.rs index 9267416..5b884e8 100644 --- a/src/valid/mod.rs +++ b/src/valid/mod.rs @@ -34,6 +34,20 @@ impl fmt::Display for ValidationError { } const SCHEMA_BASE: &str = "https://pgxn.org/meta/v"; +/// validator creates and returns a new validator configured with the v1 and v2 +/// PGXN Meta schemas. +#[macro_export] +macro_rules! validator { + () => {{ + let schema_v1 = include_str!(concat!(env!("OUT_DIR"), "/pgxn-meta-v1.schema.json")); + let schema_v2 = include_str!(concat!(env!("OUT_DIR"), "/pgxn-meta-v2.schema.json")); + Validator { + compiler: super::super::compiler::from_strings(&[schema_v1, schema_v2]).unwrap(), + schemas: Schemas::new(), + } + }}; +} + impl Validator { /// Validator constructor. /// @@ -143,6 +157,24 @@ mod tests { Ok(()) } + + #[test] + fn test_validator() -> Result<(), Box> { + let mut v = validator!(); + + for tc in [("v1", "widget.json"), ("v2", "typical-sql.json")] { + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("tests") + .join("corpus") + .join(tc.0) + .join(tc.1); + let meta: Value = serde_json::from_reader(File::open(path)?)?; + assert!(v.validate(&meta).is_ok()); + } + + Ok(()) + } + #[test] fn test_errors() { assert_eq!(