diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-22 02:09:59 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-22 02:09:59 +0900 |
| commit | 822d9a872807a92a5337ee8b7bab96dc9845cdbb (patch) | |
| tree | 4931365df5978caffade69cad2154718a9076f66 /crates/shirabe/tests/installed_versions_test.rs | |
| parent | f691b864b687f251c3b266e8cff2774d730567ba (diff) | |
| download | php-shirabe-822d9a872807a92a5337ee8b7bab96dc9845cdbb.tar.gz php-shirabe-822d9a872807a92a5337ee8b7bab96dc9845cdbb.tar.zst php-shirabe-822d9a872807a92a5337ee8b7bab96dc9845cdbb.zip | |
test: port more test cases
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests/installed_versions_test.rs')
| -rw-r--r-- | crates/shirabe/tests/installed_versions_test.rs | 431 |
1 files changed, 386 insertions, 45 deletions
diff --git a/crates/shirabe/tests/installed_versions_test.rs b/crates/shirabe/tests/installed_versions_test.rs index d20bc84..6757e03 100644 --- a/crates/shirabe/tests/installed_versions_test.rs +++ b/crates/shirabe/tests/installed_versions_test.rs @@ -1,108 +1,449 @@ //! ref: composer/tests/Composer/Test/InstalledVersionsTest.php -// setUpBeforeClass reflects into ClassLoader::registeredLoaders and the cases load -// installed.php fixtures via InstalledVersions::reload; the reflection and fixture loading -// are not ported. +// setUpBeforeClass reflects into ClassLoader::registeredLoaders to make it seem like no class +// loaders are registered; this is not ported because InstalledVersions::reload already disables +// the multiple-ClassLoader-based checks by setting installedIsLocalDir to false. The PHP setUp +// loads the installed_relative.php fixture via `require`; here the fixture is built inline as an +// IndexMap<String, PhpMixed> with the tmp root substituted for `$dir`. +use indexmap::IndexMap; +use shirabe::installed_versions::InstalledVersions; +use shirabe_php_shim::{PhpMixed, realpath}; +use shirabe_semver::version_parser::VersionParser; use tempfile::TempDir; -fn set_up() -> TempDir { +fn arr(entries: Vec<(&str, PhpMixed)>) -> PhpMixed { + let mut m = IndexMap::new(); + for (k, v) in entries { + m.insert(k.to_string(), v); + } + PhpMixed::Array(m) +} + +fn list(items: Vec<PhpMixed>) -> PhpMixed { + PhpMixed::List(items) +} + +fn s(value: &str) -> PhpMixed { + PhpMixed::String(value.to_string()) +} + +/// Builds the installed_relative.php fixture with `$dir` substituted by `dir`. +fn fixture(dir: &str) -> IndexMap<String, PhpMixed> { + let root_install_path = format!("{}/./", dir); + let mut data = IndexMap::new(); + + data.insert( + "root".to_string(), + arr(vec![ + ("name", s("__root__")), + ("pretty_version", s("dev-master")), + ("version", s("dev-master")), + ("reference", s("sourceref-by-default")), + ("type", s("library")), + ("install_path", s(&root_install_path)), + ("aliases", list(vec![s("1.10.x-dev")])), + ("dev", PhpMixed::Bool(true)), + ]), + ); + + data.insert( + "versions".to_string(), + arr(vec![ + ( + "__root__", + arr(vec![ + ("pretty_version", s("dev-master")), + ("version", s("dev-master")), + ("reference", s("sourceref-by-default")), + ("type", s("library")), + ("install_path", s(&root_install_path)), + ("aliases", list(vec![s("1.10.x-dev")])), + ("dev_requirement", PhpMixed::Bool(false)), + ]), + ), + ( + "a/provider", + arr(vec![ + ("pretty_version", s("1.1")), + ("version", s("1.1.0.0")), + ("reference", s("distref-as-no-source")), + ("type", s("library")), + ("install_path", s(&format!("{}/vendor/a/provider", dir))), + ("aliases", list(vec![])), + ("dev_requirement", PhpMixed::Bool(false)), + ]), + ), + ( + "a/provider2", + arr(vec![ + ("pretty_version", s("1.2")), + ("version", s("1.2.0.0")), + ("reference", s("distref-as-installed-from-dist")), + ("type", s("library")), + ("install_path", s(&format!("{}/vendor/a/provider2", dir))), + ("aliases", list(vec![s("1.4")])), + ("dev_requirement", PhpMixed::Bool(false)), + ]), + ), + ( + "b/replacer", + arr(vec![ + ("pretty_version", s("2.2")), + ("version", s("2.2.0.0")), + ("reference", PhpMixed::Null), + ("type", s("library")), + ("install_path", s(&format!("{}/vendor/b/replacer", dir))), + ("aliases", list(vec![])), + ("dev_requirement", PhpMixed::Bool(false)), + ]), + ), + ( + "c/c", + arr(vec![ + ("pretty_version", s("3.0")), + ("version", s("3.0.0.0")), + ("reference", PhpMixed::Null), + ("type", s("library")), + ("install_path", s("/foo/bar/vendor/c/c")), + ("aliases", list(vec![])), + ("dev_requirement", PhpMixed::Bool(true)), + ]), + ), + ( + "foo/impl", + arr(vec![ + ("dev_requirement", PhpMixed::Bool(false)), + ( + "provided", + list(vec![s("^1.1"), s("1.2"), s("1.4"), s("2.0")]), + ), + ]), + ), + ( + "foo/impl2", + arr(vec![ + ("dev_requirement", PhpMixed::Bool(false)), + ("provided", list(vec![s("2.0")])), + ("replaced", list(vec![s("2.2")])), + ]), + ), + ( + "foo/replaced", + arr(vec![ + ("dev_requirement", PhpMixed::Bool(false)), + ("replaced", list(vec![s("^3.0")])), + ]), + ), + ( + "meta/package", + arr(vec![ + ("pretty_version", s("3.0")), + ("version", s("3.0.0.0")), + ("reference", PhpMixed::Null), + ("type", s("metapackage")), + ("install_path", PhpMixed::Null), + ("aliases", list(vec![])), + ("dev_requirement", PhpMixed::Bool(false)), + ]), + ), + ]), + ); + + data +} + +/// Returns the tmp root (kept alive for the duration of the test) and its path string. +fn set_up() -> (TempDir, String) { let root = TempDir::new().unwrap(); + let dir = root.path().to_str().unwrap().to_string(); - // Loading the installed_relative.php fixture and InstalledVersions::reload are not ported. - todo!(); + InstalledVersions::reload(fixture(&dir)); - #[allow(unreachable_code)] - root + (root, dir) } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_installed_packages() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let names = vec![ + "__root__".to_string(), + "a/provider".to_string(), + "a/provider2".to_string(), + "b/replacer".to_string(), + "c/c".to_string(), + "foo/impl".to_string(), + "foo/impl2".to_string(), + "foo/replaced".to_string(), + "meta/package".to_string(), + ]; + assert_eq!(names, InstalledVersions::get_installed_packages()); } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_is_installed() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let cases: Vec<(bool, &str, bool)> = vec![ + (true, "foo/impl", true), + (true, "foo/replaced", true), + (true, "c/c", true), + (false, "c/c", false), + (true, "__root__", true), + (true, "b/replacer", true), + (false, "not/there", true), + (true, "meta/package", true), + ]; + + for (expected, name, include_dev_requirements) in cases { + assert_eq!( + expected, + InstalledVersions::is_installed(name, include_dev_requirements) + ); + } } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_satisfies() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let cases: Vec<(bool, &str, &str)> = vec![ + (true, "foo/impl", "1.5"), + (true, "foo/impl", "1.2"), + (true, "foo/impl", "^1.0"), + (true, "foo/impl", "^3 || ^2"), + (false, "foo/impl", "^3"), + (true, "foo/replaced", "3.5"), + (true, "foo/replaced", "^3.2"), + (false, "foo/replaced", "4.0"), + (true, "c/c", "3.0.0"), + (true, "c/c", "^3"), + (false, "c/c", "^3.1"), + (true, "__root__", "dev-master"), + (true, "__root__", "^1.10"), + (false, "__root__", "^2"), + (true, "b/replacer", "^2.1"), + (false, "b/replacer", "^2.3"), + (true, "a/provider2", "^1.2"), + (true, "a/provider2", "^1.4"), + (false, "a/provider2", "^1.5"), + ]; + + for (expected, name, constraint) in cases { + assert_eq!( + expected, + InstalledVersions::satisfies(&VersionParser, name, Some(constraint)).unwrap() + ); + } } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_version_ranges() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let cases: Vec<(&str, &str)> = vec![ + ("dev-master || 1.10.x-dev", "__root__"), + ("^1.1 || 1.2 || 1.4 || 2.0", "foo/impl"), + ("2.2 || 2.0", "foo/impl2"), + ("^3.0", "foo/replaced"), + ("1.1", "a/provider"), + ("1.2 || 1.4", "a/provider2"), + ("2.2", "b/replacer"), + ("3.0", "c/c"), + ]; + + for (expected, name) in cases { + assert_eq!( + expected, + InstalledVersions::get_version_ranges(name).unwrap() + ); + } } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_version() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let cases: Vec<(Option<&str>, &str)> = vec![ + (Some("dev-master"), "__root__"), + (None, "foo/impl"), + (None, "foo/impl2"), + (None, "foo/replaced"), + (Some("1.1.0.0"), "a/provider"), + (Some("1.2.0.0"), "a/provider2"), + (Some("2.2.0.0"), "b/replacer"), + (Some("3.0.0.0"), "c/c"), + ]; + + for (expected, name) in cases { + assert_eq!( + expected.map(|s| s.to_string()), + InstalledVersions::get_version(name).unwrap() + ); + } } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_pretty_version() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let cases: Vec<(Option<&str>, &str)> = vec![ + (Some("dev-master"), "__root__"), + (None, "foo/impl"), + (None, "foo/impl2"), + (None, "foo/replaced"), + (Some("1.1"), "a/provider"), + (Some("1.2"), "a/provider2"), + (Some("2.2"), "b/replacer"), + (Some("3.0"), "c/c"), + ]; + + for (expected, name) in cases { + assert_eq!( + expected.map(|s| s.to_string()), + InstalledVersions::get_pretty_version(name).unwrap() + ); + } } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_version_out_of_bounds() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + assert!(InstalledVersions::get_version("not/installed").is_err()); } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_root_package() { - let _root = set_up(); - todo!() + let (_root, dir) = set_up(); + + let expected = { + let mut m = IndexMap::new(); + m.insert("name".to_string(), s("__root__")); + m.insert("pretty_version".to_string(), s("dev-master")); + m.insert("version".to_string(), s("dev-master")); + m.insert("reference".to_string(), s("sourceref-by-default")); + m.insert("type".to_string(), s("library")); + m.insert("install_path".to_string(), s(&format!("{}/./", dir))); + m.insert("aliases".to_string(), list(vec![s("1.10.x-dev")])); + m.insert("dev".to_string(), PhpMixed::Bool(true)); + m + }; + + assert_eq!(expected, InstalledVersions::get_root_package()); } +#[ignore = "InstalledVersions::get_raw_data not ported (only get_all_raw_data exists)"] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_raw_data() { let _root = set_up(); todo!() } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_reference() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let cases: Vec<(Option<&str>, &str)> = vec![ + (Some("sourceref-by-default"), "__root__"), + (None, "foo/impl"), + (None, "foo/impl2"), + (None, "foo/replaced"), + (Some("distref-as-no-source"), "a/provider"), + (Some("distref-as-installed-from-dist"), "a/provider2"), + (None, "b/replacer"), + (None, "c/c"), + ]; + + for (expected, name) in cases { + assert_eq!( + expected.map(|s| s.to_string()), + InstalledVersions::get_reference(name).unwrap() + ); + } } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_installed_packages_by_type() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + let names = vec![ + "__root__".to_string(), + "a/provider".to_string(), + "a/provider2".to_string(), + "b/replacer".to_string(), + "c/c".to_string(), + ]; + + assert_eq!( + names, + InstalledVersions::get_installed_packages_by_type("library") + ); } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_get_install_path() { - let _root = set_up(); - todo!() + let (_root, dir) = set_up(); + + assert_eq!( + realpath(&dir), + realpath( + &InstalledVersions::get_install_path("__root__") + .unwrap() + .unwrap() + ) + ); + assert_eq!( + Some("/foo/bar/vendor/c/c".to_string()), + InstalledVersions::get_install_path("c/c").unwrap() + ); + assert_eq!( + None, + InstalledVersions::get_install_path("foo/impl").unwrap() + ); } +#[ignore] #[test] -#[ignore = "needs reflection into ClassLoader::registeredLoaders and installed.php fixtures (not ported)"] fn test_with_class_loader_loaded() { - let _root = set_up(); - todo!() + let (_root, _dir) = set_up(); + + // The reflection into ClassLoader::registeredLoaders is not ported; installedIsLocalDir is + // toggled directly via the exposed setter to mirror the PHP reflection on it. + InstalledVersions::set_installed_is_local_dir(true); + + assert!(!InstalledVersions::is_installed("foo/bar", true)); + + let reload_data = { + let mut m = IndexMap::new(); + m.insert( + "root".to_string(), + PhpMixed::Array(InstalledVersions::get_root_package()), + ); + m.insert( + "versions".to_string(), + arr(vec![( + "foo/bar", + arr(vec![ + ("version", s("1.0.0")), + ("dev_requirement", PhpMixed::Bool(false)), + ]), + )]), + ); + m + }; + InstalledVersions::reload(reload_data); + assert!(InstalledVersions::is_installed("foo/bar", true)); } |
