github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/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  }