#![cfg(feature = "e2e")]
use std::path::{Path, PathBuf};
use std::time::Instant;
use assert_cmd::Command;
use predicates::prelude::*;
fn kiln() -> Command {
Command::cargo_bin("kiln").expect("kiln binary should be built")
}
fn workspace_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(2)
.expect("workspace root above crates/kiln-cli")
.to_path_buf()
}
fn copy_example(name: &str) -> tempfile::TempDir {
let src = workspace_root().join("examples").join(name);
let tmp = tempfile::tempdir().unwrap();
copy_recursive(&src, tmp.path());
tmp
}
fn copy_recursive(src: &Path, dst: &Path) {
for entry in walkdir::WalkDir::new(src) {
let entry = entry.unwrap();
let rel = entry.path().strip_prefix(src).unwrap();
let target = dst.join(rel);
if entry.file_type().is_dir() {
std::fs::create_dir_all(&target).unwrap();
} else if entry.file_type().is_file() {
if let Some(parent) = target.parent() {
std::fs::create_dir_all(parent).unwrap();
}
std::fs::copy(entry.path(), &target).unwrap();
}
}
}
#[test]
fn list_is_stable() {
let tmp = copy_example("hello-counter");
let out = kiln()
.args(["test", "--list"])
.current_dir(tmp.path())
.assert()
.success()
.get_output()
.stdout
.clone();
insta::assert_snapshot!(
"kiln_test_list",
String::from_utf8_lossy(&out).trim().to_string()
);
}
#[test]
fn test_runs_at_least_one_pass() {
let tmp = copy_example("hello-counter");
kiln()
.arg("test")
.current_dir(tmp.path())
.assert()
.success()
.stdout(predicate::str::contains("PASS"))
.stderr(predicate::str::contains("Result"));
}
#[test]
fn substring_filter_matches_smoke() {
let tmp = copy_example("hello-counter");
let out = kiln()
.args(["test", "smoke"])
.current_dir(tmp.path())
.assert()
.success()
.get_output()
.stdout
.clone();
let stdout = String::from_utf8_lossy(&out);
assert!(stdout.contains("smoke"));
assert!(!stdout.contains("test parity"));
}
#[test]
fn no_match_returns_zero_with_helpful_text() {
let tmp = copy_example("hello-counter");
kiln()
.args(["test", "does_not_exist"])
.current_dir(tmp.path())
.assert()
.success()
.stderr(predicate::str::contains("no tests matched"));
}
#[test]
fn parallel_observably_faster_than_serial() {
let tmp = copy_example("hello-counter");
kiln()
.args(["test", "--jobs", "1"])
.current_dir(tmp.path())
.assert()
.success();
let serial = {
let t = Instant::now();
kiln()
.args(["test", "--jobs", "1"])
.current_dir(tmp.path())
.assert()
.success();
t.elapsed()
};
let parallel = {
let t = Instant::now();
kiln()
.args(["test", "--jobs", "4"])
.current_dir(tmp.path())
.assert()
.success();
t.elapsed()
};
let slack = std::time::Duration::from_millis(100);
assert!(
parallel <= serial + slack,
"parallel {parallel:?} should be ~<= serial {serial:?} (slack {slack:?})"
);
}