aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests/downloader/archive_downloader_test.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-22 23:42:07 +0900
committernsfisis <nsfisis@gmail.com>2026-06-22 23:42:07 +0900
commit5ab5f3b316798c1411ce8e6a7f5b091fda93589c (patch)
treec7669f94f5d9bd9adc07bc1aab3f14cfdec1ae5f /crates/shirabe/tests/downloader/archive_downloader_test.rs
parentb291e714bc739262140323e08fe2fb9e91e00ee7 (diff)
downloadphp-shirabe-5ab5f3b316798c1411ce8e6a7f5b091fda93589c.tar.gz
php-shirabe-5ab5f3b316798c1411ce8e6a7f5b091fda93589c.tar.zst
php-shirabe-5ab5f3b316798c1411ce8e6a7f5b091fda93589c.zip
test: port previously-ignored Composer tests via __ test hatches
Re-evaluate the reason'd #[ignore] tests under the Phase D criterion: a test is unportable ONLY if the APIs/types needed to WRITE it do not exist. A test that compiles but panics at runtime (todo!() body, a regex the regex crate cannot compile) or fails at runtime (incomplete or incorrect impl behavior) is portable -- it is written in full and marked with a reason-less #[ignore]. About 120 test functions move from reason'd #[ignore] to reason-less #[ignore] (the ported-but-not-yet-passing signal). Impl crates gain only additive __ test hatches (init_command, pool, file_downloader, package handle link setters, artifact/path repository, repository manager, svn); no existing logic changes. Tests whose required APIs genuinely do not exist (mock/reflection harness, ApplicationTester, solve() discarding SolverProblemsException, a script::Event that cannot be passed as an originating event) keep their reason'd #[ignore]. cargo check -p shirabe --tests passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests/downloader/archive_downloader_test.rs')
-rw-r--r--crates/shirabe/tests/downloader/archive_downloader_test.rs163
1 files changed, 148 insertions, 15 deletions
diff --git a/crates/shirabe/tests/downloader/archive_downloader_test.rs b/crates/shirabe/tests/downloader/archive_downloader_test.rs
index dfba3bf..7062d48 100644
--- a/crates/shirabe/tests/downloader/archive_downloader_test.rs
+++ b/crates/shirabe/tests/downloader/archive_downloader_test.rs
@@ -1,41 +1,174 @@
//! ref: composer/tests/Composer/Test/Downloader/ArchiveDownloaderTest.php
-// These exercise getFileName/processUrl on an anonymous ArchiveDownloader subclass built
-// with a mocked IO and a real HttpDownloader (curl_multi_init is todo!()), and pass mocked
-// packages.
+// The PHP test builds an anonymous ArchiveDownloader subclass; getFileName/processUrl are
+// inherited unchanged from FileDownloader, so the concrete FileDownloader is exercised here
+// directly. The PHP mocks of IOInterface/Config/PackageInterface are replaced by a NullIO, a
+// real Config merged with `vendor-dir`, and real CompletePackage instances with dist
+// url/reference set.
+
+use std::cell::RefCell;
+use std::rc::Rc;
+
+use indexmap::IndexMap;
+use shirabe::config::Config;
+use shirabe::downloader::FileDownloader;
+use shirabe::io::IOInterface;
+use shirabe::io::null_io::NullIO;
+use shirabe::package::handle::{CompletePackageHandle, PackageInterfaceHandle};
+use shirabe::util::HttpDownloader;
+use shirabe_php_shim::PhpMixed;
+use shirabe_semver::version_parser::VersionParser;
+
+/// ref: TestCase::getPackage (default class CompletePackage)
+fn get_package(name: &str, version: &str) -> PackageInterfaceHandle {
+ let norm_version = VersionParser.normalize(version, None).unwrap();
+ CompletePackageHandle::new(name.to_string(), norm_version, version.to_string()).into()
+}
+
+/// ref: ArchiveDownloaderTest::getArchiveDownloaderMock (the inherited getFileName/processUrl
+/// live on FileDownloader, so the concrete downloader is built directly).
+fn get_archive_downloader(vendor_dir: Option<&str>) -> FileDownloader {
+ let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new()));
+
+ let mut config = Config::new(false, None);
+ if let Some(vendor_dir) = vendor_dir {
+ let mut config_options: IndexMap<String, PhpMixed> = IndexMap::new();
+ config_options.insert(
+ "vendor-dir".to_string(),
+ PhpMixed::String(vendor_dir.to_string()),
+ );
+ let mut merged: IndexMap<String, PhpMixed> = IndexMap::new();
+ merged.insert("config".to_string(), PhpMixed::Array(config_options));
+ config.merge(&merged, "test");
+ }
+ let config = Rc::new(RefCell::new(config));
+
+ let http_downloader = Rc::new(RefCell::new(HttpDownloader::new(
+ io.clone(),
+ config.clone(),
+ IndexMap::new(),
+ false,
+ )));
+
+ FileDownloader::new(io, config, http_downloader, None, None, None, None)
+}
#[test]
-#[ignore = "FileDownloader::get_file_name is pub(crate); not reachable from the integration test crate"]
+#[ignore]
fn test_get_file_name() {
- todo!()
+ let package = get_package("dummy/pkg", "1.0.0");
+ package.set_dist_url(Some("http://example.com/script.js".to_string()));
+
+ let downloader = get_archive_downloader(Some("/vendor"));
+
+ let first = downloader.__get_file_name(package.clone(), "/path");
+ let re = regex::Regex::new(r"/vendor/composer/tmp-[a-z0-9]+\.js").unwrap();
+ assert!(re.is_match(&first));
+ assert_eq!(first, downloader.__get_file_name(package, "/path"));
}
#[test]
-#[ignore = "FileDownloader::process_url is pub(crate); not reachable from the integration test crate"]
+#[ignore]
fn test_process_url() {
- todo!()
+ let downloader = get_archive_downloader(None);
+
+ let expected = "https://github.com/composer/composer/zipball/master";
+ let package = get_package("dummy/pkg", "1.0.0");
+ let url = downloader.__process_url(package, expected).unwrap();
+
+ assert_eq!(expected, url);
}
#[test]
-#[ignore = "FileDownloader::process_url is pub(crate); not reachable from the integration test crate"]
+#[ignore]
fn test_process_url2() {
- todo!()
+ let downloader = get_archive_downloader(None);
+
+ let expected = "https://github.com/composer/composer/archive/master.tar.gz";
+ let package = get_package("dummy/pkg", "1.0.0");
+ let url = downloader.__process_url(package, expected).unwrap();
+
+ assert_eq!(expected, url);
}
#[test]
-#[ignore = "FileDownloader::process_url is pub(crate); not reachable from the integration test crate"]
+#[ignore]
fn test_process_url3() {
- todo!()
+ let downloader = get_archive_downloader(None);
+
+ let expected = "https://api.github.com/repos/composer/composer/zipball/master";
+ let package = get_package("dummy/pkg", "1.0.0");
+ let url = downloader.__process_url(package, expected).unwrap();
+
+ assert_eq!(expected, url);
+}
+
+/// ref: ArchiveDownloaderTest::provideUrls
+fn provide_urls() -> Vec<&'static str> {
+ vec![
+ "https://api.github.com/repos/composer/composer/zipball/master",
+ "https://api.github.com/repos/composer/composer/tarball/master",
+ "https://github.com/composer/composer/zipball/master",
+ "https://www.github.com/composer/composer/tarball/master",
+ "https://github.com/composer/composer/archive/master.zip",
+ "https://github.com/composer/composer/archive/master.tar.gz",
+ ]
}
#[test]
-#[ignore = "FileDownloader::process_url is pub(crate); not reachable from the integration test crate"]
+#[ignore]
fn test_process_url_rewrite_dist() {
- todo!()
+ let downloader = get_archive_downloader(None);
+
+ for url in provide_urls() {
+ let r#type = if url.contains("tar") { "tar" } else { "zip" };
+ let expected = format!(
+ "https://api.github.com/repos/composer/composer/{}ball/ref",
+ r#type
+ );
+
+ let package = get_package("dummy/pkg", "1.0.0");
+ package.set_dist_reference(Some("ref".to_string()));
+ let url = downloader.__process_url(package, url).unwrap();
+
+ assert_eq!(expected, url);
+ }
+}
+
+/// ref: ArchiveDownloaderTest::provideBitbucketUrls
+fn provide_bitbucket_urls() -> Vec<(&'static str, &'static str)> {
+ vec![
+ (
+ "https://bitbucket.org/davereid/drush-virtualhost/get/77ca490c26ac818e024d1138aa8bd3677d1ef21f",
+ "zip",
+ ),
+ (
+ "https://bitbucket.org/davereid/drush-virtualhost/get/master",
+ "tar.gz",
+ ),
+ (
+ "https://bitbucket.org/davereid/drush-virtualhost/get/v1.0",
+ "tar.bz2",
+ ),
+ ]
}
#[test]
-#[ignore = "FileDownloader::process_url is pub(crate); not reachable from the integration test crate"]
+#[ignore]
fn test_process_url_rewrite_bitbucket_dist() {
- todo!()
+ let downloader = get_archive_downloader(None);
+
+ for (url, extension) in provide_bitbucket_urls() {
+ let url = format!("{}.{}", url, extension);
+ let expected = format!(
+ "https://bitbucket.org/davereid/drush-virtualhost/get/ref.{}",
+ extension
+ );
+
+ let package = get_package("dummy/pkg", "1.0.0");
+ package.set_dist_reference(Some("ref".to_string()));
+ let url = downloader.__process_url(package, &url).unwrap();
+
+ assert_eq!(expected, url);
+ }
}