use std::fs;
use std::path::Path;
use std::process::Command;
fn list_examples() -> Vec<String> {
let mut names = Vec::new();
let entries = fs::read_dir("examples").expect("read examples dir");
for entry in entries {
let entry = entry.expect("read dir entry");
let path = entry.path();
if path.extension().and_then(|ext| ext.to_str()) != Some("rs") {
continue;
}
let Some(stem) = path.file_stem().and_then(|s| s.to_str()) else {
continue;
};
names.push(stem.to_string());
}
names.sort();
names
}
fn run_cargo(args: &[&str]) -> std::process::Output {
Command::new("cargo")
.args(args)
.output()
.expect("failed to execute cargo")
}
#[test]
fn examples_compile() {
let examples = list_examples();
let mut failures = Vec::new();
for name in &examples {
let output = run_cargo(&["build", "--all-features", "--example", name]);
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
eprintln!("Example {name} failed to compile:\n{stderr}");
failures.push(name.clone());
}
}
assert!(
failures.is_empty(),
"Examples failed to compile: {failures:?}"
);
}
#[test]
fn hello_example_runs() {
if !Path::new("examples/hello.rs").exists() {
return;
}
let output = run_cargo(&["run", "--all-features", "--example", "hello"]);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
output.status.success(),
"hello example failed: {}",
String::from_utf8_lossy(&output.stderr)
);
assert!(
stdout.contains("Buffer created"),
"hello example output missing expected text"
);
}
#[test]
fn demo_showcase_compiles() {
assert!(
Path::new("src/bin/demo_showcase.rs").exists(),
"demo_showcase.rs not found - binary target missing"
);
let output = run_cargo(&["build", "--all-features", "--bin", "demo_showcase"]);
assert!(
output.status.success(),
"demo_showcase binary failed to compile:\n\n{}\n\n\
This is a critical failure - the demo is a flagship deliverable.",
String::from_utf8_lossy(&output.stderr)
);
}
#[test]
fn demo_showcase_headless_smoke() {
let output = run_cargo(&[
"run",
"--all-features",
"--bin",
"demo_showcase",
"--",
"--headless-smoke",
"--max-frames",
"10",
"--headless-size",
"80x24",
]);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
if !output.status.success() {
eprintln!("=== STDOUT ===\n{stdout}");
eprintln!("=== STDERR ===\n{stderr}");
}
assert!(
output.status.success(),
"demo_showcase headless smoke test failed with exit code {:?}\n\
STDERR:\n{}\n\n\
This indicates a bug in the demo's render pipeline.",
output.status.code(),
stderr
);
assert!(
stdout.contains("HEADLESS_SMOKE_OK"),
"demo_showcase headless output missing HEADLESS_SMOKE_OK marker.\n\
STDOUT:\n{stdout}\n\n\
The demo should print this marker when headless smoke completes successfully."
);
}