redis 3.3.5 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +32 -50
  3. data/CHANGELOG.md +7 -9
  4. data/Gemfile +0 -1
  5. data/README.md +31 -75
  6. data/benchmarking/logging.rb +1 -1
  7. data/lib/redis.rb +31 -35
  8. data/lib/redis/client.rb +13 -8
  9. data/lib/redis/connection.rb +2 -2
  10. data/lib/redis/connection/command_helper.rb +2 -8
  11. data/lib/redis/connection/hiredis.rb +2 -2
  12. data/lib/redis/connection/ruby.rb +7 -27
  13. data/lib/redis/connection/synchrony.rb +3 -3
  14. data/lib/redis/pipeline.rb +0 -6
  15. data/lib/redis/version.rb +1 -1
  16. data/makefile +42 -0
  17. data/redis.gemspec +4 -8
  18. data/test/bitpos_test.rb +13 -19
  19. data/test/blocking_commands_test.rb +147 -6
  20. data/test/client_test.rb +1 -1
  21. data/test/command_map_test.rb +3 -5
  22. data/test/commands_on_hashes_test.rb +158 -5
  23. data/test/commands_on_hyper_log_log_test.rb +55 -6
  24. data/test/commands_on_lists_test.rb +139 -5
  25. data/test/commands_on_sets_test.rb +136 -5
  26. data/test/commands_on_sorted_sets_test.rb +312 -5
  27. data/test/commands_on_strings_test.rb +243 -6
  28. data/test/commands_on_value_types_test.rb +120 -7
  29. data/test/connection_handling_test.rb +5 -7
  30. data/test/encoding_test.rb +4 -8
  31. data/test/error_replies_test.rb +2 -4
  32. data/test/fork_safety_test.rb +1 -6
  33. data/test/helper.rb +9 -62
  34. data/test/helper_test.rb +1 -3
  35. data/test/internals_test.rb +67 -49
  36. data/test/persistence_control_commands_test.rb +1 -3
  37. data/test/pipelining_commands_test.rb +4 -8
  38. data/test/publish_subscribe_test.rb +1 -3
  39. data/test/remote_server_control_commands_test.rb +61 -4
  40. data/test/scanning_test.rb +1 -7
  41. data/test/scripting_test.rb +1 -3
  42. data/test/sentinel_command_test.rb +1 -3
  43. data/test/sentinel_test.rb +1 -3
  44. data/test/sorting_test.rb +1 -3
  45. data/test/ssl_test.rb +45 -49
  46. data/test/support/connection/hiredis.rb +1 -1
  47. data/test/support/connection/ruby.rb +1 -1
  48. data/test/support/connection/synchrony.rb +1 -1
  49. data/test/synchrony_driver.rb +6 -9
  50. data/test/thread_safety_test.rb +1 -3
  51. data/test/transactions_test.rb +1 -3
  52. data/test/unknown_commands_test.rb +1 -3
  53. data/test/url_param_test.rb +44 -46
  54. metadata +31 -77
  55. data/Rakefile +0 -87
  56. data/examples/dist_redis.rb +0 -43
  57. data/lib/redis/distributed.rb +0 -873
  58. data/lib/redis/hash_ring.rb +0 -132
  59. data/test/connection_test.rb +0 -57
  60. data/test/distributed_blocking_commands_test.rb +0 -46
  61. data/test/distributed_commands_on_hashes_test.rb +0 -10
  62. data/test/distributed_commands_on_hyper_log_log_test.rb +0 -33
  63. data/test/distributed_commands_on_lists_test.rb +0 -22
  64. data/test/distributed_commands_on_sets_test.rb +0 -83
  65. data/test/distributed_commands_on_sorted_sets_test.rb +0 -18
  66. data/test/distributed_commands_on_strings_test.rb +0 -59
  67. data/test/distributed_commands_on_value_types_test.rb +0 -95
  68. data/test/distributed_commands_requiring_clustering_test.rb +0 -164
  69. data/test/distributed_connection_handling_test.rb +0 -23
  70. data/test/distributed_internals_test.rb +0 -79
  71. data/test/distributed_key_tags_test.rb +0 -52
  72. data/test/distributed_persistence_control_commands_test.rb +0 -26
  73. data/test/distributed_publish_subscribe_test.rb +0 -92
  74. data/test/distributed_remote_server_control_commands_test.rb +0 -66
  75. data/test/distributed_scripting_test.rb +0 -102
  76. data/test/distributed_sorting_test.rb +0 -20
  77. data/test/distributed_test.rb +0 -58
  78. data/test/distributed_transactions_test.rb +0 -32
  79. data/test/lint/blocking_commands.rb +0 -150
  80. data/test/lint/hashes.rb +0 -162
  81. data/test/lint/hyper_log_log.rb +0 -60
  82. data/test/lint/lists.rb +0 -143
  83. data/test/lint/sets.rb +0 -140
  84. data/test/lint/sorted_sets.rb +0 -316
  85. data/test/lint/strings.rb +0 -260
  86. data/test/lint/value_types.rb +0 -122
