YAML parses cleanly and kubectl dry-run returns no errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
185 lines
5.4 KiB
Rust
185 lines
5.4 KiB
Rust
use clap::Parser;
|
|
/// CLI tests (Phase 10).
|
|
///
|
|
/// Verifies that the CLI struct parses correctly and that the `version_string`
|
|
/// helper produces the expected output.
|
|
use claude_print::cli::{version_string, Cli, OutputFormat};
|
|
|
|
// ── OutputFormat Display ──────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn output_format_display_text() {
|
|
assert_eq!(format!("{}", OutputFormat::Text), "text");
|
|
}
|
|
|
|
#[test]
|
|
fn output_format_display_json() {
|
|
assert_eq!(format!("{}", OutputFormat::Json), "json");
|
|
}
|
|
|
|
#[test]
|
|
fn output_format_display_stream_json() {
|
|
assert_eq!(format!("{}", OutputFormat::StreamJson), "stream-json");
|
|
}
|
|
|
|
// ── version_string format ─────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn version_string_contains_claude_print_prefix() {
|
|
let s = version_string(Some("2.1.168"));
|
|
assert!(
|
|
s.starts_with("claude-print "),
|
|
"version string must start with 'claude-print '; got: {s:?}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn version_string_contains_wrapping_claude() {
|
|
let s = version_string(Some("2.1.168"));
|
|
assert!(
|
|
s.contains("wrapping claude 2.1.168"),
|
|
"version string must contain 'wrapping claude <version>'; got: {s:?}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn version_string_not_found() {
|
|
let s = version_string(None);
|
|
assert!(
|
|
s.contains("not found"),
|
|
"version string with None must say 'not found'; got: {s:?}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn version_string_format_is_parseable() {
|
|
let s = version_string(Some("2.0.0"));
|
|
// Must match: "claude-print X.Y.Z (wrapping claude A.B.C)"
|
|
assert!(s.contains('('), "must have opening paren");
|
|
assert!(s.contains(')'), "must have closing paren");
|
|
let inside: &str = s
|
|
.split('(')
|
|
.nth(1)
|
|
.and_then(|s| s.split(')').next())
|
|
.unwrap_or("");
|
|
assert!(
|
|
inside.starts_with("wrapping claude"),
|
|
"content in parens must start with 'wrapping claude'; got: {inside:?}"
|
|
);
|
|
}
|
|
|
|
// ── CLI argument parsing ──────────────────────────────────────────────────────
|
|
|
|
#[test]
|
|
fn cli_positional_prompt_parsed() {
|
|
let cli = Cli::try_parse_from(["claude-print", "hello world"]).unwrap();
|
|
assert_eq!(cli.prompt.as_deref(), Some("hello world"));
|
|
}
|
|
|
|
#[test]
|
|
fn cli_no_prompt_gives_none() {
|
|
let cli = Cli::try_parse_from(["claude-print"]).unwrap();
|
|
assert!(
|
|
cli.prompt.is_none(),
|
|
"no positional arg should give None prompt"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_output_format_default_is_text() {
|
|
let cli = Cli::try_parse_from(["claude-print"]).unwrap();
|
|
assert!(matches!(cli.output_format, OutputFormat::Text));
|
|
}
|
|
|
|
#[test]
|
|
fn cli_output_format_json() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--output-format", "json"]).unwrap();
|
|
assert!(matches!(cli.output_format, OutputFormat::Json));
|
|
}
|
|
|
|
#[test]
|
|
fn cli_output_format_stream_json() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--output-format", "stream-json"]).unwrap();
|
|
assert!(matches!(cli.output_format, OutputFormat::StreamJson));
|
|
}
|
|
|
|
#[test]
|
|
fn cli_output_format_invalid_returns_error() {
|
|
let result = Cli::try_parse_from(["claude-print", "--output-format", "xml"]);
|
|
assert!(
|
|
result.is_err(),
|
|
"invalid output format must produce a parse error"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_no_inherit_hooks_flag() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--no-inherit-hooks"]).unwrap();
|
|
assert!(
|
|
cli.no_inherit_hooks,
|
|
"--no-inherit-hooks must set no_inherit_hooks=true"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_no_inherit_hooks_defaults_false() {
|
|
let cli = Cli::try_parse_from(["claude-print"]).unwrap();
|
|
assert!(
|
|
!cli.no_inherit_hooks,
|
|
"no_inherit_hooks must default to false"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_verbose_flag() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--verbose"]).unwrap();
|
|
assert!(cli.verbose);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_dangerously_skip_permissions_flag() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--dangerously-skip-permissions"]).unwrap();
|
|
assert!(cli.dangerously_skip_permissions);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_max_turns_default_is_30() {
|
|
let cli = Cli::try_parse_from(["claude-print"]).unwrap();
|
|
assert_eq!(cli.max_turns, 30, "max_turns must default to 30");
|
|
}
|
|
|
|
#[test]
|
|
fn cli_max_turns_custom() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--max-turns", "5"]).unwrap();
|
|
assert_eq!(cli.max_turns, 5);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_timeout_default_is_3600() {
|
|
let cli = Cli::try_parse_from(["claude-print"]).unwrap();
|
|
assert_eq!(cli.timeout, 3600, "timeout must default to 3600");
|
|
}
|
|
|
|
#[test]
|
|
fn cli_input_file_flag() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--input-file", "/tmp/prompt.txt"]).unwrap();
|
|
assert_eq!(
|
|
cli.input_file.as_deref(),
|
|
Some(std::path::Path::new("/tmp/prompt.txt"))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_claude_binary_flag() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--claude-binary", "/usr/bin/claude"]).unwrap();
|
|
assert_eq!(
|
|
cli.claude_binary.as_deref(),
|
|
Some(std::path::Path::new("/usr/bin/claude"))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cli_model_flag() {
|
|
let cli = Cli::try_parse_from(["claude-print", "--model", "claude-opus-4-8"]).unwrap();
|
|
assert_eq!(cli.model.as_deref(), Some("claude-opus-4-8"));
|
|
}
|