github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbtime/long_duration_test.go (about) 1 package kbtime 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 ) 10 11 const testTTzFmt = `2006-01-02 15:04:05 -0700` 12 13 type longDurTestCase struct { 14 expected string 15 duration string 16 } 17 18 func TestAddLongDurationLong(t *testing.T) { 19 then, err := time.Parse(testTTzFmt, "2020-04-01 12:23:08 +0000") 20 require.NoError(t, err) 21 22 cases := []longDurTestCase{ 23 {"2021-04-01 12:23:08 +0000", "1 Y"}, 24 {"2021-04-01 12:23:08 +0000", "1Y"}, 25 {"2022-04-01 12:23:08 +0000", "2 Y"}, 26 {"2023-04-01 12:23:08 +0000", "3Y"}, 27 {"2030-04-01 12:23:08 +0000", "10 Y"}, 28 {"3020-04-01 12:23:08 +0000", "1000 Y"}, 29 30 {"2020-04-08 12:23:08 +0000", "7D"}, 31 {"2020-04-08 12:23:08 +0000", "7D"}, 32 {"2020-04-15 12:23:08 +0000", "14 D"}, 33 34 {"2020-05-01 12:23:08 +0000", "1M"}, 35 {"2020-06-01 12:23:08 +0000", "2 M"}, 36 {"2020-07-01 12:23:08 +0000", "3M"}, 37 {"2020-10-01 12:23:08 +0000", "6M"}, 38 {"2021-02-01 12:23:08 +0000", "10M"}, 39 } 40 41 for _, c := range cases { 42 ret, err := AddLongDuration(then, c.duration) 43 require.NoError(t, err, "failed for %q", c.duration) 44 require.Equal(t, c.expected, ret.Format(testTTzFmt), "failed for %q", c.duration) 45 } 46 } 47 48 func TestAddLongDurationForTimeTravelers(t *testing.T) { 49 then, err := time.Parse(testTTzFmt, "3062-04-01 12:23:08 +0200") 50 require.NoError(t, err) 51 52 cases := []longDurTestCase{ 53 {"3072-04-01 12:23:08 +0200", "10 Y"}, 54 {"4062-04-01 12:23:08 +0200", "1000 Y"}, 55 {"3062-04-15 12:23:08 +0200", "14 D"}, 56 {"3062-05-01 12:23:08 +0200", "1M"}, 57 {"3062-10-01 12:23:08 +0200", "6M"}, 58 } 59 60 for _, c := range cases { 61 ret, err := AddLongDuration(then, c.duration) 62 require.NoError(t, err, "failed for %q", c.duration) 63 require.Equal(t, c.expected, ret.Format(testTTzFmt), "failed for %q", c.duration) 64 } 65 } 66 67 func TestAddLongDurationFallback(t *testing.T) { 68 // For short durations (<= hour) the function should fall back to 69 // time.ParseDuration. Make sure that's the case. 70 now := time.Now() 71 72 for _, amount := range []int{1, 3, 6, 10, 2883, 2312, 93762} { 73 for _, unit := range []string{"ns", "us", "µs", "μs", "ms", "s", "m", "h"} { 74 timeDuration, err := time.ParseDuration(fmt.Sprintf("%d%s", amount, unit)) 75 require.NoError(t, err) 76 77 expected := now.Add(timeDuration) 78 79 for _, format := range []string{"%d %s", "%d%s", " %d %s", "%d %s ", " %d %s "} { 80 durStr := fmt.Sprintf(format, amount, unit) 81 ret, err := AddLongDuration(now, durStr) 82 require.NoError(t, err, "failed on %q", durStr) 83 require.Equal(t, expected, ret, "ret value not equal on %q", durStr) 84 } 85 } 86 } 87 } 88 89 func TestAddLongDurationBad(t *testing.T) { 90 now := time.Now() 91 for _, duration := range []string{ 92 // Invalid units 93 "1 xs", "10 years", "1 year", "2 days", 94 // No units 95 "1", "2123", "520", 96 // More than one whitespace between int and unit. 97 "1 s", "1 y", "1 M", 98 // Unit alone 99 "s", "m", "y", "Y", "M", 100 // Negative ints 101 "-10s", "-15 d", "-1 y", "-1h", "-1 Y", 102 // Fractions 103 "341.2h", "50.5s", 104 // Ambiguous units 105 "1d", "2 d", "10y", 106 } { 107 ret, err := AddLongDuration(now, "1 xs") 108 require.Error(t, err, "expected an error for %q", duration) 109 require.Zero(t, ret) 110 } 111 } 112 113 func TestAddLongDurationTimezone(t *testing.T) { 114 loc, err := time.LoadLocation("Europe/Warsaw") 115 require.NoError(t, err) 116 then, err := time.ParseInLocation(testTTzFmt, "2020-04-01 12:23:08 +0200", loc) 117 require.NoError(t, err) 118 119 ret, err := AddLongDuration(then, "1000 Y") 120 require.NoError(t, err) 121 require.Equal(t, 122 "3020-04-01 12:23:08 +0200", 123 ret.Format(testTTzFmt)) 124 }