From 586cfd83f5c5b8e0ff439a9b21348a5c9163a29d Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 28 Jun 2026 05:29:48 +0900 Subject: test(command/status): port testLocallyModifiedPackages Replace the todo!() stub with a faithful port of StatusCommandTest's data-provided locally-modified-packages cases (source/dist), kept #[ignore]d since install does not yet populate vendor/ offline. Co-Authored-By: Claude Opus 4.8 --- .../shirabe/tests/command/status_command_test.rs | 120 +++++++++++++++++++-- 1 file changed, 112 insertions(+), 8 deletions(-) (limited to 'crates') diff --git a/crates/shirabe/tests/command/status_command_test.rs b/crates/shirabe/tests/command/status_command_test.rs index f10df7b..9752fe1 100644 --- a/crates/shirabe/tests/command/status_command_test.rs +++ b/crates/shirabe/tests/command/status_command_test.rs @@ -2,12 +2,19 @@ use crate::test_case::{ RunOptions, create_composer_lock, create_installed_json, get_application_tester, - get_complete_package, init_temp_composer, + get_complete_package, get_package, init_temp_composer, }; use serial_test::serial; use shirabe::package::handle::PackageInterfaceHandle; use shirabe_php_shim::PhpMixed; +fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { + pairs + .into_iter() + .map(|(k, v)| (PhpMixed::from(k), v)) + .collect() +} + #[test] #[serial] fn test_no_local_changes() { @@ -39,12 +46,109 @@ fn test_no_local_changes() { drop(tear_down); } -#[ignore = "not a partial-mock test: it runs `install` to download composer/class-map-generator (git \ - source) or smarty/smarty (dist zip), mutates the installed package, then runs `status`. \ - Porting without network would require fabricating a real git checkout under vendor/, a \ - `.git` metadata repo, and wiring download-manager routing so GitDownloader::get_local_changes \ - runs `git status` against it — a full VCS integration fixture, not a SUT seam"] +/// ref: StatusCommandTest::locallyModifiedPackagesUseCaseProvider entry. +struct LocallyModifiedPackageData { + name: &'static str, + version: &'static str, + installation_source: &'static str, + r#type: &'static str, + url: &'static str, + reference: Option<&'static str>, +} + +/// ref: StatusCommandTest::testLocallyModifiedPackages (data provider rolled into a helper). +fn run_locally_modified_packages_case( + composer_json: serde_json::Value, + command_flags: Vec<(&str, PhpMixed)>, + package_data: LocallyModifiedPackageData, +) { + let _tear_down = init_temp_composer(Some(&composer_json), None, None, true); + + let package = get_package(package_data.name, package_data.version); + package.set_installation_source(Some(package_data.installation_source.to_string())); + + if package_data.installation_source == "source" { + package.__set_source_type(Some(package_data.r#type.to_string())); + package.set_source_url(Some(package_data.url.to_string())); + package.set_source_reference(package_data.reference.map(str::to_string)); + } + + if package_data.installation_source == "dist" { + package.set_dist_type(Some(package_data.r#type.to_string())); + package.set_dist_url(Some(package_data.url.to_string())); + package.set_dist_reference(package_data.reference.map(str::to_string)); + } + + create_composer_lock(&[package], &[]); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![("command", PhpMixed::from("install"))]), + RunOptions::default(), + ) + .unwrap(); + + std::fs::write( + std::env::current_dir() + .unwrap() + .join("vendor") + .join(package_data.name) + .join("composer.json"), + "{}", + ) + .unwrap(); + + let mut status_input = vec![("command", PhpMixed::from("status"))]; + status_input.extend(command_flags); + app_tester + .run(input(status_input), RunOptions::default()) + .unwrap(); + + let expected = "You have changes in the following dependencies:"; + let actual = app_tester.get_display(); + let actual = actual.trim(); + + assert!(actual.contains(expected)); + assert!(actual.contains(package_data.name)); +} + #[test] -fn test_locally_modified_packages() { - todo!() +#[serial] +#[ignore = "runs `install` to download the package (git source / dist zip) before `status`, but \ + InstallationManager::execute is still a todo!() stub so install never populates vendor/, \ + and init_temp_composer disables packagist.org — running this needs a real VCS/zip fixture"] +fn test_locally_modified_packages_from_source() { + run_locally_modified_packages_case( + serde_json::json!({ "require": { "composer/class-map-generator": "^1.0" } }), + vec![], + LocallyModifiedPackageData { + name: "composer/class-map-generator", + version: "1.1", + installation_source: "source", + r#type: "git", + url: "https://github.com/composer/class-map-generator.git", + reference: Some("953cc4ea32e0c31f2185549c7d216d7921f03da9"), + }, + ); +} + +#[test] +#[serial] +#[ignore = "runs `install` to download the package (git source / dist zip) before `status`, but \ + InstallationManager::execute is still a todo!() stub so install never populates vendor/, \ + and init_temp_composer disables packagist.org — running this needs a real VCS/zip fixture"] +fn test_locally_modified_packages_from_dist() { + run_locally_modified_packages_case( + serde_json::json!({ "require": { "smarty/smarty": "^3.1" } }), + vec![("--verbose", PhpMixed::from(true))], + LocallyModifiedPackageData { + name: "smarty/smarty", + version: "3.1.7", + installation_source: "dist", + r#type: "zip", + url: "https://www.smarty.net/files/Smarty-3.1.7.zip", + reference: None, + }, + ); } -- cgit v1.3.1