//! Tests for `[compact]` on `loopd.toml`. Do not edit. use loopd::config::Config; 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() } #[test] fn missing_table_gets_the_documented_defaults() { let c = Config::load(&fixture("minimal.toml")).unwrap(); assert_eq!(c.compact.threshold, 0.85); assert_eq!(c.compact.summary_chars, 4_000); assert_eq!(c.compact.summarise, vec!["http_fetch".to_string()]); } #[test] fn the_table_overrides_every_default() { let text = format!( "{}\n[compact]\nthreshold = 0.5\nsummary_chars = 100\nsummarise = [\"clock\"]\n", minimal() ); let c = Config::parse(&text).unwrap(); assert_eq!(c.compact.threshold, 0.5); assert_eq!(c.compact.summary_chars, 100); assert_eq!(c.compact.summarise, vec!["clock".to_string()]); } #[test] fn a_partial_table_keeps_the_other_defaults() { let text = format!("{}\n[compact]\nthreshold = 0.9\n", minimal()); let c = Config::parse(&text).unwrap(); assert_eq!(c.compact.threshold, 0.9); assert_eq!(c.compact.summary_chars, 4_000); assert_eq!(c.compact.summarise, vec!["http_fetch".to_string()]); } #[test] fn unknown_keys_are_errors() { let text = minimal(); let bad = format!("{text}\n[compact]\nzz_unknown = 1\n"); assert!( Config::parse(&bad).is_err(), "[compact] accepted an unknown key" ); let misspelt = format!("{text}\n[compact]\nsummary_char = 10\n"); assert!( Config::parse(&misspelt).is_err(), "[compact] accepted a misspelt key" ); } #[test] fn empty_summarise_is_allowed() { let text = format!("{}\n[compact]\nsummarise = []\n", minimal()); let c = Config::parse(&text).unwrap(); assert!(c.compact.summarise.is_empty()); } #[test] fn compact_prompt_is_compact_md_beside_system_md() { let c = Config::load(&fixture("minimal.toml")).unwrap(); assert_eq!(c.compact_prompt(), fixture("compact.md")); 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.compact_prompt(), home.dir.join("compact.md")); } struct Scratch { dir: PathBuf, } impl Scratch { fn new() -> Scratch { let dir = std::env::temp_dir().join(format!( "loopd-compact-cfg-{}-{}", std::process::id(), std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_nanos() )); 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 compact_prompt_follows_an_overridden_system_path() { let text = std::fs::read_to_string(fixture("m2b.toml")).unwrap(); let c = Config::load(&fixture("m2b.toml")).unwrap(); assert!( text.contains("prompts/agent.md"), "m2b fixture names a prompt in a subdirectory" ); assert_eq!(c.compact_prompt(), fixture("prompts/compact.md")); } #[test] fn defaults_match_the_struct_default() { let c = Config::load(&fixture("minimal.toml")).unwrap(); assert_eq!(c.compact, loopd::config::Compact::default()); }