use std::env;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use stern4rust::source_walker::SourceWalker;
fn names(root: &Path) -> Vec<String> {
SourceWalker::walk(root)
.iter()
.map(|path| {
path.strip_prefix(root)
.unwrap_or(path)
.to_string_lossy()
.replace('\\', "/")
})
.collect()
}
fn temp_root(name: &str) -> PathBuf {
let root = env::temp_dir().join(format!("stern4rust_walker_{name}"));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(&root).expect("create the temp root");
root
}
fn write(root: &Path, relative: &str) {
let path = root.join(relative);
fs::create_dir_all(path.parent().expect("a parent")).expect("create parents");
fs::write(path, "// file").expect("write the file");
}
#[test]
fn walk_descends_into_nested_directories() {
let root = temp_root("nested");
write(&root, "src/rules/deep/subject.rs");
let found = names(&root);
assert_eq!(found, ["src/rules/deep/subject.rs"]);
}
#[test]
fn walk_finds_a_fixture_package_nested_under_tests() {
let root = temp_root("fixture_package");
write(&root, "Cargo.toml");
write(&root, "tests/a_tests.rs");
write(&root, "tests/fixtures/sample/Cargo.toml");
write(&root, "tests/fixtures/sample/src/lib.rs");
let found = names(&root);
assert_eq!(
found,
["tests/a_tests.rs", "tests/fixtures/sample/src/lib.rs"]
);
}
#[test]
fn walk_finds_a_nested_package_holding_its_own_manifest() {
let root = temp_root("nested_package");
write(&root, "Cargo.toml");
write(&root, "src/a.rs");
write(&root, "vendored/other/Cargo.toml");
write(&root, "vendored/other/src/b.rs");
let found = names(&root);
assert_eq!(found, ["src/a.rs", "vendored/other/src/b.rs"]);
}
#[test]
fn walk_finds_a_rust_file_at_the_root() {
let root = temp_root("root_file");
write(&root, "build.rs");
let found = names(&root);
assert_eq!(found, ["build.rs"]);
}
#[test]
fn walk_finds_rust_files_under_src_and_tests_alike() {
let root = temp_root("src_and_tests");
write(&root, "src/a.rs");
write(&root, "tests/a_tests.rs");
let found = names(&root);
assert_eq!(found, ["src/a.rs", "tests/a_tests.rs"]);
}
#[test]
fn walk_ignores_files_that_are_not_rust() {
let root = temp_root("non_rust");
write(&root, "src/a.rs");
write(&root, "README.md");
write(&root, "Cargo.toml");
let found = names(&root);
assert_eq!(found, ["src/a.rs"]);
}
#[test]
fn walk_keeps_the_root_package_even_though_it_holds_a_manifest() {
let root = temp_root("root_manifest");
write(&root, "Cargo.toml");
write(&root, "src/a.rs");
let found = names(&root);
assert_eq!(found, ["src/a.rs"]);
}
#[test]
fn walk_of_a_directory_that_does_not_exist_returns_nothing() {
let root = env::temp_dir().join("stern4rust_walker_absent");
let _ = fs::remove_dir_all(&root);
let found = SourceWalker::walk(&root);
assert!(found.is_empty());
}
#[test]
fn walk_of_a_directory_without_rust_files_returns_nothing() {
let root = temp_root("empty");
write(&root, "docs/notes.md");
let found = names(&root);
assert!(found.is_empty());
}
#[test]
fn walk_returns_paths_in_a_stable_order() {
let root = temp_root("order");
write(&root, "src/z.rs");
write(&root, "src/a.rs");
write(&root, "src/m.rs");
let found = names(&root);
assert_eq!(found, ["src/a.rs", "src/m.rs", "src/z.rs"]);
}
#[test]
fn walk_skips_the_target_directory() {
let root = temp_root("target");
write(&root, "src/a.rs");
write(&root, "target/debug/build/generated.rs");
let found = names(&root);
assert_eq!(found, ["src/a.rs"]);
}