aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests/repository
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-22 02:09:59 +0900
committernsfisis <nsfisis@gmail.com>2026-06-22 02:09:59 +0900
commit822d9a872807a92a5337ee8b7bab96dc9845cdbb (patch)
tree4931365df5978caffade69cad2154718a9076f66 /crates/shirabe/tests/repository
parentf691b864b687f251c3b266e8cff2774d730567ba (diff)
downloadphp-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')
-rw-r--r--crates/shirabe/tests/repository/artifact_repository_test.rs6
-rw-r--r--crates/shirabe/tests/repository/composer_repository_test.rs18
-rw-r--r--crates/shirabe/tests/repository/filesystem_repository_test.rs144
-rw-r--r--crates/shirabe/tests/repository/path_repository_test.rs16
-rw-r--r--crates/shirabe/tests/repository/platform_repository_test.rs45
-rw-r--r--crates/shirabe/tests/repository/repository_factory_test.rs2
-rw-r--r--crates/shirabe/tests/repository/repository_manager_test.rs163
-rw-r--r--crates/shirabe/tests/repository/vcs/forgejo_driver_test.rs8
-rw-r--r--crates/shirabe/tests/repository/vcs/git_bitbucket_driver_test.rs10
-rw-r--r--crates/shirabe/tests/repository/vcs/git_driver_test.rs12
-rw-r--r--crates/shirabe/tests/repository/vcs/github_driver_test.rs18
-rw-r--r--crates/shirabe/tests/repository/vcs/gitlab_driver_test.rs112
-rw-r--r--crates/shirabe/tests/repository/vcs/hg_driver_test.rs6
-rw-r--r--crates/shirabe/tests/repository/vcs/perforce_driver_test.rs39
-rw-r--r--crates/shirabe/tests/repository/vcs/svn_driver_test.rs2
-rw-r--r--crates/shirabe/tests/repository/vcs_repository_test.rs23
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!()
}