use super::*;
use tempfile::TempDir;
fn write(dir: &Path, name: &str, body: &str) {
let messages = dir.join(MESSAGES_DIR);
std::fs::create_dir_all(&messages).expect("messages/");
std::fs::write(messages.join(name), body).expect("entry");
}
fn usage_of(prompt: u64, window: Option<u64>, model: &str) -> LastUsage {
LastUsage {
prompt_tokens: prompt,
context_window: window,
model: model.to_string(),
}
}
#[test]
fn the_prompt_side_is_the_served_total_and_ignores_the_output() {
let dir = TempDir::new().unwrap();
write(
dir.path(),
"004-claude-fable-5.json",
r#"{"content":[],"usage":{"input_tokens":10,"cache_read_tokens":20,
"cache_write_tokens":5,"input_total_tokens":30,
"output_tokens":900,"context_window":1000}}"#,
);
let last = last(dir.path()).unwrap().expect("a model entry");
assert_eq!(last.prompt_tokens, 30);
assert_eq!(last.context_window, Some(1000));
assert_eq!(last.model, "claude-fable-5");
}
#[test]
fn an_entry_without_the_served_total_falls_back_to_the_three_counters() {
let dir = TempDir::new().unwrap();
write(
dir.path(),
"004-claude-fable-5.json",
r#"{"content":[],"usage":{"input_tokens":10,"cache_read_tokens":20,
"cache_write_tokens":5,"output_tokens":900,"context_window":1000}}"#,
);
let last = last(dir.path()).unwrap().expect("a model entry");
assert_eq!(last.prompt_tokens, 35);
assert_eq!(last.context_window, Some(1000));
assert_eq!(last.model, "claude-fable-5");
}
#[test]
fn an_absent_counter_contributes_nothing_rather_than_zero() {
let dir = TempDir::new().unwrap();
write(
dir.path(),
"001-m.json",
r#"{"content":[],"usage":{"input_tokens":7}}"#,
);
let last = last(dir.path()).unwrap().expect("a model entry");
assert_eq!(last.prompt_tokens, 7);
assert_eq!(last.context_window, None);
}
#[test]
fn the_newest_model_entry_answers_past_tool_and_delivery_entries() {
let dir = TempDir::new().unwrap();
write(
dir.path(),
"001-m.json",
r#"{"content":[],"usage":{"input_tokens":1}}"#,
);
write(
dir.path(),
"010-m.json",
r#"{"content":[],"usage":{"input_tokens":99}}"#,
);
write(
dir.path(),
"011-tool.json",
r#"[{"type":"text","text":"t"}]"#,
);
write(dir.path(), "012-someone.md", "hello");
write(dir.path(), "not-an-entry.json", "{}");
write(dir.path(), "013-.json", "{}");
let last = last(dir.path()).unwrap().expect("a model entry");
assert_eq!(last.prompt_tokens, 99);
}
#[test]
fn a_branch_with_no_transcript_or_no_usage_reports_nothing() {
let dir = TempDir::new().unwrap();
assert_eq!(last(dir.path()).unwrap(), None);
write(dir.path(), "001-someone.md", "hi");
assert_eq!(last(dir.path()).unwrap(), None);
write(dir.path(), "002-m.json", r#"[{"type":"text","text":"hi"}]"#);
assert_eq!(last(dir.path()).unwrap(), None);
}
#[test]
fn an_unreadable_transcript_directory_surfaces_as_io() {
let dir = TempDir::new().unwrap();
std::fs::write(dir.path().join(MESSAGES_DIR), "not a directory").unwrap();
assert!(matches!(last(dir.path()), Err(Error::Io(_))));
}
#[test]
fn the_window_trigger_fires_at_or_past_the_percentage() {
let due_at = |prompt| due(Some(50), Some(&usage_of(prompt, Some(1000), "m"))).unwrap();
assert!(!due_at(499));
assert!(due_at(500));
assert!(due_at(999));
}
#[test]
fn no_last_usage_and_no_threshold_are_both_not_due() {
assert!(!due(Some(50), None).unwrap());
assert!(!due(None, Some(&usage_of(999, Some(1000), "m"))).unwrap());
assert!(!due(Some(0), Some(&usage_of(999, Some(1000), "m"))).unwrap());
}
#[test]
fn an_unknown_window_is_declined_naming_the_model() {
let err = due(Some(50), Some(&usage_of(999, None, "gpt-mystery"))).unwrap_err();
assert!(
matches!(&err, Error::CompactionWindowUnknown { model } if model == "gpt-mystery"),
"{err:?}"
);
assert!(format!("{err}").contains("window_percent"), "{err}");
}
#[test]
fn both_numbers_are_read_at_brazens_own_serialized_names() {
let mut reported = brazen::Usage::default();
reported.input_tokens = Some(11);
reported.cache_read_tokens = Some(22);
reported.context_window = Some(200_000);
let sealed = format!(
r#"{{"content":[],"usage":{}}}"#,
serde_json::to_string(&reported).expect("Usage serializes")
);
let dir = TempDir::new().unwrap();
write(dir.path(), "007-claude-fable-5.json", &sealed);
let report = last(dir.path()).unwrap().expect("a model entry");
assert_eq!(report.prompt_tokens, 33);
assert_eq!(report.context_window, Some(200_000));
let mut window_less = brazen::Usage::default();
window_less.input_tokens = Some(11);
let sealed = format!(
r#"{{"content":[],"usage":{}}}"#,
serde_json::to_string(&window_less).expect("Usage serializes")
);
write(dir.path(), "008-claude-fable-5.json", &sealed);
let report = last(dir.path()).unwrap().expect("a model entry");
assert_eq!(report.context_window, None);
assert!(due(Some(50), Some(&report)).is_err());
}