use std::path::PathBuf;
use std::process::{Command, Stdio};
fn lifeloop_bin() -> std::path::PathBuf {
std::path::PathBuf::from(env!("CARGO_BIN_EXE_lifeloop"))
}
fn conformance_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("conformance")
}
fn run(args: &[&str]) -> (i32, String, String) {
let out = Command::new(lifeloop_bin())
.args(args)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.expect("spawn lifeloop");
(
out.status.code().unwrap_or(-1),
String::from_utf8_lossy(&out.stdout).into_owned(),
String::from_utf8_lossy(&out.stderr).into_owned(),
)
}
#[test]
fn conformance_run_walks_full_corpus_and_emits_jsonl() {
let root = conformance_root();
let (code, stdout, stderr) = run(&["conformance", "run", "--root", root.to_str().unwrap()]);
assert_eq!(code, 0, "stderr=`{stderr}`");
let lines: Vec<&str> = stdout.lines().filter(|l| !l.is_empty()).collect();
assert!(
lines.len() >= 30,
"expected many fixtures, got {}",
lines.len()
);
for line in &lines {
let v: serde_json::Value = serde_json::from_str(line).expect("each line is JSON");
assert!(v.get("path").is_some(), "row missing path: {line}");
assert!(v.get("kind").is_some(), "row missing kind: {line}");
assert!(v.get("expect").is_some(), "row missing expect: {line}");
assert!(v.get("outcome").is_some(), "row missing outcome: {line}");
}
}
#[test]
fn conformance_run_summary_emits_one_object() {
let root = conformance_root();
let (code, stdout, stderr) = run(&[
"conformance",
"run",
"--root",
root.to_str().unwrap(),
"--summary",
]);
assert_eq!(code, 0, "stderr=`{stderr}`");
let v: serde_json::Value = serde_json::from_str(&stdout).expect("summary is JSON");
let total = v.get("total").and_then(|n| n.as_u64()).unwrap();
let passed = v.get("passed").and_then(|n| n.as_u64()).unwrap();
assert!(total > 0);
assert_eq!(total, passed, "every fixture should have passed");
}
#[test]
fn conformance_run_missing_root_is_input_error() {
let (code, _stdout, stderr) = run(&["conformance", "run", "--root", "/nonexistent/path/xyz"]);
assert_eq!(code, 3, "expected input exit (3), got {code}");
assert!(stderr.contains("not a directory"));
}
#[test]
fn conformance_run_unknown_flag_is_usage_error() {
let (code, _stdout, stderr) = run(&["conformance", "run", "--bogus"]);
assert_eq!(code, 2);
assert!(stderr.contains("unknown flag"));
}