From 822d9a872807a92a5337ee8b7bab96dc9845cdbb Mon Sep 17 00:00:00 2001 From: nsfisis Date: Mon, 22 Jun 2026 02:09:59 +0900 Subject: test: port more test cases Co-Authored-By: Claude Opus 4.8 (1M context) --- .../tests/repository/filesystem_repository_test.rs | 144 +++++++++++++++++++-- 1 file changed, 134 insertions(+), 10 deletions(-) (limited to 'crates/shirabe/tests/repository/filesystem_repository_test.rs') diff --git a/crates/shirabe/tests/repository/filesystem_repository_test.rs b/crates/shirabe/tests/repository/filesystem_repository_test.rs index a14804b..ae6e4ef 100644 --- a/crates/shirabe/tests/repository/filesystem_repository_test.rs +++ b/crates/shirabe/tests/repository/filesystem_repository_test.rs @@ -1,37 +1,161 @@ //! ref: composer/tests/Composer/Test/Repository/FilesystemRepositoryTest.php +use indexmap::IndexMap; +use shirabe::installed_versions::InstalledVersions; +use shirabe::json::json_file::JsonFile; +use shirabe::repository::RepositoryInterface; +use shirabe::repository::filesystem_repository::FilesystemRepository; +use shirabe_php_shim::PhpMixed; + +/// PHP mocks JsonFile::read()/exists(); without a mocking framework the canned read value is +/// materialized as a real temp file whose decoded JSON reproduces the mock return value exactly. +fn create_temp_json_file(contents: &str) -> String { + let mut path = std::env::temp_dir(); + let unique = format!( + "shirabe_filesystemrepositorytest_{}_{}", + std::process::id(), + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() + ); + path.push(unique); + std::fs::write(&path, contents.as_bytes()).unwrap(); + path.to_str().unwrap().to_string() +} + +#[ignore] #[test] -#[ignore = "test body not yet ported (todo!() stub)"] fn test_repository_read() { - todo!() + let path = create_temp_json_file( + r#"[{"name": "package1", "version": "1.0.0-beta", "type": "vendor"}]"#, + ); + let json = JsonFile::new(path, None, None).unwrap(); + + let mut repository = FilesystemRepository::new(json, false, None, None).unwrap(); + + let packages = repository.get_packages().unwrap(); + + assert_eq!(packages.len(), 1); + assert_eq!(packages[0].get_name(), "package1"); + assert_eq!(packages[0].get_version(), "1.0.0.0-beta"); + assert_eq!(packages[0].get_type(), "vendor"); } +#[ignore] #[test] -#[ignore = "test body not yet ported (todo!() stub)"] fn test_corrupted_repository_file() { - todo!() + // PHP mocks read() to return the scalar string 'foo'; a real file containing the JSON string + // "foo" decodes to the same value, which the repository rejects as a non-array package list. + let path = create_temp_json_file(r#""foo""#); + let json = JsonFile::new(path, None, None).unwrap(); + + let mut repository = FilesystemRepository::new(json, false, None, None).unwrap(); + + let result = repository.get_packages(); + let err = result.unwrap_err(); + assert!( + err.is::(), + "expected InvalidRepositoryException, got: {err}" + ); } +#[ignore] #[test] -#[ignore = "test body not yet ported (todo!() stub)"] fn test_unexistent_repository_file() { - todo!() + let mut path = std::env::temp_dir(); + path.push(format!( + "shirabe_filesystemrepositorytest_missing_{}_{}", + std::process::id(), + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() + )); + let json = JsonFile::new(path.to_str().unwrap().to_string(), None, None).unwrap(); + + let mut repository = FilesystemRepository::new(json, false, None, None).unwrap(); + + let packages = repository.get_packages().unwrap(); + assert_eq!(packages.len(), 0); } #[test] -#[ignore = "test body not yet ported (todo!() stub)"] +#[ignore = "requires mocking InstallationManager::get_install_path; write() takes a concrete InstallationManager with no trait/seam to stub the canned per-package paths the PHP test relies on"] fn test_repository_write() { todo!() } #[test] -#[ignore = "test body not yet ported (todo!() stub)"] +#[ignore = "requires mocking InstallationManager::get_install_path (concrete method, no stub seam) plus missing test helpers get_root_package and configure_links"] fn test_repository_writes_installed_php() { todo!() } +#[ignore] #[test] -#[ignore = "test body not yet ported (todo!() stub)"] fn test_safely_load_installed_versions() { - todo!() + let fixtures_dir = format!( + "{}/../../composer/tests/Composer/Test/Repository/Fixtures", + env!("CARGO_MANIFEST_DIR") + ); + let path = format!("{}/installed_complex.php", fixtures_dir); + + let result = FilesystemRepository::safely_load_installed_versions(&path); + assert!(result, "The file should be considered valid"); + + let raw_data = InstalledVersions::get_all_raw_data(); + let raw_data = raw_data.last().cloned().unwrap(); + + let mut root: IndexMap = IndexMap::new(); + root.insert( + "install_path".to_string(), + PhpMixed::String(format!("{}/./", fixtures_dir)), + ); + root.insert( + "aliases".to_string(), + PhpMixed::List(vec![ + PhpMixed::String("1.10.x-dev".to_string()), + PhpMixed::String("2.10.x-dev".to_string()), + ]), + ); + root.insert("name".to_string(), PhpMixed::String("__root__".to_string())); + root.insert("true".to_string(), PhpMixed::Bool(true)); + root.insert("false".to_string(), PhpMixed::Bool(false)); + root.insert("null".to_string(), PhpMixed::Null); + + let mut a_provider: IndexMap = IndexMap::new(); + a_provider.insert( + "foo".to_string(), + PhpMixed::String("simple string/no backslash".to_string()), + ); + a_provider.insert( + "install_path".to_string(), + PhpMixed::String(format!( + "{}/vendor/{{${{passthru('bash -i')}}}}", + fixtures_dir + )), + ); + a_provider.insert("empty array".to_string(), PhpMixed::List(vec![])); + + let mut c_c: IndexMap = IndexMap::new(); + c_c.insert( + "install_path".to_string(), + PhpMixed::String("/foo/bar/ven/do{}r/c/c${}".to_string()), + ); + c_c.insert("aliases".to_string(), PhpMixed::List(vec![])); + c_c.insert( + "reference".to_string(), + PhpMixed::String("{${passthru('bash -i')}} Foo\\Bar\n\ttab\u{0b}verticaltab\0".to_string()), + ); + + let mut versions: IndexMap = IndexMap::new(); + versions.insert("a/provider".to_string(), PhpMixed::Array(a_provider)); + versions.insert("c/c".to_string(), PhpMixed::Array(c_c)); + + let mut expected: IndexMap = IndexMap::new(); + expected.insert("root".to_string(), PhpMixed::Array(root)); + expected.insert("versions".to_string(), PhpMixed::Array(versions)); + + assert_eq!(raw_data, expected); } -- cgit v1.3.1