use std::ffi::OsString;
use std::path::{Path, PathBuf};
use testing_conventions::location::missing_unit_tests;
use testing_conventions::run;
fn fixture(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/unit_location")
.join(name)
}
fn relative_orphans(root: &Path) -> Vec<String> {
missing_unit_tests(root)
.expect("walking a readable tree should succeed")
.iter()
.map(|path| {
path.strip_prefix(root)
.expect("an orphan must live under the scanned root")
.to_string_lossy()
.replace('\\', "/")
})
.collect()
}
fn run_unit_location(fixture_name: &str) -> i32 {
let args: Vec<OsString> = vec![
"testing-conventions".into(),
"unit-location".into(),
fixture(fixture_name).into_os_string(),
];
run(args).expect("a readable tree should not error")
}
#[test]
fn clean_tree_reports_no_orphans() {
assert!(
relative_orphans(&fixture("clean")).is_empty(),
"every source in the clean tree has a colocated _test.py"
);
}
#[test]
fn red_tree_reports_every_missing_twin() {
assert_eq!(
relative_orphans(&fixture("red")),
vec!["lonely.py", "pkg/orphan.py"],
);
}
#[test]
fn package_markers_are_not_orphans() {
assert!(
relative_orphans(&fixture("exempt")).is_empty(),
"__init__.py is a package marker, never a unit-test subject"
);
}
#[test]
fn a_missing_root_is_an_error() {
let result = missing_unit_tests(fixture("does_not_exist"));
assert!(
result.is_err(),
"an unreadable root must be an error, got: {result:?}"
);
}
#[test]
fn subcommand_exits_zero_on_a_clean_tree() {
assert_eq!(run_unit_location("clean"), 0);
}
#[test]
fn subcommand_exits_nonzero_on_a_red_tree() {
assert_eq!(run_unit_location("red"), 1);
}