data/test/client_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path("helper", File.dirname(__FILE__))
1
+ require_relative "helper"
2
2
 
3
3
  class TestClient < Test::Unit::TestCase
4
4
 
@@ -1,6 +1,4 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
1
+ require_relative "helper"
4
2
 
5
3
  class TestCommandMap < Test::Unit::TestCase
6
4
 
@@ -11,7 +9,7 @@ class TestCommandMap < Test::Unit::TestCase
11
9
 
12
10
  assert_equal 2, r.incr("counter")
13
11
 
14
- r.client.command_map[:incr] = :decr
12
+ r._client.command_map[:incr] = :decr
15
13
 
16
14
  assert_equal 1, r.incr("counter")
17
15
  end
@@ -23,7 +21,7 @@ class TestCommandMap < Test::Unit::TestCase
23
21
  r.idontexist("key")
24
22
  end
25
23
 
26
- r.client.command_map[:idontexist] = :get
24
+ r._client.command_map[:idontexist] = :get
27
25
 
28
26
  assert_equal "value", r.idontexist("key")
29
27
  end
@@ -1,12 +1,165 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/hashes"
1
+ require_relative "helper"
5
2
 
6
3
  class TestCommandsOnHashes < Test::Unit::TestCase
7
4
 
8
5
  include Helper::Client
