use std::borrow::Cow;
use secure_output::encode::OutputEncoder;
use secure_output::shell::{encode, ShellEncoder};
fn assert_single_quoted(result: &str, label: &str) {
assert!(
result.starts_with('\'') && result.ends_with('\''),
"{label}: expected single-quoted output, got: {result}"
);
}
#[test]
fn shell_alphanumeric_passes_through() {
let input = "backup-2024";
let result = encode(input);
assert_eq!(result, "backup-2024");
assert!(matches!(result, Cow::Borrowed(_)));
}
#[test]
fn shell_semicolon_escaped() {
let input = "file; rm -rf /";
let result = encode(input);
assert_single_quoted(&result, "semicolon");
assert_eq!(result, "'file; rm -rf /'");
}
#[test]
fn shell_pipe_escaped() {
let input = "file | cat /etc/passwd";
let result = encode(input);
assert_single_quoted(&result, "pipe");
}
#[test]
fn shell_backtick_escaped() {
let input = "file`id`";
let result = encode(input);
assert_single_quoted(&result, "backtick");
}
#[test]
fn shell_dollar_sign_escaped() {
let input = "$HOME";
let result = encode(input);
assert_single_quoted(&result, "dollar");
}
#[test]
fn shell_newline_escaped() {
let input = "file\nid";
let result = encode(input);
assert_single_quoted(&result, "newline");
}
#[test]
fn shell_empty_input_returns_empty() {
let input = "";
let result = encode(input);
assert_eq!(result, "");
}
#[test]
fn shell_null_byte_stripped() {
let input = "file\x00name";
let result = encode(input);
assert!(!result.contains('\x00'));
assert!(result.contains("filename"));
}
#[test]
fn shell_ampersand_escaped() {
let input = "file & id";
let result = encode(input);
assert_single_quoted(&result, "ampersand");
}
#[test]
fn shell_parentheses_escaped() {
let input = "$(id)";
let result = encode(input);
assert_single_quoted(&result, "parens");
}
#[test]
fn shell_single_quote_escaped() {
let input = "it's";
let result = encode(input);
assert_eq!(result, "'it'\\''s'");
}
#[test]
fn free_function_matches_trait_shell() {
let inputs = [
"backup-2024",
"file; rm -rf /",
"file | cat /etc/passwd",
"file`id`",
"$HOME",
"file\nid",
"",
];
let encoder = ShellEncoder;
for input in &inputs {
assert_eq!(
encode(input).as_ref(),
encoder.encode(input).as_ref(),
"Mismatch for shell input: {:?}",
input
);
}
}