Eight closed tasks for epochs and compaction, then ten for the scheduler, ToolSummary, and tiers. Given tests first. Gate 1456 → 1507 → 1572. Co-Authored-By: Grok 4.6 <noreply@x.ai>
111 lines
3.0 KiB
Rust
111 lines
3.0 KiB
Rust
//! Tests for `[heartbeat]` and unknown `[compact] summarise` names. Do not edit.
|
|
|
|
use loopd::config::Config;
|
|
use loopd::tools::Registry;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
fn fixture(name: &str) -> PathBuf {
|
|
Path::new(env!("CARGO_MANIFEST_DIR"))
|
|
.join("tests/fixtures/config")
|
|
.join(name)
|
|
}
|
|
|
|
fn minimal() -> String {
|
|
std::fs::read_to_string(fixture("minimal.toml")).unwrap()
|
|
}
|
|
|
|
struct Scratch {
|
|
dir: PathBuf,
|
|
}
|
|
|
|
impl Scratch {
|
|
fn new() -> Scratch {
|
|
let n = std::time::SystemTime::now()
|
|
.duration_since(std::time::UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_nanos();
|
|
let dir = std::env::temp_dir().join(format!("loopd-hb-{}-{n}", std::process::id()));
|
|
let _ = std::fs::remove_dir_all(&dir);
|
|
std::fs::create_dir_all(&dir).unwrap();
|
|
Scratch { dir }
|
|
}
|
|
}
|
|
|
|
impl Drop for Scratch {
|
|
fn drop(&mut self) {
|
|
let _ = std::fs::remove_dir_all(&self.dir);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn missing_heartbeat_table_is_disabled() {
|
|
let c = Config::load(&fixture("minimal.toml")).unwrap();
|
|
assert_eq!(c.heartbeat.every_s, 0);
|
|
assert_eq!(
|
|
c.heartbeat_prompt(),
|
|
fixture("minimal.toml")
|
|
.parent()
|
|
.unwrap()
|
|
.join("heartbeat.md")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn the_table_overrides_every_default() {
|
|
let text = format!(
|
|
"{}\n[heartbeat]\nevery_s = 60\nprompt = \"pulse.md\"\n",
|
|
minimal()
|
|
);
|
|
let c = Config::parse(&text).unwrap();
|
|
assert_eq!(c.heartbeat.every_s, 60);
|
|
assert_eq!(c.heartbeat.prompt, PathBuf::from("pulse.md"));
|
|
}
|
|
|
|
#[test]
|
|
fn unknown_keys_are_errors() {
|
|
let bad = format!("{}\n[heartbeat]\nzz_unknown = 1\n", minimal());
|
|
assert!(Config::parse(&bad).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn heartbeat_prompt_is_beside_the_config_file() {
|
|
let home = Scratch::new();
|
|
let cfg_path = home.dir.join("loopd.toml");
|
|
std::fs::write(&cfg_path, minimal()).unwrap();
|
|
std::fs::write(home.dir.join("system.md"), "sys\n").unwrap();
|
|
let c = Config::load(&cfg_path).unwrap();
|
|
assert_eq!(c.heartbeat_prompt(), home.dir.join("heartbeat.md"));
|
|
}
|
|
|
|
#[test]
|
|
fn default_summarise_http_fetch_is_known_to_m5c() {
|
|
let c = Config::parse(&minimal()).unwrap();
|
|
c.check_summarise(&Registry::m5c()).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn an_unknown_summarise_name_is_an_error() {
|
|
let text = format!("{}\n[compact]\nsummarise = [\"no_such_tool\"]\n", minimal());
|
|
let c = Config::parse(&text).unwrap();
|
|
let err = c.check_summarise(&Registry::m5c()).unwrap_err();
|
|
assert!(err.contains("no_such_tool"), "{err}");
|
|
assert!(err.contains("summarise"), "{err}");
|
|
}
|
|
|
|
#[test]
|
|
fn empty_summarise_is_allowed() {
|
|
let text = format!("{}\n[compact]\nsummarise = []\n", minimal());
|
|
let c = Config::parse(&text).unwrap();
|
|
c.check_summarise(&Registry::m5c()).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn http_fetch_is_known_and_clock_is_known() {
|
|
let text = format!(
|
|
"{}\n[compact]\nsummarise = [\"http_fetch\", \"clock\"]\n",
|
|
minimal()
|
|
);
|
|
let c = Config::parse(&text).unwrap();
|
|
c.check_summarise(&Registry::m5c()).unwrap();
|
|
}
|