From 5d395ad789f24c15fe40439baf5ca546b61fd7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 5 Oct 2026 13:49:09 -0400 Subject: [PATCH] Refactor: Toaster returns its wake time instead of storing it toastQueue.wake kept state only tests read. Toaster now reports the frame's wake time in an unexported ToasterResult field, and TestToastExpiresAndHoverPauses asserts on the returned value. --- toast.go | 5 ++--- toast_test.go | 17 ++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/toast.go b/toast.go index 872997a..570205d 100644 --- a/toast.go +++ b/toast.go @@ -32,6 +32,7 @@ type ToastMessage struct { type ToasterResult struct { Action string Closed string + wake time.Time // when this frame asked for the next one; zero for none } type toastItem struct { @@ -46,7 +47,6 @@ type toastItem struct { // toastQueue holds a window's toasts, visible ones first in order shown. type toastQueue struct { items []toastItem - wake time.Time // when Toaster last asked for a frame; zero for none } type toastKey struct{} @@ -231,9 +231,8 @@ func Toaster(c *ui.Context) ToasterResult { } } // Scheduled after resuming, so a toast released this frame still expires. - q.wake = time.Time{} if next := q.settle(now, held); next > 0 { - q.wake = now.Add(next) + res.wake = now.Add(next) c.After(next) } return res diff --git a/toast_test.go b/toast_test.go index c0da1f0..5767a89 100644 --- a/toast_test.go +++ b/toast_test.go @@ -158,23 +158,22 @@ func TestToastKeepsFocusAndEscapeCloses(t *testing.T) { } func TestToastExpiresAndHoverPauses(t *testing.T) { - var q *toastQueue + var res ToasterResult const life = 40 * time.Millisecond tt := ui.NewTester(func(c *ui.Context) { Use(c, Settings{}) if Button(c, "Notify", ButtonOptions{}).Clicked() { ShowToast(c, ToastMessage{Message: "Copied", Duration: life}) } - q = toasts(c) - Toaster(c) + res = Toaster(c) }, 600, 400) _ = tt.Click("Notify") - if q.wake.IsZero() { + if res.wake.IsZero() { t.Fatal("no wake-up scheduled for a running toast") } r, _ := tt.Find("Copied") tt.Move(r.X+r.W/2, r.Y+r.H/2) - if !q.wake.IsZero() { + if !res.wake.IsZero() { t.Fatal("hovered toast still schedules its expiry") } time.Sleep(2 * life) @@ -182,14 +181,14 @@ func TestToastExpiresAndHoverPauses(t *testing.T) { tt.Move(5, 395) done := time.Now() // The frame that ends the hover must schedule the expiry itself. - if q.wake.IsZero() || q.wake.Before(released) || q.wake.After(done.Add(life)) { - t.Fatalf("release scheduled wake %v, released %v", q.wake, released) + if res.wake.IsZero() || res.wake.Before(released) || res.wake.After(done.Add(life)) { + t.Fatalf("release scheduled wake %v, released %v", res.wake, released) } if !tt.HasText("Copied") { t.Fatal("hovered toast expired") } - // Stands in for the frame MyGo's timer runs at q.wake. - time.Sleep(time.Until(q.wake) + 5*time.Millisecond) + // Stands in for the frame MyGo's timer runs at res.wake. + time.Sleep(time.Until(res.wake) + 5*time.Millisecond) tt.Frame() if tt.HasText("Copied") { t.Fatal("toast stayed after its wake-up")