//! ref: composer/tests/Composer/Test/Command/ShowCommandTest.php 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 = 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 ! 1.1.1 outdated/patch 1.0.0 ! 1.0.1", 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 ! 1.1.1 2 years old outdated/patch 1.0.0 ! 1.0.1 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] #[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 ! 1.1.1 Transitive dependencies not required in composer.json: outdated/major 1.0.0 ! 1.1.1 outdated/patch 1.0.0 ! 1.0.1", serde_json::json!({"outdated/minor": "*"}), ); } #[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 ! 1.0.1 outdated/minor 1.0.0 ! 1.0.1 outdated/patch 1.0.0 ! 1.0.1", 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() { 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!( "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!( "Cannot use vendor/package's latest version 1.3.0 as it requires ext-missing 3 which is missing from your platform. Cannot use vendor/package 1.2.0 as it requires ext-missing 3 which is missing from your platform. 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 = "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() { 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 ! 1.2.0", 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_show_direct_with_name_does_not_show_transient_dependencies() { // 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 = "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() { 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 = "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() { 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 = "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() { 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 = "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() { 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 ! 0.1.2.1", 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 ! 0.1.2 zero/patch 0.1.2 ! 0.1.2.1", 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 = "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() { 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 = "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() { 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 = "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() { 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 = "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() { let combos: Vec> = 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 = "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() { 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 = "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() { 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 = "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() { 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 = "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() { 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::>() .join("\n") + "\n"; assert_eq!(expected_string, app_tester.get_display()); } #[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() { 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 = "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() { 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 = "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() { 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 = "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_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 = "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() { 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, 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 = "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_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 = "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() { 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() ); }