use std::process::Command;
fn cleanlib_bin() -> std::path::PathBuf {
std::path::PathBuf::from(std::env!("CARGO_BIN_EXE_cleanlib"))
}
#[test]
fn cleanlib_157_shared_write_to_accumulates_all_ecosystems() {
let dir = tempfile::tempdir().expect("tempdir");
let target = dir.path().join("proxy.conf");
let out = Command::new(cleanlib_bin())
.args([
"config",
"init",
"--ecosystem",
"npm,pypi",
"--write-to",
target.to_str().unwrap(),
])
.output()
.expect("invoke cleanlib");
assert!(
out.status.success(),
"config init should exit 0; stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let body = std::fs::read_to_string(&target).unwrap();
assert!(
body.contains("registry=") && body.contains("always-auth=true"),
"npm snippet must survive in shared file; got: {body}"
);
assert!(
body.contains("[global]") && body.contains("index-url"),
"pypi snippet must be appended after npm; got: {body}"
);
assert!(
body.find("registry=").unwrap() < body.find("[global]").unwrap(),
"npm block should precede pypi block (truncate-then-append order); got: {body}"
);
}
#[test]
fn cleanlib_373_config_init_accepts_crates() {
let out = Command::new(cleanlib_bin())
.args(["config", "init", "--ecosystem", "crates"])
.output()
.expect("invoke cleanlib");
assert!(
out.status.success(),
"config init --ecosystem crates must exit 0; stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
stdout.contains("[registries.cleanlibrary]"),
"crates snippet must carry the [registries.cleanlibrary] block; stdout:\n{stdout}"
);
assert!(
stdout.contains("sparse+"),
"crates snippet must use the sparse+ HTTP registry index; stdout:\n{stdout}"
);
}
#[test]
fn cleanlib_374_config_init_accepts_maven() {
let out = Command::new(cleanlib_bin())
.args(["config", "init", "--ecosystem", "maven"])
.output()
.expect("invoke cleanlib");
assert!(
out.status.success(),
"config init --ecosystem maven must exit 0; stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
stdout.contains("<mirror>") && stdout.contains("<mirrorOf>*</mirrorOf>"),
"maven snippet must carry the <mirror> + <mirrorOf>*</mirrorOf> block; stdout:\n{stdout}"
);
assert!(
stdout.contains("Authorization"),
"maven snippet must carry the Authorization httpHeader property; stdout:\n{stdout}"
);
}
#[test]
fn cleanlib_373_374_config_init_accepts_mixed_5_ecosystem_batch() {
let out = Command::new(cleanlib_bin())
.args(["config", "init", "--ecosystem", "npm,pypi,go,crates,maven"])
.output()
.expect("invoke cleanlib");
assert!(
out.status.success(),
"config init must accept the full 5-ecosystem batch; stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let stdout = String::from_utf8_lossy(&out.stdout);
for token in [
"=== npm",
"=== pypi",
"=== go",
"=== crates",
"=== maven",
] {
assert!(
stdout.contains(token),
"expected header `{token}` in stdout; got:\n{stdout}"
);
}
}
#[test]
fn cleanlib_373_374_config_init_error_message_lists_new_ecosystems() {
let out = Command::new(cleanlib_bin())
.args(["config", "init", "--ecosystem", "nonexistent-ecosystem"])
.output()
.expect("invoke cleanlib");
assert!(
!out.status.success(),
"unknown ecosystem must fail; stdout: {}",
String::from_utf8_lossy(&out.stdout)
);
let stderr = String::from_utf8_lossy(&out.stderr);
for expected in &["npm", "pypi", "go", "crates", "maven"] {
assert!(
stderr.contains(expected),
"error message must advertise supported ecosystem `{}`; got:\n{}",
expected,
stderr
);
}
}
#[test]
fn cleanlib_157_shared_write_to_creates_single_backup() {
let dir = tempfile::tempdir().expect("tempdir");
let target = dir.path().join("proxy.conf");
std::fs::write(&target, "prior proxy config\n").unwrap();
let out = Command::new(cleanlib_bin())
.args([
"config",
"init",
"--ecosystem",
"npm,pypi",
"--write-to",
target.to_str().unwrap(),
])
.output()
.expect("invoke cleanlib");
assert!(
out.status.success(),
"config init should exit 0; stderr: {}",
String::from_utf8_lossy(&out.stderr)
);
let backups: Vec<_> = std::fs::read_dir(dir.path())
.unwrap()
.filter_map(|e| e.ok())
.map(|e| e.file_name().to_string_lossy().into_owned())
.filter(|n| n.contains("cleanlib-backup"))
.collect();
assert_eq!(
backups.len(),
1,
"multi-ecosystem write must create exactly one backup; dir had: {backups:?}"
);
let backup_body = std::fs::read_to_string(dir.path().join(&backups[0])).unwrap();
assert!(
backup_body.contains("prior proxy config"),
"backup should preserve pre-existing content; got: {backup_body}"
);
let live = std::fs::read_to_string(&target).unwrap();
assert!(
live.contains("registry=") && live.contains("[global]"),
"live file must hold every ecosystem snippet; got: {live}"
);
}