129 lines
3.8 KiB
Rust
129 lines
3.8 KiB
Rust
use std::{cmp::Ordering, path::Path};
|
|
|
|
use cuddle_clusters::{process::ProcessOpts, ConcreteComponent, IntoComponent};
|
|
use walkdir::DirEntry;
|
|
|
|
pub(crate) async fn run_test_with_components(
|
|
name: &str,
|
|
components: Vec<impl IntoComponent>,
|
|
) -> anyhow::Result<()> {
|
|
let _ = tracing_subscriber::fmt::try_init();
|
|
|
|
println!("running for: {name}");
|
|
|
|
let current_dir = std::env::current_dir()?;
|
|
|
|
let test_folder = current_dir.join("tests").join(name);
|
|
|
|
let actual = test_folder.join("actual");
|
|
tokio::fs::create_dir_all(&actual).await?;
|
|
let expected = test_folder.join("expected");
|
|
tokio::fs::create_dir_all(&expected).await?;
|
|
|
|
let components: Vec<_> = components.into_iter().map(|p| p.into_component()).collect();
|
|
|
|
cuddle_clusters::process_opts(
|
|
components.clone(),
|
|
ProcessOpts {
|
|
path: test_folder.clone(),
|
|
output: actual.clone(),
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
if std::env::var("TEST_OVERRIDE") == Ok("true".to_string()) {
|
|
cuddle_clusters::process_opts(
|
|
components,
|
|
ProcessOpts {
|
|
path: test_folder,
|
|
output: expected.clone(),
|
|
},
|
|
)
|
|
.await?;
|
|
}
|
|
|
|
compare(&expected, &actual).await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn run_test(name: &str) -> anyhow::Result<()> {
|
|
run_test_with_components(name, Vec::<ConcreteComponent>::new()).await
|
|
}
|
|
|
|
async fn compare(expected: &Path, actual: &Path) -> anyhow::Result<()> {
|
|
let mut exp = walk_dir(expected)?;
|
|
let mut act = walk_dir(actual)?;
|
|
|
|
for (exp, act) in (&mut exp).zip(&mut act) {
|
|
let exp = exp?;
|
|
let act = act?;
|
|
|
|
if exp.depth() != act.depth() {
|
|
return Err(anyhow::anyhow!(
|
|
"path(different depth): expected {} is different from actual: {}",
|
|
exp.path().display(),
|
|
act.path().display()
|
|
));
|
|
}
|
|
|
|
if exp.file_type() != act.file_type() {
|
|
return Err(anyhow::anyhow!(
|
|
"path(different filetype): expected {} is different from actual: {}",
|
|
exp.path().display(),
|
|
act.path().display()
|
|
));
|
|
}
|
|
|
|
if exp.file_name() != act.file_name() {
|
|
return Err(anyhow::anyhow!(
|
|
"path(different filename): expected {} is different from actual: {}",
|
|
exp.path().display(),
|
|
act.path().display()
|
|
));
|
|
}
|
|
|
|
if exp.metadata()?.is_file() {
|
|
let exp_file = tokio::fs::read_to_string(exp.path()).await?;
|
|
let act_file = tokio::fs::read_to_string(act.path()).await?;
|
|
|
|
similar_asserts::assert_eq!(exp_file, act_file);
|
|
}
|
|
}
|
|
|
|
if exp.next().is_some() || act.next().is_some() {
|
|
return Err(anyhow::anyhow!(
|
|
"path(uneven amount of items): expected: {}, actual: {}",
|
|
exp.next()
|
|
.map(|o| match o {
|
|
Ok(o) => o.path().display().to_string(),
|
|
Err(_) => "expected: not-found".to_string(),
|
|
})
|
|
.unwrap_or("expected: not-found".into()),
|
|
act.next()
|
|
.map(|o| match o {
|
|
Ok(o) => o.path().display().to_string(),
|
|
Err(_) => "actual: not-found".to_string(),
|
|
})
|
|
.unwrap_or("actual: not-found".into()),
|
|
));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn walk_dir(path: &Path) -> anyhow::Result<walkdir::IntoIter> {
|
|
let mut walkdir = walkdir::WalkDir::new(path)
|
|
.sort_by(compare_by_file_name)
|
|
.into_iter();
|
|
if let Some(Err(e)) = walkdir.next() {
|
|
Err(e.into())
|
|
} else {
|
|
Ok(walkdir)
|
|
}
|
|
}
|
|
|
|
fn compare_by_file_name(a: &DirEntry, b: &DirEntry) -> Ordering {
|
|
a.file_name().cmp(b.file_name())
|
|
}
|