use std::process::Command;
#[test]
fn test_cli_help() {
let output = Command::new("cargo")
.args(["run", "--", "--help"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
assert!(stdout.contains("bandwidth"));
}
#[test]
fn test_cli_version() {
let output = Command::new("cargo")
.args(["run", "--", "--version"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
assert!(
stdout.chars().any(|c| c.is_ascii_digit()),
"Version output should contain at least one digit"
);
}
#[test]
fn test_shell_completion_bash() {
let output = Command::new("cargo")
.args(["run", "--", "--generate-completion", "bash"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
}
#[test]
fn test_shell_completion_zsh() {
let output = Command::new("cargo")
.args(["run", "--", "--generate-completion", "zsh"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
}
#[test]
fn test_shell_completion_fish() {
let output = Command::new("cargo")
.args(["run", "--", "--generate-completion", "fish"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
}
#[test]
fn test_shell_completion_powershell() {
let output = Command::new("cargo")
.args(["run", "--", "--generate-completion", "power-shell"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
}
#[test]
fn test_shell_completion_elvish() {
let output = Command::new("cargo")
.args(["run", "--", "--generate-completion", "elvish"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(stdout.contains("netspeed-cli"));
}
#[test]
fn test_invalid_csv_delimiter() {
let output = Command::new("cargo")
.args(["run", "--", "--csv-delimiter", "abc"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!output.status.success());
assert!(stderr.contains("CSV delimiter") || stderr.contains("error"));
}
#[test]
fn test_invalid_source_ip() {
let output = Command::new("cargo")
.args(["run", "--", "--source", "999.999.999.999"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!output.status.success());
assert!(stderr.contains("IP") || stderr.contains("error"));
}
#[test]
fn test_zero_timeout() {
let output = Command::new("cargo")
.args(["run", "--", "--timeout", "0"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!output.status.success());
assert!(stderr.contains("timeout") || stderr.contains("error"));
}
#[test]
fn test_timeout_too_large() {
let output = Command::new("cargo")
.args(["run", "--", "--timeout", "999"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!output.status.success());
assert!(stderr.contains("timeout") || stderr.contains("error"));
}
#[test]
fn test_list_flag_parsing() {
let output = Command::new("cargo")
.args(["run", "--", "--list"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_json_flag_parsing() {
let output = Command::new("cargo")
.args(["run", "--", "--json"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_csv_flag_parsing() {
let output = Command::new("cargo")
.args(["run", "--", "--csv"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_no_download_flag_parsing() {
let output = Command::new("cargo")
.args(["run", "--", "--no-download"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_no_upload_flag_parsing() {
let output = Command::new("cargo")
.args(["run", "--", "--no-upload"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_single_flag_parsing() {
let output = Command::new("cargo")
.args(["run", "--", "--single"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_multiple_server_flags() {
let output = Command::new("cargo")
.args(["run", "--", "--server", "1234", "--server", "5678"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_combined_flags() {
let output = Command::new("cargo")
.args([
"run",
"--",
"--no-upload",
"--json",
"--single",
"--timeout",
"5",
])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("error: unexpected argument"));
}
#[test]
fn test_error_output_format() {
let output = Command::new("cargo")
.args(["run", "--", "--source", "invalid"])
.output()
.expect("Failed to execute command");
assert!(!output.status.success());
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("Error") || stderr.contains("error") || stderr.contains("invalid"),
"Expected user-friendly error message, got: {stderr}"
);
}
#[test]
fn test_exit_code_on_error() {
let output = Command::new("cargo")
.args(["run", "--", "--source", "999.999.999.999"])
.output()
.expect("Failed to execute command");
assert!(!output.status.success());
let exit_code = output.status.code();
assert!(
exit_code == Some(1) || exit_code == Some(2),
"Expected exit code 1 (runtime error) or 2 (clap validation error), got {exit_code:?}"
);
}
#[test]
fn test_version_matches_cargo_toml() {
let output = Command::new("cargo")
.args(["run", "--", "--version"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(
stdout.contains("netspeed-cli"),
"Version output should contain binary name: {stdout}"
);
}
#[test]
fn test_history_no_data() {
let output = Command::new("cargo")
.args(["run", "--", "--history"])
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(!stderr.contains("panicked"));
assert!(!stderr.contains("panic"));
}
#[test]
fn test_help_contains_expected_options() {
let output = Command::new("cargo")
.args(["run", "--", "--help"])
.output()
.expect("Failed to execute command");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(output.status.success());
assert!(
stdout.contains("--no-download"),
"Missing --no-download in help"
);
assert!(
stdout.contains("--no-upload"),
"Missing --no-upload in help"
);
assert!(stdout.contains("--single"), "Missing --single in help");
assert!(stdout.contains("--json"), "Missing --json in help");
assert!(stdout.contains("--csv"), "Missing --csv in help");
assert!(stdout.contains("--list"), "Missing --list in help");
assert!(stdout.contains("--server"), "Missing --server in help");
assert!(stdout.contains("--history"), "Missing --history in help");
assert!(stdout.contains("--timeout"), "Missing --timeout in help");
}