9
- include Lint::Hashes
6
+
7
+ def test_hset_and_hget
8
+ r.hset("foo", "f1", "s1")
9
+
10
+ assert_equal "s1", r.hget("foo", "f1")
11
+ end
12
+
13
+ def test_hsetnx
14
+ r.hset("foo", "f1", "s1")
15
+ r.hsetnx("foo", "f1", "s2")
16
+
17
+ assert_equal "s1", r.hget("foo", "f1")
18
+
19
+ r.del("foo")
20
+ r.hsetnx("foo", "f1", "s2")
21
+
22
+ assert_equal "s2", r.hget("foo", "f1")
23
+ end
24
+
25
+ def test_hdel
26
+ r.hset("foo", "f1", "s1")
27
+
28
+ assert_equal "s1", r.hget("foo", "f1")
29
+
30
+ assert_equal 1, r.hdel("foo", "f1")
31
+
32
+ assert_equal nil, r.hget("foo", "f1")
33
+ end
34
+
35
+ def test_variadic_hdel
36
+ target_version "2.3.9" do
37
+ r.hset("foo", "f1", "s1")
38
+ r.hset("foo", "f2", "s2")
39
+
40
+ assert_equal "s1", r.hget("foo", "f1")
41
+ assert_equal "s2", r.hget("foo", "f2")
42
+
43
+ assert_equal 2, r.hdel("foo", ["f1", "f2"])
44
+
45
+ assert_equal nil, r.hget("foo", "f1")
46
+ assert_equal nil, r.hget("foo", "f2")
47
+ end
48
+ end
49
+
50
+ def test_hexists
51
+ assert_equal false, r.hexists("foo", "f1")
52
+
53
+ r.hset("foo", "f1", "s1")
54
+
55
+ assert r.hexists("foo", "f1")
56
+ end
57
+
58
+ def test_hlen
59
+ assert_equal 0, r.hlen("foo")
60
+
61
+ r.hset("foo", "f1", "s1")
62
+
63
+ assert_equal 1, r.hlen("foo")
64
+
65
+ r.hset("foo", "f2", "s2")
66
+
67
+ assert_equal 2, r.hlen("foo")
68
+ end
69
+
70
+ def test_hkeys
71
+ assert_equal [], r.hkeys("foo")
72
+
73
+ r.hset("foo", "f1", "s1")
74
+ r.hset("foo", "f2", "s2")
75
+
76
+ assert_equal ["f1", "f2"], r.hkeys("foo")
77
+ end
78
+
79
+ def test_hvals
80
+ assert_equal [], r.hvals("foo")
81
+
82
+ r.hset("foo", "f1", "s1")
83
+ r.hset("foo", "f2", "s2")
84
+
85
+ assert_equal ["s1", "s2"], r.hvals("foo")
86
+ end
87
+
88
+ def test_hgetall
89
+ assert({} == r.hgetall("foo"))
90
+
91
+ r.hset("foo", "f1", "s1")
92
+ r.hset("foo", "f2", "s2")
93
+
94
+ assert({"f1" => "s1", "f2" => "s2"} == r.hgetall("foo"))
95
+ end
96
+
97
+ def test_hmset
98
+ r.hmset("hash", "foo1", "bar1", "foo2", "bar2")
99
+
100
+ assert_equal "bar1", r.hget("hash", "foo1")
101
+ assert_equal "bar2", r.hget("hash", "foo2")
102
+ end
103
+
104
+ def test_hmset_with_invalid_arguments
105
+ assert_raise(Redis::CommandError) do
106
+ r.hmset("hash", "foo1", "bar1", "foo2", "bar2", "foo3")
107
+ end
108
+ end
109
+
110
+ def test_mapped_hmset
111
+ r.mapped_hmset("foo", :f1 => "s1", :f2 => "s2")
112
+
113
+ assert_equal "s1", r.hget("foo", "f1")
114
+ assert_equal "s2", r.hget("foo", "f2")
115
+ end
116
+
117
+ def test_hmget
118
+ r.hset("foo", "f1", "s1")
119
+ r.hset("foo", "f2", "s2")
120
+ r.hset("foo", "f3", "s3")
121
+
122
+ assert_equal ["s2", "s3"], r.hmget("foo", "f2", "f3")
123
+ end
124
+
125
+ def test_hmget_mapped
126
+ r.hset("foo", "f1", "s1")
127
+ r.hset("foo", "f2", "s2")
128
+ r.hset("foo", "f3", "s3")
129
+
130
+ assert({"f1" => "s1"} == r.mapped_hmget("foo", "f1"))
131
+ assert({"f1" => "s1", "f2" => "s2"} == r.mapped_hmget("foo", "f1", "f2"))
132
+ end
133
+
134
+ def test_hincrby
135
+ r.hincrby("foo", "f1", 1)
136
+
137
+ assert_equal "1", r.hget("foo", "f1")
138
+
139
+ r.hincrby("foo", "f1", 2)
140
+
141
+ assert_equal "3", r.hget("foo", "f1")
142
+
143
+ r.hincrby("foo", "f1", -1)
144
+
145
+ assert_equal "2", r.hget("foo", "f1")
146
+ end
147
+
148
+ def test_hincrbyfloat
149
+ target_version "2.5.4" do
150
+ r.hincrbyfloat("foo", "f1", 1.23)
151
+
152
+ assert_equal "1.23", r.hget("foo", "f1")
153
+
154
+ r.hincrbyfloat("foo", "f1", 0.77)
155
+
156
+ assert_equal "2", r.hget("foo", "f1")
157
+
158
+ r.hincrbyfloat("foo", "f1", -0.1)
159
+
160
+ assert_equal "1.9", r.hget("foo", "f1")
161
+ end
162
+ end
10
163
 
11
164
  def test_mapped_hmget_in_a_pipeline_returns_hash
12
165
  r.hset("foo", "f1", "s1")
@@ -1,12 +1,61 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/hyper_log_log"
1
+ require_relative "helper"
5
2
 
6
3
  class TestCommandsOnHyperLogLog < Test::Unit::TestCase
7
4
 
8
5
  include Helper::Client
