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/repository | |
| 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/repository')
16 files changed, 508 insertions, 116 deletions
diff --git a/crates/shirabe/tests/repository/artifact_repository_test.rs b/crates/shirabe/tests/repository/artifact_repository_test.rs index 5e70650..14475da 100644 --- a/crates/shirabe/tests/repository/artifact_repository_test.rs +++ b/crates/shirabe/tests/repository/artifact_repository_test.rs @@ -13,21 +13,21 @@ fn set_up() { } #[test] -#[ignore = "ArtifactRepository reads archives via ZipArchive/PharData, which are todo!() in the php-shim"] +#[ignore = "ArtifactRepository exposes no public get_packages(); it does not impl RepositoryInterface and initialize/scan_directory are private"] fn test_extracts_configs_from_zip_archives() { set_up(); todo!() } #[test] -#[ignore = "ArtifactRepository reads archives via ZipArchive/PharData, which are todo!() in the php-shim"] +#[ignore = "ArtifactRepository exposes no public get_packages(); it does not impl RepositoryInterface and initialize/scan_directory are private"] fn test_absolute_repo_url_creates_absolute_url_packages() { set_up(); todo!() } #[test] -#[ignore = "ArtifactRepository reads archives via ZipArchive/PharData, which are todo!() in the php-shim"] +#[ignore = "ArtifactRepository exposes no public get_packages(); it does not impl RepositoryInterface and initialize/scan_directory are private"] fn test_relative_repo_url_creates_relative_url_packages() { set_up(); todo!() diff --git a/crates/shirabe/tests/repository/composer_repository_test.rs b/crates/shirabe/tests/repository/composer_repository_test.rs index f600a55..d36c2e1 100644 --- a/crates/shirabe/tests/repository/composer_repository_test.rs +++ b/crates/shirabe/tests/repository/composer_repository_test.rs @@ -3,56 +3,56 @@ // These construct a ComposerRepository with a mocked HttpDownloader/IO/Config and parse // provider/package data whose constraints go through a look-around regex; mocking is not // available and a real HttpDownloader reaches curl_multi_init (todo!()). +#[ignore = "needs PHPUnit getMockBuilder to override loadRootServerFile; no method-mocking framework ported"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_load_data() { todo!() } +#[ignore = "needs getMockBuilder to override fetchFile plus ReflectionProperty/ReflectionMethod to set private props and invoke whatProvides; no mocking/reflection ported"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_what_provides() { todo!() } +#[ignore = "needs getHttpDownloaderMock test helper (HttpDownloaderMock not ported); real HttpDownloader hits todo!() curl I/O"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_search_with_type() { todo!() } +#[ignore = "needs getHttpDownloaderMock test helper (HttpDownloaderMock not ported); real HttpDownloader hits todo!() curl I/O"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_search_with_special_chars() { todo!() } +#[ignore = "needs getHttpDownloaderMock test helper (HttpDownloaderMock not ported); real HttpDownloader hits todo!() curl I/O"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_search_with_abandoned_packages() { todo!() } +#[ignore = "needs getMockBuilder HttpDownloader mock plus ReflectionObject getMethod/getProperty to set private url and invoke canonicalizeUrl; no mocking/reflection ported"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_canonicalize_url() { todo!() } +#[ignore = "needs getHttpDownloaderMock test helper (HttpDownloaderMock not ported); real HttpDownloader hits todo!() curl I/O"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_get_provider_names_will_return_partial_package_names() { todo!() } +#[ignore = "needs getHttpDownloaderMock test helper (HttpDownloaderMock not ported); real HttpDownloader hits todo!() curl I/O"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_get_security_advisories_assert_repository_http_options_are_used() { todo!() } +#[ignore = "needs getHttpDownloaderMock test helper (HttpDownloaderMock not ported); real HttpDownloader hits todo!() curl I/O"] #[test] -#[ignore = "mocks HttpDownloader/IO (curl_multi_init todo!()) and parses constraints via a look-around regex"] fn test_get_security_advisories_assert_repository_advisories_is_zero_indexed_array_with_consecutive_keys() { todo!() 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::<shirabe::repository::InvalidRepositoryException>(), + "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<String, PhpMixed> = 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<String, PhpMixed> = 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<String, PhpMixed> = 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<String, PhpMixed> = 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<String, PhpMixed> = IndexMap::new(); + expected.insert("root".to_string(), PhpMixed::Array(root)); + expected.insert("versions".to_string(), PhpMixed::Array(versions)); + + assert_eq!(raw_data, expected); } diff --git a/crates/shirabe/tests/repository/path_repository_test.rs b/crates/shirabe/tests/repository/path_repository_test.rs index c2e8e72..c2cf892 100644 --- a/crates/shirabe/tests/repository/path_repository_test.rs +++ b/crates/shirabe/tests/repository/path_repository_test.rs @@ -5,50 +5,50 @@ // ported, so there is no way to drive these tests. The unversioned cases additionally // require the VersionGuesser (git). +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_load_package_from_file_system_with_incorrect_path() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_load_package_from_file_system_with_version() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_load_package_from_file_system_without_version() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_load_package_from_file_system_with_wildcard() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_load_package_with_explicit_versions() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_url_remains_relative() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_reference_none() { todo!() } +#[ignore = "PathRepository exposes no public RepositoryInterface::get_packages/count/has_package; the inner ArrayRepository delegation is not ported"] #[test] -#[ignore = "PathRepository exposes no public getPackages/count/hasPackage (RepositoryInterface delegation not ported)"] fn test_reference_config() { todo!() } diff --git a/crates/shirabe/tests/repository/platform_repository_test.rs b/crates/shirabe/tests/repository/platform_repository_test.rs index d19b615..fb84fd6 100644 --- a/crates/shirabe/tests/repository/platform_repository_test.rs +++ b/crates/shirabe/tests/repository/platform_repository_test.rs @@ -1,40 +1,71 @@ //! ref: composer/tests/Composer/Test/Repository/PlatformRepositoryTest.php +use shirabe::repository::PlatformRepository; + // These probe runtime/extension/library versions and assert the synthesized platform // packages; the detection mocks ProcessExecutor/Runtime/HhvmDetector and the package // versions are parsed through a look-around regex. #[test] -#[ignore = "not yet ported (platform detection mocks Runtime/ProcessExecutor; version parsing uses a look-around regex)"] +#[ignore = "requires PHPUnit getMockBuilder mock of Composer\\Platform\\HhvmDetector (willReturn getVersion); Runtime/HhvmDetector are concrete structs with no mock/override mechanism"] fn test_hhvm_package() { todo!() } #[test] -#[ignore = "not yet ported (platform detection mocks Runtime/ProcessExecutor; version parsing uses a look-around regex)"] +#[ignore = "requires PHPUnit getMockBuilder mock of Composer\\Platform\\Runtime (willReturnCallback/willReturnMap for hasConstant/getConstant/invoke/getExtensions); no mocking framework and Runtime is a concrete struct"] fn test_php_version() { todo!() } #[test] -#[ignore = "not yet ported (platform detection mocks Runtime/ProcessExecutor; version parsing uses a look-around regex)"] +#[ignore = "requires PHPUnit getMockBuilder mock of Composer\\Platform\\Runtime (expects(once)/with/willReturn for invoke, willReturnCallback for getConstant); no mocking framework"] fn test_inet_pton_regression() { todo!() } #[test] -#[ignore = "not yet ported (platform detection mocks Runtime/ProcessExecutor; version parsing uses a look-around regex)"] +#[ignore = "requires PHPUnit getMockBuilder mock of Composer\\Platform\\Runtime (willReturnMap/willReturnCallback for getExtensions/getExtensionVersion/getExtensionInfo/invoke/hasConstant/getConstant/hasClass/construct) plus ResourceBundleStub/ImagickStub; no mocking framework"] fn test_library_information() { todo!() } #[test] -#[ignore = "not yet ported (platform detection mocks Runtime/ProcessExecutor; version parsing uses a look-around regex)"] +#[ignore = "requires PHPUnit getMockBuilder mock of Composer\\Platform\\Runtime (willReturnMap for getConstant/getExtensions); no mocking framework and Runtime is a concrete struct"] fn test_composer_platform_version() { todo!() } #[test] -#[ignore = "not yet ported (platform detection mocks Runtime/ProcessExecutor; version parsing uses a look-around regex)"] +#[ignore] fn test_valid_platform_packages() { - todo!() + let cases: Vec<(&str, bool)> = vec![ + ("php", true), + ("php-debug", true), + ("php-ipv6", true), + ("php-64bit", true), + ("php-zts", true), + ("hhvm", true), + ("hhvm-foo", false), + ("ext-foo", true), + ("ext-123", true), + ("extfoo", false), + ("ext", false), + ("lib-foo", true), + ("lib-123", true), + ("libfoo", false), + ("lib", false), + ("composer", true), + ("composer-foo", false), + ("composer-plugin-api", true), + ("composer-plugin", false), + ("composer-runtime-api", true), + ("composer-runtime", false), + ]; + + for (package_name, expectation) in cases { + assert_eq!( + expectation, + PlatformRepository::is_platform_package(package_name) + ); + } } diff --git a/crates/shirabe/tests/repository/repository_factory_test.rs b/crates/shirabe/tests/repository/repository_factory_test.rs index 98e2c85..a0eb81f 100644 --- a/crates/shirabe/tests/repository/repository_factory_test.rs +++ b/crates/shirabe/tests/repository/repository_factory_test.rs @@ -5,7 +5,7 @@ use shirabe::repository::RepositoryFactory; use shirabe_php_shim::PhpMixed; #[test] -#[ignore = "mocks IO/Config/HttpDownloader/EventDispatcher and reads the private repositoryClasses via reflection; not portable"] +#[ignore = "PHP test uses ReflectionProperty to read the private RepositoryManager::repository_classes field; no public accessor for repository_classes keys exists in the Rust impl"] fn test_manager_with_all_repository_types() { todo!() } diff --git a/crates/shirabe/tests/repository/repository_manager_test.rs b/crates/shirabe/tests/repository/repository_manager_test.rs index dec018a..bb85d6a 100644 --- a/crates/shirabe/tests/repository/repository_manager_test.rs +++ b/crates/shirabe/tests/repository/repository_manager_test.rs @@ -4,7 +4,17 @@ // curl_multi_init, todo!()) with a mocked IO/Config/EventDispatcher and exercise repo // creation/prepending/wrapping. +use std::cell::RefCell; +use std::rc::Rc; + +use indexmap::IndexMap; +use shirabe::config::Config; +use shirabe::io::IOInterface; +use shirabe::io::null_io::NullIO; +use shirabe::repository::{ArrayRepository, RepositoryInterfaceHandle, RepositoryManager}; use shirabe::util::filesystem::Filesystem; +use shirabe::util::http_downloader::HttpDownloader; +use shirabe_php_shim::PhpMixed; use tempfile::TempDir; struct SetUp { @@ -39,32 +49,171 @@ impl Drop for TearDown { } } +fn null_io() -> Rc<RefCell<dyn IOInterface>> { + Rc::new(RefCell::new(NullIO::new())) +} + +fn http_downloader(io: &Rc<RefCell<dyn IOInterface>>) -> Rc<RefCell<HttpDownloader>> { + let config = Rc::new(RefCell::new(Config::new(false, None))); + Rc::new(RefCell::new(HttpDownloader::new( + io.clone(), + config, + IndexMap::new(), + true, + ))) +} + +fn str_config(pairs: &[(&str, PhpMixed)]) -> IndexMap<String, PhpMixed> { + let mut c: IndexMap<String, PhpMixed> = IndexMap::new(); + for (k, v) in pairs { + c.insert(k.to_string(), v.clone()); + } + c +} + #[test] -#[ignore = "RepositoryManager::new builds an HttpDownloader (curl_multi_init todo!()) and mocks IO/Config"] +#[ignore] fn test_prepend() { let SetUp { tmpdir } = set_up(); let _tear_down = TearDown::new(tmpdir.path().to_path_buf()); - todo!() + + let io = null_io(); + let config = Rc::new(RefCell::new(Config::new(false, None))); + let mut rm = RepositoryManager::new(io.clone(), config, http_downloader(&io), None, None); + + let repository1 = RepositoryInterfaceHandle::new(ArrayRepository::new(vec![]).unwrap()); + let repository2 = RepositoryInterfaceHandle::new(ArrayRepository::new(vec![]).unwrap()); + rm.add_repository(repository1.clone()); + rm.prepend_repository(repository2.clone()); + + assert_eq!(&vec![repository2, repository1], rm.get_repositories()); } #[test] -#[ignore = "RepositoryManager::new builds an HttpDownloader (curl_multi_init todo!()) and mocks IO/Config"] +#[ignore] fn test_repo_creation() { let SetUp { tmpdir } = set_up(); let _tear_down = TearDown::new(tmpdir.path().to_path_buf()); - todo!() + + let io = null_io(); + let config = Rc::new(RefCell::new(Config::new(false, None))); + let mut rm = + RepositoryManager::new(io.clone(), config.clone(), http_downloader(&io), None, None); + + config.borrow_mut().merge( + &str_config(&[( + "config", + PhpMixed::Array(str_config(&[( + "cache-repo-dir", + PhpMixed::String(tmpdir.path().to_string_lossy().to_string()), + )])), + )]), + "unknown", + ); + + rm.set_repository_class("composer", "Composer\\Repository\\ComposerRepository"); + rm.set_repository_class("vcs", "Composer\\Repository\\VcsRepository"); + rm.set_repository_class("package", "Composer\\Repository\\PackageRepository"); + rm.set_repository_class("pear", "Composer\\Repository\\PearRepository"); + rm.set_repository_class("git", "Composer\\Repository\\VcsRepository"); + rm.set_repository_class("svn", "Composer\\Repository\\VcsRepository"); + rm.set_repository_class("perforce", "Composer\\Repository\\VcsRepository"); + rm.set_repository_class("hg", "Composer\\Repository\\VcsRepository"); + rm.set_repository_class("artifact", "Composer\\Repository\\ArtifactRepository"); + + let cases: Vec<(&str, IndexMap<String, PhpMixed>)> = vec![ + ( + "composer", + str_config(&[("url", PhpMixed::String("http://example.org".to_string()))]), + ), + ( + "vcs", + str_config(&[( + "url", + PhpMixed::String("http://github.com/foo/bar".to_string()), + )]), + ), + ( + "git", + str_config(&[( + "url", + PhpMixed::String("http://github.com/foo/bar".to_string()), + )]), + ), + ( + "git", + str_config(&[( + "url", + PhpMixed::String("git@example.org:foo/bar.git".to_string()), + )]), + ), + ( + "svn", + str_config(&[( + "url", + PhpMixed::String("svn://example.org/foo/bar".to_string()), + )]), + ), + ( + "package", + str_config(&[("package", PhpMixed::Array(IndexMap::new()))]), + ), + ( + "artifact", + str_config(&[("url", PhpMixed::String("/path/to/zips".to_string()))]), + ), + ]; + + for (r#type, options) in cases { + rm.create_repository( + "composer", + str_config(&[("url", PhpMixed::String("http://example.org".to_string()))]), + None, + ) + .unwrap(); + rm.create_repository(r#type, options, None).unwrap(); + } } #[test] -#[ignore = "RepositoryManager::new builds an HttpDownloader (curl_multi_init todo!()) and mocks IO/Config"] +#[ignore] fn test_invalid_repo_creation_throws() { let SetUp { tmpdir } = set_up(); let _tear_down = TearDown::new(tmpdir.path().to_path_buf()); - todo!() + + let io = null_io(); + let config = Rc::new(RefCell::new(Config::new(false, None))); + let rm = RepositoryManager::new(io.clone(), config.clone(), http_downloader(&io), None, None); + + config.borrow_mut().merge( + &str_config(&[( + "config", + PhpMixed::Array(str_config(&[( + "cache-repo-dir", + PhpMixed::String(tmpdir.path().to_string_lossy().to_string()), + )])), + )]), + "unknown", + ); + + let cases: Vec<(&str, IndexMap<String, PhpMixed>)> = vec![ + ( + "pear", + str_config(&[( + "url", + PhpMixed::String("http://pear.example.org/foo".to_string()), + )]), + ), + ("invalid", IndexMap::new()), + ]; + + for (r#type, options) in cases { + assert!(rm.create_repository(r#type, options, None).is_err()); + } } #[test] -#[ignore = "RepositoryManager::new builds an HttpDownloader (curl_multi_init todo!()) and mocks IO/Config"] +#[ignore = "PathRepository does not implement RepositoryInterface (only ConfigurableRepositoryInterface), so it cannot live inside a RepositoryInterfaceHandle nor be recovered via as_any().downcast_ref::<PathRepository>(); the assertInstanceOf(PathRepository) check is unportable"] fn test_filter_repo_wrapping() { let SetUp { tmpdir } = set_up(); let _tear_down = TearDown::new(tmpdir.path().to_path_buf()); diff --git a/crates/shirabe/tests/repository/vcs/forgejo_driver_test.rs b/crates/shirabe/tests/repository/vcs/forgejo_driver_test.rs index a67bce3..0836fc5 100644 --- a/crates/shirabe/tests/repository/vcs/forgejo_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/forgejo_driver_test.rs @@ -93,7 +93,7 @@ fn test_supports() { // Forgejo API responses; mocking is not available, and a real HttpDownloader reaches // curl_multi_init (todo!()). #[test] -#[ignore = "constructs a ForgejoDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_public_repository() { let SetUp { home, @@ -107,7 +107,7 @@ fn test_public_repository() { } #[test] -#[ignore = "constructs a ForgejoDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_get_branches() { let SetUp { home, @@ -121,7 +121,7 @@ fn test_get_branches() { } #[test] -#[ignore = "constructs a ForgejoDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_get_tags() { let SetUp { home, @@ -135,7 +135,7 @@ fn test_get_tags() { } #[test] -#[ignore = "constructs a ForgejoDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_get_empty_file_content() { let SetUp { home, diff --git a/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs b/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs index b6759b5..2fedba1 100644 --- a/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs @@ -103,7 +103,7 @@ fn test_supports() { // Bitbucket API responses; mocking is not available, and a real HttpDownloader reaches // curl_multi_init (todo!()). #[test] -#[ignore = "constructs a GitBitbucketDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "needs IOInterface mock (getMockBuilder) and getHttpDownloaderMock/HttpDownloaderMock (not ported); set_up()'s io and http_downloader are todo!() and real HttpDownloader hits todo!() curl I/O"] fn test_get_root_identifier_wrong_scm_type() { let SetUp { home, @@ -116,7 +116,7 @@ fn test_get_root_identifier_wrong_scm_type() { } #[test] -#[ignore = "constructs a GitBitbucketDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "needs IOInterface mock (getMockBuilder) and getHttpDownloaderMock/HttpDownloaderMock (not ported); set_up()'s io and http_downloader are todo!() and real HttpDownloader hits todo!() curl I/O"] fn test_driver() { let SetUp { home, @@ -129,7 +129,7 @@ fn test_driver() { } #[test] -#[ignore = "constructs a GitBitbucketDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "needs IOInterface mock (getMockBuilder) and getHttpDownloaderMock/HttpDownloaderMock (not ported); depends on test_driver's driver and set_up()'s todo!() mocks"] fn test_get_params() { let SetUp { home, @@ -142,7 +142,7 @@ fn test_get_params() { } #[test] -#[ignore = "constructs a GitBitbucketDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "needs IOInterface mock (getMockBuilder) and getHttpDownloaderMock/HttpDownloaderMock (not ported); set_up()'s io and http_downloader are todo!()"] fn test_initialize_invalid_repository_url() { let SetUp { home, @@ -155,7 +155,7 @@ fn test_initialize_invalid_repository_url() { } #[test] -#[ignore = "constructs a GitBitbucketDriver and mocks the HttpDownloader (curl_multi_init todo!())"] +#[ignore = "needs IOInterface mock (getMockBuilder) and getHttpDownloaderMock/HttpDownloaderMock (not ported); set_up()'s io and http_downloader are todo!() and real HttpDownloader hits todo!() curl I/O"] fn test_invalid_support_data() { let SetUp { home, diff --git a/crates/shirabe/tests/repository/vcs/git_driver_test.rs b/crates/shirabe/tests/repository/vcs/git_driver_test.rs index 1aacbf9..56c2755 100644 --- a/crates/shirabe/tests/repository/vcs/git_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/git_driver_test.rs @@ -64,7 +64,7 @@ impl Drop for TearDown { } #[test] -#[ignore = "constructs a GitDriver and mocks a ProcessExecutor/HttpDownloader (curl_multi_init todo!())"] +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock/expects) and Reflection setRepoDir, neither available"] fn test_get_root_identifier_from_remote_local_repository() { let SetUp { home, @@ -76,7 +76,7 @@ fn test_get_root_identifier_from_remote_local_repository() { } #[test] -#[ignore = "constructs a GitDriver and mocks a ProcessExecutor/HttpDownloader (curl_multi_init todo!())"] +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock/expects), IO mock and Reflection setRepoDir, none available"] fn test_get_root_identifier_from_remote() { let SetUp { home, @@ -88,7 +88,7 @@ fn test_get_root_identifier_from_remote() { } #[test] -#[ignore = "constructs a GitDriver and mocks a ProcessExecutor/HttpDownloader (curl_multi_init todo!())"] +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock/expects) and Reflection setRepoDir, neither available"] fn test_get_root_identifier_from_local_with_network_disabled() { let SetUp { home, @@ -100,7 +100,7 @@ fn test_get_root_identifier_from_local_with_network_disabled() { } #[test] -#[ignore = "constructs a GitDriver and mocks a ProcessExecutor/HttpDownloader (curl_multi_init todo!())"] +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock/expects), IOInterface mock and Reflection setRepoDir, none available"] fn test_get_branches_filter_invalid_branch_names() { let SetUp { home, @@ -112,7 +112,7 @@ fn test_get_branches_filter_invalid_branch_names() { } #[test] -#[ignore = "constructs a GitDriver and mocks a ProcessExecutor/HttpDownloader (curl_multi_init todo!())"] +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock) and IOInterface/HttpDownloader mocks, none available"] fn test_file_get_content_invalid_identifier() { let SetUp { home, @@ -124,7 +124,7 @@ fn test_file_get_content_invalid_identifier() { } #[test] -#[ignore = "constructs a GitDriver and mocks a ProcessExecutor/HttpDownloader (curl_multi_init todo!())"] +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock) and IOInterface/HttpDownloader mocks, none available"] fn test_get_change_date_invalid_identifier() { let SetUp { home, diff --git a/crates/shirabe/tests/repository/vcs/github_driver_test.rs b/crates/shirabe/tests/repository/vcs/github_driver_test.rs index 3e97599..5313c0b 100644 --- a/crates/shirabe/tests/repository/vcs/github_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/github_driver_test.rs @@ -84,7 +84,7 @@ fn test_supports() { // GitHub API responses; mocking is not available, and a real HttpDownloader reaches // curl_multi_init (todo!()). #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, the IOInterface MockObject (askAndHideAnswer/setAuthentication), and setAttribute reflection are not ported"] fn test_private_repository() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -92,7 +92,7 @@ fn test_private_repository() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, the IOInterface MockObject, and setAttribute reflection are not ported"] fn test_public_repository() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -100,7 +100,7 @@ fn test_public_repository() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, the IOInterface MockObject, and setAttribute reflection are not ported"] fn test_public_repository2() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -108,7 +108,7 @@ fn test_public_repository2() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, the IOInterface MockObject, and setAttribute reflection are not ported"] fn test_invalid_support_data() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -116,7 +116,7 @@ fn test_invalid_support_data() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, the IOInterface MockObject, setAttribute reflection, and the fundingUrlProvider data provider are not ported"] fn test_funding_format() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -124,7 +124,7 @@ fn test_funding_format() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, the IOInterface MockObject, and setAttribute reflection are not ported"] fn test_public_repository_archived() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -132,7 +132,7 @@ fn test_public_repository_archived() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, and the IOInterface MockObject are not ported"] fn test_private_repository_no_interaction() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -140,7 +140,7 @@ fn test_private_repository_no_interaction() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "IOInterface MockObject (getMockBuilder) and HttpDownloader MockObject (getMockBuilder) plus the invalidUrlProvider data provider are not ported"] fn test_initialize_invalid_repo_url() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -148,7 +148,7 @@ fn test_initialize_invalid_repo_url() { } #[test] -#[ignore = "constructs a GitHubDriver and mocks the HttpDownloader/IO (curl_multi_init todo!())"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock), ProcessExecutorMock, and the IOInterface MockObject are not ported"] fn test_get_empty_file_content() { let SetUp { home, config: _ } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); diff --git a/crates/shirabe/tests/repository/vcs/gitlab_driver_test.rs b/crates/shirabe/tests/repository/vcs/gitlab_driver_test.rs index 1e13ada..0333a2b 100644 --- a/crates/shirabe/tests/repository/vcs/gitlab_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/gitlab_driver_test.rs @@ -1,107 +1,177 @@ //! ref: composer/tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php -// All cases either mock the HttpDownloader/IO to return GitLab API responses (a real -// HttpDownloader reaches curl_multi_init, todo!()), or — for testSupports — rely on the -// gitlab-domains configured in setUp plus the openssl extension, which are not modeled. +use std::cell::RefCell; +use std::rc::Rc; + +use indexmap::IndexMap; +use shirabe::config::Config; +use shirabe::io::IOInterface; +use shirabe::io::null_io::NullIO; +use shirabe::repository::vcs::GitLabDriver; +use shirabe_php_shim::{PhpMixed, extension_loaded}; + +// Mirrors GitLabDriverTest::setUp's `gitlab-domains` configuration. +fn make_config() -> Config { + let mut config = Config::new(true, None); + let mut top: IndexMap<String, PhpMixed> = IndexMap::new(); + let mut config_section: IndexMap<String, PhpMixed> = IndexMap::new(); + config_section.insert( + "gitlab-domains".to_string(), + PhpMixed::List(vec![ + PhpMixed::String("mycompany.com/gitlab".to_string()), + PhpMixed::String("gitlab.mycompany.com".to_string()), + PhpMixed::String("othercompany.com/nested/gitlab".to_string()), + PhpMixed::String("gitlab.com".to_string()), + PhpMixed::String("gitlab.mycompany.local".to_string()), + ]), + ); + top.insert("config".to_string(), PhpMixed::Array(config_section)); + config.merge(&top, Config::SOURCE_UNKNOWN); + config +} #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_initialize() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_initialize_public_project() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_initialize_public_project_as_anonymous() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_initialize_with_port_number() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitialize, which needs HttpDownloaderMock + setAttribute (\\ReflectionProperty) not ported"] fn test_invalid_support_data() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitialize, which needs HttpDownloaderMock + the IOInterface MockObject not ported"] fn test_get_dist() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitialize, which needs HttpDownloaderMock + the IOInterface MockObject not ported"] fn test_get_source() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitializePublicProject, which needs HttpDownloaderMock + the IOInterface MockObject not ported"] fn test_get_source_given_public_project() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitialize, which needs HttpDownloaderMock + the IOInterface MockObject not ported"] fn test_get_tags() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitialize, which needs HttpDownloaderMock + the IOInterface MockObject not ported"] fn test_get_paginated_refs() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "depends on testInitialize, which needs HttpDownloaderMock + the IOInterface MockObject not ported"] fn test_get_branches() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore] fn test_supports() { - todo!() + for (url, expected) in data_for_test_supports() { + let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new())); + let config = Rc::new(RefCell::new(make_config())); + + assert_eq!( + expected, + GitLabDriver::supports(io, config, url, false).unwrap() + ); + } +} + +fn data_for_test_supports() -> Vec<(&'static str, bool)> { + let openssl = extension_loaded("openssl"); + vec![ + ("http://gitlab.com/foo/bar", true), + ("http://gitlab.mycompany.com:5443/foo/bar", true), + ("http://gitlab.com/foo/bar/", true), + ("http://gitlab.com/foo/bar/", true), + ("http://gitlab.com/foo/bar.git", true), + ("http://gitlab.com/foo/bar.git", true), + ("http://gitlab.com/foo/bar.baz.git", true), + ("https://gitlab.com/foo/bar", openssl), + ("https://gitlab.mycompany.com:5443/foo/bar", openssl), + ("git@gitlab.com:foo/bar.git", openssl), + ("git@example.com:foo/bar.git", false), + ("http://example.com/foo/bar", false), + ("http://mycompany.com/gitlab/mygroup/myproject", true), + ("https://mycompany.com/gitlab/mygroup/myproject", openssl), + ( + "http://othercompany.com/nested/gitlab/mygroup/myproject", + true, + ), + ( + "https://othercompany.com/nested/gitlab/mygroup/myproject", + openssl, + ), + ( + "http://gitlab.com/mygroup/mysubgroup/mysubsubgroup/myproject", + true, + ), + ( + "https://gitlab.com/mygroup/mysubgroup/mysubsubgroup/myproject", + openssl, + ), + ] } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_gitlab_sub_directory() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_gitlab_sub_group() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_gitlab_sub_directory_sub_group() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_forwards_options() { todo!() } #[test] -#[ignore = "GitLabDriver tests mock HttpDownloader/IO (curl_multi_init todo!()) or need setUp gitlab-domains config"] +#[ignore = "HttpDownloaderMock (getHttpDownloaderMock) and the IOInterface MockObject are not ported"] fn test_protocol_override_repository_url_generation() { todo!() } diff --git a/crates/shirabe/tests/repository/vcs/hg_driver_test.rs b/crates/shirabe/tests/repository/vcs/hg_driver_test.rs index 155d7ce..7b6f1e6 100644 --- a/crates/shirabe/tests/repository/vcs/hg_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/hg_driver_test.rs @@ -80,7 +80,7 @@ fn test_supports() { // (curl_multi_init is todo!() in the php-shim) and a mocked ProcessExecutor to feed // hg command output, neither of which is available here. #[test] -#[ignore = "needs an HgDriver instance (HttpDownloader reaches curl_multi_init, todo!()) and a mocked ProcessExecutor"] +#[ignore = "requires getProcessExecutorMock with expects() hg branches/bookmarks command-sequence assertions and a getMockBuilder HttpDownloader mock; no ProcessExecutorMock/HttpDownloader mocking infrastructure exists"] fn test_get_branches_filter_invalid_branch_names() { let SetUp { home, config, io } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -89,7 +89,7 @@ fn test_get_branches_filter_invalid_branch_names() { } #[test] -#[ignore = "needs an HgDriver instance (HttpDownloader reaches curl_multi_init, todo!()) and a mocked ProcessExecutor"] +#[ignore = "requires getProcessExecutorMock and a getMockBuilder HttpDownloader mock to construct HgDriver; no ProcessExecutorMock/HttpDownloader mocking infrastructure exists"] fn test_file_get_content_invalid_identifier() { let SetUp { home, config, io } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); @@ -98,7 +98,7 @@ fn test_file_get_content_invalid_identifier() { } #[test] -#[ignore = "needs an HgDriver instance (HttpDownloader reaches curl_multi_init, todo!()) and a mocked ProcessExecutor"] +#[ignore = "requires getProcessExecutorMock and a getMockBuilder HttpDownloader mock to construct HgDriver; no ProcessExecutorMock/HttpDownloader mocking infrastructure exists"] fn test_get_change_date_invalid_identifier() { let SetUp { home, config, io } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); diff --git a/crates/shirabe/tests/repository/vcs/perforce_driver_test.rs b/crates/shirabe/tests/repository/vcs/perforce_driver_test.rs index 1c28487..d9178dd 100644 --- a/crates/shirabe/tests/repository/vcs/perforce_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/perforce_driver_test.rs @@ -108,8 +108,8 @@ fn test_supports_returns_false_no_deep_check() { // The remaining cases mock Perforce, the repository config and IO to drive initialization, // composer-file detection and cleanup; mocking is not available here. +#[ignore] #[test] -#[ignore = "mocks Perforce/repository/IO; mocking is not available"] fn test_initialize_captures_variables_from_repo_config() { let SetUp { test_path, @@ -122,20 +122,29 @@ fn test_initialize_captures_variables_from_repo_config() { driver, } = set_up(); let _tear_down = TearDown::new(test_path.path().to_path_buf()); - let _ = ( - &config, - &repo_config, - &io, - &process, - &http_downloader, - &perforce, - &driver, - ); - todo!() + let _ = (&io, &process, &http_downloader, &perforce, &driver); + + let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new())); + let config = Rc::new(RefCell::new(config)); + let http_downloader = Rc::new(RefCell::new(shirabe::util::HttpDownloader::new( + io.clone(), + config.clone(), + IndexMap::new(), + false, + ))); + let process = Rc::new(RefCell::new(shirabe::util::ProcessExecutor::new(Some( + io.clone(), + )))); + + let mut driver = PerforceDriver::new(repo_config, io, config, http_downloader, process); + driver.initialize().unwrap(); + assert_eq!(TEST_URL, driver.get_url()); + assert_eq!(TEST_DEPOT, driver.get_depot()); + assert_eq!(TEST_BRANCH, driver.get_branch()); } +#[ignore = "needs a Perforce mock injected via reflection (overrideDriverInternalPerforce) to assert p4Login/checkStream/writeP4ClientSpec/connectClient are each called once; the perforce field is pub(crate) and no mock infra exists"] #[test] -#[ignore = "mocks Perforce/repository/IO; mocking is not available"] fn test_initialize_logs_in_and_connects_client() { let SetUp { test_path, @@ -160,8 +169,8 @@ fn test_initialize_logs_in_and_connects_client() { todo!() } +#[ignore = "needs a Perforce mock injected via reflection (overrideDriverInternalPerforce) to stub getComposerInformation; the perforce field is pub(crate) and no mock infra exists"] #[test] -#[ignore = "mocks Perforce/repository/IO; mocking is not available"] fn test_has_composer_file_returns_false_on_no_composer_file() { let SetUp { test_path, @@ -186,8 +195,8 @@ fn test_has_composer_file_returns_false_on_no_composer_file() { todo!() } +#[ignore = "needs a Perforce mock injected via reflection (overrideDriverInternalPerforce) to stub getComposerInformation; the perforce field is pub(crate) and no mock infra exists"] #[test] -#[ignore = "mocks Perforce/repository/IO; mocking is not available"] fn test_has_composer_file_returns_true_with_one_or_more_composer_files() { let SetUp { test_path, @@ -212,8 +221,8 @@ fn test_has_composer_file_returns_true_with_one_or_more_composer_files() { todo!() } +#[ignore = "needs a Perforce mock injected via reflection (overrideDriverInternalPerforce) to assert cleanupClientSpec is called once; the perforce field is pub(crate) and no mock infra exists"] #[test] -#[ignore = "mocks Perforce/repository/IO; mocking is not available"] fn test_cleanup() { let SetUp { test_path, diff --git a/crates/shirabe/tests/repository/vcs/svn_driver_test.rs b/crates/shirabe/tests/repository/vcs/svn_driver_test.rs index 9625088..5ec9097 100644 --- a/crates/shirabe/tests/repository/vcs/svn_driver_test.rs +++ b/crates/shirabe/tests/repository/vcs/svn_driver_test.rs @@ -77,8 +77,8 @@ fn test_support() { // Constructs an SvnDriver and runs an svn command via a mocked ProcessExecutor; mocking is // not available here. +#[ignore = "requires ProcessExecutor mock (getProcessExecutorMock/expects) and IOInterface/HttpDownloader mocks, none available"] #[test] -#[ignore = "constructs an SvnDriver and mocks a ProcessExecutor for the svn invocation"] fn test_wrong_credentials_in_url() { let SetUp { home, config } = set_up(); let _tear_down = TearDown::new(home.path().to_path_buf()); diff --git a/crates/shirabe/tests/repository/vcs_repository_test.rs b/crates/shirabe/tests/repository/vcs_repository_test.rs index c687b3d..d84ed51 100644 --- a/crates/shirabe/tests/repository/vcs_repository_test.rs +++ b/crates/shirabe/tests/repository/vcs_repository_test.rs @@ -1,6 +1,18 @@ //! ref: composer/tests/Composer/Test/Repository/VcsRepositoryTest.php +use std::cell::RefCell; +use std::rc::Rc; + +use indexmap::IndexMap; +use shirabe::config::Config; +use shirabe::io::IOInterface; +use shirabe::io::null_io::NullIO; +use shirabe::package::dumper::ArrayDumper; +use shirabe::repository::RepositoryInterface; +use shirabe::repository::VcsRepository; use shirabe::util::filesystem::Filesystem; +use shirabe::util::http_downloader::HttpDownloader; +use shirabe_php_shim::PhpMixed; struct SetUp { composer_home: std::path::PathBuf, @@ -42,14 +54,11 @@ impl Drop for TearDown { // testLoadVersions initialises a real git repository on disk and drives a VcsRepository over // it, then asserts the loaded package versions; the git fixture setup and constraint parsing -// (look-around regex) are not ported. +// (look-around regex) are not ported. In addition, VcsRepository does not implement +// RepositoryInterface and keeps its inner ArrayRepository pub(crate), so getPackages() (inherited +// from ArrayRepository in PHP) is not reachable from the test crate. #[test] -#[ignore = "not yet ported (initialises a git repo on disk and loads versions; constraint parsing uses a look-around regex)"] +#[ignore = "VcsRepository does not expose get_packages() to the test crate; git fixture setup not ported"] fn test_load_versions() { - let SetUp { - composer_home, - git_repo, - } = set_up(); - let _tear_down = TearDown::new(composer_home, git_repo); todo!() } |
