use crate::commands::InitMode;
use crate::commands::parse_init_mode;
use crate::init::InitFormat;
fn args(t: &[&str]) -> Vec<String> {
t.iter().map(|s| s.to_string()).collect()
}
#[test]
fn agent_without_value_is_error() {
let err = parse_init_mode(&args(&["--agent"])).expect_err("--agent without a value must error");
assert!(
err.contains("--agent"),
"error must name the --agent flag: {err:?}"
);
assert!(
err.contains("pi, claude-code"),
"error must name the supported values: {err:?}"
);
}
#[test]
fn agent_followed_by_flag_is_error() {
let err =
parse_init_mode(&args(&["--agent", "--global"])).expect_err("flag-like value must error");
assert!(
err.contains("--agent"),
"error must name the --agent flag: {err:?}"
);
assert!(
err.contains("pi, claude-code"),
"error must name the supported values: {err:?}"
);
}
#[test]
fn format_without_value_is_error() {
let err = parse_init_mode(&args(&["--format"])).expect_err("bare --format must error");
assert!(
err.contains("--format requires a value"),
"message: {err:?}"
);
}
#[test]
fn format_followed_by_flag_does_not_consume_it() {
let err =
parse_init_mode(&args(&["--format", "--bogus"])).expect_err("flag-like value must error");
assert!(err.contains("'--bogus'"), "message: {err:?}");
}
#[test]
fn agent_and_format_mutually_exclusive_any_order_any_value() {
for flag_order in [
&["--agent", "pi", "--format", "bogus"][..],
&["--format", "bogus", "--agent", "pi"][..],
&["--agent", "pi", "--format", "claude"][..],
&["--format", "generic", "--agent", "pi"][..],
&["--agent", "pi", "--format"][..],
] {
let err = parse_init_mode(&args(flag_order))
.expect_err("combining --agent and --format must error: {flag_order:?}");
assert!(
err.contains("--agent and --format"),
"error must name the conflicting flags ({flag_order:?}): {err:?}"
);
}
}
#[test]
fn global_without_agent_is_error() {
let err =
parse_init_mode(&args(&["--global"])).expect_err("--global without --agent must error");
assert!(
err.contains("--global"),
"error must name the --global flag: {err:?}"
);
}
#[test]
fn global_with_format_without_agent_is_error() {
let err = parse_init_mode(&args(&["--global", "--format", "generic"]))
.expect_err("--global with --format but no --agent must error");
assert!(
err.contains("--global"),
"error must name the --global flag: {err:?}"
);
}
#[test]
fn agent_pi_global_works_both_orders() {
for flag_order in [
&["--agent", "pi", "--global"][..],
&["--global", "--agent", "pi"][..],
] {
let mode = parse_init_mode(&args(flag_order))
.expect("--agent pi --global must parse: {flag_order:?}");
assert_eq!(mode, InitMode::Pi { global: true }, "order {flag_order:?}");
}
}
#[test]
fn unknown_flags_are_errors() {
for case in [
&["--bogus"][..],
&["--agent", "pi", "--bogus"][..],
&["--format", "generic", "--bogus"][..],
] {
let err = parse_init_mode(&args(case)).expect_err("unknown option must error");
assert_eq!(
err, "init: unknown option '--bogus' (try: oo init --help)",
"case {case:?}"
);
}
}
#[test]
fn stray_positional_is_error() {
let err = parse_init_mode(&args(&["stray"])).expect_err("stray positional must error");
assert!(err.contains("'stray'"), "message: {err:?}");
}
#[test]
fn plain_init_is_claude() {
let mode = parse_init_mode(&args(&[])).expect("plain init must parse");
assert_eq!(mode, InitMode::Format(InitFormat::Claude));
}
#[test]
fn format_generic_unchanged() {
let mode = parse_init_mode(&args(&["--format", "generic"])).expect("must parse");
assert_eq!(mode, InitMode::Format(InitFormat::Generic));
}
#[test]
fn format_claude_unchanged() {
let mode = parse_init_mode(&args(&["--format", "claude"])).expect("must parse");
assert_eq!(mode, InitMode::Format(InitFormat::Claude));
}
#[test]
fn format_bogus_is_error() {
let err = parse_init_mode(&args(&["--format", "bogus"])).expect_err("bogus format must error");
assert_eq!(
err,
"oo init: unsupported format 'bogus' (supported: claude, generic)"
);
}
#[test]
fn format_repeated_is_error() {
for pair in [
["claude", "generic"],
["bogus", "claude"],
["claude", "bogus"],
] {
let err = parse_init_mode(&args(&["--format", pair[0], "--format", pair[1]]))
.expect_err("repeated --format must error");
assert!(
err.contains("--format given more than once"),
"message: {err:?}"
);
}
}
#[test]
fn agent_pi_selects_pi_installer() {
let mode = parse_init_mode(&args(&["--agent", "pi"])).expect("must parse");
assert_eq!(mode, InitMode::Pi { global: false });
}
#[test]
fn agent_claude_code_selects_installer() {
let mode = parse_init_mode(&args(&["--agent", "claude-code"]))
.expect("--agent claude-code must parse");
assert_eq!(mode, InitMode::ClaudeCode { global: false });
}
#[test]
fn agent_claude_code_global_works_both_orders() {
for flag_order in [
&["--agent", "claude-code", "--global"][..],
&["--global", "--agent", "claude-code"][..],
] {
let mode = parse_init_mode(&args(flag_order))
.expect("--agent claude-code --global must parse: {flag_order:?}");
assert_eq!(
mode,
InitMode::ClaudeCode { global: true },
"order {flag_order:?}"
);
}
}
#[test]
fn repeated_flags_are_errors_in_every_order() {
let cases: &[(&[&str], &str)] = &[
(&["--format", "claude", "--format", "generic"], "--format"),
(&["--format", "generic", "--format", "claude"], "--format"),
(&["--format", "bogus", "--format", "claude"], "--format"),
(&["--format", "claude", "--format"], "--format"),
(&["--format", "--format", "claude"], "--format"),
(&["--agent", "pi", "--agent", "claude-code"], "--agent"),
(&["--agent", "claude-code", "--agent", "pi"], "--agent"),
(&["--agent", "pi", "--agent", "bogus"], "--agent"),
(&["--agent", "pi", "--global", "--agent", "pi"], "--agent"),
(&["--global", "--agent", "pi", "--global"], "--global"),
(&["--agent", "pi", "--global", "--global"], "--global"),
(&["--global", "--global", "--agent", "pi"], "--global"),
(&["--global", "--format", "claude", "--global"], "--global"),
];
for (case, flag) in cases {
let err = parse_init_mode(&args(case)).expect_err("repeated flag must error");
assert!(
err.contains(&format!("{flag} given more than once")),
"case {case:?}: {err:?}"
);
}
}
#[test]
fn every_supported_agent_parses() {
for agent in crate::init_cmd::SUPPORTED_AGENTS {
let res = parse_init_mode(&args(&["--agent", agent]));
assert!(res.is_ok(), "supported agent {agent} must parse: {res:?}");
}
}
#[test]
fn agent_unknown_value_errors_naming_supported() {
let err = parse_init_mode(&args(&["--agent", "cursor"])).expect_err("unknown agent must error");
assert!(
err.contains("unknown --agent value 'cursor'"),
"message: {err:?}"
);
assert!(
err.contains("pi, claude-code"),
"error must name the supported values: {err:?}"
);
}