use assert_cmd::Command;
use assert_cmd::cargo::cargo_bin_cmd;
use predicates::prelude::*;
use tempfile::TempDir;
fn agentic_cmd() -> Command {
cargo_bin_cmd!("agentic")
}
const CONFIG_DIR_TEST_VAR: &str = "__AGENTIC_CONFIG_DIR_FOR_TESTS";
fn agentic_cmd_isolated(config_dir: &std::path::Path) -> Command {
let mut cmd = agentic_cmd();
cmd.env(CONFIG_DIR_TEST_VAR, config_dir);
for k in [
"AGENTIC_SUBAGENTS_LOCATOR_MODEL",
"AGENTIC_SUBAGENTS_ANALYZER_MODEL",
"AGENTIC_REASONING_OPTIMIZER_MODEL",
"AGENTIC_REASONING_EXECUTOR_MODEL",
"AGENTIC_REASONING_EFFORT",
] {
cmd.env_remove(k);
}
cmd
}
#[test]
fn test_schema_outputs_valid_json() {
let mut cmd = agentic_cmd();
cmd.args(["config", "schema"])
.assert()
.success()
.stdout(
predicate::str::contains("\"$defs\"").or(predicate::str::contains("\"definitions\"")),
)
.stdout(predicate::str::contains("AgenticConfig"));
}
#[test]
fn test_show_outputs_toml() {
let temp = TempDir::new().unwrap();
let mut cmd = agentic_cmd();
cmd.args(["config", "show", "--path", temp.path().to_str().unwrap()])
.assert()
.success()
.stdout(predicate::str::contains("[subagents]"))
.stdout(predicate::str::contains("[services.anthropic]"));
}
#[test]
fn test_show_json_flag() {
let temp = TempDir::new().unwrap();
let mut cmd = agentic_cmd();
cmd.args([
"config",
"show",
"--json",
"--path",
temp.path().to_str().unwrap(),
])
.assert()
.success()
.stdout(predicate::str::contains("\"subagents\""))
.stdout(predicate::str::contains("\"services\""));
}
#[test]
fn test_init_creates_config_file() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("agentic.toml");
let mut cmd = agentic_cmd();
cmd.current_dir(temp.path())
.args(["config", "init"])
.assert()
.success()
.stdout(predicate::str::contains("Created"));
assert!(config_path.exists());
let content = std::fs::read_to_string(&config_path).unwrap();
let _: toml::Value = toml::from_str(&content).unwrap();
}
#[test]
fn test_init_fails_if_exists_without_force() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("agentic.toml");
std::fs::write(&config_path, "# existing config").unwrap();
let mut cmd = agentic_cmd();
cmd.current_dir(temp.path())
.args(["config", "init"])
.assert()
.failure()
.stderr(predicate::str::contains("already exists"));
}
#[test]
fn test_init_succeeds_with_force() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("agentic.toml");
std::fs::write(&config_path, "# old config").unwrap();
let mut cmd = agentic_cmd();
cmd.current_dir(temp.path())
.args(["config", "init", "--force"])
.assert()
.success();
let content = std::fs::read_to_string(&config_path).unwrap();
assert!(content.contains("[subagents]"));
}
#[test]
fn test_validate_succeeds_on_valid_config() {
let temp = TempDir::new().unwrap();
let mut cmd = agentic_cmd();
cmd.args([
"config",
"validate",
"--path",
temp.path().to_str().unwrap(),
])
.assert()
.success()
.stdout(predicate::str::contains("valid"));
}
#[test]
fn test_validate_shows_warnings() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("agentic.toml");
std::fs::write(
&config_path,
r#"
[services.anthropic]
base_url = "not-a-url"
"#,
)
.unwrap();
let mut cmd = agentic_cmd();
cmd.args([
"config",
"validate",
"--path",
temp.path().to_str().unwrap(),
])
.assert()
.success()
.stdout(predicate::str::contains("warning"));
}
#[test]
fn test_show_with_local_config() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("agentic.toml");
std::fs::write(
&config_path,
r#"
[subagents]
locator_model = "custom-locator-model"
"#,
)
.unwrap();
let mut cmd = agentic_cmd();
cmd.args(["config", "show", "--path", temp.path().to_str().unwrap()])
.assert()
.success()
.stdout(predicate::str::contains("custom-locator-model"));
}
#[test]
fn test_show_reflects_env_overrides() {
let temp = TempDir::new().unwrap();
let mut cmd = agentic_cmd_isolated(temp.path());
cmd.env("AGENTIC_SUBAGENTS_LOCATOR_MODEL", "env-override-model")
.args(["config", "show", "--path", temp.path().to_str().unwrap()])
.assert()
.success()
.stdout(predicate::str::contains("env-override-model"));
}
#[test]
fn test_version_flag() {
let mut cmd = agentic_cmd();
cmd.arg("--version")
.assert()
.success()
.stdout(predicate::str::contains("agentic"));
}
#[test]
fn test_help_flag() {
let mut cmd = agentic_cmd();
cmd.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("config"))
.stdout(predicate::str::contains("Configuration"));
}
#[test]
fn test_warns_on_unknown_top_level_key() {
let temp = TempDir::new().unwrap();
let config_path = temp.path().join("agentic.toml");
std::fs::write(
&config_path,
r#"
unknown_section = "value"
"#,
)
.unwrap();
let mut cmd = agentic_cmd();
cmd.args([
"config",
"validate",
"--path",
temp.path().to_str().unwrap(),
])
.assert()
.success()
.stdout(predicate::str::contains("unknown").or(predicate::str::contains("Unknown")));
}