From d0a86359c29d5ed943ce9037358afbd303c0d589 Mon Sep 17 00:00:00 2001 From: Jean Date: Sun, 19 Jul 2026 18:52:26 +0000 Subject: [PATCH] Fix the caps kicker to trigger on ratio, not uppercase count --- src/engine/db/mod.rs | 4 +++- src/engine/db/tests.rs | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/engine/db/mod.rs b/src/engine/db/mod.rs index 6024eb3..e330b6b 100644 --- a/src/engine/db/mod.rs +++ b/src/engine/db/mod.rs @@ -635,7 +635,9 @@ impl KickerSettings { if text.chars().count() >= min { let upper = text.chars().filter(|c| c.is_ascii_uppercase()).count() as u32; let lower = text.chars().filter(|c| c.is_ascii_lowercase()).count() as u32; - if upper as usize >= min && upper + lower > 0 && upper * 100 / (upper + lower) >= percent { + // Length is already gated above; gate only on the caps ratio here + // (a prior `upper >= min` clause wrongly demanded min uppercase letters). + if upper + lower > 0 && upper * 100 / (upper + lower) >= percent { return Some("Turn caps lock off!"); } } diff --git a/src/engine/db/tests.rs b/src/engine/db/tests.rs index d8639e5..b7d0262 100644 --- a/src/engine/db/tests.rs +++ b/src/engine/db/tests.rs @@ -941,3 +941,15 @@ assert_eq!(db.channel("#foo").unwrap().join_mode("alice"), None, "purge holds after replay"); assert_eq!(db.channel_successor("#bar"), None, "successor purge holds after replay"); } + + #[test] + fn caps_kicker_triggers_on_ratio_not_uppercase_count() { + let k = KickerSettings { caps: true, ..Default::default() }; + // 9 uppercase in an 18-char line is ~50% caps and over the length floor — + // it must trip even though the uppercase count is below caps_min (a prior + // `upper >= min` bug let it slip through). + assert_eq!(k.violation("AAAAAAAAA hi there"), Some("Turn caps lock off!")); + // A short or low-ratio line still doesn't trip. + assert_eq!(k.violation("Hello there"), None); + assert_eq!(k.violation("YO"), None, "too short for the length floor"); + }