blob: f7f72f2f6504d9a8faadc3ac3a2037e46526a056 [file] [log] [blame] [edit]
use anyhow::{Context, Result};
use pretty_assertions::assert_eq;
use std::{fs, path::Path};
use wit_component::WitPrinter;
use wit_parser::Resolve;
/// This is a test which iterates over the `tests/merge` directory and treats
/// each subdirectory as its own test. Each subdirectory has an `into` and a
/// `from` folder which represent two different `Resolve` sets, each with their
/// own set of dependencies as well.
///
/// Each test will merge the `from` into the `into` and assert that everything
/// is valid along the way. On successful merge the resulting documents
/// are printed and asserted against expectations. Failures assert the
/// correct error message.
#[test]
fn merging() -> Result<()> {
drop(env_logger::try_init());
for entry in fs::read_dir("tests/merge")? {
let path = entry?.path();
if !path.is_dir() {
continue;
}
let test_case = path.file_stem().unwrap().to_str().unwrap();
println!("testing {test_case}");
let mut from = Resolve::default();
from.push_dir(&path.join("from"))?;
let mut into = Resolve::default();
into.push_dir(&path.join("into"))?;
from.assert_valid();
into.assert_valid();
match into.merge(from) {
Ok(_) => {
assert!(
!test_case.starts_with("bad-"),
"should have failed to merge"
);
into.assert_valid();
for (id, pkg) in into.packages.iter() {
let expected = path
.join("merge")
.join(&pkg.name.name)
.with_extension("wit");
let output = WitPrinter::default().print(&into, id, &[])?;
assert_output(&expected, &output)?;
}
}
Err(e) => {
assert!(test_case.starts_with("bad-"), "failed to merge with {e:?}");
assert_output(&path.join("error.txt"), &format!("{e:#}"))?;
}
}
}
Ok(())
}
fn assert_output(expected: &Path, actual: &str) -> Result<()> {
if std::env::var_os("BLESS").is_some() {
fs::create_dir_all(expected.parent().unwrap())?;
fs::write(expected, actual).with_context(|| format!("failed to write {expected:?}"))?;
} else {
assert_eq!(
fs::read_to_string(expected)
.with_context(|| format!("failed to read {expected:?}"))?
.replace("\r\n", "\n"),
actual,
"expectation `{}` did not match actual",
expected.display(),
);
}
Ok(())
}