From 04eb301ffd37924d22254c33c69d47642bf75d2b Mon Sep 17 00:00:00 2001 From: Rob Zolkos Date: Thu, 2 Jul 2026 14:46:15 -0400 Subject: [PATCH 1/2] Fix TestFormatDueDate year-boundary flake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same-year assertion used now.AddDate(0, 6, 0), which crosses into the next calendar year for any run after June — so from July onward the date carried a year and the 'should not contain year' assertion failed. Pick a date in the opposite half of the current year instead, keeping it same-year and clear of the today/tomorrow/yesterday window regardless of when in the year the suite runs. --- internal/tui/workspace/views/detail_test.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/internal/tui/workspace/views/detail_test.go b/internal/tui/workspace/views/detail_test.go index 0af142555..ffbf30517 100644 --- a/internal/tui/workspace/views/detail_test.go +++ b/internal/tui/workspace/views/detail_test.go @@ -809,12 +809,18 @@ func TestFormatDueDate(t *testing.T) { assert.Equal(t, "Tomorrow", formatDueDate(tomorrow)) assert.Equal(t, "Yesterday", formatDueDate(yesterday)) - // Same year, far enough from today to avoid collisions - farDate := now.AddDate(0, 6, 0) // 6 months ahead - farISO := farDate.Format("2006-01-02") - result := formatDueDate(farISO) - assert.Contains(t, result, farDate.Format("Jan 2")) - assert.NotContains(t, result, farDate.Format("2006"), "same-year dates should omit year") + // A date in the same calendar year as today, comfortably away from today. + // Pick the opposite half of the year so it stays same-year and clear of the + // today/tomorrow/yesterday window no matter when in the year this runs — + // AddDate(0, 6, 0) would cross into next year for any date after June. + sameYearMonth := time.November + if now.Month() >= time.July { + sameYearMonth = time.February + } + sameYear := time.Date(now.Year(), sameYearMonth, 15, 0, 0, 0, 0, now.Location()) + result := formatDueDate(sameYear.Format("2006-01-02")) + assert.Contains(t, result, sameYear.Format("Jan 2")) + assert.NotContains(t, result, sameYear.Format("2006"), "same-year dates should omit year") // Different year: includes year otherYear := now.AddDate(-2, 0, 0).Format("2006-01-02") From 2fc8ef577d65644a2276dec355e64cd2a56e1633 Mon Sep 17 00:00:00 2001 From: Rob Zolkos Date: Thu, 2 Jul 2026 14:53:33 -0400 Subject: [PATCH 2/2] Make TestFormatDueDate fully deterministic Address review: the test still read time.Now() while formatDueDate computed its own time.Now() internally, leaving a residual midnight/New-Year race where the two calls could observe different years. Extract formatDueDateAt(iso, now) as a testable seam (formatDueDate stays a thin wrapper passing time.Now()), and drive the test from a fixed reference now so none of the relative-label cases depend on the wall clock. --- internal/tui/workspace/views/detail.go | 8 +++- internal/tui/workspace/views/detail_test.go | 41 ++++++++++----------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/internal/tui/workspace/views/detail.go b/internal/tui/workspace/views/detail.go index 711952d34..7c6206883 100644 --- a/internal/tui/workspace/views/detail.go +++ b/internal/tui/workspace/views/detail.go @@ -1549,11 +1549,17 @@ func fetchSubscriptionState(sub *basecamp.Subscription, err error) bool { // formatDueDate converts an ISO date string to a human-friendly label. func formatDueDate(iso string) string { + return formatDueDateAt(iso, time.Now()) +} + +// formatDueDateAt formats a due date relative to a caller-supplied now, so the +// relative labels ("Today"/"Tomorrow"/same-year) are deterministic and testable +// without depending on the wall clock. formatDueDate passes time.Now(). +func formatDueDateAt(iso string, now time.Time) string { t, err := time.ParseInLocation("2006-01-02", iso, time.Local) if err != nil { return iso } - now := time.Now() today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local) switch { case t.Equal(today): diff --git a/internal/tui/workspace/views/detail_test.go b/internal/tui/workspace/views/detail_test.go index ffbf30517..4697f4ade 100644 --- a/internal/tui/workspace/views/detail_test.go +++ b/internal/tui/workspace/views/detail_test.go @@ -800,35 +800,34 @@ func TestDetail_EditingCallsRelayout(t *testing.T) { } func TestFormatDueDate(t *testing.T) { - now := time.Now() + // Fixed reference time so the test is fully deterministic — it never reads + // the wall clock, so there's no midnight/New-Year race between the test's + // now and the one formatDueDate would compute internally. + now := time.Date(2026, time.July, 2, 12, 0, 0, 0, time.Local) + format := func(iso string) string { return formatDueDateAt(iso, now) } + today := now.Format("2006-01-02") tomorrow := now.AddDate(0, 0, 1).Format("2006-01-02") yesterday := now.AddDate(0, 0, -1).Format("2006-01-02") - assert.Equal(t, "Today", formatDueDate(today)) - assert.Equal(t, "Tomorrow", formatDueDate(tomorrow)) - assert.Equal(t, "Yesterday", formatDueDate(yesterday)) - - // A date in the same calendar year as today, comfortably away from today. - // Pick the opposite half of the year so it stays same-year and clear of the - // today/tomorrow/yesterday window no matter when in the year this runs — - // AddDate(0, 6, 0) would cross into next year for any date after June. - sameYearMonth := time.November - if now.Month() >= time.July { - sameYearMonth = time.February - } - sameYear := time.Date(now.Year(), sameYearMonth, 15, 0, 0, 0, 0, now.Location()) - result := formatDueDate(sameYear.Format("2006-01-02")) + assert.Equal(t, "Today", format(today)) + assert.Equal(t, "Tomorrow", format(tomorrow)) + assert.Equal(t, "Yesterday", format(yesterday)) + + // Same calendar year as now, comfortably away from the today/tomorrow/ + // yesterday window. + sameYear := time.Date(now.Year(), time.February, 15, 0, 0, 0, 0, now.Location()) + result := format(sameYear.Format("2006-01-02")) assert.Contains(t, result, sameYear.Format("Jan 2")) assert.NotContains(t, result, sameYear.Format("2006"), "same-year dates should omit year") - // Different year: includes year - otherYear := now.AddDate(-2, 0, 0).Format("2006-01-02") - result = formatDueDate(otherYear) - assert.Contains(t, result, now.AddDate(-2, 0, 0).Format("2006")) + // Different year: includes year. + otherYear := now.AddDate(-2, 0, 0) + result = format(otherYear.Format("2006-01-02")) + assert.Contains(t, result, otherYear.Format("2006")) - // Invalid input: pass through - assert.Equal(t, "not-a-date", formatDueDate("not-a-date")) + // Invalid input: pass through. + assert.Equal(t, "not-a-date", format("not-a-date")) } func TestDetail_SyncPreview_DueDateFormatted(t *testing.T) {