9
- include Lint::HyperLogLog
6
+
7
+ def test_pfadd
8
+ target_version "2.8.9" do
9
+ assert_equal true, r.pfadd("foo", "s1")
10
+ assert_equal true, r.pfadd("foo", "s2")
11
+ assert_equal false, r.pfadd("foo", "s1")
12
+
13
+ assert_equal 2, r.pfcount("foo")
14
+ end
15
+ end
16
+
17
+ def test_variadic_pfadd
18
+ target_version "2.8.9" do
19
+ assert_equal true, r.pfadd("foo", ["s1", "s2"])
20
+ assert_equal true, r.pfadd("foo", ["s1", "s2", "s3"])
21
+
22
+ assert_equal 3, r.pfcount("foo")
23
+ end
24
+ end
25
+
26
+ def test_pfcount
27
+ target_version "2.8.9" do
28
+ assert_equal 0, r.pfcount("foo")
29
+
30
+ assert_equal true, r.pfadd("foo", "s1")
31
+
32
+ assert_equal 1, r.pfcount("foo")
33
+ end
34
+ end
35
+
36
+ def test_variadic_pfcount
37
+ target_version "2.8.9" do
38
+ assert_equal 0, r.pfcount(["{1}foo", "{1}bar"])
39
+
40
+ assert_equal true, r.pfadd("{1}foo", "s1")
41
+ assert_equal true, r.pfadd("{1}bar", "s1")
42
+ assert_equal true, r.pfadd("{1}bar", "s2")
43
+
44
+ assert_equal 2, r.pfcount("{1}foo", "{1}bar")
45
+ end
46
+ end
47
+
48
+ def test_variadic_pfcount_expanded
49
+ target_version "2.8.9" do
50
+ assert_equal 0, r.pfcount("{1}foo", "{1}bar")
51
+
52
+ assert_equal true, r.pfadd("{1}foo", "s1")
53
+ assert_equal true, r.pfadd("{1}bar", "s1")
54
+ assert_equal true, r.pfadd("{1}bar", "s2")
55
+
56
+ assert_equal 2, r.pfcount("{1}foo", "{1}bar")
57
+ end
58
+ end
10
59
 
11
60
  def test_pfmerge
12
61
  target_version "2.8.9" do
@@ -18,4 +67,4 @@ class TestCommandsOnHyperLogLog < Test::Unit::TestCase
18
67
  end
19
68
  end
20
69
 
21
- end
70
+ end
@@ -1,12 +1,146 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/lists"
1
+ require_relative "helper"
5
2
 
6
3
  class TestCommandsOnLists < Test::Unit::TestCase
7
4
 
8
5
  include Helper::Client
