use std::fs;
use std::path::Path;
use assert_cmd::Command;
use tempfile::TempDir;
const MARKER: &str = "/*__TINYVIEW__*/ null /*__TINYVIEW__*/";
fn home_with_template(name: &str, body: &str) -> TempDir {
let home = tempfile::tempdir().expect("create temp HOME");
let templates = home.path().join(".tinyview").join("templates");
fs::create_dir_all(&templates).expect("mkdir templates");
fs::write(templates.join(format!("{name}.html")), body).expect("write template");
home
}
fn dump_cmd(home: &Path) -> Command {
let mut cmd = Command::cargo_bin("tinyview").expect("locate tinyview binary");
cmd.env("HOME", home)
.env_remove("XDG_CONFIG_HOME")
.env("TINYVIEW_DUMP_HTML", "1");
cmd
}
fn template_with_marker() -> String {
format!(
"<!doctype html>\n<html><head>\n\
<script>window.__TINYVIEW__ = {MARKER};</script>\n\
</head><body><main id=\"out\"></main>\n\
<script>document.getElementById('out').textContent = \
window.__TINYVIEW__.input;</script>\n\
</body></html>",
)
}
#[test]
fn user_template_resolves_reads_and_injects() {
let home = home_with_template("custom", &template_with_marker());
let assert = dump_cmd(home.path())
.args(["-t", "custom"])
.write_stdin("<h1>Hello & world</h1>")
.assert()
.success();
let out = String::from_utf8(assert.get_output().stdout.clone()).expect("utf8 stdout");
assert!(
out.contains(r#"<main id="out">"#),
"template body missing:\n{out}"
);
assert!(!out.contains(MARKER), "marker should be gone:\n{out}");
assert!(
out.contains(r#""input":"<h1>Hello & world</h1>""#),
"input not injected:\n{out}"
);
assert!(
out.contains(r#""path":null"#),
"path should be null:\n{out}"
);
assert!(
out.contains(r#""title":"tinyview""#),
"title missing:\n{out}"
);
}
#[test]
fn user_template_params_are_injected() {
let home = home_with_template("themed", &template_with_marker());
let assert = dump_cmd(home.path())
.args(["-t", "themed", "--param", "theme=solarized"])
.write_stdin("x")
.assert()
.success();
let out = String::from_utf8(assert.get_output().stdout.clone()).expect("utf8 stdout");
assert!(
out.contains(r#""theme":"solarized""#),
"param not injected:\n{out}"
);
}
#[test]
fn user_template_without_marker_passes_through_with_warning() {
let body = "<!doctype html>\n<html><body>no marker here</body></html>";
let home = home_with_template("nomarker", body);
let assert = dump_cmd(home.path())
.args(["--html", "ignored", "-t", "nomarker"])
.write_stdin("")
.assert()
.success();
let out = String::from_utf8(assert.get_output().stdout.clone()).expect("utf8 stdout");
let err = String::from_utf8(assert.get_output().stderr.clone()).expect("utf8 stderr");
assert_eq!(
out, body,
"marker-less template must pass through unchanged"
);
assert!(
err.contains("no") && err.contains("marker"),
"expected a marker warning on stderr, got:\n{err}"
);
}
#[test]
fn missing_user_template_fails_cleanly() {
let home = tempfile::tempdir().expect("temp HOME");
fs::create_dir_all(home.path().join(".tinyview").join("templates")).expect("mkdir");
let assert = dump_cmd(home.path())
.args(["--html", "x", "-t", "does-not-exist"])
.write_stdin("")
.assert()
.failure();
let out = assert.get_output().stdout.clone();
let err = String::from_utf8(assert.get_output().stderr.clone()).expect("utf8 stderr");
assert!(out.is_empty(), "no HTML should be emitted on error");
assert!(
err.contains("tinyview:") && err.contains("template"),
"expected a clean template-read error, got:\n{err}"
);
assert!(!err.contains("panicked"), "should not panic:\n{err}");
}