diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-26 02:23:58 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-26 02:23:58 +0900 |
| commit | 6c89c720d9e4728c288e3c66ffb7dcb4cba5121c (patch) | |
| tree | 4697f897302425df1b57eb87bf9441308530d0bf /crates/shirabe/tests/command/show_command_test.rs | |
| parent | 4bd544608e4934fff4463fd6b104d06162a51ba0 (diff) | |
| download | php-shirabe-6c89c720d9e4728c288e3c66ffb7dcb4cba5121c.tar.gz php-shirabe-6c89c720d9e4728c288e3c66ffb7dcb4cba5121c.tar.zst php-shirabe-6c89c720d9e4728c288e3c66ffb7dcb4cba5121c.zip | |
test(command): port show/remove/global/audit/check-platform-reqs/status/self-update/validate tests
Faithfully port the remaining stubbed command test bodies from their PHP
counterparts (expected values verbatim). Newly passing: remove (6), global (2),
check-platform-reqs (1), status (1), audit (1), self-update (1).
Tests whose ported bodies reach a genuine unported src path keep faithful bodies
but stay #[ignore] with precise reasons. Dominant blockers surfaced:
- ShowCommand::configure stub (empty set_definition) blocks all 42 show tests
- Composer-handle RefCell re-entrancy in the Installer (composer.rs:500) and
Factory::create_composer (composer.rs:446) paths
- check_platform_reqs nests InstalledRepository in InstalledRepository
- audit's non-locked branch (audit_command.rs:285) and write_error3 re-entrancy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests/command/show_command_test.rs')
| -rw-r--r-- | crates/shirabe/tests/command/show_command_test.rs | 1490 |
1 files changed, 1441 insertions, 49 deletions
diff --git a/crates/shirabe/tests/command/show_command_test.rs b/crates/shirabe/tests/command/show_command_test.rs index 56e8106..1ba3882 100644 --- a/crates/shirabe/tests/command/show_command_test.rs +++ b/crates/shirabe/tests/command/show_command_test.rs @@ -1,139 +1,1531 @@ //! ref: composer/tests/Composer/Test/Command/ShowCommandTest.php -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, create_composer_lock, and get_application_tester (ApplicationTester) infrastructure"] +use crate::test_case::{ + RunOptions, get_application_tester, get_complete_package, get_package, get_version_constraint, + init_temp_composer, +}; +use serial_test::serial; +use shirabe::package::Link; +use shirabe::package::handle::PackageInterfaceHandle; +use shirabe::repository::PlatformRepository; +use shirabe_php_shim::PhpMixed; + +/// Build a `Vec<(PhpMixed, PhpMixed)>` command input from `(key, value)` pairs. +fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { + pairs + .into_iter() + .map(|(k, v)| (PhpMixed::from(k), v)) + .collect() +} + +/// ref: ShowCommandTest::testShow composer.json fixture. +fn show_composer_json(requires: serde_json::Value) -> serde_json::Value { + serde_json::json!({ + "name": "root/pkg", + "version": "1.2.3", + "repositories": { + "packages": { + "type": "package", + "package": [ + {"name": "vendor/package", "description": "generic description", "version": "v1.0.0"}, + + {"name": "outdated/major", "description": "outdated/major v1.0.0 description", "version": "v1.0.0"}, + {"name": "outdated/major", "description": "outdated/major v1.0.1 description", "version": "v1.0.1"}, + {"name": "outdated/major", "description": "outdated/major v1.1.0 description", "version": "v1.1.0"}, + {"name": "outdated/major", "description": "outdated/major v1.1.1 description", "version": "v1.1.1"}, + {"name": "outdated/major", "description": "outdated/major v2.0.0 description", "version": "v2.0.0"}, + + {"name": "outdated/minor", "description": "outdated/minor v1.0.0 description", "version": "1.0.0"}, + {"name": "outdated/minor", "description": "outdated/minor v1.0.1 description", "version": "1.0.1"}, + {"name": "outdated/minor", "description": "outdated/minor v1.1.0 description", "version": "1.1.0"}, + {"name": "outdated/minor", "description": "outdated/minor v1.1.1 description", "version": "1.1.1"}, + + {"name": "outdated/patch", "description": "outdated/patch v1.0.0 description", "version": "1.0.0"}, + {"name": "outdated/patch", "description": "outdated/patch v1.0.1 description", "version": "1.0.1"}, + ], + }, + }, + "require": requires, + }) +} + +/// ref: ShowCommandTest::testShow (one data-provider case). +/// +/// NOTE: PHP sets release dates on the installed packages via `setReleaseDate`, but no such setter +/// is exposed on `PackageInterfaceHandle`, so it is omitted here. Only the "sorting by age" case +/// depends on release dates; every other case produces identical output without them. +fn run_show_case(command: Vec<(PhpMixed, PhpMixed)>, expected: &str, requires: serde_json::Value) { + let _tear_down = init_temp_composer(Some(&show_composer_json(requires)), None, None, true); + + let pkg = get_complete_package("vendor/package", "v1.0.0"); + pkg.set_description("description of installed package".to_string()); + let major = get_complete_package("outdated/major", "v1.0.0"); + let minor = get_complete_package("outdated/minor", "1.0.0"); + let patch = get_complete_package("outdated/patch", "1.0.0"); + + let packages: Vec<PackageInterfaceHandle> = + vec![pkg.into(), major.into(), minor.into(), patch.into()]; + create_installed_json(&packages, &[], true); + + let locked = get_complete_package("vendor/locked", "3.0.0"); + locked.set_description("description of locked package".to_string()); + create_composer_lock(&[locked.into()], &[]); + + let mut app_tester = get_application_tester(); + app_tester.run(command, RunOptions::default()).unwrap(); + assert_eq!(expected.trim(), app_tester.get_display().trim()); +} + +use crate::test_case::{create_composer_lock, create_installed_json}; + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_default_shows_installed_with_version_and_description() { + run_show_case( + input(vec![("command", PhpMixed::from("show"))]), + "outdated/major 1.0.0 +outdated/minor 1.0.0 +outdated/patch 1.0.0 +vendor/package 1.0.0 description of installed package", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_with_installed_and_self() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("show")), + ("--installed", PhpMixed::from(true)), + ("--self", PhpMixed::from(true)), + ]), + "outdated/major 1.0.0 +outdated/minor 1.0.0 +outdated/patch 1.0.0 +root/pkg 1.2.3 +vendor/package 1.0.0 description of installed package", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_with_locked_and_self() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("show")), + ("--locked", PhpMixed::from(true)), + ("--self", PhpMixed::from(true)), + ]), + "root/pkg 1.2.3 +vendor/locked 3.0.0 description of locked package", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_with_available() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("show")), + ("-a", PhpMixed::from(true)), + ]), + "outdated/major outdated/major v2.0.0 description +outdated/minor outdated/minor v1.1.1 description +outdated/patch outdated/patch v1.0.1 description +vendor/package generic description", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_with_direct_shows_nothing_if_no_deps() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("show")), + ("--direct", PhpMixed::from(true)), + ]), + "", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_with_direct_shows_only_root_deps() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("show")), + ("--direct", PhpMixed::from(true)), + ]), + "outdated/major 1.0.0", + serde_json::json!({"outdated/major": "*"}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_outdated_deps() { + run_show_case( + input(vec![("command", PhpMixed::from("outdated"))]), + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +outdated/major 1.0.0 ~ 2.0.0 +outdated/minor 1.0.0 <highlight>! 1.1.1</highlight> +outdated/patch 1.0.0 <highlight>! 1.0.1</highlight>", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition(), so outdated->show fails with an option-does-not-exist error. Additionally, PackageInterfaceHandle exposes no set_release_date setter, so the 'sorting by age' output ('2 years old', '2 weeks old', 'from today') cannot be reproduced even once the definition is ported."] +#[test] +#[serial] +fn test_show_outdated_deps_sorting_by_age() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--sort-by-age", PhpMixed::from(true)), + ]), + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +outdated/minor 1.0.0 <highlight>! 1.1.1</highlight> 2 years old +outdated/patch 1.0.0 <highlight>! 1.0.1</highlight> 2 weeks old +outdated/major 1.0.0 ~ 2.0.0 from today", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] -fn test_show() { - todo!() +#[serial] +fn test_show_outdated_deps_with_direct_only_show_direct_deps_with_updated() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--direct", PhpMixed::from(true)), + ]), + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible +outdated/major 1.0.0 ~ 2.0.0", + serde_json::json!({ + "vendor/package": "*", + "outdated/major": "*", + }), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_outdated_deps_with_direct_show_msg_if_all_up_to_date() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--direct", PhpMixed::from(true)), + ]), + "All your direct dependencies are up to date", + serde_json::json!({"vendor/package": "*"}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_outdated_deps_with_major_only() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--major-only", PhpMixed::from(true)), + ]), + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +outdated/major 1.0.0 ~ 2.0.0", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_show_outdated_deps_with_minor_only() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--minor-only", PhpMixed::from(true)), + ]), + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +outdated/minor 1.0.0 <highlight>! 1.1.1</highlight> + +Transitive dependencies not required in composer.json: +outdated/major 1.0.0 <highlight>! 1.1.1</highlight> +outdated/patch 1.0.0 <highlight>! 1.0.1</highlight>", + serde_json::json!({"outdated/minor": "*"}), + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] +fn test_show_outdated_deps_with_patch_only() { + run_show_case( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--patch-only", PhpMixed::from(true)), + ]), + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +outdated/major 1.0.0 <highlight>! 1.0.1</highlight> +outdated/minor 1.0.0 <highlight>! 1.0.1</highlight> +outdated/patch 1.0.0 <highlight>! 1.0.1</highlight>", + serde_json::json!({}), + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] fn test_outdated_filters_according_to_platform_reqs_and_warns() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": { + "packages": { + "type": "package", + "package": [ + {"name": "vendor/package", "description": "generic description", "version": "1.0.0"}, + {"name": "vendor/package", "description": "generic description", "version": "1.1.0", "require": {"ext-missing": "3"}}, + {"name": "vendor/package", "description": "generic description", "version": "1.2.0", "require": {"ext-missing": "3"}}, + {"name": "vendor/package", "description": "generic description", "version": "1.3.0", "require": {"ext-missing": "3"}}, + ], + }, + }, + })), + None, + None, + true, + ); + + create_installed_json(&[get_package("vendor/package", "1.1.0")], &[], true); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![("command", PhpMixed::from("outdated"))]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "<warning>Cannot use vendor/package 1.1.0 as it requires ext-missing 3 which is missing from your platform. +Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +vendor/package 1.1.0 ~ 1.0.0", + app_tester.get_display().trim() + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--verbose", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "<warning>Cannot use vendor/package's latest version 1.3.0 as it requires ext-missing 3 which is missing from your platform. +<warning>Cannot use vendor/package 1.2.0 as it requires ext-missing 3 which is missing from your platform. +<warning>Cannot use vendor/package 1.1.0 as it requires ext-missing 3 which is missing from your platform. +Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +vendor/package 1.1.0 ~ 1.0.0", + app_tester.get_display().trim() + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_outdated_filters_according_to_platform_reqs_without_warning_for_higher_versions() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": { + "packages": { + "type": "package", + "package": [ + {"name": "vendor/package", "description": "generic description", "version": "1.0.0"}, + {"name": "vendor/package", "description": "generic description", "version": "1.1.0"}, + {"name": "vendor/package", "description": "generic description", "version": "1.2.0"}, + {"name": "vendor/package", "description": "generic description", "version": "1.3.0", "require": {"php": "^99"}}, + ], + }, + }, + })), + None, + None, + true, + ); + + create_installed_json(&[get_package("vendor/package", "1.1.0")], &[], true); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![("command", PhpMixed::from("outdated"))]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible + +Direct dependencies required in composer.json: +Everything up to date + +Transitive dependencies not required in composer.json: +vendor/package 1.1.0 <highlight>! 1.2.0</highlight>", + app_tester.get_display().trim() + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, configure_links, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_show_direct_with_name_does_not_show_transient_dependencies() { - todo!() + // NOTE: PHP also wires `direct/dependent` -> `vendor/package` via configureLinks, which has no + // public handle API. It is omitted: vendor/package is installed but not a direct root dependency + // either way, so the same InvalidArgumentException is thrown. + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": [], + "require": { + "direct/dependent": "*", + }, + })), + None, + None, + false, + ); + + create_installed_json( + &[ + get_package("direct/dependent", "1.0.0"), + get_package("vendor/package", "1.0.0"), + ], + &[], + true, + ); + + let mut app_tester = get_application_tester(); + let err = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--direct", PhpMixed::from(true)), + ("package", PhpMixed::from("vendor/package")), + ]), + RunOptions::default(), + ) + .expect_err("expected an InvalidArgumentException"); + assert!( + err.to_string().contains( + "Package \"vendor/package\" is installed but not a direct dependent of the root package." + ), + "unexpected error: {}", + err + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_show_direct_with_name_only_shows_direct_dependents() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": [], + "require": { + "direct/dependent": "*", + }, + "require-dev": { + "direct/dependent2": "*", + }, + })), + None, + None, + false, + ); + + create_installed_json( + &[ + get_package("direct/dependent", "1.0.0"), + get_package("direct/dependent2", "1.0.0"), + ], + &[], + true, + ); + + let mut app_tester = get_application_tester(); + let status_code = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--direct", PhpMixed::from(true)), + ("package", PhpMixed::from("direct/dependent")), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!(0, status_code); + assert!( + app_tester + .get_display() + .contains("name : direct/dependent\n") + ); + + let mut app_tester = get_application_tester(); + let status_code = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--direct", PhpMixed::from(true)), + ("package", PhpMixed::from("direct/dependent2")), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!(0, status_code); + assert!( + app_tester + .get_display() + .contains("name : direct/dependent2\n") + ); +} + +/// Assert every leading-word of each output line is a platform package, replicating +/// `Regex::matchAll('{^(\w+)}m', $output)`. +fn assert_all_platform_packages(output: &str) { + let re = regex::Regex::new(r"(?m)^(\w+)").unwrap(); + for caps in re.captures_iter(output) { + let m = caps.get(1).unwrap().as_str(); + assert!( + PlatformRepository::is_platform_package(m), + "{} is not a platform package", + m + ); + } } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_show_platform_only_shows_platform_packages() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": { + "packages": { + "type": "package", + "package": [ + {"name": "vendor/package", "description": "generic description", "version": "1.0.0"}, + ], + }, + }, + })), + None, + None, + true, + ); + + create_installed_json(&[get_package("vendor/package", "1.0.0")], &[], true); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("-p", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + let output = app_tester.get_display(); + assert_all_platform_packages(output.trim()); } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_show_platform_works_without_composer_json() { - todo!() + let _tear_down = init_temp_composer(Some(&serde_json::json!({})), None, None, true); + let _ = std::fs::remove_file("./composer.json"); + let _ = std::fs::remove_file("./auth.json"); + + // listing packages + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("-p", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + let output = app_tester.get_display(); + assert_all_platform_packages(output.trim()); + + // getting a single package + let status_code = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("-p", PhpMixed::from(true)), + ("package", PhpMixed::from("php")), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!(0, status_code); + + let status_code = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("-p", PhpMixed::from(true)), + ("-f", PhpMixed::from("json")), + ("package", PhpMixed::from("php")), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!(0, status_code); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_outdated_with_zero_major() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": { + "packages": { + "type": "package", + "package": [ + {"name": "zerozero/major", "description": "generic description", "version": "0.0.1"}, + {"name": "zerozero/major", "description": "generic description", "version": "0.0.2"}, + {"name": "zero/major", "description": "generic description", "version": "0.1.0"}, + {"name": "zero/major", "description": "generic description", "version": "0.2.0"}, + {"name": "zero/minor", "description": "generic description", "version": "0.1.0"}, + {"name": "zero/minor", "description": "generic description", "version": "0.1.2"}, + {"name": "zero/patch", "description": "generic description", "version": "0.1.2"}, + {"name": "zero/patch", "description": "generic description", "version": "0.1.2.1"}, + ], + }, + }, + "require": { + "zerozero/major": "^0.0.1", + "zero/major": "^0.1", + "zero/minor": "^0.1", + "zero/patch": "^0.1", + }, + })), + None, + None, + true, + ); + + create_installed_json( + &[ + get_package("zerozero/major", "0.0.1"), + get_package("zero/major", "0.1.0"), + get_package("zero/minor", "0.1.0"), + get_package("zero/patch", "0.1.2"), + ], + &[], + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--direct", PhpMixed::from(true)), + ("--patch-only", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible +zero/patch 0.1.2 <highlight>! 0.1.2.1</highlight>", + app_tester.get_display().trim() + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--direct", PhpMixed::from(true)), + ("--minor-only", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible +zero/minor 0.1.0 <highlight>! 0.1.2 </highlight> +zero/patch 0.1.2 <highlight>! 0.1.2.1</highlight>", + app_tester.get_display().trim() + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("outdated")), + ("--direct", PhpMixed::from(true)), + ("--major-only", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible +zero/major 0.1.0 ~ 0.2.0 +zerozero/major 0.0.1 ~ 0.0.2", + app_tester.get_display().trim() + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, create_composer_lock, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_show_all_shows_all_sections() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": { + "packages": { + "type": "package", + "package": [ + {"name": "vendor/available", "description": "generic description", "version": "1.0.0"}, + ], + }, + }, + })), + None, + None, + true, + ); + + let pkg = get_complete_package("vendor/installed", "2.0.0"); + pkg.set_description("description of installed package".to_string()); + create_installed_json(&[pkg.into()], &[], true); + + let locked = get_complete_package("vendor/locked", "3.0.0"); + locked.set_description("description of locked package".to_string()); + create_composer_lock(&[locked.into()], &[]); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--all", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + let output = app_tester.get_display(); + let output = output.trim(); + let re = regex::Regex::new(r"platform:(\n .*)+").unwrap(); + let output = re.replace(output, "platform: wiped"); + + assert_eq!( + "platform: wiped + +locked: + vendor/locked 3.0.0 description of locked package + +available: + vendor/available generic description + +installed: + vendor/installed 2.0.0 description of installed package", + output + ); } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_locked_requires_valid_lock_file() { - todo!() + let _tear_down = init_temp_composer(None, None, None, true); + + let mut app_tester = get_application_tester(); + let err = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--locked", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .expect_err("expected an exception"); + assert!( + err.to_string().contains( + "A valid composer.json and composer.lock files is required to run this command with --locked" + ), + "unexpected error: {}", + err + ); } -#[ignore = "missing TestCase::init_temp_composer, create_composer_lock, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_locked_shows_all_locked() { - todo!() + let _tear_down = init_temp_composer(None, None, None, true); + + let pkg = get_complete_package("vendor/locked", "3.0.0"); + pkg.set_description("description of locked package".to_string()); + create_composer_lock(&[pkg.clone().into()], &[]); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--locked", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "vendor/locked 3.0.0 description of locked package", + app_tester.get_display().trim() + ); + + let pkg2 = get_complete_package("vendor/locked2", "2.0.0"); + pkg2.set_description("description of locked2 package".to_string()); + create_composer_lock(&[pkg.into(), pkg2.into()], &[]); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--locked", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "vendor/locked 3.0.0 description of locked package +vendor/locked2 2.0.0 description of locked2 package", + app_tester.get_display().trim() + ); } -#[ignore = "missing TestCase::get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_invalid_option_combinations() { - todo!() + let combos: Vec<Vec<(&str, PhpMixed)>> = vec![ + vec![ + ("--direct", PhpMixed::from(true)), + ("--all", PhpMixed::from(true)), + ], + vec![ + ("--direct", PhpMixed::from(true)), + ("--available", PhpMixed::from(true)), + ], + vec![ + ("--direct", PhpMixed::from(true)), + ("--platform", PhpMixed::from(true)), + ], + vec![ + ("--tree", PhpMixed::from(true)), + ("--all", PhpMixed::from(true)), + ], + vec![ + ("--tree", PhpMixed::from(true)), + ("--available", PhpMixed::from(true)), + ], + vec![ + ("--tree", PhpMixed::from(true)), + ("--latest", PhpMixed::from(true)), + ], + vec![ + ("--tree", PhpMixed::from(true)), + ("--path", PhpMixed::from(true)), + ], + vec![ + ("--patch-only", PhpMixed::from(true)), + ("--minor-only", PhpMixed::from(true)), + ], + vec![ + ("--patch-only", PhpMixed::from(true)), + ("--major-only", PhpMixed::from(true)), + ], + vec![ + ("--minor-only", PhpMixed::from(true)), + ("--major-only", PhpMixed::from(true)), + ], + vec![ + ("--minor-only", PhpMixed::from(true)), + ("--major-only", PhpMixed::from(true)), + ("--patch-only", PhpMixed::from(true)), + ], + vec![("--format", PhpMixed::from("test"))], + ]; + + for combo in combos { + let mut pairs = vec![("command", PhpMixed::from("show"))]; + pairs.extend(combo.clone()); + let mut app_tester = get_application_tester(); + let status_code = app_tester.run(input(pairs), RunOptions::default()).unwrap(); + assert_eq!(1, status_code, "combo {:?}", combo); + } } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_ignored_option_combinations() { - todo!() + let _tear_down = init_temp_composer(None, None, None, true); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--installed", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert!( + app_tester + .get_display() + .contains("You are using the deprecated option \"installed\".") + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ( + "--ignore", + PhpMixed::List(vec![PhpMixed::from("vendor/package")]), + ), + ]), + RunOptions::default(), + ) + .unwrap(); + assert!( + app_tester + .get_display() + .contains("You are using the option \"ignore\"") + ); } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_self_and_name_only() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({"name": "vendor/package", "version": "1.2.3"})), + None, + None, + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--self", PhpMixed::from(true)), + ("--name-only", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!("vendor/package", app_tester.get_display().trim()); } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_self_and_package_combination() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({"name": "vendor/package"})), + None, + None, + true, + ); + + let mut app_tester = get_application_tester(); + let result = app_tester.run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--self", PhpMixed::from(true)), + ("package", PhpMixed::from("vendor/package")), + ]), + RunOptions::default(), + ); + assert!( + result.is_err(), + "expected an InvalidArgumentException, got {:?}", + result + ); } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_self() { - todo!() + let today = chrono::Local::now().format("%Y-%m-%d").to_string(); + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "name": "vendor/package", + "version": "1.2.3", + "time": today, + })), + None, + None, + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--self", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + + let expected: Vec<(&str, String)> = vec![ + ("name", "vendor/package".to_string()), + ("descrip.", "".to_string()), + ("keywords", "".to_string()), + ("versions", "* 1.2.3".to_string()), + ("released", format!("{}, today", today)), + ("type", "library".to_string()), + ("homepage", "".to_string()), + ("source", "[] ".to_string()), + ("dist", "[] ".to_string()), + ("path", "".to_string()), + ("names", "vendor/package".to_string()), + ]; + let expected_string = expected + .iter() + .map(|(k, v)| format!("{:<8} : {}", k, v)) + .collect::<Vec<_>>() + .join("\n") + + "\n"; + + assert_eq!(expected_string, app_tester.get_display()); } -#[ignore = "missing TestCase::init_temp_composer and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_not_installed_error() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "require": {"vendor/package": "1.0.0"}, + "require-dev": {"vendor/package-dev": "1.0.0"}, + })), + None, + None, + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![("command", PhpMixed::from("show"))]), + RunOptions::default(), + ) + .unwrap(); + assert!( + app_tester + .get_display() + .trim() + .contains("No dependencies installed. Try running composer install or update."), + "Should show error message when no dependencies are installed" + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_no_dev_option() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "require": {"vendor/package": "1.0.0"}, + "require-dev": {"vendor/package-dev": "1.0.0"}, + })), + None, + None, + true, + ); + create_installed_json( + &[ + get_package("vendor/package", "1.0.0"), + get_package("vendor/package-dev", "1.0.0"), + ], + &[], + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--no-dev", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!("vendor/package 1.0.0", app_tester.get_display().trim()); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] fn test_package_filter() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "require": { + "vendor/package": "1.0.0", + "vendor/other-package": "1.0.0", + "company/package": "1.0.0", + "company/other-package": "1.0.0", + }, + })), + None, + None, + true, + ); + create_installed_json( + &[ + get_package("vendor/package", "1.0.0"), + get_package("vendor/other-package", "1.0.0"), + get_package("company/package", "1.0.0"), + get_package("company/other-package", "1.0.0"), + ], + &[], + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("package", PhpMixed::from("vendor/package")), + ]), + RunOptions::default(), + ) + .unwrap(); + let output = app_tester.get_display(); + let output = output.trim(); + assert!(output.contains("vendor/package")); + assert!(!output.contains("vendor/other-package")); + assert!(!output.contains("company/package")); + assert!(!output.contains("company/other-package")); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("package", PhpMixed::from("company/*")), + ("--name-only", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + let output = app_tester.get_display(); + let output = output.trim(); + assert!(!output.contains("vendor/package")); + assert!(!output.contains("vendor/other-package")); + assert!(output.contains("company/package")); + assert!(output.contains("company/other-package")); +} + +/// ref: ShowCommandTest::testNotExistingPackage (one data-provider case). +fn run_not_existing_package_case(package: &str, options: Vec<(&str, PhpMixed)>, expected: &str) { + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "require": {"vendor/package": "1.0.0"}, + })), + None, + None, + true, + ); + let pkg = get_package("vendor/package", "1.0.0"); + create_installed_json(&[pkg.clone()], &[], true); + create_composer_lock(&[pkg], &[]); + + let mut pairs = vec![ + ("command", PhpMixed::from("show")), + ("package", PhpMixed::from(package)), + ]; + pairs.extend(options); + + let mut app_tester = get_application_tester(); + let err = app_tester + .run(input(pairs), RunOptions::default()) + .expect_err("expected an exception"); + assert!( + err.to_string().contains(expected), + "expected message starting with {:?}, got: {}", + expected, + err + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, create_composer_lock, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] -fn test_not_existing_package() { - todo!() +#[serial] +fn test_not_existing_package_with_no_options() { + run_not_existing_package_case( + "not/existing", + vec![], + "Package \"not/existing\" not found, try using --available (-a) to show all available packages.", + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] +fn test_not_existing_package_with_all_option() { + run_not_existing_package_case( + "not/existing", + vec![("--all", PhpMixed::from(true))], + "Package \"not/existing\" not found.", + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_not_existing_package_with_locked_option() { + run_not_existing_package_case( + "not/existing", + vec![("--locked", PhpMixed::from(true))], + "Package \"not/existing\" not found in lock file, try using --available (-a) to show all available packages.", + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_not_existing_platform_with_platform_option() { + run_not_existing_package_case( + "ext-nonexisting", + vec![("--platform", PhpMixed::from(true))], + "Package \"ext-nonexisting\" not found, try using --available (-a) to show all available packages.", + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_not_existing_platform_without_platform_option() { + run_not_existing_package_case( + "ext-nonexisting", + vec![], + "Package \"ext-nonexisting\" not found, try using --platform (-p) to show platform packages, try using --available (-a) to show all available packages.", + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] fn test_not_existing_package_with_working_dir() { - todo!() + let tear_down = init_temp_composer( + Some(&serde_json::json!({ + "require": {"vendor/package": "1.0.0"}, + })), + None, + None, + true, + ); + let dir = tear_down.working_dir(); + create_installed_json(&[get_package("vendor/package", "1.0.0")], &[], true); + + let expected = format!( + "Package \"not/existing\" not found in {}/composer.json, try using --available (-a) to show all available packages.", + dir.display() + ); + + let mut app_tester = get_application_tester(); + let err = app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("package", PhpMixed::from("not/existing")), + ( + "--working-dir", + PhpMixed::from(dir.display().to_string().as_str()), + ), + ]), + RunOptions::default(), + ) + .expect_err("expected an exception"); + assert!( + err.to_string().contains(&expected), + "expected message starting with {:?}, got: {}", + expected, + err + ); + + drop(tear_down); +} + +/// ref: ShowCommandTest::testSpecificPackageAndTree (one data-provider case). +fn run_specific_package_and_tree_case( + packages: Vec<PackageInterfaceHandle>, + options: Vec<(&str, PhpMixed)>, + expected: &str, +) { + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "require": {"vendor/package": "1.0.0"}, + })), + None, + None, + true, + ); + + create_installed_json(&packages, &[], true); + + let mut pairs = vec![ + ("command", PhpMixed::from("show")), + ("package", PhpMixed::from("vendor/package")), + ("--tree", PhpMixed::from(true)), + ]; + pairs.extend(options); + + let mut app_tester = get_application_tester(); + app_tester.run(input(pairs), RunOptions::default()).unwrap(); + assert_eq!(expected, app_tester.get_display().trim()); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_specific_package_and_tree_just_package() { + let pkg = get_package("vendor/package", "1.0.0"); + run_specific_package_and_tree_case(vec![pkg], vec![], "vendor/package 1.0.0"); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] -fn test_specific_package_and_tree() { - todo!() +#[serial] +fn test_specific_package_and_tree_with_one_package_requirement() { + let pkg = get_complete_package("vendor/package", "1.0.0"); + let mut requires = indexmap::IndexMap::new(); + requires.insert( + "vendor/required-package".to_string(), + Link::new( + "vendor/package".to_string(), + "vendor/required-package".to_string(), + get_version_constraint("=", "1.0.0"), + Some(Link::TYPE_REQUIRE.to_string()), + "1.0.0".to_string(), + ), + ); + pkg.__set_requires(requires); + run_specific_package_and_tree_case( + vec![pkg.into()], + vec![], + "vendor/package 1.0.0 +`--vendor/required-package 1.0.0", + ); } -#[ignore = "missing TestCase::init_temp_composer, create_installed_json, and get_application_tester (ApplicationTester) infrastructure"] +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] #[test] +#[serial] +fn test_specific_package_and_tree_with_platform_requirement() { + let pkg = get_complete_package("vendor/package", "1.0.0"); + let mut requires = indexmap::IndexMap::new(); + requires.insert( + "php".to_string(), + Link::new( + "vendor/package".to_string(), + "php".to_string(), + get_version_constraint("=", "8.2.0"), + Some(Link::TYPE_REQUIRE.to_string()), + "8.2.0".to_string(), + ), + ); + pkg.__set_requires(requires); + run_specific_package_and_tree_case( + vec![pkg.into()], + vec![], + "vendor/package 1.0.0 +`--php 8.2.0", + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] +fn test_specific_package_and_tree_with_json_format() { + let pkg = get_package("vendor/package", "1.0.0"); + run_specific_package_and_tree_case( + vec![pkg], + vec![("--format", PhpMixed::from("json"))], + "{ + \"installed\": [ + { + \"name\": \"vendor/package\", + \"version\": \"1.0.0\", + \"description\": null + } + ] +}", + ); +} + +#[ignore = "blocked: ShowCommand::configure() at src/command/show_command.rs:98-100 registers an empty set_definition() (TODO placeholder); no package argument or options are defined, so every show invocation fails with an option/argument-does-not-exist InvalidArgumentException (the outdated command proxies into show and fails identically). Unported src path; cannot fix from test files."] +#[test] +#[serial] fn test_name_only_prints_no_trailing_whitespace() { - todo!() + let _tear_down = init_temp_composer( + Some(&serde_json::json!({ + "repositories": { + "packages": { + "type": "package", + "package": [ + // CAUTION: package names matter - output is sorted, and we want shorter before longer ones + {"name": "vendor/apackage", "description": "generic description", "version": "1.0.0"}, + {"name": "vendor/apackage", "description": "generic description", "version": "1.1.0"}, + {"name": "vendor/longpackagename", "description": "generic description", "version": "1.0.0"}, + {"name": "vendor/longpackagename", "description": "generic description", "version": "1.1.0"}, + {"name": "vendor/somepackage", "description": "generic description", "version": "1.0.0"}, + ], + }, + }, + })), + None, + None, + true, + ); + + create_installed_json( + &[ + get_package("vendor/apackage", "1.0.0"), + get_package("vendor/longpackagename", "1.0.0"), + get_package("vendor/somepackage", "1.0.0"), + ], + &[], + true, + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("-N", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "vendor/apackage +vendor/longpackagename +vendor/somepackage", + app_tester.get_display().trim() + ); + + let mut app_tester = get_application_tester(); + app_tester + .run( + input(vec![ + ("command", PhpMixed::from("show")), + ("--outdated", PhpMixed::from(true)), + ("-N", PhpMixed::from(true)), + ]), + RunOptions::default(), + ) + .unwrap(); + assert_eq!( + "Legend: +! patch or minor release available - update recommended +~ major release available - update possible +vendor/apackage +vendor/longpackagename", + app_tester.get_display().trim() + ); } |
