use std::path::Path;
pub(crate) const DEMO_ARTIFACT: &str = "hello_metaharness.txt";
pub(crate) const DEMO_CONTENT: &str = "metaharness OK";
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum VerifyOutcome {
Pass,
Missing,
WrongContent {
found_preview: String,
},
}
impl VerifyOutcome {
pub(crate) fn is_pass(&self) -> bool {
matches!(self, VerifyOutcome::Pass)
}
pub(crate) fn status(&self) -> &'static str {
match self {
VerifyOutcome::Pass => "pass",
VerifyOutcome::Missing => "missing",
VerifyOutcome::WrongContent { .. } => "wrong-content",
}
}
}
pub(crate) fn expected_content(run_id: &str) -> String {
format!("{DEMO_CONTENT} (run {run_id})")
}
pub(crate) fn demo_task(run_id: &str) -> String {
let body = expected_content(run_id);
format!(
"Create a file named `{DEMO_ARTIFACT}` in the current project directory \
whose contents are exactly the single line `{body}`. Use your file-writing \
tools to create it, confirm it exists, then end the session."
)
}
fn preview(body: &str) -> String {
const MAX: usize = 120;
let one_line: String = body.replace(['\n', '\r'], " ");
if one_line.chars().count() > MAX {
let truncated: String = one_line.chars().take(MAX).collect();
format!("{truncated}…")
} else {
one_line
}
}
pub(crate) fn verify_artifact(project_dir: &Path, expected_marker: &str) -> VerifyOutcome {
let path = project_dir.join(DEMO_ARTIFACT);
match std::fs::read_to_string(&path) {
Ok(body) if body.contains(expected_marker) => VerifyOutcome::Pass,
Ok(body) => VerifyOutcome::WrongContent {
found_preview: preview(&body),
},
Err(_) => VerifyOutcome::Missing,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn demo_task_names_artifact() {
let task = demo_task("abc123");
assert!(
task.contains(DEMO_ARTIFACT),
"task must name the artifact file: {task}"
);
}
#[test]
fn demo_task_embeds_expected_content() {
let task = demo_task("abc123");
assert!(
task.contains(&expected_content("abc123")),
"task must embed the expected content marker: {task}"
);
}
#[test]
fn expected_content_embeds_run_id() {
let body = expected_content("run-42");
assert!(body.contains(DEMO_CONTENT), "body keeps the stable marker");
assert!(body.contains("run-42"), "body embeds the run id");
}
#[test]
fn verify_reports_missing() {
let tmp = tempfile::tempdir().expect("tempdir");
assert_eq!(
verify_artifact(tmp.path(), DEMO_CONTENT),
VerifyOutcome::Missing
);
}
#[test]
fn verify_passes_on_matching_content() {
let tmp = tempfile::tempdir().expect("tempdir");
let marker = expected_content("run-1");
std::fs::write(tmp.path().join(DEMO_ARTIFACT), format!("{marker}\n"))
.expect("write artifact");
let outcome = verify_artifact(tmp.path(), &marker);
assert_eq!(outcome, VerifyOutcome::Pass);
assert!(outcome.is_pass());
assert_eq!(outcome.status(), "pass");
}
#[test]
fn verify_passes_when_marker_is_substring() {
let tmp = tempfile::tempdir().expect("tempdir");
std::fs::write(
tmp.path().join(DEMO_ARTIFACT),
"Done!\nmetaharness OK (run x)\nGoodbye.\n",
)
.expect("write artifact");
assert_eq!(
verify_artifact(tmp.path(), "metaharness OK (run x)"),
VerifyOutcome::Pass
);
}
#[test]
fn verify_fails_on_wrong_content() {
let tmp = tempfile::tempdir().expect("tempdir");
std::fs::write(tmp.path().join(DEMO_ARTIFACT), "something else entirely")
.expect("write artifact");
let outcome = verify_artifact(tmp.path(), DEMO_CONTENT);
match &outcome {
VerifyOutcome::WrongContent { found_preview } => {
assert!(found_preview.contains("something else"));
}
other => panic!("expected WrongContent, got {other:?}"),
}
assert!(!outcome.is_pass());
assert_eq!(outcome.status(), "wrong-content");
}
#[test]
fn verify_outcome_status_tokens() {
assert_eq!(VerifyOutcome::Pass.status(), "pass");
assert_eq!(VerifyOutcome::Missing.status(), "missing");
assert_eq!(
VerifyOutcome::WrongContent {
found_preview: "x".into()
}
.status(),
"wrong-content"
);
}
#[test]
fn preview_truncates_long_bodies() {
let body = "a".repeat(500);
let p = preview(&body);
assert_eq!(p.chars().count(), 121);
assert!(p.ends_with('…'));
}
#[test]
fn preview_collapses_newlines() {
let p = preview("line1\nline2\r\nline3");
assert!(!p.contains('\n'));
assert!(!p.contains('\r'));
assert!(p.contains("line1 line2"));
}
}