diff --git a/cmd/mecatui/customization/lifecycle_test.go b/cmd/mecatui/customization/lifecycle_test.go
index dd985815b1..8d447cd595 100644
--- a/cmd/mecatui/customization/lifecycle_test.go
+++ b/cmd/mecatui/customization/lifecycle_test.go
@@ -25,18 +25,21 @@ func TestStatusLine_Scenario4_DebounceTemplateRefreshAndClock(t *testing.T) {
t.Fatalf("command footer = %q, want latest refresh", got)
}
- templates := NewTemplateSource(TemplateSet{Footer: SurfaceTemplates{Full: ``}}, time.Second)
+ // Interval ticks carry the clock value; drive them by hand so the refresh
+ // never lands in the same wall-clock second as the first render.
+ ticks := make(chan time.Time)
+ templates := newTemplateSourceWithTicks(TemplateSet{Footer: SurfaceTemplates{Full: ``}}, ticks)
t.Cleanup(func() { _ = templates.Close(context.Background()) })
+ templates.now = func() time.Time { return time.Date(2026, time.August, 28, 12, 0, 0, 0, time.UTC) }
templates.Submit(Input{Terminal: Terminal{FooterAvailCols: 80}})
waitStatusChange(t, templates)
- first := statusSurfaceText(templates.Latest().Footer)
- select {
- case <-templates.Changed():
- case <-time.After(1500 * time.Millisecond):
- t.Fatal("template clock did not refresh on its interval")
+ if got := statusSurfaceText(templates.Latest().Footer); got != "12:00:00" {
+ t.Fatalf("template footer = %q, want submit-time clock", got)
}
- if got := statusSurfaceText(templates.Latest().Footer); got == first {
- t.Fatalf("template clock did not advance: %q", got)
+ ticks <- time.Date(2026, time.August, 28, 12, 0, 1, 0, time.UTC)
+ waitStatusChange(t, templates)
+ if got := statusSurfaceText(templates.Latest().Footer); got != "12:00:01" {
+ t.Fatalf("template footer = %q, want interval-tick clock", got)
}
}
diff --git a/cmd/mecatui/customization/template.go b/cmd/mecatui/customization/template.go
index f195155d8b..6d3b423b71 100644
--- a/cmd/mecatui/customization/template.go
+++ b/cmd/mecatui/customization/template.go
@@ -33,16 +33,20 @@ func newTemplateSource(templates TemplateSet, interval time.Duration) *statusLin
ticker = time.NewTicker(interval)
ticks = ticker.C
}
+ s := newTemplateSourceWithTicks(templates, ticks)
+ if ticker != nil {
+ s.stopTicker = ticker.Stop
+ }
+ return s
+}
+
+func newTemplateSourceWithTicks(templates TemplateSet, ticks <-chan time.Time) *statusLineSource {
defaults := defaultTemplateSet()
header := compileVariants(templates.Header, defaults.Header)
footer := compileVariants(templates.Footer, defaults.Footer)
- s := newSource(ticks, func(ctx context.Context, input Input) Result {
+ return newSource(ticks, func(ctx context.Context, input Input) Result {
return renderTemplates(ctx, header, footer, input)
})
- if ticker != nil {
- s.stopTicker = ticker.Stop
- }
- return s
}
type templateVariants struct{ full, compact, minimal statusTemplate }