use std::fs;
use std::io::Write;
use std::process::{Command, Stdio};
use tempfile::TempDir;
const STATUSLINE_PAYLOAD: &[u8] = include_bytes!("fixtures/claude_minimal.json");
const LOG_PLUGIN: &str = r#"
const ID = "echo";
fn render(ctx) {
log("hello");
#{ runs: [#{ text: "echo" }] }
}
"#;
const CONFIG: &str = r#"
[line]
segments = ["echo"]
"#;
struct Fixture {
_xdg: TempDir,
xdg_path: std::path::PathBuf,
}
impl Fixture {
fn new() -> Self {
let xdg = TempDir::new().expect("tempdir");
let segments_dir = xdg.path().join("linesmith").join("segments");
fs::create_dir_all(&segments_dir).expect("mkdir segments/");
fs::write(segments_dir.join("echo.rhai"), LOG_PLUGIN).expect("write plugin");
let config_dir = xdg.path().join("linesmith");
fs::write(config_dir.join("config.toml"), CONFIG).expect("write config");
let xdg_path = xdg.path().to_path_buf();
Self {
_xdg: xdg,
xdg_path,
}
}
}
fn run_with_log_level(fixture: &Fixture, level: &str) -> String {
let mut child = Command::new(env!("CARGO_BIN_EXE_linesmith"))
.env("XDG_CONFIG_HOME", &fixture.xdg_path)
.env("LINESMITH_LOG", level)
.env_remove("LINESMITH_CONFIG")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("spawn linesmith binary");
child
.stdin
.as_mut()
.expect("stdin pipe")
.write_all(STATUSLINE_PAYLOAD)
.expect("write stdin payload");
let out = child.wait_with_output().expect("wait_with_output");
assert!(
out.status.success(),
"linesmith exited {:?}\nstderr: {}\nstdout: {}",
out.status.code(),
String::from_utf8_lossy(&out.stderr),
String::from_utf8_lossy(&out.stdout),
);
let stdout = String::from_utf8_lossy(&out.stdout).into_owned();
assert!(
stdout.contains("echo"),
"expected `echo` segment in stdout, got {stdout:?}"
);
String::from_utf8_lossy(&out.stderr).into_owned()
}
#[test]
fn plugin_log_emits_warn_line_when_level_warn() {
let fixture = Fixture::new();
let stderr = run_with_log_level(&fixture, "warn");
assert!(
stderr.contains("linesmith [warn]: plugin echo: hello"),
"expected the plugin log line in stderr, got {stderr:?}"
);
}
#[test]
fn plugin_log_suppressed_when_level_off() {
let fixture = Fixture::new();
let stderr = run_with_log_level(&fixture, "off");
assert!(
!stderr.contains("plugin echo: hello"),
"expected plugin log line suppressed, got {stderr:?}"
);
assert!(
!stderr.contains("linesmith [warn]"),
"no warn-level lines should appear under LINESMITH_LOG=off, got {stderr:?}"
);
}