1 Star 1 Fork 0

benjamin.zhang/miniredis

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cmd_hash_test.go 12.36 KB
一键复制 编辑 原始数据 按行查看 历史
Pierre Prinetti 提交于 2018-05-09 12:09 . Use the new redigo import path
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
package miniredis
import (
"sort"
"testing"
"time"
"github.com/gomodule/redigo/redis"
)
// Test Hash.
func TestHash(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
{
b, err := redis.Int(c.Do("HSET", "aap", "noot", "mies"))
ok(t, err)
equals(t, 1, b) // New field.
}
{
v, err := redis.String(c.Do("HGET", "aap", "noot"))
ok(t, err)
equals(t, "mies", v)
equals(t, "mies", s.HGet("aap", "noot"))
}
{
b, err := redis.Int(c.Do("HSET", "aap", "noot", "mies"))
ok(t, err)
equals(t, 0, b) // Existing field.
}
// Wrong type of key
{
_, err := redis.String(c.Do("SET", "foo", "bar"))
ok(t, err)
_, err = redis.Int(c.Do("HSET", "foo", "noot", "mies"))
assert(t, err != nil, "HSET error")
}
// hash exists, key doesn't.
{
b, err := c.Do("HGET", "aap", "nosuch")
ok(t, err)
equals(t, nil, b)
}
// hash doesn't exists.
{
b, err := c.Do("HGET", "nosuch", "nosuch")
ok(t, err)
equals(t, nil, b)
equals(t, "", s.HGet("nosuch", "nosuch"))
}
// HGET on wrong type
{
_, err := redis.Int(c.Do("HGET", "aap"))
assert(t, err != nil, "HGET error")
}
// Direct HSet()
{
s.HSet("wim", "zus", "jet")
v, err := redis.String(c.Do("HGET", "wim", "zus"))
ok(t, err)
equals(t, "jet", v)
}
}
func TestHashSetNX(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
// New Hash
v, err := redis.Int(c.Do("HSETNX", "wim", "zus", "jet"))
ok(t, err)
equals(t, 1, v)
v, err = redis.Int(c.Do("HSETNX", "wim", "zus", "jet"))
ok(t, err)
equals(t, 0, v)
// Just a new key
v, err = redis.Int(c.Do("HSETNX", "wim", "aap", "noot"))
ok(t, err)
equals(t, 1, v)
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HSETNX", "foo", "nosuch", "nosuch"))
assert(t, err != nil, "no HSETNX error")
}
func TestHashMSet(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
// New Hash
{
v, err := redis.String(c.Do("HMSET", "hash", "wim", "zus", "jet", "vuur"))
ok(t, err)
equals(t, "OK", v)
equals(t, "zus", s.HGet("hash", "wim"))
equals(t, "vuur", s.HGet("hash", "jet"))
}
// Doesn't touch ttl.
{
s.SetTTL("hash", time.Second*999)
v, err := redis.String(c.Do("HMSET", "hash", "gijs", "lam"))
ok(t, err)
equals(t, "OK", v)
equals(t, time.Second*999, s.TTL("hash"))
}
{
// Wrong key type
s.Set("str", "value")
_, err = redis.Int(c.Do("HMSET", "str", "key", "value"))
assert(t, err != nil, "no HSETerror")
// Usage error
_, err = redis.Int(c.Do("HMSET", "str"))
assert(t, err != nil, "no HSETerror")
_, err = redis.Int(c.Do("HMSET", "str", "odd"))
assert(t, err != nil, "no HSETerror")
_, err = redis.Int(c.Do("HMSET", "str", "key", "value", "odd"))
assert(t, err != nil, "no HSETerror")
}
}
func TestHashDel(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
s.HSet("wim", "gijs", "lam")
s.HSet("wim", "kees", "bok")
v, err := redis.Int(c.Do("HDEL", "wim", "zus", "gijs"))
ok(t, err)
equals(t, 2, v)
v, err = redis.Int(c.Do("HDEL", "wim", "nosuch"))
ok(t, err)
equals(t, 0, v)
// Deleting all makes the key disappear
v, err = redis.Int(c.Do("HDEL", "wim", "teun", "kees"))
ok(t, err)
equals(t, 2, v)
assert(t, !s.Exists("wim"), "no more wim key")
// Key doesn't exists.
v, err = redis.Int(c.Do("HDEL", "nosuch", "nosuch"))
ok(t, err)
equals(t, 0, v)
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HDEL", "foo", "nosuch"))
assert(t, err != nil, "no HDEL error")
// Direct HDel()
s.HSet("aap", "noot", "mies")
s.HDel("aap", "noot")
equals(t, "", s.HGet("aap", "noot"))
}
func TestHashExists(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
v, err := redis.Int(c.Do("HEXISTS", "wim", "zus"))
ok(t, err)
equals(t, 1, v)
v, err = redis.Int(c.Do("HEXISTS", "wim", "nosuch"))
ok(t, err)
equals(t, 0, v)
v, err = redis.Int(c.Do("HEXISTS", "nosuch", "nosuch"))
ok(t, err)
equals(t, 0, v)
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HEXISTS", "foo", "nosuch"))
assert(t, err != nil, "no HDEL error")
}
func TestHashGetall(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
s.HSet("wim", "gijs", "lam")
s.HSet("wim", "kees", "bok")
v, err := redis.Strings(c.Do("HGETALL", "wim"))
ok(t, err)
equals(t, 8, len(v))
d := map[string]string{}
for len(v) > 0 {
d[v[0]] = v[1]
v = v[2:]
}
equals(t, map[string]string{
"zus": "jet",
"teun": "vuur",
"gijs": "lam",
"kees": "bok",
}, d)
v, err = redis.Strings(c.Do("HGETALL", "nosuch"))
ok(t, err)
equals(t, 0, len(v))
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HGETALL", "foo"))
assert(t, err != nil, "no HGETALL error")
}
func TestHashKeys(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
s.HSet("wim", "gijs", "lam")
s.HSet("wim", "kees", "bok")
{
v, err := redis.Strings(c.Do("HKEYS", "wim"))
ok(t, err)
equals(t, 4, len(v))
sort.Strings(v)
equals(t, []string{
"gijs",
"kees",
"teun",
"zus",
}, v)
}
// Direct command
{
direct, err := s.HKeys("wim")
ok(t, err)
sort.Strings(direct)
equals(t, []string{
"gijs",
"kees",
"teun",
"zus",
}, direct)
_, err = s.HKeys("nosuch")
equals(t, err, ErrKeyNotFound)
}
v, err := redis.Strings(c.Do("HKEYS", "nosuch"))
ok(t, err)
equals(t, 0, len(v))
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HKEYS", "foo"))
assert(t, err != nil, "no HKEYS error")
}
func TestHashValues(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
s.HSet("wim", "gijs", "lam")
s.HSet("wim", "kees", "bok")
v, err := redis.Strings(c.Do("HVALS", "wim"))
ok(t, err)
equals(t, 4, len(v))
sort.Strings(v)
equals(t, []string{
"bok",
"jet",
"lam",
"vuur",
}, v)
v, err = redis.Strings(c.Do("HVALS", "nosuch"))
ok(t, err)
equals(t, 0, len(v))
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HVALS", "foo"))
assert(t, err != nil, "no HVALS error")
}
func TestHashLen(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
s.HSet("wim", "gijs", "lam")
s.HSet("wim", "kees", "bok")
v, err := redis.Int(c.Do("HLEN", "wim"))
ok(t, err)
equals(t, 4, v)
v, err = redis.Int(c.Do("HLEN", "nosuch"))
ok(t, err)
equals(t, 0, v)
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HLEN", "foo"))
assert(t, err != nil, "no HLEN error")
}
func TestHashMget(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
s.HSet("wim", "zus", "jet")
s.HSet("wim", "teun", "vuur")
s.HSet("wim", "gijs", "lam")
s.HSet("wim", "kees", "bok")
v, err := redis.Values(c.Do("HMGET", "wim", "zus", "nosuch", "kees"))
ok(t, err)
equals(t, 3, len(v))
equals(t, "jet", string(v[0].([]byte)))
equals(t, nil, v[1])
equals(t, "bok", string(v[2].([]byte)))
v, err = redis.Values(c.Do("HMGET", "nosuch", "zus", "kees"))
ok(t, err)
equals(t, 2, len(v))
equals(t, nil, v[0])
equals(t, nil, v[1])
// Wrong key type
s.Set("foo", "bar")
_, err = redis.Int(c.Do("HMGET", "foo", "bar"))
assert(t, err != nil, "no HMGET error")
}
func TestHashIncrby(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
// New key
{
v, err := redis.Int(c.Do("HINCRBY", "hash", "field", 1))
ok(t, err)
equals(t, 1, v)
}
// Existing key
{
v, err := redis.Int(c.Do("HINCRBY", "hash", "field", 100))
ok(t, err)
equals(t, 101, v)
}
// Minus works.
{
v, err := redis.Int(c.Do("HINCRBY", "hash", "field", -12))
ok(t, err)
equals(t, 101-12, v)
}
// Direct usage
s.HIncr("hash", "field", -3)
equals(t, "86", s.HGet("hash", "field"))
// Error cases.
{
// Wrong key type
s.Set("str", "cake")
_, err = redis.Values(c.Do("HINCRBY", "str", "case", 4))
assert(t, err != nil, "no HINCRBY error")
_, err = redis.Values(c.Do("HINCRBY", "str", "case", "foo"))
assert(t, err != nil, "no HINCRBY error")
_, err = redis.Values(c.Do("HINCRBY", "str"))
assert(t, err != nil, "no HINCRBY error")
}
}
func TestHashIncrbyfloat(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
// Existing key
{
s.HSet("hash", "field", "12")
v, err := redis.Float64(c.Do("HINCRBYFLOAT", "hash", "field", "400.12"))
ok(t, err)
equals(t, 412.12, v)
equals(t, "412.12", s.HGet("hash", "field"))
}
// Existing key, not a number
{
s.HSet("hash", "field", "noint")
_, err := redis.Float64(c.Do("HINCRBYFLOAT", "hash", "field", "400"))
assert(t, err != nil, "do HINCRBYFLOAT error")
}
// New key
{
v, err := redis.Float64(c.Do("HINCRBYFLOAT", "hash", "newfield", "40.33"))
ok(t, err)
equals(t, 40.33, v)
equals(t, "40.33", s.HGet("hash", "newfield"))
}
// Direct usage
{
s.HSet("hash", "field", "500.1")
f, err := s.HIncrfloat("hash", "field", 12)
ok(t, err)
equals(t, 512.1, f)
equals(t, "512.1", s.HGet("hash", "field"))
}
// Wrong type of existing key
{
s.Set("wrong", "type")
_, err := redis.Int(c.Do("HINCRBYFLOAT", "wrong", "type", "400"))
assert(t, err != nil, "do HINCRBYFLOAT error")
}
// Wrong usage
{
_, err := redis.Int(c.Do("HINCRBYFLOAT"))
assert(t, err != nil, "do HINCRBYFLOAT error")
_, err = redis.Int(c.Do("HINCRBYFLOAT", "wrong"))
assert(t, err != nil, "do HINCRBYFLOAT error")
_, err = redis.Int(c.Do("HINCRBYFLOAT", "wrong", "value"))
assert(t, err != nil, "do HINCRBYFLOAT error")
_, err = redis.Int(c.Do("HINCRBYFLOAT", "wrong", "value", "noint"))
assert(t, err != nil, "do HINCRBYFLOAT error")
_, err = redis.Int(c.Do("HINCRBYFLOAT", "foo", "bar", 12, "tomanye"))
assert(t, err != nil, "do HINCRBYFLOAT error")
}
}
func TestHscan(t *testing.T) {
s, err := Run()
ok(t, err)
defer s.Close()
c, err := redis.Dial("tcp", s.Addr())
ok(t, err)
// We cheat with hscan. It always returns everything.
s.HSet("h", "field1", "value1")
s.HSet("h", "field2", "value2")
// No problem
{
res, err := redis.Values(c.Do("HSCAN", "h", 0))
ok(t, err)
equals(t, 2, len(res))
var c int
var keys []string
_, err = redis.Scan(res, &c, &keys)
ok(t, err)
equals(t, 0, c)
equals(t, []string{"field1", "value1", "field2", "value2"}, keys)
}
// Invalid cursor
{
res, err := redis.Values(c.Do("HSCAN", "h", 42))
ok(t, err)
equals(t, 2, len(res))
var c int
var keys []string
_, err = redis.Scan(res, &c, &keys)
ok(t, err)
equals(t, 0, c)
equals(t, []string(nil), keys)
}
// COUNT (ignored)
{
res, err := redis.Values(c.Do("HSCAN", "h", 0, "COUNT", 200))
ok(t, err)
equals(t, 2, len(res))
var c int
var keys []string
_, err = redis.Scan(res, &c, &keys)
ok(t, err)
equals(t, 0, c)
equals(t, []string{"field1", "value1", "field2", "value2"}, keys)
}
// MATCH
{
s.HSet("h", "aap", "a")
s.HSet("h", "noot", "b")
s.HSet("h", "mies", "m")
res, err := redis.Values(c.Do("HSCAN", "h", 0, "MATCH", "mi*"))
ok(t, err)
equals(t, 2, len(res))
var c int
var keys []string
_, err = redis.Scan(res, &c, &keys)
ok(t, err)
equals(t, 0, c)
equals(t, []string{"mies", "m"}, keys)
}
// Wrong usage
{
_, err := redis.Int(c.Do("HSCAN"))
assert(t, err != nil, "do HSCAN error")
_, err = redis.Int(c.Do("HSCAN", "set"))
assert(t, err != nil, "do HSCAN error")
_, err = redis.Int(c.Do("HSCAN", "set", "noint"))
assert(t, err != nil, "do HSCAN error")
_, err = redis.Int(c.Do("HSCAN", "set", 1, "MATCH"))
assert(t, err != nil, "do HSCAN error")
_, err = redis.Int(c.Do("HSCAN", "set", 1, "COUNT"))
assert(t, err != nil, "do HSCAN error")
_, err = redis.Int(c.Do("HSCAN", "set", 1, "COUNT", "noint"))
assert(t, err != nil, "do HSCAN error")
s.Set("str", "value")
_, err = redis.Int(c.Do("HSCAN", "str", 1))
assert(t, err != nil, "do HSCAN error")
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/threeDaoLiu/miniredis.git
git@gitee.com:threeDaoLiu/miniredis.git
threeDaoLiu
miniredis
miniredis
master

搜索帮助