#![cfg(feature = "cli")]
use std::path::PathBuf;
use std::process::Command;
fn oxirouter_cli_bin() -> PathBuf {
let mut path = std::env::current_exe().expect("could not determine test binary path");
path.pop(); if path.ends_with("deps") {
path.pop(); }
path.join("oxirouter-cli")
}
#[test]
fn test_cli_help_mentions_subcommands() {
let bin = oxirouter_cli_bin();
if !bin.exists() {
return;
}
let output = Command::new(&bin)
.arg("--help")
.output()
.expect("failed to run oxirouter-cli --help");
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
let combined = format!("{stdout}{stderr}");
assert!(combined.contains("route"), "help should mention 'route'");
assert!(
combined.contains("explain"),
"help should mention 'explain'"
);
assert!(combined.contains("state"), "help should mention 'state'");
}
#[test]
fn test_cli_version_flag() {
let bin = oxirouter_cli_bin();
if !bin.exists() {
return;
}
let output = Command::new(&bin)
.arg("--version")
.output()
.expect("failed to run oxirouter-cli --version");
assert!(
output.status.success(),
"oxirouter-cli --version should exit 0"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("oxirouter-cli"),
"version output should mention binary name"
);
}
#[test]
fn test_cli_state_save_load_roundtrip() {
let bin = oxirouter_cli_bin();
if !bin.exists() {
return;
}
let state_file = std::env::temp_dir().join("oxirouter_cli_smoke_state.bin");
let save_out = Command::new(&bin)
.args([
"state",
"save",
"--file",
state_file.to_str().expect("valid path"),
])
.output()
.expect("failed to run state save");
assert!(
save_out.status.success(),
"state save failed: {}",
String::from_utf8_lossy(&save_out.stderr),
);
assert!(state_file.exists(), "state file should exist after save");
let load_out = Command::new(&bin)
.args([
"state",
"load",
"--file",
state_file.to_str().expect("valid path"),
])
.output()
.expect("failed to run state load");
assert!(
load_out.status.success(),
"state load failed: {}",
String::from_utf8_lossy(&load_out.stderr),
);
let stdout = String::from_utf8_lossy(&load_out.stdout);
assert!(
stdout.contains("sources"),
"load output should mention sources count"
);
let _ = std::fs::remove_file(&state_file);
}
#[test]
fn test_cli_state_save_json_output() {
let bin = oxirouter_cli_bin();
if !bin.exists() {
return;
}
let state_file = std::env::temp_dir().join("oxirouter_cli_smoke_json_state.bin");
let save_out = Command::new(&bin)
.args([
"--json",
"state",
"save",
"--file",
state_file.to_str().expect("valid path"),
])
.output()
.expect("failed to run --json state save");
assert!(
save_out.status.success(),
"state save --json failed: {}",
String::from_utf8_lossy(&save_out.stderr),
);
let stdout = String::from_utf8_lossy(&save_out.stdout);
let parsed: serde_json::Value =
serde_json::from_str(&stdout).expect("--json output should be valid JSON");
assert_eq!(
parsed["kind"], "state_saved",
"JSON kind should be 'state_saved'"
);
assert!(
parsed["bytes_written"].is_number(),
"JSON should include bytes_written"
);
let _ = std::fs::remove_file(&state_file);
}