use super::*;
#[test]
fn test_parses_conformance_target_selection() {
let cli = Cli::parse_from([
"harn",
"test",
"conformance",
"tests/worktree_runtime.harn",
"--verbose",
"--differential-optimizations",
]);
let Command::Test(args) = cli.command.unwrap() else {
panic!("expected test command");
};
assert_eq!(args.target.as_deref(), Some("conformance"));
assert_eq!(
args.selection.as_deref(),
Some("tests/worktree_runtime.harn")
);
assert!(args.verbose);
assert!(args.differential_optimizations);
}
#[test]
fn test_parses_config_inspect_explain() {
let cli = Cli::parse_from([
"harn",
"config",
"inspect",
"--explain",
"--config",
"local.toml",
"--managed",
"managed.toml",
]);
let Command::Config(args) = cli.command.unwrap() else {
panic!("expected config command");
};
let ConfigCommand::Inspect(inspect) = args.command else {
panic!("expected inspect command");
};
assert!(inspect.explain);
assert_eq!(inspect.config_files, vec![PathBuf::from("local.toml")]);
assert_eq!(inspect.managed_files, vec![PathBuf::from("managed.toml")]);
}
#[test]
fn test_parses_config_validate_and_schema() {
let cli = Cli::parse_from(["harn", "config", "validate", "--managed", "policy.toml"]);
let Command::Config(args) = cli.command.unwrap() else {
panic!("expected config command");
};
let ConfigCommand::Validate(validate) = args.command else {
panic!("expected validate command");
};
assert!(validate.managed);
assert_eq!(validate.files, vec![PathBuf::from("policy.toml")]);
let cli = Cli::parse_from(["harn", "config", "schema", "--output", "schema.json"]);
let Command::Config(args) = cli.command.unwrap() else {
panic!("expected config command");
};
let ConfigCommand::Schema(schema) = args.command else {
panic!("expected schema command");
};
assert_eq!(schema.output, Some(PathBuf::from("schema.json")));
}
#[test]
fn test_parses_parse_and_tokens_json() {
let parse = Cli::parse_from(["harn", "parse", "main.harn", "--json"]);
let Command::Parse(parse_args) = parse.command.unwrap() else {
panic!("expected parse command");
};
assert_eq!(parse_args.path, "main.harn");
assert!(parse_args.json);
let tokens = Cli::parse_from(["harn", "tokens", "main.harn", "--json"]);
let Command::Tokens(tokens_args) = tokens.command.unwrap() else {
panic!("expected tokens command");
};
assert_eq!(tokens_args.path, "main.harn");
assert!(tokens_args.json);
}
#[test]
fn test_parses_fix_plan_json_args() {
let cli = Cli::parse_from([
"harn",
"fix",
"--plan",
"--json",
"--safety",
"behavior-preserving",
"main.harn",
]);
let Command::Fix(args) = cli.command.unwrap() else {
panic!("expected fix command");
};
assert!(args.plan);
assert!(args.json);
assert_eq!(
args.safety.map(|safety| safety.as_str()),
Some("behavior-preserving")
);
assert_eq!(args.harness_threading, HarnessThreadingMode::LocalGlobal);
assert_eq!(args.path, PathBuf::from("main.harn"));
}
#[test]
fn test_parses_fix_apply_dry_run_args() {
let cli = Cli::parse_from([
"harn",
"fix",
"--apply",
"--dry-run",
"--json",
"--safety",
"scope-local",
"--harness-threading",
"thread-params",
"src/",
]);
let Command::Fix(args) = cli.command.unwrap() else {
panic!("expected fix command");
};
assert!(args.apply);
assert!(args.dry_run);
assert!(args.json);
assert_eq!(
args.safety.map(|safety| safety.as_str()),
Some("scope-local")
);
assert_eq!(args.harness_threading, HarnessThreadingMode::ThreadParams);
assert_eq!(args.path, PathBuf::from("src/"));
}
#[test]
fn test_parses_test_determinism_flag() {
let cli = Cli::parse_from([
"harn",
"test",
"--determinism",
"--filter",
"agent",
"tests/agent_loop.harn",
]);
let Command::Test(args) = cli.command.unwrap() else {
panic!("expected test command");
};
assert!(args.determinism);
assert_eq!(args.filter.as_deref(), Some("agent"));
assert_eq!(args.target.as_deref(), Some("tests/agent_loop.harn"));
}
#[test]
fn test_parses_new_template() {
let cli = Cli::parse_from(["harn", "new", "review-bot", "--template", "agent"]);
let Command::New(args) = cli.command.unwrap() else {
panic!("expected new command");
};
assert_eq!(args.first.as_deref(), Some("review-bot"));
assert_eq!(args.second.as_deref(), None);
assert_eq!(args.template, Some(ProjectTemplate::Agent));
}
#[test]
fn test_parses_new_package_kind() {
let cli = Cli::parse_from(["harn", "new", "package", "acme-lib"]);
let Command::New(args) = cli.command.unwrap() else {
panic!("expected new command");
};
assert_eq!(args.first.as_deref(), Some("package"));
assert_eq!(args.second.as_deref(), Some("acme-lib"));
assert_eq!(args.template, None);
}
#[test]
fn test_parses_doctor_flags() {
let cli = Cli::parse_from([
"harn",
"doctor",
"--json",
"--check-providers",
"--check-targets",
]);
let Command::Doctor(args) = cli.command.unwrap() else {
panic!("expected doctor command");
};
assert!(args.json);
assert!(args.check_providers);
assert!(args.check_targets);
}
#[test]
fn test_parses_add_registry_override() {
let cli = Cli::parse_from([
"harn",
"add",
"@burin/notion-sdk@1.2.3",
"--registry",
"index.toml",
]);
let Command::Add(args) = cli.command.unwrap() else {
panic!("expected add command");
};
assert_eq!(args.name_or_spec, "@burin/notion-sdk@1.2.3");
assert_eq!(args.registry.as_deref(), Some("index.toml"));
}
#[test]
fn test_parses_completions_args() {
let cli = Cli::parse_from(["harn", "completions", "zsh"]);
let Command::Completions(args) = cli.command.unwrap() else {
panic!("expected completions command");
};
assert_eq!(args.shell, CompletionShell::Zsh);
}
#[test]
fn test_completion_scripts_include_subcommands() {
let mut command = Cli::command();
let mut output = Vec::new();
clap_complete::generate(
clap_complete::Shell::Bash,
&mut command,
"harn",
&mut output,
);
let script = String::from_utf8(output).expect("completion script should be utf-8");
assert!(script.contains("completions"));
assert!(script.contains("provider-ready"));
}
#[test]
fn test_parses_check_provider_matrix_args() {
let cli = Cli::parse_from([
"harn",
"check",
"--provider-matrix",
"--format",
"markdown",
"--filter",
"json-schema",
]);
let Command::Check(args) = cli.command.unwrap() else {
panic!("expected check command");
};
assert!(args.provider_matrix);
assert_eq!(args.format, CheckOutputFormat::Markdown);
assert_eq!(args.filter.as_deref(), Some("json-schema"));
assert!(args.targets.is_empty());
}
#[test]
fn test_parses_check_connector_matrix_args() {
let cli = Cli::parse_from([
"harn",
"check",
"--connector-matrix",
"--format",
"json",
"--filter",
"rate-limit",
"fixtures/connectors",
]);
let Command::Check(args) = cli.command.unwrap() else {
panic!("expected check command");
};
assert!(args.connector_matrix);
assert_eq!(args.format, CheckOutputFormat::Json);
assert_eq!(args.filter.as_deref(), Some("rate-limit"));
assert_eq!(args.targets, vec!["fixtures/connectors"]);
}