use super::*;
#[test]
fn the_cached_slice_is_billed_once_whatever_shape_the_provider_reports() {
let contained = spend_from_bytes(
br#"{"type":"usage","input_tokens":93556,"output_tokens":132,"cache_read_tokens":91648,"cache_write_tokens":null}"#,
);
assert_eq!(contained.prompt_tokens(), 93_556);
assert_eq!(contained.uncached_prompt_tokens(), 1_908);
assert_eq!(contained.total_tokens(), 93_688);
let disjoint = BudgetSpend {
input_tokens: 4_000,
output_tokens: 500,
cache_read_tokens: 90_000,
cache_write_tokens: 6_000,
};
assert_eq!(disjoint.prompt_tokens(), 96_000);
assert_eq!(disjoint.uncached_prompt_tokens(), 0);
assert_eq!(disjoint.total_tokens(), 96_500);
let uncached = BudgetSpend {
input_tokens: 30_000,
output_tokens: 900,
..BudgetSpend::default()
};
assert_eq!(uncached.prompt_tokens(), 30_000);
assert_eq!(uncached.uncached_prompt_tokens(), 30_000);
assert_eq!(uncached.total_tokens(), 30_900);
assert_eq!(BudgetSpend::default().total_tokens(), 0);
}
#[test]
fn the_priced_partition_sums_to_the_counted_total() {
for s in [
BudgetSpend {
input_tokens: 93_556,
output_tokens: 132,
cache_read_tokens: 91_648,
cache_write_tokens: 0,
},
BudgetSpend {
input_tokens: 0,
output_tokens: 0,
cache_read_tokens: 5,
cache_write_tokens: 0,
},
BudgetSpend {
input_tokens: 4_000,
output_tokens: 500,
cache_read_tokens: 90_000,
cache_write_tokens: 6_000,
},
BudgetSpend {
input_tokens: 30_000,
output_tokens: 900,
..BudgetSpend::default()
},
] {
assert_eq!(
s.uncached_prompt_tokens() + s.cached_tokens() + s.output_tokens,
s.total_tokens(),
"{s:?}"
);
}
}
#[test]
fn folds_every_segment_and_ignores_everything_else() {
let jsonl = [
r#"{"type":"usage","input_tokens":10,"output_tokens":5,"cache_read_tokens":2,"cache_write_tokens":1}"#,
r#"{"type":"content_delta","index":0,"delta":{"text_delta":"hi"}}"#,
r#"{"type":"usage","input_tokens":3,"output_tokens":null}"#,
"not json",
r#"{"no_type":1}"#,
r#"{"type":123}"#,
]
.join("\n");
let s = spend_from_bytes(jsonl.as_bytes());
assert_eq!(s.input_tokens, 13);
assert_eq!(s.output_tokens, 5);
assert_eq!(s.cache_read_tokens, 2);
assert_eq!(s.cache_write_tokens, 1);
assert_eq!(s.total_tokens(), 18);
}
#[test]
fn empty_bytes_are_zero_spend() {
assert_eq!(spend_from_bytes(b""), BudgetSpend::default());
}
#[test]
fn last_usage_takes_the_final_segment_per_field_not_the_fold() {
let jsonl = [
r#"{"type":"usage","input_tokens":10,"cache_read_tokens":90}"#,
r#"{"type":"content_delta","index":0,"delta":{"text_delta":"hi"}}"#,
r#"{"type":"usage","input_tokens":4,"cache_read_tokens":120,"output_tokens":null}"#,
r#"{"type":"usage","input_tokens":null,"output_tokens":15}"#,
]
.join("\n");
let last = last_usage(jsonl.as_bytes());
assert_eq!(last.input_tokens, 4);
assert_eq!(last.cache_read_tokens, 120);
assert_eq!(last.output_tokens, 15);
assert_eq!(spend_from_bytes(jsonl.as_bytes()).input_tokens, 14);
}
#[test]
fn a_payload_with_no_usage_line_has_no_last_segment() {
assert_eq!(last_usage(b"{\"type\":\"end\"}"), BudgetSpend::default());
assert_eq!(context_window(b"{\"type\":\"end\"}"), None);
}
#[test]
fn the_sealed_prompt_total_is_read_where_a_line_carries_it() {
let sealed = spend_from_bytes(
br#"{"type":"usage","input_tokens":4000,"output_tokens":500,"cache_read_tokens":90000,"cache_write_tokens":6000,"input_total_tokens":100000}"#,
);
assert_eq!(sealed.prompt_tokens(), 100_000);
assert_eq!(sealed.uncached_prompt_tokens(), 4_000);
assert_eq!(sealed.total_tokens(), 100_500);
assert_eq!(
sealed.uncached_prompt_tokens() + sealed.cached_tokens() + sealed.output_tokens,
sealed.total_tokens()
);
}
#[test]
fn each_line_is_read_by_its_own_shape_when_a_record_carries_both() {
let mixed = [
r#"{"type":"usage","input_tokens":4000,"output_tokens":500,"cache_read_tokens":90000,"cache_write_tokens":6000}"#,
r#"{"type":"usage","input_tokens":4000,"output_tokens":500,"cache_read_tokens":90000,"cache_write_tokens":6000,"input_total_tokens":100000}"#,
]
.join("\n");
let folded = spend_from_bytes(mixed.as_bytes());
assert_eq!(folded.input_tokens, 4_000 + 100_000);
assert_eq!(folded.cached_tokens(), 192_000);
assert_eq!(folded.prompt_tokens(), 192_000, "the floor is the fold's");
assert_eq!(folded.total_tokens(), 193_000);
let old_only = spend_from_bytes(mixed.split('\n').next().unwrap().as_bytes());
assert_eq!(old_only.prompt_tokens(), 96_000);
let new_only = spend_from_bytes(mixed.split('\n').nth(1).unwrap().as_bytes());
assert_eq!(new_only.prompt_tokens(), 100_000);
}
#[test]
fn the_window_is_the_last_one_the_usage_lines_state() {
let stated = [
r#"{"type":"usage","input_tokens":10,"context_window":200000}"#,
r#"{"type":"usage","output_tokens":5}"#,
]
.join("\n");
assert_eq!(context_window(stated.as_bytes()), Some(200_000));
let moved = [
r#"{"type":"usage","input_tokens":10,"context_window":200000}"#,
r#"{"type":"usage","input_tokens":10,"context_window":1000000}"#,
]
.join("\n");
assert_eq!(context_window(moved.as_bytes()), Some(1_000_000));
assert_eq!(
context_window(br#"{"type":"usage","input_tokens":10,"context_window":0}"#),
None
);
assert_eq!(
context_window(br#"{"type":"usage","input_tokens":10}"#),
None
);
}