use std::collections::HashSet;
use crate::package_manager::Project;
use crate::package_manager::matching::*;
use crate::path::AbsolutePath;
#[test]
fn basic_prefix_match() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("a", "/repo/packages/a"),
Project::new_test("b", "/repo/packages/b"),
];
let mut files = HashSet::new();
files.insert("packages/a/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![true, false]
);
}
#[test]
fn no_match_for_different_project() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("a", "/repo/packages/a"),
Project::new_test("b", "/repo/packages/b"),
];
let mut files = HashSet::new();
files.insert("packages/b/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, true]
);
}
#[test]
fn no_prefix_match_without_separator() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("a", "/repo/packages/a"),
Project::new_test("a-extra", "/repo/packages/a-extra"),
];
let mut files = HashSet::new();
files.insert("packages/a-extra/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, true]
);
}
#[test]
fn nested_file_goes_to_child() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("parent", "/repo/packages/a"),
Project::new_test("child", "/repo/packages/a/sub"),
];
let mut files = HashSet::new();
files.insert("packages/a/sub/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, true]
);
}
#[test]
fn nested_parent_file_goes_to_parent() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("parent", "/repo/packages/a"),
Project::new_test("child", "/repo/packages/a/sub"),
];
let mut files = HashSet::new();
files.insert("packages/a/README.md".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![true, false]
);
}
#[test]
fn root_project_matches_unowned_file() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("root", "/repo"),
Project::new_test("a", "/repo/packages/a"),
];
let mut files = HashSet::new();
files.insert("src/main.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![true, false]
);
}
#[test]
fn root_does_not_steal_from_subproject() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("root", "/repo"),
Project::new_test("a", "/repo/packages/a"),
];
let mut files = HashSet::new();
files.insert("packages/a/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, true]
);
}
#[test]
fn empty_files() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![Project::new_test("root", "/repo")];
let files = HashSet::new();
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false]
);
}
#[test]
fn outside_git_root_always_unchanged() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![Project::new_test("outside", "/other/path")];
let files = HashSet::new();
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false]
);
}
#[test]
fn outside_git_root_unchanged_even_with_files() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("outside", "/other/path"),
Project::new_test("a", "/repo/packages/a"),
];
let mut files = HashSet::new();
files.insert("packages/a/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, true]
);
}
#[test]
fn unowned_file_with_no_root() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("a", "/repo/packages/a"),
Project::new_test("b", "/repo/packages/b"),
];
let mut files = HashSet::new();
files.insert("other/random.txt".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, false]
);
}
#[test]
fn multiple_at_same_path_all_marked() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("npm-root", "/repo"),
Project::new_test("cargo-root", "/repo"),
Project::new_test("sub", "/repo/packages/sub"),
];
let mut files = HashSet::new();
files.insert("README.md".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![true, true, false]
);
}
#[test]
fn exact_path_length_match() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![Project::new_test("my-pkg", "/repo/my-pkg")];
let mut files = HashSet::new();
files.insert("my-pkg".to_string()); assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![true]
);
}
#[test]
fn in_scope_ignored_subproject_prevents_parent_attribution() {
let path = AbsolutePath::new("/repo").unwrap();
let releasable = vec![
Project::new_test("root", "/repo"),
Project::new_test("foo", "/repo/foo"),
];
let all = vec![
Project::new_test("root", "/repo"),
Project::new_test("foo", "/repo/foo"),
Project::new_test("foo-tests", "/repo/foo/tests"),
];
let mut files = HashSet::new();
files.insert("foo/tests/README.md".to_string());
assert_eq!(
match_files_to_projects_in_scope(&releasable, &all, &path, &files),
vec![false, false]
);
}
#[test]
fn in_scope_file_outside_ignored_subproject_still_attributes_parent() {
let path = AbsolutePath::new("/repo").unwrap();
let releasable = vec![
Project::new_test("root", "/repo"),
Project::new_test("foo", "/repo/foo"),
];
let all = vec![
Project::new_test("root", "/repo"),
Project::new_test("foo", "/repo/foo"),
Project::new_test("foo-tests", "/repo/foo/tests"),
];
let mut files = HashSet::new();
files.insert("foo/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects_in_scope(&releasable, &all, &path, &files),
vec![false, true]
);
}
#[test]
fn in_scope_same_scope_as_projects_matches_identically() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("a", "/repo/packages/a"),
Project::new_test("b", "/repo/packages/b"),
];
let mut files = HashSet::new();
files.insert("packages/a/src/lib.rs".to_string());
let direct = match_files_to_projects(&projects, &path, &files);
let scoped = match_files_to_projects_in_scope(&projects, &projects, &path, &files);
assert_eq!(direct, scoped);
}
#[test]
fn multiple_at_same_path_subproject_wins() {
let path = AbsolutePath::new("/repo").unwrap();
let projects = vec![
Project::new_test("npm-root", "/repo"),
Project::new_test("cargo-root", "/repo"),
Project::new_test("sub", "/repo/packages/sub"),
];
let mut files = HashSet::new();
files.insert("packages/sub/src/lib.rs".to_string());
assert_eq!(
match_files_to_projects(&projects, &path, &files),
vec![false, false, true]
);
}