You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
4.9 KiB

package cache_test
import (
"context"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/require"
"gitoa.ru/go-4devs/cache"
"gitoa.ru/go-4devs/cache/test"
)
func TestCache_Get(t *testing.T) {
t.Parallel()
ctx := context.Background()
pro := test.NewProviderMock(t, test.WithGet(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
u := test.NewUser(1)
return cache.TypeAssert(u, d.Value)
}
}))
cache := cache.New(pro)
var user test.User
require.Nil(t, cache.Get(ctx, 1, &user))
require.Equal(t, test.NewUser(1), user)
}
func TestCache_Set(t *testing.T) {
t.Parallel()
ctx := context.Background()
pro := test.NewProviderMock(t, test.WithSet(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
require.Equal(t, 1, d.Key.Key)
require.Equal(t, test.NewUser(1), d.Value)
require.Equal(t, "1", d.Key.String())
return nil
}
}))
cache := cache.New(pro)
require.Nil(t, cache.Set(ctx, 1, test.NewUser(1)))
}
func TestCache_Delete(t *testing.T) {
t.Parallel()
ctx := context.Background()
pro := test.NewProviderMock(t, test.WithDelete(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
require.Equal(t, 1, d.Key.Key)
require.Empty(t, d.Value)
require.Equal(t, "1", d.Key.String())
return nil
}
}))
cache := cache.New(pro)
require.Nil(t, cache.Delete(ctx, 1))
}
func TestCache_Get_withMiddleware(t *testing.T) {
t.Parallel()
ctx := context.Background()
pro := test.NewProviderMock(t,
test.WithSet(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
require.Equal(t, 2, d.Key.Key)
require.Equal(t, test.NewUser(2), d.Value)
require.Equal(t, "mw_prefix::_2", d.Key.String())
require.Equal(t, time.Minute, d.TTL)
return nil
}
}),
test.WithGet(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
require.Equal(t, 2, d.Key.Key)
require.Equal(t, "mw_prefix----2", d.Key.String())
return nil
}
}),
)
c := cache.New(pro,
cache.WithDataOption(
func(i *cache.Item) {
i.Key.Prefix = "mw_prefix"
},
cache.WithTTL(time.Hour),
),
cache.WithHandleSet(
func(ctx context.Context, op string, d *cache.Item, n cache.Provider) error {
d.Key.Separator = "::"
return n(ctx, op, d)
}, func(ctx context.Context, op string, d *cache.Item, n cache.Provider) error {
d.Key.Separator += "_"
return n(ctx, op, d)
}),
cache.WithHandleGet(func(ctx context.Context, op string, d *cache.Item, n cache.Provider) error {
d.Key.Separator = "----"
return n(ctx, op, d)
}),
)
var user test.User
require.Nil(t, c.Set(ctx, 2, test.NewUser(2), cache.WithTTL(time.Minute)))
require.Nil(t, c.Get(ctx, 2, &user))
}
func TestCacheWith(t *testing.T) {
t.Parallel()
ctx := context.Background()
pro := test.NewProviderMock(t,
test.WithGet(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
switch d.Key.Key.(int) {
case 1:
require.Equal(t, "ns:1", d.Key.String())
case 2:
require.Equal(t, "new_ns_2", d.Key.String())
default:
t.Errorf("key %v no allowed", d.Key.Key)
}
return nil
}
}),
test.WithSet(func(t *testing.T) func(ctx context.Context, item *cache.Item) error {
t.Helper()
return func(ctx context.Context, d *cache.Item) error {
switch d.Key.Key.(int) {
case 1:
require.Equal(t, time.Hour, d.TTL)
case 2:
require.Equal(t, time.Minute, d.TTL)
default:
t.Errorf("key %v no allowed", d.Key.Key)
}
return nil
}
}),
)
var (
cntSetCache2, cntGetCache1 int32
val1, val2 string
)
cache1 := cache.New(pro,
cache.WithHandleGet(func(ctx context.Context, operation string, item *cache.Item, next cache.Provider) error {
atomic.AddInt32(&cntGetCache1, 1)
return next(ctx, operation, item)
}),
cache.WithDataOption(
cache.WithNamespace("ns", ":"),
cache.WithTTL(time.Hour),
),
)
cache2 := cache1.With(
cache.WithHandleSet(func(ctx context.Context, operation string, item *cache.Item, next cache.Provider) error {
atomic.AddInt32(&cntSetCache2, 1)
return next(ctx, operation, item)
}),
cache.WithDataOption(
cache.WithNamespace("new_ns", "_"),
cache.WithTTL(time.Minute),
),
)
require.NoError(t, cache1.Get(ctx, 1, &val1))
require.NoError(t, cache2.Get(ctx, 2, &val2))
require.NoError(t, cache1.Set(ctx, 1, val1))
require.NoError(t, cache2.Set(ctx, 2, val2))
require.Equal(t, int32(1), cntSetCache2)
require.Equal(t, int32(2), cntGetCache1)
}