Skip to content

Commit

Permalink
Add valid and invalid test corpuses
Browse files Browse the repository at this point in the history
  • Loading branch information
theory committed Jun 28, 2024
1 parent e1b1034 commit c0b7721
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ exclude = [ ".github", ".gitattributes", "target", ".vscode", ".gitignore" ]
[dev-dependencies]
boon = "0.6"
serde_json = "1.0"

[dependencies]
serde = { version = "1", features = ["derive"] }
1 change: 1 addition & 0 deletions tests/corpus/v1/invalid.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"test":"no_version","error":"missing properties 'version'","meta":{"name":"pair","abstract":"A key/value pair data type","maintainer":"David E. Wheeler <[email protected]>","license":"postgresql","provides":{"pair":{"abstract":"A key/value pair data type","file":"sql/pair.sql","docfile":"doc/pair.md","version":"0.1.0"}},"meta-spec":{"version":"1.0.0","url":"https://pgxn.org/meta/spec.txt"}}}
3 changes: 3 additions & 0 deletions tests/corpus/v1/valid.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{"test":"howto1","meta":{"name":"pair","abstract":"A key/value pair data type","version":"0.1.0","maintainer":"David E. Wheeler <[email protected]>","license":"postgresql","provides":{"pair":{"abstract":"A key/value pair data type","file":"sql/pair.sql","docfile":"doc/pair.md","version":"0.1.0"}},"meta-spec":{"version":"1.0.0","url":"https://pgxn.org/meta/spec.txt"}}}
{"test":"howto2","meta":{"name":"pair","abstract":"A key/value pair data type","description":"This library contains a single PostgreSQL extension, a key/value pair data type called “pair”, along with a convenience function for constructing key/value pairs.","version":"0.1.4","maintainer":["David E. Wheeler <[email protected]>"],"license":"postgresql","provides":{"pair":{"abstract":"A key/value pair data type","file":"sql/pair.sql","docfile":"doc/pair.md","version":"0.1.0"}},"resources":{"bugtracker":{"web":"https://github.com/theory/kv-pair/issues/"},"repository":{"url":"git://github.com/theory/kv-pair.git","web":"https://github.com/theory/kv-pair/","type":"git"}},"generated_by":"David E. Wheeler","meta-spec":{"version":"1.0.0","url":"https://pgxn.org/meta/spec.txt"},"tags":["variadic function","ordered pair","pair","key value","key value pair","data type"]}}
{"test":"widget","meta":{"name":"widget","abstract":"Widget for PostgreSQL","description":"¿A widget is just thing thing, yoŭ know?","version":"0.2.5","maintainer":["David E. Wheeler <[email protected]>"],"license":{"PostgreSQL":"https://www.postgresql.org/about/licence"},"prereqs":{"runtime":{"requires":{"plpgsql":0,"PostgreSQL":"8.0.0"},"recommends":{"PostgreSQL":"8.4.0"}}},"provides":{"widget":{"file":"sql/widget.sql.in","version":"0.2.5"}},"resources":{"homepage":"http://widget.example.org/"},"generated_by":"theory","meta-spec":{"version":"1.0.0","url":"https://pgxn.org/meta/spec.txt"},"tags":["widget","gadget","full text search"]}}
93 changes: 86 additions & 7 deletions tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use std::{
collections::HashMap,
error::Error,
fs::{self, File},
};
use std::fs::{self, File};
use std::io::{prelude::*, BufReader};
use std::{collections::HashMap, error::Error};

use boon::{Compiler, Schemas};
use serde::{Deserialize, Serialize};
use serde_json::Value;

#[test]
Expand Down Expand Up @@ -34,11 +33,13 @@ fn test_schema_v1() -> Result<(), Box<dyn Error>> {
} else {
panic!("Unable to find ID in {}", path.display());
}
} else {
println!("Skipping {}", path.display());
}
}

// Make sure we found schemas.
assert!(!loaded.is_empty());
assert!(!loaded.is_empty(), "No schemas loaded!");

// Make sure each schema we loaded is valid.
let mut schemas = Schemas::new();
Expand All @@ -51,7 +52,85 @@ fn test_schema_v1() -> Result<(), Box<dyn Error>> {
if let Err(e) = schemas.validate(example, index) {
panic!("Example {i} failed: {e}");
}
println!(" Example {i} ok");
// println!(" Example {i} ok");
}
}

Ok(())
}

fn new_compiler(dir: &str) -> Result<Compiler, Box<dyn Error>> {
let mut compiler = Compiler::new();
let paths = fs::read_dir(dir)?;
for path in paths {
let path = path?.path();
let bn = path.file_name().unwrap().to_str().unwrap();
if bn.ends_with(".schema.json") {
let schema: Value = serde_json::from_reader(File::open(path.clone())?)?;
if let Value::String(s) = &schema["$id"] {
// Add the schema to the compiler.
compiler.add_resource(s, schema.to_owned())?;
} else {
panic!("Unable to find ID in {}", path.display());
}
} else {
println!("Skipping {}", path.display());
}
}

Ok(compiler)
}

#[derive(Deserialize, Serialize)]
struct CorpusCase {
test: String,
error: Option<String>,
meta: Value,
}

#[test]
fn test_corpus_v1_valid() -> Result<(), Box<dyn Error>> {
// Load the schema and compile the root schema.
let mut compiler = new_compiler("schema/v1")?;
const SCHEMA_ID: &str = "https://pgxn.org/meta/v1/distribution.schema.json";
let mut schemas = Schemas::new();
let index = compiler.compile(SCHEMA_ID, &mut schemas)?;

// Test each meta JSON in the corpus.
let file = File::open("tests/corpus/v1/valid.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() {
let tc: CorpusCase = serde_json::from_str(&line?)?;

if let Err(e) = schemas.validate(&tc.meta, index) {
panic!("{} failed: {e}", &tc.test);
}
println!("Example {} ok", &tc.test);
}

Ok(())
}

#[test]
fn test_corpus_v1_invalid() -> Result<(), Box<dyn Error>> {
// Load the schema and compile the root schema.
let mut compiler = new_compiler("schema/v1")?;
const SCHEMA_ID: &str = "https://pgxn.org/meta/v1/distribution.schema.json";
let mut schemas = Schemas::new();
let index = compiler.compile(SCHEMA_ID, &mut schemas)?;

// Test each meta JSON in the corpus.
let file = File::open("tests/corpus/v1/invalid.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() {
let tc: CorpusCase = serde_json::from_str(&line?)?;
match schemas.validate(&tc.meta, index) {
Ok(_) => panic!("{} unexpectedly passed!", &tc.test),
Err(e) => assert!(
e.to_string().contains(&tc.error.unwrap()),
"{} error: {e}",
&tc.test,
),
}
}

Expand Down

0 comments on commit c0b7721

Please sign in to comment.