use std::sync::Arc;
use super::*;
use crate::agent::compaction::compaction::CompactionSettings;
use crate::agent::session::session::SessionTreeEntry;
fn settings() -> CompactionSettings {
CompactionSettings::default()
}
#[test]
fn builtin_algorithm_name_is_builtin() {
assert_eq!(BuiltinCompactAlgorithm.name(), "builtin");
}
#[test]
fn registry_default_is_empty_and_falls_back_to_builtin() {
let registry = CompactAlgorithmRegistry::default();
assert!(registry.custom_names().is_empty());
let algorithm = registry.algorithm("builtin");
assert_eq!(algorithm.name(), "builtin");
let algorithm = registry.algorithm("");
assert_eq!(algorithm.name(), "builtin");
let algorithm = registry.algorithm("does-not-exist");
assert_eq!(algorithm.name(), "builtin");
}
#[test]
fn registry_register_rejects_builtin_shadowing_and_lists_sorted_custom_names() {
let registry = CompactAlgorithmRegistry::new();
registry.register(Arc::new(BuiltinCompactAlgorithm));
assert!(registry.custom_names().is_empty());
registry.register(Arc::new(StubAlgorithm("z-algo")));
registry.register(Arc::new(StubAlgorithm("a-algo")));
assert_eq!(registry.custom_names(), vec!["a-algo", "z-algo"]);
let algorithm = registry.algorithm("a-algo");
assert_eq!(algorithm.name(), "a-algo");
}
#[test]
fn registry_atomically_replaces_custom_algorithms() {
let registry = CompactAlgorithmRegistry::new();
registry.register(Arc::new(StubAlgorithm("old")));
registry.replace_custom([
Arc::new(StubAlgorithm("new")) as Arc<dyn CompactAlgorithm>,
Arc::new(StubAlgorithm("builtin")) as Arc<dyn CompactAlgorithm>,
]);
assert_eq!(registry.custom_names(), vec!["new"]);
assert_eq!(registry.algorithm("old").name(), "builtin");
assert_eq!(registry.algorithm("new").name(), "new");
}
struct StubAlgorithm(&'static str);
#[async_trait::async_trait]
impl CompactAlgorithm for StubAlgorithm {
fn name(&self) -> &str {
self.0
}
}
#[tokio::test]
async fn trait_defaults_delegate_to_builtin_helpers() {
let algorithm = StubAlgorithm("stub");
let s = settings();
assert!(!algorithm.decide_compact(1, 128_000, &s).await);
assert!(algorithm.decide_compact(200_000, 128_000, &s).await);
let entries = vec![SessionTreeEntry::ThinkingLevelChange {
id: "t".into(),
parent_id: None,
timestamp: "t".into(),
thinking_level: "high".into(),
}];
let cut = algorithm.select_cut_point(&entries, &s).await;
assert_eq!(cut.cut_index, 0);
}