diff options
Diffstat (limited to 'crates/mozart/src/commands/dependency.rs')
| -rw-r--r-- | crates/mozart/src/commands/dependency.rs | 209 |
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()); - } -} |
