use std::path::{Path, PathBuf};
use tempfile::TempDir;
use crate::{Diagnostic, Severity};
pub struct FixtureDir {
pub dir: TempDir,
}
impl FixtureDir {
pub fn new() -> Self {
Self {
dir: TempDir::new().expect("TempDir::new"),
}
}
pub fn write(&self, rel_path: &str, content: &str) -> PathBuf {
let path = self.dir.path().join(rel_path);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).expect("create_dir_all");
}
std::fs::write(&path, content).expect("write fixture");
path
}
pub fn path(&self) -> &Path {
self.dir.path()
}
}
impl Default for FixtureDir {
fn default() -> Self {
Self::new()
}
}
pub fn assert_error_contains(diags: &[Diagnostic], msg: &str) {
assert!(
diags
.iter()
.any(|d| matches!(d.severity, Severity::Error) && d.message.contains(msg)),
"expected error containing {:?}\ngot diagnostics:\n{}",
msg,
fmt_diags(diags),
);
}
pub fn assert_error_at(diags: &[Diagnostic], line: usize, msg: &str) {
assert!(
diags.iter().any(|d| {
matches!(d.severity, Severity::Error) && d.line == line && d.message.contains(msg)
}),
"expected error at line {line} containing {:?}\ngot diagnostics:\n{}",
msg,
fmt_diags(diags),
);
}
pub fn assert_no_errors(diags: &[Diagnostic]) {
let errors: Vec<_> = diags
.iter()
.filter(|d| matches!(d.severity, Severity::Error))
.collect();
assert!(
errors.is_empty(),
"expected no errors\ngot:\n{}",
fmt_diags(&errors.into_iter().cloned().collect::<Vec<_>>()),
);
}
pub fn assert_clean(diags: &[Diagnostic]) {
assert!(
diags.is_empty(),
"expected no diagnostics\ngot:\n{}",
fmt_diags(diags),
);
}
fn fmt_diags(diags: &[Diagnostic]) -> String {
if diags.is_empty() {
return " (none)".to_string();
}
diags
.iter()
.map(|d| format!(" {}", d.gnu_format()))
.collect::<Vec<_>>()
.join("\n")
}