refactor: split cargo workspace
This commit is contained in:
parent
5db14936e7
commit
1c21bd1259
695 changed files with 32023 additions and 44964 deletions
136
crates/toml-parser/src/tests.rs
Normal file
136
crates/toml-parser/src/tests.rs
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
use {
|
||||
crate::{
|
||||
toml_parser::{ErrorHandler, ParserError, parse},
|
||||
toml_span::{Span, Spanned, SpannedExt},
|
||||
toml_value::Value,
|
||||
},
|
||||
bstr::{BStr, ByteSlice},
|
||||
std::{
|
||||
os::unix::ffi::OsStrExt,
|
||||
panic::{AssertUnwindSafe, catch_unwind},
|
||||
str::FromStr,
|
||||
},
|
||||
walkdir::WalkDir,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let mut have_failures = false;
|
||||
let mut num = 0;
|
||||
let tests = std::path::Path::new(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/../toml-config/toml-test/tests/valid"
|
||||
));
|
||||
if !tests.exists() {
|
||||
eprintln!("skipping TOML conformance tests because fixtures are not present");
|
||||
return;
|
||||
}
|
||||
for path in WalkDir::new(tests) {
|
||||
let path = path.unwrap();
|
||||
if let Some(prefix) = path.path().as_os_str().as_bytes().strip_suffix(b".toml") {
|
||||
num += 1;
|
||||
let res = catch_unwind(AssertUnwindSafe(|| {
|
||||
have_failures |= run_test(prefix.as_bstr());
|
||||
}));
|
||||
if res.is_err() {
|
||||
eprintln!("panic while running {}", prefix.as_bstr());
|
||||
}
|
||||
}
|
||||
}
|
||||
if have_failures {
|
||||
panic!("There were test failures");
|
||||
}
|
||||
eprintln!("ran {num} tests");
|
||||
}
|
||||
|
||||
fn run_test(prefix: &BStr) -> bool {
|
||||
let toml = std::fs::read(&format!("{}.toml", prefix)).unwrap();
|
||||
let json = std::fs::read_to_string(&format!("{}.json", prefix)).unwrap();
|
||||
|
||||
let json: serde_json::Value = serde_json::from_str(&json).unwrap();
|
||||
let json_as_toml = json_to_value(json);
|
||||
let toml = match parse(toml.as_bytes(), &NoErrorHandler(prefix)) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
eprintln!("toml could not be parsed in test {}", prefix);
|
||||
NoErrorHandler(prefix).handle(e);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
if toml != json_as_toml {
|
||||
eprintln!("toml and json differ in test {}", prefix);
|
||||
eprintln!("toml: {:#?}", toml);
|
||||
eprintln!("json: {:#?}", json_as_toml);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn json_to_value(json: serde_json::Value) -> Spanned<Value> {
|
||||
let span = Span { lo: 0, hi: 0 };
|
||||
let val = match json {
|
||||
serde_json::Value::String(_)
|
||||
| serde_json::Value::Number(_)
|
||||
| serde_json::Value::Null
|
||||
| serde_json::Value::Bool(_) => panic!("Unexpected type"),
|
||||
serde_json::Value::Array(v) => Value::Array(v.into_iter().map(json_to_value).collect()),
|
||||
serde_json::Value::Object(v) => {
|
||||
if v.len() == 2 && v.contains_key("type") && v.contains_key("value") {
|
||||
let ty = v.get("type").unwrap().as_str().unwrap();
|
||||
let val = v.get("value").unwrap().as_str().unwrap();
|
||||
match ty {
|
||||
"string" => Value::String(val.to_owned()),
|
||||
"integer" => Value::Integer(i64::from_str(val).unwrap()),
|
||||
"float" => Value::Float(f64::from_str(val).unwrap()),
|
||||
"bool" => Value::Boolean(bool::from_str(val).unwrap()),
|
||||
_ => panic!("unexpected type {}", ty),
|
||||
}
|
||||
} else {
|
||||
Value::Table(
|
||||
v.into_iter()
|
||||
.map(|(k, v)| (k.spanned(span), json_to_value(v)))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
val.spanned(span)
|
||||
}
|
||||
|
||||
struct NoErrorHandler<'a>(&'a BStr);
|
||||
|
||||
impl<'a> ErrorHandler for NoErrorHandler<'a> {
|
||||
fn handle(&self, err: Spanned<ParserError>) {
|
||||
eprintln!(
|
||||
"{}: An error occurred during validation: {}",
|
||||
self.0,
|
||||
FormatError(err.span, Some(err.value)),
|
||||
);
|
||||
}
|
||||
|
||||
fn redefinition(&self, err: Spanned<ParserError>, prev: Span) {
|
||||
eprintln!(
|
||||
"{}: Redefinition: {}",
|
||||
self.0,
|
||||
FormatError(err.span, Some(err.value)),
|
||||
);
|
||||
eprintln!(
|
||||
"{}: Previous: {}",
|
||||
self.0,
|
||||
FormatError(prev, None),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
struct FormatError(Span, Option<ParserError>);
|
||||
|
||||
impl std::fmt::Display for FormatError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if let Some(cause) = &self.1 {
|
||||
write!(f, "{cause}: ")?;
|
||||
}
|
||||
write!(f, "span {}..{}", self.0.lo, self.0.hi)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue