Render on/off-task split in the reflection block

This commit is contained in:
2026-06-01 21:02:23 -04:00
parent 7eb2b5dc58
commit e5c32563d0
2 changed files with 93 additions and 9 deletions
+57
View File
@@ -1408,3 +1408,60 @@ func TestCreditLockedSplitsByDriftStatus(t *testing.T) {
t.Errorf("Buckets total = %v, want 20s", got)
}
}
func TestReflectionBlockShowsOnOffSplit(t *testing.T) {
c, _ := newTestController(t)
startActive(t, c, nil) // sets commitment ("write report" / "report drafted") and stats
c.stats.SwitchCount = 2
c.stats.OnTask = map[bucketKey]time.Duration{
{Class: "code", Title: "main.go"}: 20 * time.Minute,
}
c.stats.OffTask = map[bucketKey]time.Duration{
{Class: "firefox", Title: "YouTube"}: 8 * time.Minute,
{Class: "firefox", Title: "Reddit"}: 4 * time.Minute,
}
c.stats.unclassified = 5 * time.Minute
c.outcomePending = "completed"
c.mu.Lock()
got := c.buildReflectionFinishedLocked()
c.mu.Unlock()
want := "Next action: write report\n" +
"Success condition: report drafted\n" +
"Outcome: completed\n" +
"On-task 20m / Off-task 12m / Unclassified 5m\n" +
"Context switches: 2\n" +
"On-task:\n" +
"- code · main.go: 20m\n" +
"Off-task:\n" +
"- firefox · YouTube: 8m\n" +
"- firefox · Reddit: 4m"
if got != want {
t.Errorf("reflection block mismatch:\n--- got ---\n%s\n--- want ---\n%s", got, want)
}
}
func TestReflectionBlockOmitsEmptyOffTaskList(t *testing.T) {
c, _ := newTestController(t)
startActive(t, c, nil)
c.stats.OnTask = map[bucketKey]time.Duration{
{Class: "code", Title: "main.go"}: 20 * time.Minute,
}
c.stats.OffTask = map[bucketKey]time.Duration{} // none
c.stats.unclassified = 0
c.outcomePending = "completed"
c.mu.Lock()
got := c.buildReflectionFinishedLocked()
c.mu.Unlock()
if strings.Contains(got, "Off-task:") {
t.Errorf("fully on-task session must omit the Off-task list, got:\n%s", got)
}
if !strings.Contains(got, "On-task 20m / Off-task 0m / Unclassified 0m") {
t.Errorf("totals line missing or wrong, got:\n%s", got)
}
}