use crate::test_helpers::{output_includes, run_succeeds};
use bel7_cli::CommandShellExt;
use std::error::Error;
use std::ffi::OsStr;
use std::process::Command;
fn run_with_shell_env<I, S>(args: I, shell_path: &str) -> assert_cmd::assert::Assert
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let mut cmd = Command::new(assert_cmd::cargo::cargo_bin!("rabbitmqadmin"));
cmd.clear_shell_detection_env();
cmd.env("SHELL", shell_path);
cmd.args(args);
assert_cmd::assert::Assert::new(cmd.output().unwrap())
}
#[test]
fn shell_completions_bash() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--shell", "bash"])
.stdout(output_includes("_rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_zsh() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--shell", "zsh"])
.stdout(output_includes("#compdef rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_fish() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--shell", "fish"])
.stdout(output_includes("complete -c rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_elvish() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--shell", "elvish"]).stdout(output_includes(
"set edit:completion:arg-completer[rabbitmqadmin]",
));
Ok(())
}
#[test]
fn shell_completions_nushell() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--shell", "nushell"])
.stdout(output_includes("module completions"));
Ok(())
}
#[test]
fn shell_completions_nu_alias() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--shell", "nu"])
.stdout(output_includes("module completions"));
Ok(())
}
#[test]
fn shell_completions_detects_bash() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "/bin/bash")
.success()
.stdout(output_includes("_rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_detects_zsh() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "/bin/zsh")
.success()
.stdout(output_includes("#compdef rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_detects_fish() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "/usr/bin/fish")
.success()
.stdout(output_includes("complete -c rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_detects_elvish() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "/usr/local/bin/elvish")
.success()
.stdout(output_includes(
"set edit:completion:arg-completer[rabbitmqadmin]",
));
Ok(())
}
#[test]
fn shell_completions_detects_nushell() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "/opt/homebrew/bin/nu")
.success()
.stdout(output_includes("module completions"));
Ok(())
}
#[test]
fn shell_completions_defaults_to_bash_for_unknown_shell() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "/unknown/shell")
.success()
.stdout(output_includes("_rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_defaults_to_bash_when_shell_env_unset() -> Result<(), Box<dyn Error>> {
let mut cmd = Command::new(assert_cmd::cargo::cargo_bin!("rabbitmqadmin"));
cmd.clear_shell_detection_env();
cmd.args(["shell", "completions"]);
let output = cmd.output().unwrap();
assert!(output.status.success());
assert!(String::from_utf8_lossy(&output.stdout).contains("_rabbitmqadmin"));
Ok(())
}
#[test]
fn shell_completions_includes_subcommands() -> Result<(), Box<dyn Error>> {
let output = run_succeeds(["shell", "completions", "--shell", "bash"]);
let stdout = String::from_utf8_lossy(&output.get_output().stdout);
assert!(stdout.contains("declare"));
assert!(stdout.contains("delete"));
assert!(stdout.contains("list"));
assert!(stdout.contains("show"));
assert!(stdout.contains("queues"));
assert!(stdout.contains("exchanges"));
assert!(stdout.contains("vhosts"));
Ok(())
}
#[test]
fn shell_help_shows_completions_subcommand() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "--help"]).stdout(output_includes("completions"));
Ok(())
}
#[test]
fn shell_completions_help() -> Result<(), Box<dyn Error>> {
run_succeeds(["shell", "completions", "--help"])
.stdout(output_includes("shell completion scripts"));
Ok(())
}
#[test]
fn shell_completions_rejects_invalid_shell() {
crate::test_helpers::run_fails(["shell", "completions", "--shell", "invalid"])
.stderr(output_includes("invalid value 'invalid'"));
}
#[test]
fn shell_completions_detects_shell_name_without_path() -> Result<(), Box<dyn Error>> {
run_with_shell_env(["shell", "completions"], "zsh")
.success()
.stdout(output_includes("#compdef rabbitmqadmin"));
Ok(())
}
mod property_tests {
use bel7_cli::CommandShellExt;
use proptest::prelude::*;
use std::ffi::OsStr;
use std::process::Command;
fn run_with_shell_env<I, S>(args: I, shell_path: &str) -> assert_cmd::assert::Assert
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
let mut cmd = Command::new(assert_cmd::cargo::cargo_bin!("rabbitmqadmin"));
cmd.clear_shell_detection_env();
cmd.env("SHELL", shell_path);
cmd.args(args);
assert_cmd::assert::Assert::new(cmd.output().unwrap())
}
proptest! {
#[test]
fn unknown_shells_default_to_bash(random_path in "[a-z0-9/]{1,50}") {
let path = format!("/some/path/{}", random_path);
let result = run_with_shell_env(["shell", "completions"], &path);
let output = result.get_output();
prop_assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
prop_assert!(stdout.contains("_rabbitmqadmin") || stdout.contains("#compdef") ||
stdout.contains("complete -c") || stdout.contains("module completions") ||
stdout.contains("edit:completion:arg-completer"));
}
#[test]
fn bash_detected_with_any_path_prefix(prefix in "[a-z0-9/]{0,30}") {
let path = format!("{}/bash", prefix);
let result = run_with_shell_env(["shell", "completions"], &path);
let output = result.get_output();
prop_assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
prop_assert!(stdout.contains("_rabbitmqadmin"));
}
#[test]
fn zsh_detected_with_any_path_prefix(prefix in "[a-z0-9/]{0,30}") {
let path = format!("{}/zsh", prefix);
let result = run_with_shell_env(["shell", "completions"], &path);
let output = result.get_output();
prop_assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
prop_assert!(stdout.contains("#compdef rabbitmqadmin"));
}
#[test]
fn fish_detected_with_any_path_prefix(prefix in "[a-z0-9/]{0,30}") {
let path = format!("{}/fish", prefix);
let result = run_with_shell_env(["shell", "completions"], &path);
let output = result.get_output();
prop_assert!(output.status.success());
let stdout = String::from_utf8_lossy(&output.stdout);
prop_assert!(stdout.contains("complete -c rabbitmqadmin"));
}
}
}