9
- include Lint::Lists
6
+
7
+ def test_lpush
8
+ r.lpush "foo", "s1"
9
+ r.lpush "foo", "s2"
10
+
11
+ assert_equal 2, r.llen("foo")
12
+ assert_equal "s2", r.lpop("foo")
13
+ end
14
+
15
+ def test_variadic_lpush
16
+ target_version "2.3.9" do # 2.4-rc6
17
+ assert_equal 3, r.lpush("foo", ["s1", "s2", "s3"])
18
+ assert_equal 3, r.llen("foo")
19
+ assert_equal "s3", r.lpop("foo")
20
+ end
21
+ end
22
+
23
+ def test_lpushx
24
+ r.lpushx "foo", "s1"
25
+ r.lpush "foo", "s2"
26
+ r.lpushx "foo", "s3"
27
+
28
+ assert_equal 2, r.llen("foo")
29
+ assert_equal ["s3", "s2"], r.lrange("foo", 0, -1)
30
+ end
31
+
32
+ def test_rpush
33
+ r.rpush "foo", "s1"
34
+ r.rpush "foo", "s2"
35
+
36
+ assert_equal 2, r.llen("foo")
37
+ assert_equal "s2", r.rpop("foo")
38
+ end
39
+
40
+ def test_variadic_rpush
41
+ target_version "2.3.9" do # 2.4-rc6
42
+ assert_equal 3, r.rpush("foo", ["s1", "s2", "s3"])
43
+ assert_equal 3, r.llen("foo")
44
+ assert_equal "s3", r.rpop("foo")
45
+ end
46
+ end
47
+
48
+ def test_rpushx
49
+ r.rpushx "foo", "s1"
50
+ r.rpush "foo", "s2"
51
+ r.rpushx "foo", "s3"
52
+
53
+ assert_equal 2, r.llen("foo")
54
+ assert_equal ["s2", "s3"], r.lrange("foo", 0, -1)
55
+ end
56
+
57
+ def test_llen
58
+ r.rpush "foo", "s1"
59
+ r.rpush "foo", "s2"
60
+
61
+ assert_equal 2, r.llen("foo")
62
+ end
63
+
64
+ def test_lrange
65
+ r.rpush "foo", "s1"
66
+ r.rpush "foo", "s2"
67
+ r.rpush "foo", "s3"
68
+
69
+ assert_equal ["s2", "s3"], r.lrange("foo", 1, -1)
70
+ assert_equal ["s1", "s2"], r.lrange("foo", 0, 1)
71
+
72
+ assert_equal [], r.lrange("bar", 0, -1)
73
+ end
74
+
75
+ def test_ltrim
76
+ r.rpush "foo", "s1"
77
+ r.rpush "foo", "s2"
78
+ r.rpush "foo", "s3"
79
+
80
+ r.ltrim "foo", 0, 1
81
+
82
+ assert_equal 2, r.llen("foo")
83
+ assert_equal ["s1", "s2"], r.lrange("foo", 0, -1)
84
+ end
85
+
86
+ def test_lindex
87
+ r.rpush "foo", "s1"
88
+ r.rpush "foo", "s2"
89
+
90
+ assert_equal "s1", r.lindex("foo", 0)
91
+ assert_equal "s2", r.lindex("foo", 1)
92
+ end
93
+
94
+ def test_lset
95
+ r.rpush "foo", "s1"
96
+ r.rpush "foo", "s2"
97
+
98
+ assert_equal "s2", r.lindex("foo", 1)
99
+ assert r.lset("foo", 1, "s3")
100
+ assert_equal "s3", r.lindex("foo", 1)
101
+
102
+ assert_raise Redis::CommandError do
103
+ r.lset("foo", 4, "s3")
104
+ end
105
+ end
106
+
107
+ def test_lrem
108
+ r.rpush "foo", "s1"
109
+ r.rpush "foo", "s2"
110
+
111
+ assert_equal 1, r.lrem("foo", 1, "s1")
112
+ assert_equal ["s2"], r.lrange("foo", 0, -1)
113
+ end
114
+
115
+ def test_lpop
116
+ r.rpush "foo", "s1"
117
+ r.rpush "foo", "s2"
118
+
119
+ assert_equal 2, r.llen("foo")
120
+ assert_equal "s1", r.lpop("foo")
121
+ assert_equal 1, r.llen("foo")
122
+ end
123
+
124
+ def test_rpop
125
+ r.rpush "foo", "s1"
126
+ r.rpush "foo", "s2"
127
+
128
+ assert_equal 2, r.llen("foo")
129
+ assert_equal "s2", r.rpop("foo")
130
+ assert_equal 1, r.llen("foo")
131
+ end
132
+
133
+ def test_linsert
134
+ r.rpush "foo", "s1"
135
+ r.rpush "foo", "s3"
136
+ r.linsert "foo", :before, "s3", "s2"
137
+
138
+ assert_equal ["s1", "s2", "s3"], r.lrange("foo", 0, -1)
139
+
140
+ assert_raise(Redis::CommandError) do
141
+ r.linsert "foo", :anywhere, "s3", "s2"
142
+ end
143
+ end
10
144
 
11
145
  def test_rpoplpush
12
146
  r.rpush "foo", "s1"
@@ -1,12 +1,143 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("helper", File.dirname(__FILE__))
4
- require "lint/sets"
1
+ require_relative "helper"
5
2
 
6
3
  class TestCommandsOnSets < Test::Unit::TestCase
7
4
 
8
5
  include Helper::Client
