use std::path::{Path, PathBuf};
fn resolve_from_workspace_root(raw: &str) -> PathBuf {
let path = PathBuf::from(raw);
if path.is_absolute() {
return path;
}
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
.join(path)
}
fn collect_gd_files(dir: &Path, out: &mut Vec<PathBuf>) {
let Ok(entries) = std::fs::read_dir(dir) else {
return;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_dir() {
collect_gd_files(&path, out);
} else if path.extension().is_some_and(|ext| ext == "gd") {
out.push(path);
}
}
}
#[test]
fn corpus_round_trips() {
let Ok(root) = std::env::var("GDCK_CORPUS") else {
eprintln!("GDCK_CORPUS not set; skipping corpus conformance test");
return;
};
let root = resolve_from_workspace_root(&root);
let mut paths = Vec::new();
collect_gd_files(&root, &mut paths);
paths.sort();
assert!(
!paths.is_empty(),
"no .gd files found under {}",
root.display()
);
let mut checked = 0;
let mut with_errors = Vec::new();
for path in &paths {
let Ok(source) = std::fs::read_to_string(path) else {
continue;
};
let tree = gdck_syntax::parse(&source);
assert_eq!(
tree.text(),
source,
"{} did not round-trip through the tree",
path.display()
);
let covered = tree.root().range().end() as usize;
assert_eq!(
covered,
source.len(),
"{} left bytes outside the tree",
path.display()
);
if tree.has_errors() {
with_errors.push(path.clone());
}
checked += 1;
}
eprintln!(
"checked {checked} files, {} parsed with errors",
with_errors.len()
);
}