Files
redka/internal/rzset/db_test.go
Anton 818954d339 refactor: use vfs=memdb instead of mode=memory&cache=shared
Shared cache is discouraged. The supported alternative
(and increasingly recommended by SQLite developers),
is the memdb VFS (which I believe is supported by all drivers).
I'm sure modernc has it, and mattn also does if compiled with
SQLITE_ENABLE_DESERIALIZE, which became the default in 2021.

https://github.com/ncruces/go-sqlite3/issues/94#issuecomment-2157679766
2024-06-10 21:55:49 +05:00

1593 lines
39 KiB
Go

package rzset_test
import (
"math"
"testing"
"github.com/nalgeon/redka"
"github.com/nalgeon/redka/internal/core"
"github.com/nalgeon/redka/internal/rzset"
"github.com/nalgeon/redka/internal/testx"
)
func TestAdd(t *testing.T) {
t.Run("create", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
created, err := zset.Add("key", "one", 1)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, created, true)
created, err = zset.Add("key", "two", 2)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, created, true)
created, err = zset.Add("key", "thr", 3)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, created, true)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 3)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 3)
one, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, one, 1.0)
two, _ := zset.GetScore("key", "two")
testx.AssertEqual(t, two, 2.0)
thr, _ := zset.GetScore("key", "thr")
testx.AssertEqual(t, thr, 3.0)
})
t.Run("update", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
created, err := zset.Add("key", "one", 1)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, created, true)
created, err = zset.Add("key", "two", 2)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, created, true)
created, err = zset.Add("key", "two", 3)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, created, false)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 3)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 2)
one, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, one, 1.0)
two, _ := zset.GetScore("key", "two")
testx.AssertEqual(t, two, 3.0)
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "string")
created, err := zset.Add("key", "one", 1)
testx.AssertErr(t, err, core.ErrKeyType)
testx.AssertEqual(t, created, false)
_, err = zset.GetScore("key", "one")
testx.AssertErr(t, err, core.ErrNotFound)
sval, _ := db.Str().Get("key")
testx.AssertEqual(t, sval.String(), "string")
})
}
func TestAddMany(t *testing.T) {
t.Run("create", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
items := map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
}
n, err := zset.AddMany("key", items)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 3)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 3)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 3)
one, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, one, 1.0)
two, _ := zset.GetScore("key", "two")
testx.AssertEqual(t, two, 2.0)
thr, _ := zset.GetScore("key", "thr")
testx.AssertEqual(t, thr, 3.0)
})
t.Run("update", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
items := map[any]float64{
"one": 10,
"two": 20,
"fou": 4,
"fiv": 5,
}
n, err := zset.AddMany("key", items)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 2)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 7)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 5)
one, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, one, 10.0)
two, _ := zset.GetScore("key", "two")
testx.AssertEqual(t, two, 20.0)
thr, _ := zset.GetScore("key", "thr")
testx.AssertEqual(t, thr, 3.0)
fou, _ := zset.GetScore("key", "fou")
testx.AssertEqual(t, fou, 4.0)
fiv, _ := zset.GetScore("key", "fiv")
testx.AssertEqual(t, fiv, 5.0)
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "str")
items := map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
}
n, err := zset.AddMany("key", items)
testx.AssertErr(t, err, core.ErrKeyType)
testx.AssertEqual(t, n, 0)
_, err = zset.GetScore("key", "one")
testx.AssertErr(t, err, core.ErrNotFound)
_, err = zset.GetScore("key", "two")
testx.AssertErr(t, err, core.ErrNotFound)
_, err = zset.GetScore("key", "thr")
testx.AssertErr(t, err, core.ErrNotFound)
sval, _ := db.Str().Get("key")
testx.AssertEqual(t, sval.String(), "str")
})
}
func TestCount(t *testing.T) {
t.Run("count", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
tests := []struct {
min, max float64
count int
}{
{0, 0, 0},
{1, 1, 1},
{1, 2, 3},
{1, 3, 4},
{2, 2, 2},
{2, 3, 3},
{3, 3, 1},
{4, 4, 0},
{math.Inf(-1), 1, 1},
{1, math.Inf(1), 4},
{math.Inf(-1), math.Inf(1), 4},
}
for _, test := range tests {
count, err := zset.Count("key", test.min, test.max)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, count, test.count)
}
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
count, err := zset.Count("key", 1, 2)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, count, 0)
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "str")
count, err := zset.Count("key", 1, 2)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, count, 0)
})
}
func TestDelete(t *testing.T) {
t.Run("some", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
n, err := zset.Delete("key", "one", "two")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 2)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 4)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 1)
thr, _ := zset.GetScore("key", "thr")
testx.AssertEqual(t, thr, 3.0)
})
t.Run("all", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
n, err := zset.Delete("key", "one", "two", "thr")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 3)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 4)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 0)
_, err = zset.GetScore("key", "one")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("none", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
n, err := zset.Delete("key", "fou", "fiv")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 3)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 3)
one, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, one, 1.0)
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
n, err := zset.Delete("key", "one", "two")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "str")
n, err := zset.Delete("key", "one", "two")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
})
}
func TestDeleteRank(t *testing.T) {
t.Run("delete", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "2nd", 2)
_, _ = zset.Add("key", "thr", 3)
n, err := zset.DeleteWith("key").ByRank(1, 2).Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 2)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 5)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 2)
two, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, two, 1.0)
thr, _ := zset.GetScore("key", "thr")
testx.AssertEqual(t, thr, 3.0)
})
t.Run("negative indexes", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
n, err := zset.DeleteWith("key").ByRank(-2, -1).Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
})
}
func TestDeleteScore(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "2nd", 2)
_, _ = zset.Add("key", "thr", 3)
n, err := zset.DeleteWith("key").ByScore(1, 2).Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 3)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 5)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 1)
thr, _ := zset.GetScore("key", "thr")
testx.AssertEqual(t, thr, 3.0)
}
func TestGetRank(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
_ = db.Str().Set("str", "str")
rank, score, _ := zset.GetRank("key", "one")
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 1.0)
rank, score, _ = zset.GetRank("key", "2nd")
testx.AssertEqual(t, rank, 1)
testx.AssertEqual(t, score, 2.0)
rank, score, _ = zset.GetRank("key", "two")
testx.AssertEqual(t, rank, 2)
testx.AssertEqual(t, score, 2.0)
rank, score, _ = zset.GetRank("key", "thr")
testx.AssertEqual(t, rank, 3)
testx.AssertEqual(t, score, 3.0)
rank, score, err := zset.GetRank("key", "not")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 0.0)
rank, score, err = zset.GetRank("other", "one")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 0.0)
rank, score, err = zset.GetRank("str", "one")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 0.0)
}
func TestGetRankRev(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
_ = db.Str().Set("str", "str")
rank, score, _ := zset.GetRankRev("key", "thr")
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 3.0)
rank, score, _ = zset.GetRankRev("key", "two")
testx.AssertEqual(t, rank, 1)
testx.AssertEqual(t, score, 2.0)
rank, score, _ = zset.GetRankRev("key", "2nd")
testx.AssertEqual(t, rank, 2)
testx.AssertEqual(t, score, 2.0)
rank, score, _ = zset.GetRankRev("key", "one")
testx.AssertEqual(t, rank, 3)
testx.AssertEqual(t, score, 1.0)
rank, score, err := zset.GetRankRev("key", "not")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 0.0)
rank, score, err = zset.GetRankRev("other", "one")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 0.0)
rank, score, err = zset.GetRankRev("str", "one")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, rank, 0)
testx.AssertEqual(t, score, 0.0)
}
func TestGetScore(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
_ = db.Str().Set("str", "str")
score, _ := zset.GetScore("key", "one")
testx.AssertEqual(t, score, 1.0)
score, _ = zset.GetScore("key", "two")
testx.AssertEqual(t, score, 2.0)
score, _ = zset.GetScore("key", "thr")
testx.AssertEqual(t, score, 3.0)
score, _ = zset.GetScore("key", "2nd")
testx.AssertEqual(t, score, 2.0)
score, err := zset.GetScore("key", "not")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, score, 0.0)
score, err = zset.GetScore("other", "one")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, score, 0.0)
score, err = zset.GetScore("str", "one")
testx.AssertErr(t, err, core.ErrNotFound)
testx.AssertEqual(t, score, 0.0)
}
func TestIncr(t *testing.T) {
t.Run("create key", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
val, err := zset.Incr("key", "one", 25.5)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, val, 25.5)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 1)
})
t.Run("create field", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 10)
val, err := zset.Incr("key", "two", 25.5)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, val, 25.5)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 2)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 2)
})
t.Run("update field", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 25.5)
val, err := zset.Incr("key", "one", 10.5)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, val, 36.0)
key, _ := db.Key().Get("key")
testx.AssertEqual(t, key.Version, 2)
zlen, _ := zset.Len("key")
testx.AssertEqual(t, zlen, 1)
})
t.Run("decrement", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 25.5)
val, err := zset.Incr("key", "one", -10.5)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, val, 15.0)
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "one")
val, err := zset.Incr("key", "one", 25.0)
testx.AssertErr(t, err, core.ErrKeyType)
testx.AssertEqual(t, val, 0.0)
_, err = zset.GetScore("key", "one")
testx.AssertErr(t, err, core.ErrNotFound)
})
}
func TestInter(t *testing.T) {
t.Run("non-empty", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.Inter("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 9},
{Elem: core.Value("two"), Score: 222},
})
})
t.Run("single key", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
items, err := zset.Inter("key1")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
{Elem: core.Value("two"), Score: 2},
{Elem: core.Value("thr"), Score: 3},
})
})
t.Run("empty", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "two", 1)
_, _ = zset.Add("key3", "thr", 1)
items, err := zset.Inter("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
items, err := zset.Inter("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("all not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
items, err := zset.Inter("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key1", "str")
_, _ = zset.Add("key2", "two", 2)
_, _ = zset.Add("key3", "two", 2)
items, err := zset.Inter("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
}
func TestInterWith(t *testing.T) {
t.Run("sum", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.InterWith("key1", "key2", "key3").Sum().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 9},
{Elem: core.Value("two"), Score: 222},
})
})
t.Run("min", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.InterWith("key1", "key2", "key3").Min().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("two"), Score: 2},
{Elem: core.Value("thr"), Score: 3},
})
})
t.Run("max", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.InterWith("key1", "key2", "key3").Max().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 3},
{Elem: core.Value("two"), Score: 200},
})
})
}
func TestInterStore(t *testing.T) {
t.Run("store", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
n, err := zset.InterWith("key1", "key2", "key3").Dest("dest").Max().Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 2)
key, _ := db.Key().Get("dest")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("dest")
testx.AssertEqual(t, zlen, 2)
thr, _ := zset.GetScore("dest", "thr")
testx.AssertEqual(t, thr, 3.0)
two, _ := zset.GetScore("dest", "two")
testx.AssertEqual(t, two, 200.0)
})
t.Run("rewrite dest", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
_, _ = zset.Add("dest", "old", 10)
n, err := zset.InterWith("key1", "key2").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 1)
key, _ := db.Key().Get("dest")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("dest")
testx.AssertEqual(t, zlen, 1)
one, _ := zset.GetScore("dest", "one")
testx.AssertEqual(t, one, 3.0)
_, err = zset.GetScore("dest", "old")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("empty", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "two", 2)
_, _ = zset.Add("dest", "old", 10)
n, err := zset.InterWith("key1", "key2").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
key, _ := db.Key().Get("dest")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("dest")
testx.AssertEqual(t, zlen, 0)
_, err = zset.GetScore("dest", "one")
testx.AssertErr(t, err, core.ErrNotFound)
_, err = zset.GetScore("dest", "two")
testx.AssertErr(t, err, core.ErrNotFound)
_, err = zset.GetScore("dest", "old")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("source key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
n, err := zset.InterWith("key1", "key2", "key3").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
_, err = zset.GetScore("dest", "one")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("source key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
_ = db.Str().Set("key3", 3)
n, err := zset.InterWith("key1", "key2", "key3").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
_, err = zset.GetScore("dest", "one")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("dest key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
_ = db.Str().Set("dest", 10)
n, err := zset.InterWith("key1", "key2").Dest("dest").Store()
testx.AssertErr(t, err, core.ErrKeyType)
testx.AssertEqual(t, n, 0)
_, err = zset.GetScore("dest", "one")
testx.AssertErr(t, err, core.ErrNotFound)
sval, _ := db.Str().Get("dest")
testx.AssertEqual(t, sval.String(), "10")
})
}
func TestLen(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
t.Run("count", func(t *testing.T) {
count, err := zset.Len("key")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, count, 4)
})
t.Run("key not found", func(t *testing.T) {
count, err := zset.Len("not")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, count, 0)
})
t.Run("key type mismatch", func(t *testing.T) {
_ = db.Str().Set("str", "str")
count, err := zset.Len("str")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, count, 0)
})
}
func TestRangeRank(t *testing.T) {
t.Run("range", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
tests := []struct {
start, stop int
items []rzset.SetItem
}{
{0, 0, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
}},
{0, 1, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1}, {Elem: core.Value("2nd"), Score: 2},
}},
{1, 2, []rzset.SetItem{
{Elem: core.Value("2nd"), Score: 2}, {Elem: core.Value("two"), Score: 2},
}},
{2, 3, []rzset.SetItem{
{Elem: core.Value("two"), Score: 2}, {Elem: core.Value("thr"), Score: 3},
}},
{3, 4, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 3},
}},
{4, 5, []rzset.SetItem(nil)},
}
for _, test := range tests {
items, err := zset.Range("key", test.start, test.stop)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, test.items)
}
})
t.Run("desc", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
_, _ = zset.Add("key", "thr", 3)
_, _ = zset.Add("key", "2nd", 2)
tests := []struct {
start, stop int
items []rzset.SetItem
}{
{0, 0, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 3},
}},
{0, 1, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 3}, {Elem: core.Value("two"), Score: 2},
}},
{1, 2, []rzset.SetItem{
{Elem: core.Value("two"), Score: 2}, {Elem: core.Value("2nd"), Score: 2},
}},
{2, 3, []rzset.SetItem{
{Elem: core.Value("2nd"), Score: 2}, {Elem: core.Value("one"), Score: 1},
}},
{3, 4, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
}},
{4, 5, []rzset.SetItem(nil)},
}
for _, test := range tests {
items, err := zset.RangeWith("key").ByRank(test.start, test.stop).Desc().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, test.items)
}
})
t.Run("negative indexes", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 1)
_, _ = zset.Add("key", "two", 2)
items, err := zset.Range("key", -2, -1)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
items, err := zset.Range("key", 0, 1)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "str")
items, err := zset.Range("key", 0, 1)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
}
func TestRangeScore(t *testing.T) {
t.Run("asc", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 10)
_, _ = zset.Add("key", "two", 20)
_, _ = zset.Add("key", "thr", 30)
_, _ = zset.Add("key", "2nd", 20)
tests := []struct {
start, stop float64
items []rzset.SetItem
}{
{0, 10, []rzset.SetItem{
{Elem: core.Value("one"), Score: 10},
}},
{10, 20, []rzset.SetItem{
{Elem: core.Value("one"), Score: 10},
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("two"), Score: 20},
}},
{20, 20, []rzset.SetItem{
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("two"), Score: 20},
}},
{20, 30, []rzset.SetItem{
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("two"), Score: 20},
{Elem: core.Value("thr"), Score: 30},
}},
{30, 40, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 30},
}},
{40, 50, []rzset.SetItem(nil)},
}
for _, test := range tests {
items, err := zset.RangeWith("key").ByScore(test.start, test.stop).Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, test.items)
}
})
t.Run("desc", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 10)
_, _ = zset.Add("key", "two", 20)
_, _ = zset.Add("key", "thr", 30)
_, _ = zset.Add("key", "2nd", 20)
tests := []struct {
start, stop float64
items []rzset.SetItem
}{
{0, 10, []rzset.SetItem{
{Elem: core.Value("one"), Score: 10},
}},
{10, 20, []rzset.SetItem{
{Elem: core.Value("two"), Score: 20},
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("one"), Score: 10},
}},
{20, 20, []rzset.SetItem{
{Elem: core.Value("two"), Score: 20},
{Elem: core.Value("2nd"), Score: 20},
}},
{20, 30, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 30},
{Elem: core.Value("two"), Score: 20},
{Elem: core.Value("2nd"), Score: 20},
}},
{30, 40, []rzset.SetItem{
{Elem: core.Value("thr"), Score: 30},
}},
{40, 50, []rzset.SetItem(nil)},
}
for _, test := range tests {
items, err := zset.RangeWith("key").ByScore(test.start, test.stop).Desc().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, test.items)
}
})
t.Run("offset/count", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "one", 10)
_, _ = zset.Add("key", "two", 20)
_, _ = zset.Add("key", "thr", 30)
_, _ = zset.Add("key", "2nd", 20)
tests := []struct {
start, stop float64
offset, count int
items []rzset.SetItem
}{
{10, 30, 0, 0, []rzset.SetItem{
{Elem: core.Value("one"), Score: 10},
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("two"), Score: 20},
{Elem: core.Value("thr"), Score: 30},
}},
{10, 30, 0, 2, []rzset.SetItem{
{Elem: core.Value("one"), Score: 10},
{Elem: core.Value("2nd"), Score: 20},
}},
{10, 30, 1, 0, []rzset.SetItem{
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("two"), Score: 20},
{Elem: core.Value("thr"), Score: 30},
}},
{10, 30, 1, 2, []rzset.SetItem{
{Elem: core.Value("2nd"), Score: 20},
{Elem: core.Value("two"), Score: 20},
}},
}
for _, test := range tests {
items, err := zset.RangeWith("key").
ByScore(test.start, test.stop).
Offset(test.offset).Count(test.count).
Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, test.items)
}
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
items, err := zset.RangeWith("key").ByScore(0, 10).Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "str")
items, err := zset.RangeWith("key").ByScore(0, 10).Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
}
func TestScan(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "f11", 11)
_, _ = zset.Add("key", "f12", 12)
_, _ = zset.Add("key", "f21", 21)
_, _ = zset.Add("key", "f22", 22)
_, _ = zset.Add("key", "f31", 31)
_ = db.Str().Set("str", "str")
tests := []struct {
name string
cursor int
pattern string
count int
wantCursor int
wantItems []rzset.SetItem
}{
{"all", 0, "*", 0, 5,
[]rzset.SetItem{
{Elem: core.Value("f11"), Score: 11},
{Elem: core.Value("f12"), Score: 12},
{Elem: core.Value("f21"), Score: 21},
{Elem: core.Value("f22"), Score: 22},
{Elem: core.Value("f31"), Score: 31},
},
},
{"some", 0, "f2*", 10, 4,
[]rzset.SetItem{
{Elem: core.Value("f21"), Score: 21},
{Elem: core.Value("f22"), Score: 22},
},
},
{"none", 0, "n*", 10, 0, []rzset.SetItem(nil)},
{"cursor 1st", 0, "*", 2, 2,
[]rzset.SetItem{
{Elem: core.Value("f11"), Score: 11},
{Elem: core.Value("f12"), Score: 12},
},
},
{"cursor 2nd", 2, "*", 2, 4,
[]rzset.SetItem{
{Elem: core.Value("f21"), Score: 21},
{Elem: core.Value("f22"), Score: 22},
},
},
{"cursor 3rd", 4, "*", 2, 5,
[]rzset.SetItem{
{Elem: core.Value("f31"), Score: 31},
},
},
{"exhausted", 6, "*", 2, 0, []rzset.SetItem(nil)},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
out, err := zset.Scan("key", test.cursor, test.pattern, test.count)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, out.Cursor, test.wantCursor)
for i, item := range out.Items {
testx.AssertEqual(t, item.Elem, test.wantItems[i].Elem)
testx.AssertEqual(t, item.Score, test.wantItems[i].Score)
}
})
}
t.Run("ignore other keys", func(t *testing.T) {
_, _ = zset.Add("key1", "elem", 10)
_, _ = zset.Add("key2", "elem", 20)
out, err := zset.Scan("key1", 0, "*", 0)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, len(out.Items), 1)
testx.AssertEqual(t, out.Items[0].Elem.String(), "elem")
testx.AssertEqual(t, out.Items[0].Score, 10.0)
})
t.Run("key not found", func(t *testing.T) {
out, err := zset.Scan("not", 0, "*", 0)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, len(out.Items), 0)
})
t.Run("key type mismatch", func(t *testing.T) {
out, err := zset.Scan("str", 0, "*", 0)
testx.AssertNoErr(t, err)
testx.AssertEqual(t, len(out.Items), 0)
})
}
func TestScanner(t *testing.T) {
t.Run("scan", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key", "f11", 11)
_, _ = zset.Add("key", "f12", 12)
_, _ = zset.Add("key", "f21", 21)
_, _ = zset.Add("key", "f22", 22)
_, _ = zset.Add("key", "f31", 31)
var items []rzset.SetItem
err := db.View(func(tx *redka.Tx) error {
sc := tx.ZSet().Scanner("key", "*", 2)
for sc.Scan() {
items = append(items, sc.Item())
}
return sc.Err()
})
testx.AssertNoErr(t, err)
elems := make([]string, len(items))
scores := make([]int, len(items))
for i, it := range items {
elems[i] = it.Elem.String()
scores[i] = int(it.Score)
}
testx.AssertEqual(t, elems, []string{"f11", "f12", "f21", "f22", "f31"})
testx.AssertEqual(t, scores, []int{11, 12, 21, 22, 31})
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
sc := zset.Scanner("not", "*", 2)
var items []rzset.SetItem
for sc.Scan() {
items = append(items, sc.Item())
}
testx.AssertNoErr(t, sc.Err())
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key", "str")
sc := zset.Scanner("key", "*", 2)
var items []rzset.SetItem
for sc.Scan() {
items = append(items, sc.Item())
}
testx.AssertNoErr(t, sc.Err())
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
}
func TestUnion(t *testing.T) {
t.Run("intersecting", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.Union("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 2},
{Elem: core.Value("thr"), Score: 9},
{Elem: core.Value("two"), Score: 222},
{Elem: core.Value("fou"), Score: 404},
})
})
t.Run("distinct", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "two", 1)
_, _ = zset.Add("key3", "thr", 1)
items, err := zset.Union("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
{Elem: core.Value("thr"), Score: 1},
{Elem: core.Value("two"), Score: 1},
})
})
t.Run("key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "two", 2)
items, err := zset.Union("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
{Elem: core.Value("two"), Score: 2},
})
})
t.Run("all not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
items, err := zset.Union("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem(nil))
})
t.Run("key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_ = db.Str().Set("key1", "str")
_, _ = zset.Add("key2", "two", 2)
_, _ = zset.Add("key3", "two", 2)
items, err := zset.Union("key1", "key2", "key3")
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("two"), Score: 4},
})
})
}
func TestUnionWith(t *testing.T) {
t.Run("sum", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.UnionWith("key1", "key2", "key3").Sum().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 2},
{Elem: core.Value("thr"), Score: 9},
{Elem: core.Value("two"), Score: 222},
{Elem: core.Value("fou"), Score: 404},
})
})
t.Run("min", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.UnionWith("key1", "key2", "key3").Min().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
{Elem: core.Value("two"), Score: 2},
{Elem: core.Value("thr"), Score: 3},
{Elem: core.Value("fou"), Score: 4},
})
})
t.Run("max", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
items, err := zset.UnionWith("key1", "key2", "key3").Max().Run()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, items, []rzset.SetItem{
{Elem: core.Value("one"), Score: 1},
{Elem: core.Value("thr"), Score: 3},
{Elem: core.Value("two"), Score: 200},
{Elem: core.Value("fou"), Score: 400},
})
})
}
func TestUnionStore(t *testing.T) {
t.Run("store", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.AddMany("key1", map[any]float64{
"one": 1,
"two": 2,
"thr": 3,
})
_, _ = zset.AddMany("key2", map[any]float64{
"two": 20,
"thr": 3,
"fou": 4,
})
_, _ = zset.AddMany("key3", map[any]float64{
"one": 1,
"two": 200,
"thr": 3,
"fou": 400,
})
n, err := zset.UnionWith("key1", "key2", "key3").Dest("dest").Max().Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 4)
key, _ := db.Key().Get("dest")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("dest")
testx.AssertEqual(t, zlen, 4)
one, _ := zset.GetScore("dest", "one")
testx.AssertEqual(t, one, 1.0)
thr, _ := zset.GetScore("dest", "thr")
testx.AssertEqual(t, thr, 3.0)
two, _ := zset.GetScore("dest", "two")
testx.AssertEqual(t, two, 200.0)
fou, _ := zset.GetScore("dest", "fou")
testx.AssertEqual(t, fou, 400.0)
})
t.Run("rewrite dest", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
_, _ = zset.Add("dest", "old", 10)
n, err := zset.UnionWith("key1", "key2").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 1)
key, _ := db.Key().Get("dest")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("dest")
testx.AssertEqual(t, zlen, 1)
one, _ := zset.GetScore("dest", "one")
testx.AssertEqual(t, one, 3.0)
_, err = zset.GetScore("dest", "old")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("empty", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("dest", "old", 10)
n, err := zset.UnionWith("key1", "key2").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 0)
key, _ := db.Key().Get("dest")
testx.AssertEqual(t, key.Version, 1)
zlen, _ := zset.Len("dest")
testx.AssertEqual(t, zlen, 0)
_, err = zset.GetScore("dest", "old")
testx.AssertErr(t, err, core.ErrNotFound)
})
t.Run("source key not found", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
n, err := zset.UnionWith("key1", "key2", "key3").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 1)
one, _ := zset.GetScore("dest", "one")
testx.AssertEqual(t, one, 3.0)
})
t.Run("source key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
_ = db.Str().Set("key3", 3)
n, err := zset.UnionWith("key1", "key2", "key3").Dest("dest").Store()
testx.AssertNoErr(t, err)
testx.AssertEqual(t, n, 1)
one, _ := zset.GetScore("dest", "one")
testx.AssertEqual(t, one, 3.0)
})
t.Run("dest key type mismatch", func(t *testing.T) {
db, zset := getDB(t)
defer db.Close()
_, _ = zset.Add("key1", "one", 1)
_, _ = zset.Add("key2", "one", 2)
_ = db.Str().Set("dest", 10)
n, err := zset.UnionWith("key1", "key2").Dest("dest").Store()
testx.AssertErr(t, err, core.ErrKeyType)
testx.AssertEqual(t, n, 0)
_, err = zset.GetScore("dest", "one")
testx.AssertErr(t, err, core.ErrNotFound)
sval, _ := db.Str().Get("dest")
testx.AssertEqual(t, sval.String(), "10")
})
}
func getDB(tb testing.TB) (*redka.DB, *rzset.DB) {
tb.Helper()
db, err := redka.Open("file:/data.db?vfs=memdb", nil)
if err != nil {
tb.Fatal(err)
}
return db, db.ZSet()
}