9
- include Lint::Sets
6
+
7
+ def test_sadd
8
+ assert_equal true, r.sadd("foo", "s1")
9
+ assert_equal true, r.sadd("foo", "s2")
10
+ assert_equal false, r.sadd("foo", "s1")
11
+
12
+ assert_equal ["s1", "s2"], r.smembers("foo").sort
13
+ end
14
+
15
+ def test_variadic_sadd
16
+ target_version "2.3.9" do # 2.4-rc6
17
+ assert_equal 2, r.sadd("foo", ["s1", "s2"])
18
+ assert_equal 1, r.sadd("foo", ["s1", "s2", "s3"])
19
+
20
+ assert_equal ["s1", "s2", "s3"], r.smembers("foo").sort
21
+ end
22
+ end
23
+
24
+ def test_srem
25
+ r.sadd("foo", "s1")
26
+ r.sadd("foo", "s2")
27
+
28
+ assert_equal true, r.srem("foo", "s1")
29
+ assert_equal false, r.srem("foo", "s3")
30
+
31
+ assert_equal ["s2"], r.smembers("foo")
32
+ end
33
+
34
+ def test_variadic_srem
35
+ target_version "2.3.9" do # 2.4-rc6
36
+ r.sadd("foo", "s1")
37
+ r.sadd("foo", "s2")
38
+ r.sadd("foo", "s3")
39
+
40
+ assert_equal 1, r.srem("foo", ["s1", "aaa"])
41
+ assert_equal 0, r.srem("foo", ["bbb", "ccc" "ddd"])
42
+ assert_equal 1, r.srem("foo", ["eee", "s3"])
43
+
44
+ assert_equal ["s2"], r.smembers("foo")
45
+ end
46
+ end
47
+
48
+ def test_spop
49
+ r.sadd "foo", "s1"
50
+ r.sadd "foo", "s2"
51
+
52
+ assert ["s1", "s2"].include?(r.spop("foo"))
53
+ assert ["s1", "s2"].include?(r.spop("foo"))
54
+ assert_equal nil, r.spop("foo")
55
+ end
56
+
57
+ def test_spop_with_positive_count
58
+ target_version "3.2.0" do
59
+ r.sadd "foo", "s1"
60
+ r.sadd "foo", "s2"
61
+ r.sadd "foo", "s3"
62
+ r.sadd "foo", "s4"
63
+
64
+ pops = r.spop("foo", 3)
65
+
66
+ assert !(["s1", "s2", "s3", "s4"] & pops).empty?
67
+ assert_equal 3, pops.size
68
+ assert_equal 1, r.scard("foo")
69
+ end
70
+ end
71
+
72
+ def test_scard
73
+ assert_equal 0, r.scard("foo")
74
+
75
+ r.sadd "foo", "s1"
76
+
77
+ assert_equal 1, r.scard("foo")
78
+
79
+ r.sadd "foo", "s2"
80
+
81
+ assert_equal 2, r.scard("foo")
82
+ end
83
+
84
+ def test_sismember
85
+ assert_equal false, r.sismember("foo", "s1")
86
+
87
+ r.sadd "foo", "s1"
88
+
89
+ assert_equal true, r.sismember("foo", "s1")
90
+ assert_equal false, r.sismember("foo", "s2")
91
+ end
92
+
93
+ def test_smembers
94
+ assert_equal [], r.smembers("foo")
95
+
96
+ r.sadd "foo", "s1"
97
+ r.sadd "foo", "s2"
98
+
99
+ assert_equal ["s1", "s2"], r.smembers("foo").sort
100
+ end
101
+
102
+ def test_srandmember
103
+ r.sadd "foo", "s1"
104
+ r.sadd "foo", "s2"
105
+
106
+ 4.times do
107
+ assert ["s1", "s2"].include?(r.srandmember("foo"))
108
+ end
109
+
110
+ assert_equal 2, r.scard("foo")
111
+ end
112
+
113
+ def test_srandmember_with_positive_count
114
+ r.sadd "foo", "s1"
115
+ r.sadd "foo", "s2"
116
+ r.sadd "foo", "s3"
117
+ r.sadd "foo", "s4"
118
+
119
+ 4.times do
120
+ assert !(["s1", "s2", "s3", "s4"] & r.srandmember("foo", 3)).empty?
121
+
122
+ assert_equal 3, r.srandmember("foo", 3).size
123
+ end
124
+
125
+ assert_equal 4, r.scard("foo")
126
+ end
127
+
128
+ def test_srandmember_with_negative_count
129
+ r.sadd "foo", "s1"
130
+ r.sadd "foo", "s2"
131
+ r.sadd "foo", "s3"
132
+ r.sadd "foo", "s4"
133
+
134
+ 4.times do
135
+ assert !(["s1", "s2", "s3", "s4"] & r.srandmember("foo", -6)).empty?
136
+ assert_equal 6, r.srandmember("foo", -6).size
137
+ end
138
+
139
+ assert_equal 4, r.scard("foo")
140
+ end
10
141
 
11
142
  def test_smove
12
143
  r.sadd "foo", "s1"