//! Integration tests for the `argv` command. use assert_cmd::Command; use predicates::prelude::*; fn cargo_command() -> Command { Command::cargo_bin("argv").expect("binary") } #[test] fn no_args_prints_quick_help_card() { let mut command = cargo_command(); command .assert() .code(2) .stdout(predicate::str::is_empty()) .stderr(predicate::str::contains( "error: provide a subcommand: quote or inspect", )) .stderr(predicate::str::contains("argv - Mercury Toolbox")) .stderr(predicate::str::contains("Usage:")) .stderr(predicate::str::contains("argv quote")) .stderr(predicate::str::contains("argv inspect")) .stderr(predicate::str::contains( "Type 'argv --help' for the full command reference.", )); } #[test] fn help_mentions_quote_inspect_and_platform_boundaries() { let mut command = cargo_command(); command .arg("--help") .assert() .success() .stdout(predicate::str::contains("argv quote")) .stdout(predicate::str::contains("argv inspect")) .stdout(predicate::str::contains("Windows-first")) .stdout(predicate::str::contains("cmd inspect is Windows-only")); } #[test] fn subcommand_help_mentions_common_output_flags() { for subcommand in ["quote", "inspect"] { let mut command = cargo_command(); command .args([subcommand, "--help"]) .assert() .success() .stdout(predicate::str::contains("--format ")) .stdout(predicate::str::contains("--json")) .stdout(predicate::str::contains("--toon")) .stdout(predicate::str::contains("--color ")) .stdout(predicate::str::contains("--quiet")) .stdout(predicate::str::contains("--shell ")); } } #[test] fn quote_accepts_json_array_from_stdin() { let mut command = cargo_command(); command .arg("quote") .arg("--shell") .arg("pwsh") .write_stdin("[\"tool\",\"two words\"]") .assert() .success() .stdout(predicate::str::contains("& 'tool' 'two words'")); } #[cfg(windows)] #[test] fn quote_renders_cmd_safe_text_for_positional_args() { let mut command = cargo_command(); command .arg("quote") .arg("--shell") .arg("cmd") .arg("--") .arg("tool.exe") .arg("two words") .assert() .success() .stdout(predicate::str::contains("tool.exe")) .stdout(predicate::str::contains("\"two words\"")); } #[cfg(windows)] #[test] fn quote_cmd_wraps_metacharacters_for_cmd_shell() { let mut command = cargo_command(); command .arg("quote") .arg("--shell") .arg("cmd") .arg("--") .arg("tool.exe") .arg("a&b") .assert() .success() .stdout(predicate::str::contains("tool.exe")) .stdout(predicate::str::contains("\"a&b\"")); } #[cfg(windows)] #[test] fn inspect_round_trips_through_powershell_helper() { let mut command = cargo_command(); command .arg("inspect") .arg("--json") .arg("--shell") .arg("pwsh") .arg("--") .arg("alpha") .arg("two words") .assert() .success() .stdout(predicate::str::contains("\"shell\":\"pwsh\"")) .stdout(predicate::str::contains( "\"argv\":[\"alpha\",\"two words\"]", )) .stdout(predicate::str::contains("\"count\":2")); } #[cfg(windows)] #[test] fn inspect_round_trips_positional_values_that_look_like_options() { let mut command = cargo_command(); command .arg("inspect") .arg("--json") .arg("--shell") .arg("pwsh") .arg("--") .arg("alpha") .arg("--filter=x|y") .assert() .success() .stdout(predicate::str::contains( "\"argv\":[\"alpha\",\"--filter=x|y\"]", )) .stdout(predicate::str::contains("\"count\":2")); } #[cfg(windows)] #[test] fn inspect_round_trips_through_cmd_helper() { let mut command = cargo_command(); command .arg("inspect") .arg("--json") .arg("--shell") .arg("cmd") .arg("--") .arg("alpha") .arg("two words") .assert() .success() .stdout(predicate::str::contains("\"shell\":\"cmd\"")) .stdout(predicate::str::contains( "\"argv\":[\"alpha\",\"two words\"]", )) .stdout(predicate::str::contains("\"count\":2")); } #[cfg(windows)] #[test] fn inspect_round_trips_cmd_caret_literals() { let mut command = cargo_command(); command .arg("inspect") .arg("--json") .arg("--shell") .arg("cmd") .arg("--") .arg("--flag") .arg("literal^caret") .assert() .success() .stdout(predicate::str::contains( "\"argv\":[\"--flag\",\"literal^caret\"]", )); } #[test] fn inspect_raw_uses_helper_without_shell() { let mut command = cargo_command(); command .arg("inspect") .arg("--json") .arg("--shell") .arg("raw") .arg("--") .arg("alpha") .arg("two words") .assert() .success() .stdout(predicate::str::contains("\"shell\":\"raw\"")) .stdout(predicate::str::contains( "\"argv\":[\"alpha\",\"two words\"]", )); } #[test] fn inspect_text_accepts_json_array_from_stdin() { let mut command = cargo_command(); command .arg("inspect") .arg("--shell") .arg("raw") .write_stdin("[\"alpha\",\"two words\"]") .assert() .success() .stdout(predicate::str::contains("shell=raw count=2")) .stdout(predicate::str::contains("argv[1]=\"two words\"")); } #[test] fn quote_rejects_invalid_stdin_json() { let mut command = cargo_command(); command .arg("quote") .arg("--shell") .arg("raw") .write_stdin("{\"argv\":[\"alpha\"]}") .assert() .code(2) .stderr(predicate::str::contains( "expected a JSON array of strings on stdin", )); }