aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src/commands/dependency.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mozart/src/commands/dependency.rs')
-rw-r--r--crates/mozart/src/commands/dependency.rs209
1 files changed, 0 insertions, 209 deletions
diff --git a/crates/mozart/src/commands/dependency.rs b/crates/mozart/src/commands/dependency.rs
index 5766b08..1edcfd4 100644
--- a/crates/mozart/src/commands/dependency.rs
+++ b/crates/mozart/src/commands/dependency.rs
@@ -740,212 +740,3 @@ fn tree_prefix(depth: usize, is_last: bool) -> String {
let branch = if is_last { "└─ " } else { "├─ " };
format!("{indent}{branch}")
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- fn make_pkg(
- name: &str,
- version: &str,
- require: &[(&str, &str)],
- conflict: &[(&str, &str)],
- is_root: bool,
- ) -> PackageInfo {
- PackageInfo {
- name: name.to_string(),
- version: version.to_string(),
- require: require
- .iter()
- .map(|(k, v)| (k.to_string(), v.to_string()))
- .collect(),
- require_dev: indexmap::IndexMap::new(),
- conflict: conflict
- .iter()
- .map(|(k, v)| (k.to_string(), v.to_string()))
- .collect(),
- is_root,
- }
- }
-
- #[test]
- fn test_forward_dependency() {
- // root requires A, A requires B → depends B returns A (and root not A)
- let packages = vec![
- make_pkg("root/project", "ROOT", &[("vendor/a", "^1.0")], &[], true),
- make_pkg("vendor/a", "1.0.0", &[("vendor/b", "^2.0")], &[], false),
- make_pkg("vendor/b", "2.0.0", &[], &[], false),
- ];
- let needles = vec!["vendor/b".to_string()];
- let results = get_dependents(&packages, &needles, None, false, false).unwrap();
- assert_eq!(results.len(), 1, "Only A requires B directly");
- assert_eq!(results[0].package_name, "vendor/a");
- assert_eq!(results[0].link_description, "requires");
- assert_eq!(results[0].link_constraint, "^2.0");
- }
-
- #[test]
- fn test_recursive_dependency() {
- // root requires A, A requires B → depends B --recursive returns A, with root as child
- let packages = vec![
- make_pkg("root/project", "ROOT", &[("vendor/a", "^1.0")], &[], true),
- make_pkg("vendor/a", "1.0.0", &[("vendor/b", "^2.0")], &[], false),
- make_pkg("vendor/b", "2.0.0", &[], &[], false),
- ];
- let needles = vec!["vendor/b".to_string()];
- let results = get_dependents(&packages, &needles, None, false, true).unwrap();
- // A is found as direct dependent of B
- assert!(!results.is_empty());
- let a_result = results.iter().find(|r| r.package_name == "vendor/a");
- assert!(a_result.is_some(), "vendor/a should be found");
- // root should appear as a child of vendor/a
- let children = &a_result.unwrap().children;
- assert!(
- children.iter().any(|c| c.package_name == "root/project"),
- "root/project should be a child of vendor/a"
- );
- }
-
- #[test]
- fn test_no_dependents() {
- // Nothing requires X
- let packages = vec![
- make_pkg("root/project", "ROOT", &[("vendor/a", "^1.0")], &[], true),
- make_pkg("vendor/a", "1.0.0", &[], &[], false),
- ];
- let needles = vec!["vendor/x".to_string()];
- let results = get_dependents(&packages, &needles, None, false, false).unwrap();
- assert!(results.is_empty());
- }
-
- #[test]
- fn test_circular_detection() {
- // A requires B, B requires A — should not loop forever
- let packages = vec![
- make_pkg("vendor/a", "1.0.0", &[("vendor/b", "^1.0")], &[], false),
- make_pkg("vendor/b", "1.0.0", &[("vendor/a", "^1.0")], &[], false),
- ];
- let needles = vec!["vendor/b".to_string()];
- // Should terminate without stack overflow
- let results = get_dependents(&packages, &needles, None, false, true).unwrap();
- // vendor/a requires vendor/b → found; vendor/b would recurse back to vendor/a
- // but visited set prevents infinite loop
- assert!(!results.is_empty());
- }
-
- #[test]
- fn test_prohibits_basic() {
- // root requires A ^1.0; user asks "who prohibits A 2.0"
- // → root requires A ^1.0 which doesn't match 2.0 → root prohibits it
- let packages = vec![
- make_pkg("root/project", "ROOT", &[("vendor/a", "^1.0")], &[], true),
- make_pkg("vendor/a", "1.0.0", &[], &[], false),
- ];
- let constraint = mozart_semver::VersionConstraint::parse("2.0.0").unwrap();
- let needles = vec!["vendor/a".to_string()];
- let results = get_dependents(&packages, &needles, Some(&constraint), true, false).unwrap();
- assert!(!results.is_empty(), "root should prohibit vendor/a 2.0");
- assert_eq!(results[0].package_name, "root/project");
- assert_eq!(results[0].link_description, "requires");
- }
-
- #[test]
- fn test_prohibits_conflict_field() {
- // pkg/b conflicts with vendor/a ^2.0 → prohibits vendor/a 2.0
- let packages = vec![
- make_pkg(
- "root/project",
- "ROOT",
- &[("vendor/a", "^1.0"), ("vendor/b", "^1.0")],
- &[],
- true,
- ),
- make_pkg("vendor/a", "1.0.0", &[], &[], false),
- make_pkg(
- "vendor/b",
- "1.0.0",
- &[],
- &[("vendor/a", "^2.0")], // conflicts with vendor/a ^2.0
- false,
- ),
- ];
- let constraint = mozart_semver::VersionConstraint::parse("2.0.0").unwrap();
- let needles = vec!["vendor/a".to_string()];
- let results = get_dependents(&packages, &needles, Some(&constraint), true, false).unwrap();
- // vendor/b conflicts with vendor/a ^2.0 which covers 2.0.0
- let conflict_result = results.iter().find(|r| r.package_name == "vendor/b");
- assert!(
- conflict_result.is_some(),
- "vendor/b should prohibit vendor/a 2.0 via conflict"
- );
- assert_eq!(conflict_result.unwrap().link_description, "conflicts");
- }
-
- #[test]
- fn test_prohibits_no_issue() {
- // root requires A ^2.0; user asks "who prohibits A 2.5"
- // → root's constraint ^2.0 DOES match 2.5 → nobody prohibits it
- let packages = vec![
- make_pkg("root/project", "ROOT", &[("vendor/a", "^2.0")], &[], true),
- make_pkg("vendor/a", "2.0.0", &[], &[], false),
- ];
- let constraint = mozart_semver::VersionConstraint::parse("2.5.0").unwrap();
- let needles = vec!["vendor/a".to_string()];
- let results = get_dependents(&packages, &needles, Some(&constraint), true, false).unwrap();
- assert!(
- results.is_empty(),
- "Nobody prohibits vendor/a 2.5 when root requires ^2.0"
- );
- }
-
- fn test_io() -> std::sync::Arc<std::sync::Mutex<Box<dyn IoInterface>>> {
- std::sync::Arc::new(std::sync::Mutex::new(
- Box::new(mozart_core::console::Console::new(
- 0, false, false, false, false,
- )) as Box<dyn IoInterface>,
- ))
- }
-
- #[test]
- fn test_print_table_empty() {
- print_table(&[], test_io());
- }
-
- #[test]
- fn test_print_table_single() {
- let results = vec![DependencyResult {
- package_name: "vendor/a".to_string(),
- package_version: "1.0.0".to_string(),
- link_description: "requires".to_string(),
- link_target: "vendor/b".to_string(),
- link_constraint: "^2.0".to_string(),
- children: vec![],
- }];
- print_table(&results, test_io());
- }
-
- #[test]
- fn test_print_tree_empty() {
- print_tree(&[], 0, test_io());
- }
-
- #[test]
- fn test_print_tree_nested() {
- let results = vec![DependencyResult {
- package_name: "vendor/a".to_string(),
- package_version: "1.0.0".to_string(),
- link_description: "requires".to_string(),
- link_target: "vendor/b".to_string(),
- link_constraint: "^2.0".to_string(),
- children: vec![DependencyResult {
- package_name: "root/project".to_string(),
- package_version: "ROOT".to_string(),
- link_description: "requires".to_string(),
- link_target: "vendor/a".to_string(),
- link_constraint: "^1.0".to_string(),
- children: vec![],
- }],
- }];
- print_tree(&results, 0, test_io());
- }
-}