From 2bc5ad53c2f0f2ff3372b2aeedf5955d40969af0 Mon Sep 17 00:00:00 2001 From: Nick Parker Date: Wed, 8 Nov 2023 18:46:15 +1300 Subject: [PATCH] Avoid long duration strings: round to nearest second For example, seeing "Next check: 14m56.245483933s" in feeds list after force-refreshing a feed. This rounds to the nearest second, so it'll instead be "14m56s" Other examples from latter two test cases: - "12.345678s" -> "12s" - "1m27.654321s" -> "1m28s" --- internal/template/functions.go | 10 ++++++++-- internal/template/functions_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/internal/template/functions.go b/internal/template/functions.go index f617029c..ef3ffd37 100644 --- a/internal/template/functions.go +++ b/internal/template/functions.go @@ -163,17 +163,23 @@ func isEmail(str string) bool { // Returns the duration in human readable format (hours and minutes). func duration(t time.Time) string { + return durationImpl(t, time.Now()) +} + +// Accepts now argument for easy testing +func durationImpl(t time.Time, now time.Time) string { if t.IsZero() { return "" } - diff := time.Until(t) + diff := t.Sub(now) if diff < 0 { return "" } - return diff.String() + // Round to nearest second to get e.g. "14m56s" rather than "14m56.245483933s" + return diff.Round(time.Second).String() } func elapsedTime(printer *locale.Printer, tz string, t time.Time) string { diff --git a/internal/template/functions_test.go b/internal/template/functions_test.go index 193ec128..35dbf6de 100644 --- a/internal/template/functions_test.go +++ b/internal/template/functions_test.go @@ -95,6 +95,32 @@ func TestIsEmail(t *testing.T) { } } +func TestDuration(t *testing.T) { + now := time.Now() + var dt = []struct { + in time.Time + out string + }{ + {time.Time{}, ""}, + {now.Add(time.Hour), "1h0m0s"}, + {now.Add(time.Minute), "1m0s"}, + {now.Add(time.Minute * 40), "40m0s"}, + {now.Add(time.Millisecond * 40), "0s"}, + {now.Add(time.Millisecond * 80), "0s"}, + {now.Add(time.Millisecond * 400), "0s"}, + {now.Add(time.Millisecond * 800), "1s"}, + {now.Add(time.Millisecond * 4321), "4s"}, + {now.Add(time.Millisecond * 8765), "9s"}, + {now.Add(time.Microsecond * 12345678), "12s"}, + {now.Add(time.Microsecond * 87654321), "1m28s"}, + } + for i, tt := range dt { + if out := durationImpl(tt.in, now); out != tt.out { + t.Errorf(`%d. content mismatch for "%v": expected=%q got=%q`, i, tt.in, tt.out, out) + } + } +} + func TestElapsedTime(t *testing.T) { printer := locale.NewPrinter("en_US") var dt = []struct {