+ test {ZINCRBY - can create a new sorted set} {
+ $r del zset
+ $r zincrby zset 1 foo
+ list [$r zrange zset 0 -1] [$r zscore zset foo]
+ } {foo 1}
+
+ test {ZINCRBY - increment and decrement} {
+ $r zincrby zset 2 foo
+ $r zincrby zset 1 bar
+ set v1 [$r zrange zset 0 -1]
+ $r zincrby zset 10 bar
+ $r zincrby zset -5 foo
+ $r zincrby zset -5 bar
+ set v2 [$r zrange zset 0 -1]
+ list $v1 $v2 [$r zscore zset foo] [$r zscore zset bar]
+ } {{bar foo} {foo bar} -2 6}
+
+ test {ZRANGEBYSCORE and ZCOUNT basics} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 2 b
+ $r zadd zset 3 c
+ $r zadd zset 4 d
+ $r zadd zset 5 e
+ list [$r zrangebyscore zset 2 4] [$r zrangebyscore zset (2 (4] \
+ [$r zcount zset 2 4] [$r zcount zset (2 (4]
+ } {{b c d} c 3 1}
+
+ test {ZRANGEBYSCORE withscores} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 2 b
+ $r zadd zset 3 c
+ $r zadd zset 4 d
+ $r zadd zset 5 e
+ $r zrangebyscore zset 2 4 withscores
+ } {b 2 c 3 d 4}
+
+ test {ZRANGEBYSCORE fuzzy test, 100 ranges in 1000 elements sorted set} {
+ set err {}
+ $r del zset
+ for {set i 0} {$i < 1000} {incr i} {
+ $r zadd zset [expr rand()] $i
+ }
+ for {set i 0} {$i < 100} {incr i} {
+ set min [expr rand()]
+ set max [expr rand()]
+ if {$min > $max} {
+ set aux $min
+ set min $max
+ set max $aux
+ }
+ set low [$r zrangebyscore zset -inf $min]
+ set ok [$r zrangebyscore zset $min $max]
+ set high [$r zrangebyscore zset $max +inf]
+ set lowx [$r zrangebyscore zset -inf ($min]
+ set okx [$r zrangebyscore zset ($min ($max]
+ set highx [$r zrangebyscore zset ($max +inf]
+
+ if {[$r zcount zset -inf $min] != [llength $low]} {
+ append err "Error, len does not match zcount\n"
+ }
+ if {[$r zcount zset $min $max] != [llength $ok]} {
+ append err "Error, len does not match zcount\n"
+ }
+ if {[$r zcount zset $max +inf] != [llength $high]} {
+ append err "Error, len does not match zcount\n"
+ }
+ if {[$r zcount zset -inf ($min] != [llength $lowx]} {
+ append err "Error, len does not match zcount\n"
+ }
+ if {[$r zcount zset ($min ($max] != [llength $okx]} {
+ append err "Error, len does not match zcount\n"
+ }
+ if {[$r zcount zset ($max +inf] != [llength $highx]} {
+ append err "Error, len does not match zcount\n"
+ }
+
+ foreach x $low {
+ set score [$r zscore zset $x]
+ if {$score > $min} {
+ append err "Error, score for $x is $score > $min\n"
+ }
+ }
+ foreach x $lowx {
+ set score [$r zscore zset $x]
+ if {$score >= $min} {
+ append err "Error, score for $x is $score >= $min\n"
+ }
+ }
+ foreach x $ok {
+ set score [$r zscore zset $x]
+ if {$score < $min || $score > $max} {
+ append err "Error, score for $x is $score outside $min-$max range\n"
+ }
+ }
+ foreach x $okx {
+ set score [$r zscore zset $x]
+ if {$score <= $min || $score >= $max} {
+ append err "Error, score for $x is $score outside $min-$max open range\n"
+ }
+ }
+ foreach x $high {
+ set score [$r zscore zset $x]
+ if {$score < $max} {
+ append err "Error, score for $x is $score < $max\n"
+ }
+ }
+ foreach x $highx {
+ set score [$r zscore zset $x]
+ if {$score <= $max} {
+ append err "Error, score for $x is $score <= $max\n"
+ }
+ }
+ }
+ set _ $err
+ } {}
+
+ test {ZRANGEBYSCORE with LIMIT} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 2 b
+ $r zadd zset 3 c
+ $r zadd zset 4 d
+ $r zadd zset 5 e
+ list \
+ [$r zrangebyscore zset 0 10 LIMIT 0 2] \
+ [$r zrangebyscore zset 0 10 LIMIT 2 3] \
+ [$r zrangebyscore zset 0 10 LIMIT 2 10] \
+ [$r zrangebyscore zset 0 10 LIMIT 20 10]
+ } {{a b} {c d e} {c d e} {}}
+
+ test {ZRANGEBYSCORE with LIMIT and withscores} {
+ $r del zset
+ $r zadd zset 10 a
+ $r zadd zset 20 b
+ $r zadd zset 30 c
+ $r zadd zset 40 d
+ $r zadd zset 50 e
+ $r zrangebyscore zset 20 50 LIMIT 2 3 withscores
+ } {d 40 e 50}
+
+ test {ZREMRANGEBYSCORE basics} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 2 b
+ $r zadd zset 3 c
+ $r zadd zset 4 d
+ $r zadd zset 5 e
+ list [$r zremrangebyscore zset 2 4] [$r zrange zset 0 -1]
+ } {3 {a e}}
+
+ test {ZREMRANGEBYSCORE from -inf to +inf} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 2 b
+ $r zadd zset 3 c
+ $r zadd zset 4 d
+ $r zadd zset 5 e
+ list [$r zremrangebyscore zset -inf +inf] [$r zrange zset 0 -1]
+ } {5 {}}
+
+ test {ZREMRANGEBYRANK basics} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 2 b
+ $r zadd zset 3 c
+ $r zadd zset 4 d
+ $r zadd zset 5 e
+ list [$r zremrangebyrank zset 1 3] [$r zrange zset 0 -1]
+ } {3 {a e}}
+
+ test {SORT against sorted sets} {
+ $r del zset
+ $r zadd zset 1 a
+ $r zadd zset 5 b
+ $r zadd zset 2 c
+ $r zadd zset 10 d
+ $r zadd zset 3 e
+ $r sort zset alpha desc
+ } {e d c b a}
+
+ test {Sorted sets +inf and -inf handling} {
+ $r del zset
+ $r zadd zset -100 a
+ $r zadd zset 200 b
+ $r zadd zset -300 c
+ $r zadd zset 1000000 d
+ $r zadd zset +inf max
+ $r zadd zset -inf min
+ $r zrange zset 0 -1
+ } {min c a b d max}
+
+ test {EXPIRE - don't set timeouts multiple times} {
+ $r set x foobar
+ set v1 [$r expire x 5]
+ set v2 [$r ttl x]
+ set v3 [$r expire x 10]
+ set v4 [$r ttl x]
+ list $v1 $v2 $v3 $v4
+ } {1 5 0 5}
+
+ test {EXPIRE - It should be still possible to read 'x'} {
+ $r get x
+ } {foobar}
+
+ test {EXPIRE - After 6 seconds the key should no longer be here} {
+ after 6000
+ list [$r get x] [$r exists x]
+ } {{} 0}
+
+ test {EXPIRE - Delete on write policy} {
+ $r del x
+ $r lpush x foo
+ $r expire x 1000
+ $r lpush x bar
+ $r lrange x 0 -1
+ } {bar}
+
+ test {EXPIREAT - Check for EXPIRE alike behavior} {
+ $r del x
+ $r set x foo
+ $r expireat x [expr [clock seconds]+15]
+ $r ttl x
+ } {1[345]}
+