diff --git a/cmd_sorted_set.go b/cmd_sorted_set.go index e92c82a..bc1afc0 100644 --- a/cmd_sorted_set.go +++ b/cmd_sorted_set.go @@ -825,6 +825,12 @@ func (m *Miniredis) makeCmdZrank(reverse bool) server.Cmd { withTx(m, c, func(c *server.Peer, ctx *connCtx) { db := m.db(ctx.selectedDB) + withScore := false + if len(args) > 0 && strings.ToUpper(args[len(args)-1]) == "WITHSCORE" { + withScore = true + args = args[:len(args)-1] + } + if len(args) > 2 { setDirty(c) c.WriteError(msgSyntaxError) @@ -832,7 +838,11 @@ func (m *Miniredis) makeCmdZrank(reverse bool) server.Cmd { } if !db.exists(key) { - c.WriteNull() + if withScore { + c.WriteLen(-1) + } else { + c.WriteNull() + } return } @@ -847,10 +857,21 @@ func (m *Miniredis) makeCmdZrank(reverse bool) server.Cmd { } rank, ok := db.ssetRank(key, member, direction) if !ok { - c.WriteNull() + if withScore { + c.WriteLen(-1) + } else { + c.WriteNull() + } return } - c.WriteInt(rank) + + if withScore { + c.WriteLen(2) + c.WriteInt(rank) + c.WriteFloat(db.ssetScore(key, member)) + } else { + c.WriteInt(rank) + } }) } } diff --git a/cmd_sorted_set_test.go b/cmd_sorted_set_test.go index 670110e..a4040d6 100644 --- a/cmd_sorted_set_test.go +++ b/cmd_sorted_set_test.go @@ -30,10 +30,27 @@ func TestSortedSet(t *testing.T) { proto.Int(2), ) + mustDo(t, c, + "ZRANK", "z", "three", "withscore", + proto.Array( + proto.Int(2), + proto.String("3"), + ), + ) + mustDo(t, c, "ZREVRANK", "z", "one", proto.Int(2), ) + + mustDo(t, c, + "ZREVRANK", "z", "one", "withscore", + proto.Array( + proto.Int(2), + proto.String("1"), + ), + ) + must0(t, c, "ZREVRANK", "z", "three", ) diff --git a/integration/sorted_set_test.go b/integration/sorted_set_test.go index 79ff45b..72b9abf 100644 --- a/integration/sorted_set_test.go +++ b/integration/sorted_set_test.go @@ -18,13 +18,18 @@ func TestSortedSet(t *testing.T) { c.Do("ZRANK", "z", "mies") c.Do("ZRANK", "z", "vuur") c.Do("ZRANK", "z", "nosuch") + c.Do("ZRANK", "z", "vuur", "WITHSCORE") c.Do("ZRANK", "nosuch", "nosuch") + c.Do("ZRANK", "z", "nosuch", "WITHSCORE") + c.Do("ZRANK", "nosuch", "nosuch", "WITHSCORE") c.Do("ZREVRANK", "z", "aap") c.Do("ZREVRANK", "z", "noot") c.Do("ZREVRANK", "z", "mies") c.Do("ZREVRANK", "z", "vuur") c.Do("ZREVRANK", "z", "nosuch") c.Do("ZREVRANK", "nosuch", "nosuch") + c.Do("ZREVRANK", "z", "noot", "WITHSCORE") + c.Do("ZREVRANK", "nosuch", "nosuch", "WITHSCORE") c.Do("ZADD", "zi", "inf", "aap", "-inf", "noot", "+inf", "mies") c.Do("ZRANK", "zi", "noot") @@ -70,6 +75,8 @@ func TestSortedSet(t *testing.T) { c.Error("wrong number", "ZPOPMIN") c.Error("out of range", "ZPOPMIN", "set", "noint") c.Error("syntax error", "ZPOPMIN", "set", "1", "toomany") + c.Error("syntax error", "ZRANK", "z", "nosuch", "WITHSCORES") + c.Error("syntax error", "ZREVRANK", "z", "nosuch", "WITHSCORES") c.Do("RENAME", "z", "z2") c.Do("EXISTS", "z")