use rupg_sql::nodes::list_text;
use rupg_sql::{Error, parse};
fn error_text(error: &Error, text: &str) -> String {
let position = error.position(text).unwrap_or(0);
let mut out = format!("ERROR {} {position} {}", error.code, error.message);
if let Some(detail) = error.detail {
out.push_str(&format!("\nDETAIL {detail}"));
}
if let Some(hint) = error.hint {
out.push_str(&format!("\nHINT {hint}"));
}
out
}
const STACK: usize = 8 << 20;
#[test]
#[allow(clippy::disallowed_methods)]
fn raw_trees() {
std::thread::Builder::new()
.stack_size(STACK)
.spawn(compare)
.expect("the test thread starts")
.join()
.expect("the cases of raw.txt parse");
}
fn compare() {
let cases = include_str!("raw.txt");
let mut failures = Vec::new();
let mut count = 0;
for case in cases.split("\n\n").filter(|case| !case.trim().is_empty()) {
let Some((text, expected)) = case.trim_start_matches('\n').split_once('\n') else {
panic!("a case of raw.txt has no tree: {case}");
};
let text = text.strip_prefix("> ").expect("a case of raw.txt starts with `> `");
count += 1;
let actual = match parse(text) {
Ok((tree, _)) => list_text(&tree),
Err(error) => error_text(&error, text),
};
if actual != expected {
failures.push(format!("{text}\n expected {expected}\n actual {actual}"));
}
}
assert!(
failures.is_empty(),
"{} of {count} cases differ:\n{}",
failures.len(),
failures.join("\n")
);
}