diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-21 03:05:51 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-21 03:05:51 +0900 |
| commit | 584a33d677cfdf8ae2309b0fe4e03fb6bcfce66b (patch) | |
| tree | a7fa03c4573cb448bb98d4aad9b317417e240c2d /crates/shirabe/tests/util/package_sorter_test.rs | |
| parent | 23609e2d989eb2fa2d44450aa0c6a058931a6e2d (diff) | |
| download | php-shirabe-584a33d677cfdf8ae2309b0fe4e03fb6bcfce66b.tar.gz php-shirabe-584a33d677cfdf8ae2309b0fe4e03fb6bcfce66b.tar.zst php-shirabe-584a33d677cfdf8ae2309b0fe4e03fb6bcfce66b.zip | |
test(util): port PackageSorterTest
PackageSorter::sort_packages reaches strnatcasecmp (a todo!() in the
php-shim) whenever it compares equally-weighted packages, so the cases
are #[ignore]. createPackage is reconstructed via ArrayLoader because the
public handle API only exposes link setters on root packages.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests/util/package_sorter_test.rs')
| -rw-r--r-- | crates/shirabe/tests/util/package_sorter_test.rs | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/crates/shirabe/tests/util/package_sorter_test.rs b/crates/shirabe/tests/util/package_sorter_test.rs index a162ac8..41770e0 100644 --- a/crates/shirabe/tests/util/package_sorter_test.rs +++ b/crates/shirabe/tests/util/package_sorter_test.rs @@ -1 +1,152 @@ //! ref: composer/tests/Composer/Test/Util/PackageSorterTest.php + +use indexmap::IndexMap; +use shirabe::package::handle::PackageInterfaceHandle; +use shirabe::package::loader::array_loader::ArrayLoader; +use shirabe::util::package_sorter::PackageSorter; +use shirabe_php_shim::PhpMixed; + +/// PHP `createPackage` sets requires directly on a `Package`; the public handle API only allows +/// link setters on root packages, so the equivalent here builds the package through ArrayLoader. +fn create_package(name: &str, requires: &[&str]) -> PackageInterfaceHandle { + let mut config: IndexMap<String, PhpMixed> = IndexMap::new(); + config.insert("name".to_string(), PhpMixed::String(name.to_string())); + config.insert("version".to_string(), PhpMixed::String("1.0.0".to_string())); + + if !requires.is_empty() { + let mut links: IndexMap<String, PhpMixed> = IndexMap::new(); + for require_name in requires { + links.insert(require_name.to_string(), PhpMixed::String("*".to_string())); + } + config.insert("require".to_string(), PhpMixed::Array(links)); + } + + ArrayLoader::new(None, false) + .load_packages(vec![config]) + .unwrap() + .remove(0) +} + +fn names(packages: &[PackageInterfaceHandle]) -> Vec<String> { + packages.iter().map(|p| p.get_name()).collect() +} + +#[test] +#[ignore = "PackageSorter::sort_packages reaches strnatcasecmp, a todo!() in the php-shim"] +fn test_sorting_does_nothing_with_no_dependencies() { + let packages = vec![ + create_package("foo/bar1", &[]), + create_package("foo/bar2", &[]), + create_package("foo/bar3", &[]), + create_package("foo/bar4", &[]), + ]; + + let expected = names(&packages); + let sorted_packages = PackageSorter::sort_packages(packages, IndexMap::new()); + + assert_eq!(expected, names(&sorted_packages)); +} + +fn sorting_orders_dependencies_higher_than_package_cases() +-> Vec<(Vec<PackageInterfaceHandle>, Vec<&'static str>, IndexMap<String, i64>)> { + vec![ + // one package is dep + ( + vec![ + create_package("foo/bar1", &["foo/bar4"]), + create_package("foo/bar2", &["foo/bar4"]), + create_package("foo/bar3", &["foo/bar4"]), + create_package("foo/bar4", &[]), + ], + vec!["foo/bar4", "foo/bar1", "foo/bar2", "foo/bar3"], + IndexMap::new(), + ), + // one package has more deps + ( + vec![ + create_package("foo/bar1", &["foo/bar2"]), + create_package("foo/bar2", &["foo/bar4"]), + create_package("foo/bar3", &["foo/bar4"]), + create_package("foo/bar4", &[]), + ], + vec!["foo/bar4", "foo/bar2", "foo/bar1", "foo/bar3"], + IndexMap::new(), + ), + // package is required by many, but requires one other + ( + vec![ + create_package("foo/bar1", &["foo/bar3"]), + create_package("foo/bar2", &["foo/bar3"]), + create_package("foo/bar3", &["foo/bar4"]), + create_package("foo/bar4", &[]), + create_package("foo/bar5", &["foo/bar3"]), + create_package("foo/bar6", &["foo/bar3"]), + ], + vec![ + "foo/bar4", "foo/bar3", "foo/bar1", "foo/bar2", "foo/bar5", "foo/bar6", + ], + IndexMap::new(), + ), + // one package has many requires + ( + vec![ + create_package("foo/bar1", &["foo/bar2"]), + create_package("foo/bar2", &[]), + create_package("foo/bar3", &["foo/bar4"]), + create_package("foo/bar4", &[]), + create_package("foo/bar5", &["foo/bar2"]), + create_package("foo/bar6", &["foo/bar2"]), + ], + vec![ + "foo/bar2", "foo/bar4", "foo/bar1", "foo/bar3", "foo/bar5", "foo/bar6", + ], + IndexMap::new(), + ), + // circular deps sorted alphabetically if weighted equally + ( + vec![ + create_package("foo/bar1", &["circular/part1"]), + create_package("foo/bar2", &["circular/part2"]), + create_package("circular/part1", &["circular/part2"]), + create_package("circular/part2", &["circular/part1"]), + ], + vec!["circular/part1", "circular/part2", "foo/bar1", "foo/bar2"], + IndexMap::new(), + ), + // equal weight sorted alphabetically + ( + vec![ + create_package("foo/bar10", &["foo/dep"]), + create_package("foo/bar2", &["foo/dep"]), + create_package("foo/baz", &["foo/dep"]), + create_package("foo/dep", &[]), + ], + vec!["foo/dep", "foo/bar2", "foo/bar10", "foo/baz"], + IndexMap::new(), + ), + // pre-weighted packages bumped to top incl their deps + ( + vec![ + create_package("foo/bar", &["foo/dep"]), + create_package("foo/bar2", &["foo/dep2"]), + create_package("foo/dep", &[]), + create_package("foo/dep2", &[]), + ], + vec!["foo/dep", "foo/bar", "foo/dep2", "foo/bar2"], + IndexMap::from([("foo/bar".to_string(), -1000)]), + ), + ] +} + +#[test] +#[ignore = "PackageSorter::sort_packages reaches strnatcasecmp, a todo!() in the php-shim"] +fn test_sorting_orders_dependencies_higher_than_package() { + for (packages, expected_ordered_list, weights) in + sorting_orders_dependencies_higher_than_package_cases() + { + let sorted_packages = PackageSorter::sort_packages(packages, weights); + let sorted_package_names = names(&sorted_packages); + + assert_eq!(expected_ordered_list, sorted_package_names); + } +} |
