extern crate debcargo;
use std::path::Path;
fn read_manifest(name: &str) -> cargo::core::manifest::Manifest {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let crate_dir = Path::new(manifest_dir).join("tests").join("dependencies");
let cargo_toml = crate_dir.join(format!("{name}.toml"));
let cargo::core::EitherManifest::Real(manifest) = cargo::util::toml::read_manifest(
&cargo_toml,
cargo::core::SourceId::for_path(cargo_toml.parent().unwrap()).unwrap(),
&cargo::GlobalContext::default().unwrap(),
)
.unwrap() else {
panic!("Manifest lacks project and package sections")
};
manifest
}
fn read_expected_output(name: &str) -> String {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let crate_dir = Path::new(manifest_dir).join("tests").join("dependencies");
std::fs::read_to_string(crate_dir.join(format!("{name}.expected"))).unwrap()
}
fn write_expected_output(name: &str, content: &str) {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let crate_dir = Path::new(manifest_dir).join("tests").join("dependencies");
std::fs::write(crate_dir.join(format!("{name}.expected")), content).unwrap();
}
fn serialize_dependency(dep: &cargo::core::Dependency) -> String {
let mut output = String::new();
output.push_str(dep.package_name().as_ref());
output.push('/');
output.push_str(&format!("{:?}", dep.version_req()));
if !dep.features().is_empty() {
output.push('/');
output.push_str(&dep.features().join("|"));
}
output
}
fn test_crate(name: &str, overwrite: bool) {
let manifest = read_manifest(name);
let all_deps = debcargo::crates::all_dependencies_and_features_filtered(&manifest, true);
let mut actual = String::new();
for (feature, (other_features, dependencies)) in &all_deps {
actual.push_str("---\n");
actual.push_str(&format!("{feature}\n"));
for f in other_features {
actual.push_str(&format!("f: {f}\n"));
}
for d in dependencies {
actual.push_str(&format!("d: {}\n", serialize_dependency(d)));
}
let (ffs, dds) = debcargo::crates::transitive_deps(&all_deps, feature).unwrap();
for ff in ffs {
assert_ne!(&ff, feature, "Found a cycle in feature {feature}");
actual.push_str(&format!("ff: {ff}\n"));
}
for dd in dds {
actual.push_str(&format!("dd: {}\n", serialize_dependency(&dd)));
}
}
let expected = read_expected_output(name);
if overwrite {
write_expected_output(name, &actual);
} else {
assert_eq!(actual, expected);
}
}
#[test]
fn debcargo_deps() {
test_crate("debcargo", false);
}
#[test]
fn gitoxide_deps() {
test_crate("gitoxide", false);
}
#[test]
fn windows_sys_deps() {
test_crate("windows-sys", false);
}
#[test]
fn cycle_deps() {
test_crate("cycle", false);
}