use std::process::Command;
fn real_session() -> String {
std::env::var("CV_REAL_SESSION")
.ok()
.filter(|s| !s.trim().is_empty())
.expect("set CV_REAL_SESSION=<session id> to run the real-data tests")
}
fn cv(args: &[&str]) -> String {
let out = Command::new(env!("CARGO_BIN_EXE_cv"))
.args(args)
.output()
.expect("cv runs");
let stdout = String::from_utf8_lossy(&out.stdout).into_owned();
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
out.status.success(),
"cv {args:?}: {}\nstdout:\n{stdout}\nstderr:\n{stderr}",
out.status
);
stdout
}
#[test]
#[ignore = "needs CV_REAL_SESSION; run with --ignored"]
fn real_prompts_are_human_lines_and_answers_only() {
let session = real_session();
let out = cv(&["show", &session, "--kind", "prompt,answer", "--json"]);
let rows: Vec<serde_json::Value> = serde_json::from_str(&out).unwrap();
assert!(!rows.is_empty(), "a real session has at least one prompt");
assert!(
rows.iter()
.all(|r| matches!(r["kind"].as_str().expect("message kind"), "prompt" | "answer")),
"every row is a prompt or an AskUserQuestion answer"
);
assert!(rows.iter().any(|r| r["kind"] == "prompt"));
assert!(!rows.iter().any(|r| r["text"]
.as_str()
.expect("prompt/answer text")
.starts_with("<command-name>")));
}
#[test]
#[ignore = "needs CV_REAL_SESSION; run with --ignored"]
fn real_lanes_census_is_consistent() {
let session = real_session();
let out = cv(&["lanes", &session, "--json"]);
let rows: Vec<serde_json::Value> = serde_json::from_str(&out).unwrap();
assert!(!rows.is_empty(), "the session has sub-agents (pick an orchestrator)");
let running = rows.iter().filter(|r| r["status"] == "running").count();
assert!(running < rows.len(), "{running} running of {}", rows.len());
assert!(rows
.iter()
.all(|r| r["model"].as_str().is_some_and(|m| m.starts_with("claude-"))));
assert!(rows.iter().all(|r| r["tokens"]["total"].as_u64().unwrap() > 0));
}