From 28973fe1d23cc2679b64502b263cf1d04b546004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sun, 27 Sep 2026 05:53:28 -0400 Subject: [PATCH] =?UTF-8?q?Project=20=C2=B7=20a=20roadmap=20bar's=20end=20?= =?UTF-8?q?and=20a=20workload=20bar's=20cap,=20tested?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A roadmap bar ran through its last day, but no test looked at its end: a bar stopping at the last day's start stayed green. The roadmap test now asserts October's bar reaches the span's end. The workload bar's share, capped at the whole track, moves into Load::filled with a unit test, so a load past capacity cannot draw past its track unseen. Co-Authored-By: Claude Opus 5.5 --- TASKS.md | 1 + src/project/tests/boards.rs | 5 +++++ src/project/workload.rs | 21 ++++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/TASKS.md b/TASKS.md index dc85d44..47741d8 100644 --- a/TASKS.md +++ b/TASKS.md @@ -366,3 +366,4 @@ Per-component lines live in `tasks/`. Tags there: | T31a | 1 | PASS | | | T31b | 1 | FAIL | a focused card past the board's fold stayed out of view; left and right steps that keep a card's place went untested | | T31b | 2 | PASS | | +| T31c | 1 | FAIL | a roadmap bar's end and the workload bar's cap went untested | diff --git a/src/project/tests/boards.rs b/src/project/tests/boards.rs index 5bd9d70..c37fc2f 100644 --- a/src/project/tests/boards.rs +++ b/src/project/tests/boards.rs @@ -223,4 +223,9 @@ fn a_roadmap_draws_only_what_falls_in_its_months(cx: &mut TestAppContext) { (share - 30.0 / 61.0).abs() < 0.01, "October starts 30 of 61 days in: {share}" ); + let end = (half.right() - map.left()) / map.size.width; + assert!( + (end - 1.0).abs() < 0.01, + "October runs through its last day: {end}" + ); } diff --git a/src/project/workload.rs b/src/project/workload.rs index cd414bc..4b1385c 100644 --- a/src/project/workload.rs +++ b/src/project/workload.rs @@ -41,6 +41,11 @@ impl Load { pub fn over(&self) -> bool { self.assigned > self.capacity } + + /// The share of the track the bar fills, whole at capacity and past it. + pub(crate) fn filled(&self) -> f32 { + (self.assigned / self.capacity).min(1.0) + } } /// Who carries how much: each person with a bar of their work against what they can take, red past it, and the two counts. @@ -84,7 +89,7 @@ impl RenderOnce for WorkloadView { } else { colors.hue(0, "workload") }; - let share = (load.assigned / load.capacity).min(1.0); + let share = load.filled(); let count = format!("{:.0} / {:.0} {}", load.assigned, load.capacity, self.unit); let key = load.person.key.clone(); div() @@ -150,3 +155,17 @@ impl RenderOnce for WorkloadView { .children(rows.collect::>()) } } + +#[cfg(test)] +mod tests { + use super::Load; + use crate::project::Person; + + #[test] + fn a_bar_fills_its_share_and_stops_at_capacity() { + let ana = Person::new("ana", "Ana Lima"); + assert_eq!(Load::new(ana.clone(), 190.0, 168.0).filled(), 1.0); + assert_eq!(Load::new(ana.clone(), 7.0, 10.0).filled(), 0.7); + assert!(Load::new(ana, 11.0, 10.0).over()); + } +}