use super::*;
#[test]
fn test_estimate_empty_text_is_zero() {
assert_eq!(HeuristicEstimator.estimate(""), 0);
assert_eq!(
HeuristicEstimator.estimate(" \t "),
0,
"spaces/tabs are free"
);
assert_eq!(HeuristicEstimator.estimate("\n"), 1);
}
#[test]
fn test_estimate_rounds_up_per_word() {
assert_eq!(HeuristicEstimator.estimate("x"), 1);
assert_eq!(HeuristicEstimator.estimate("abcde"), 2);
assert_eq!(HeuristicEstimator.estimate("a b"), 2);
}
#[test]
fn test_estimate_digits_cost_a_full_token_each() {
assert_eq!(HeuristicEstimator.estimate("2026-07-14"), 9);
}
#[test]
fn test_estimate_cjk_costs_nearly_a_token_per_char() {
assert_eq!(HeuristicEstimator.estimate("五五五五五"), 5);
}
#[test]
fn test_estimate_spaces_and_tabs_are_free() {
assert_eq!(
HeuristicEstimator.estimate("alpha beta"),
HeuristicEstimator.estimate("alpha \t beta"),
"BPE folds spaces into the following token; the estimate must too"
);
}
#[test]
fn test_estimate_newlines_cost_half_a_token_each() {
let flat = HeuristicEstimator.estimate("alpha beta");
assert_eq!(HeuristicEstimator.estimate("alpha\n\nbeta"), flat + 1);
assert_eq!(HeuristicEstimator.estimate("alpha\nbeta"), flat + 1);
}
#[test]
fn test_estimate_is_deterministic() {
let text = "the ingestion worker retried the batch 3 times après l'échec 五";
assert_eq!(
HeuristicEstimator.estimate(text),
HeuristicEstimator.estimate(text)
);
}
#[test]
fn test_estimate_forwards_through_a_box() {
let boxed: DynTokenEstimator = Box::new(HeuristicEstimator);
assert_eq!(boxed.estimate("abcde"), 2);
assert_eq!(boxed.bytes_per_token_hint(), 3);
}
#[test]
fn test_estimate_superadditive_so_piecewise_sums_bound_the_whole() {
for (a, b) in [
("abc", "defg"),
("abc", "123"),
("abc", "五五"),
("2026-07", "-14"),
("五五", "五五五"),
] {
let whole = format!("{a}{b}");
assert!(
HeuristicEstimator.estimate(a) + HeuristicEstimator.estimate(b)
>= HeuristicEstimator.estimate(&whole),
"est({a:?}) + est({b:?}) must bound est({whole:?})"
);
}
}
#[test]
fn test_estimate_overcounts_typical_prose() {
let text = "The deploy pipeline runs clippy before any artifact ships.";
let estimate = HeuristicEstimator.estimate(text);
assert!((13..=26).contains(&estimate), "estimate = {estimate}");
}