diff --git a/cache.go b/cache.go index e9f6dea..6bd54ff 100644 --- a/cache.go +++ b/cache.go @@ -77,6 +77,9 @@ type itemOptions struct { // WithExpiration is an option to set expiration time for any items. // If the expiration is zero or negative value, it treats as w/o expiration. func WithExpiration(exp time.Duration) ItemOption { + if exp <= 0 { + return func(o *itemOptions) {} + } return func(o *itemOptions) { o.expiration = nowFunc().Add(exp) } diff --git a/cache_internal_test.go b/cache_internal_test.go index 580b726..9b75b61 100644 --- a/cache_internal_test.go +++ b/cache_internal_test.go @@ -9,11 +9,17 @@ import ( func TestDeletedCache(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + restore := func() { + nowFunc = time.Now + } + defer restore() nc := NewContext[string, int](ctx) key := "key" - nc.Set(key, 1, WithExpiration(-time.Second)) - + nc.Set(key, 1, WithExpiration(1*time.Second)) + nowFunc = func() time.Time { + return time.Now().Add(2 * time.Second) + } _, ok := nc.cache.Get(key) if !ok { t.Fatal("want true") @@ -143,6 +149,30 @@ func TestDeleteExpired(t *testing.T) { t.Errorf("want %d items but got %d", want, got) } }) + + t.Run("issue #64", func(t *testing.T) { + defer restore() + c := New[string, int]() + c.Set("1", 4, WithExpiration(0)) // These should not be expired + c.Set("2", 5, WithExpiration(-1)) // These should not be expired + c.Set("3", 6, WithExpiration(1*time.Hour)) + + want := true + _, ok := c.Get("1") + if ok != want { + t.Errorf("want %t but got %t", want, ok) + } + + _, ok = c.Get("2") + if ok != want { + t.Errorf("want %t but got %t", want, ok) + } + _, ok = c.Get("3") + if ok != want { + t.Errorf("want %t but got %t", want, ok) + } + + }) } func max(x, y int) int {