redis 3.3.5 → 4.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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"