use std::path::{Path, PathBuf};
use super::load;
use crate::error::Error;
use crate::manifest::Manifest;
fn write(dir: &Path, relative: &str, body: &str) -> PathBuf {
let path = dir.join(relative);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent).expect("mkdir");
}
std::fs::write(&path, body).expect("write");
path
}
fn names(manifest: &Manifest) -> Vec<&str> {
manifest.commands.iter().map(|c| c.name.as_str()).collect()
}
#[test]
fn import_cycle_errors_with_the_chain() {
let dir = tempfile::tempdir().expect("tempdir");
let base = dir.path().canonicalize().expect("canonicalize");
write(&base, "a.yaml", "imports: [b.yaml]\n");
write(&base, "b.yaml", "imports: [a.yaml]\n");
let root = write(&base, "root.yaml", "imports: [a.yaml]\n");
let err = load(&root, &base).expect_err("import cycle");
assert_eq!(
err.to_string(),
"import cycle: root.yaml -> a.yaml -> b.yaml -> a.yaml"
);
assert!(matches!(err, Error::ImportCycle { .. }));
}
#[test]
fn a_diamond_loads_once_and_does_not_error() {
let dir = tempfile::tempdir().expect("tempdir");
write(dir.path(), "shared.yaml", "scopes:\n rust: [\"src/**\"]\n");
write(
dir.path(),
"a.yaml",
"imports: [shared.yaml]\ncommands:\n - name: a\n",
);
write(
dir.path(),
"b.yaml",
"imports: [shared.yaml]\ncommands:\n - name: b\n",
);
let root = write(dir.path(), "root.yaml", "imports: [a.yaml, b.yaml]\n");
let (manifest, provenance) =
load(&root, dir.path()).expect("a diamond loads once rather than erroring");
assert!(manifest.scopes.contains_key("rust"));
assert_eq!(names(&manifest), vec!["a", "b"]);
assert!(provenance.scopes.contains_key("rust"));
}