kuende-fakeredis 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +19 -0
  4. data/Gemfile +13 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE +21 -0
  7. data/README.md +102 -0
  8. data/Rakefile +27 -0
  9. data/fakeredis.gemspec +24 -0
  10. data/gemfiles/redisrb-master.gemfile +14 -0
  11. data/lib/fake_redis.rb +1 -0
  12. data/lib/fakeredis.rb +6 -0
  13. data/lib/fakeredis/bitop_command.rb +56 -0
  14. data/lib/fakeredis/command_executor.rb +25 -0
  15. data/lib/fakeredis/expiring_hash.rb +70 -0
  16. data/lib/fakeredis/minitest.rb +24 -0
  17. data/lib/fakeredis/rspec.rb +24 -0
  18. data/lib/fakeredis/sort_method.rb +117 -0
  19. data/lib/fakeredis/sorted_set_argument_handler.rb +74 -0
  20. data/lib/fakeredis/sorted_set_store.rb +80 -0
  21. data/lib/fakeredis/transaction_commands.rb +83 -0
  22. data/lib/fakeredis/version.rb +3 -0
  23. data/lib/fakeredis/zset.rb +39 -0
  24. data/lib/redis/connection/memory.rb +1375 -0
  25. data/spec/bitop_command_spec.rb +209 -0
  26. data/spec/compatibility_spec.rb +9 -0
  27. data/spec/connection_spec.rb +85 -0
  28. data/spec/hashes_spec.rb +261 -0
  29. data/spec/keys_spec.rb +488 -0
  30. data/spec/lists_spec.rb +229 -0
  31. data/spec/memory_spec.rb +28 -0
  32. data/spec/server_spec.rb +100 -0
  33. data/spec/sets_spec.rb +280 -0
  34. data/spec/sort_method_spec.rb +74 -0
  35. data/spec/sorted_sets_spec.rb +578 -0
  36. data/spec/spec_helper.rb +29 -0
  37. data/spec/spec_helper_live_redis.rb +14 -0
  38. data/spec/strings_spec.rb +289 -0
  39. data/spec/subscription_spec.rb +107 -0
  40. data/spec/support/shared_examples/bitwise_operation.rb +59 -0
  41. data/spec/support/shared_examples/sortable.rb +69 -0
  42. data/spec/transactions_spec.rb +92 -0
  43. data/spec/upcase_method_name_spec.rb +18 -0
  44. metadata +148 -0
@@ -0,0 +1,229 @@
1
+ require 'spec_helper'
2
+
3
+ module FakeRedis
4
+ describe "ListsMethods" do
5
+ before(:each) do
6
+ @client = Redis.new
7
+ end
8
+
9
+ it "should get an element from a list by its index" do
10
+ @client.lpush("key1", "val1")
11
+ @client.lpush("key1", "val2")
12
+
13
+ expect(@client.lindex("key1", 0)).to eq("val2")
14
+ expect(@client.lindex("key1", -1)).to eq("val1")
15
+ expect(@client.lindex("key1", 3)).to eq(nil)
16
+ end
17
+
18
+ it "should insert an element before or after another element in a list" do
19
+ @client.rpush("key1", "v1")
20
+ @client.rpush("key1", "v3")
21
+ @client.linsert("key1", :before, "v3", "v2")
22
+ @client.linsert("key1", :after, "v3", 100)
23
+ @client.linsert("key1", :before, 100, 99)
24
+
25
+ expect(@client.lrange("key1", 0, -1)).to eq(["v1", "v2", "v3", "99", "100"])
26
+ end
27
+
28
+ it "should not insert if after/before index not found" do
29
+ @client.rpush("key", "v1")
30
+ expect(@client.linsert("key", :before, "unknown", "v2")).to eq(-1)
31
+ expect(@client.linsert("key", :after, "unknown", "v3")).to eq(-1)
32
+
33
+ expect(@client.lrange("key", 0, -1)).to eq(["v1"])
34
+ end
35
+
36
+ it 'should allow multiple values to be added to a list in a single rpush' do
37
+ @client.rpush('key1', [1, 2, 3])
38
+ expect(@client.lrange('key1', 0, -1)).to eq(['1', '2', '3'])
39
+ end
40
+
41
+ it 'should allow multiple values to be added to a list in a single lpush' do
42
+ @client.lpush('key1', [1, 2, 3])
43
+ expect(@client.lrange('key1', 0, -1)).to eq(['3', '2', '1'])
44
+ end
45
+
46
+ it "should error if an invalid where argument is given" do
47
+ @client.rpush("key1", "v1")
48
+ @client.rpush("key1", "v3")
49
+ expect { @client.linsert("key1", :invalid, "v3", "v2") }.to raise_error(Redis::CommandError, "ERR syntax error")
50
+ end
51
+
52
+ it "should get the length of a list" do
53
+ @client.rpush("key1", "v1")
54
+ @client.rpush("key1", "v2")
55
+
56
+ expect(@client.llen("key1")).to eq(2)
57
+ expect(@client.llen("key2")).to eq(0)
58
+ end
59
+
60
+ it "should remove and get the first element in a list" do
61
+ @client.rpush("key1", "v1")
62
+ @client.rpush("key1", "v2")
63
+ @client.rpush("key1", "v3")
64
+
65
+ expect(@client.lpop("key1")).to eq("v1")
66
+ expect(@client.lrange("key1", 0, -1)).to eq(["v2", "v3"])
67
+ end
68
+
69
+ it "should prepend a value to a list" do
70
+ @client.rpush("key1", "v1")
71
+ @client.rpush("key1", "v2")
72
+
73
+ expect(@client.lrange("key1", 0, -1)).to eq(["v1", "v2"])
74
+ end
75
+
76
+ it "should prepend a value to a list, only if the list exists" do
77
+ @client.lpush("key1", "v1")
78
+
79
+ @client.lpushx("key1", "v2")
80
+ @client.lpushx("key2", "v3")
81
+
82
+ expect(@client.lrange("key1", 0, -1)).to eq(["v2", "v1"])
83
+ expect(@client.llen("key2")).to eq(0)
84
+ end
85
+
86
+ it "should get a range of elements from a list" do
87
+ @client.rpush("key1", "v1")
88
+ @client.rpush("key1", "v2")
89
+ @client.rpush("key1", "v3")
90
+
91
+ expect(@client.lrange("key1", 1, -1)).to eq(["v2", "v3"])
92
+ end
93
+
94
+ it "should remove elements from a list" do
95
+ @client.rpush("key1", "v1")
96
+ @client.rpush("key1", "v2")
97
+ @client.rpush("key1", "v2")
98
+ @client.rpush("key1", "v2")
99
+ @client.rpush("key1", "v1")
100
+ @client.rpush("key1", 42)
101
+
102
+ expect(@client.lrem("key1", 1, "v1")).to eq(1)
103
+ expect(@client.lrem("key1", -2, "v2")).to eq(2)
104
+ expect(@client.lrem("key1", 0, 42)).to eq(1)
105
+ expect(@client.llen("key1")).to eq(2)
106
+ end
107
+
108
+ it "should return 0 if key does not map to a list" do
109
+ expect(@client.exists("nonexistant")).to eq(false)
110
+ expect(@client.lrem("nonexistant", 0, "value")).to eq(0)
111
+ end
112
+
113
+ it "should remove list's key when list is empty" do
114
+ @client.rpush("key1", "v1")
115
+ @client.rpush("key1", "v2")
116
+ @client.lrem("key1", 1, "v1")
117
+ @client.lrem("key1", 1, "v2")
118
+
119
+ expect(@client.exists("key1")).to eq(false)
120
+ end
121
+
122
+ it "should set the value of an element in a list by its index" do
123
+ @client.rpush("key1", "one")
124
+ @client.rpush("key1", "two")
125
+ @client.rpush("key1", "three")
126
+
127
+ @client.lset("key1", 0, "four")
128
+ @client.lset("key1", -2, "five")
129
+ @client.lset("key1", 2, 6)
130
+
131
+ expect(@client.lrange("key1", 0, -1)).to eq(["four", "five", "6"])
132
+ expect { @client.lset("key1", 4, "seven") }.to raise_error(Redis::CommandError, "ERR index out of range")
133
+ end
134
+
135
+ it "should trim a list to the specified range" do
136
+ @client.rpush("key1", "one")
137
+ @client.rpush("key1", "two")
138
+ @client.rpush("key1", "three")
139
+
140
+ expect(@client.ltrim("key1", 1, -1)).to eq("OK")
141
+ expect(@client.lrange("key1", 0, -1)).to eq(["two", "three"])
142
+ end
143
+
144
+
145
+ context "when the list is smaller than the requested trim" do
146
+ before { @client.rpush("listOfOne", "one") }
147
+
148
+ context "trimming with a negative start (specifying a max)" do
149
+ before { @client.ltrim("listOfOne", -5, -1) }
150
+
151
+ it "returns the unmodified list" do
152
+ expect(@client.lrange("listOfOne", 0, -1)).to eq(["one"])
153
+ end
154
+ end
155
+ end
156
+
157
+ context "when the list is larger than the requested trim" do
158
+ before do
159
+ @client.rpush("maxTest", "one")
160
+ @client.rpush("maxTest", "two")
161
+ @client.rpush("maxTest", "three")
162
+ @client.rpush("maxTest", "four")
163
+ @client.rpush("maxTest", "five")
164
+ @client.rpush("maxTest", "six")
165
+ end
166
+
167
+ context "trimming with a negative start (specifying a max)" do
168
+ before { @client.ltrim("maxTest", -5, -1) }
169
+
170
+ it "should trim a list to the specified maximum size" do
171
+ expect(@client.lrange("maxTest", 0, -1)).to eq(["two","three", "four", "five", "six"])
172
+ end
173
+ end
174
+ end
175
+
176
+
177
+ it "should remove and return the last element in a list" do
178
+ @client.rpush("key1", "one")
179
+ @client.rpush("key1", "two")
180
+ @client.rpush("key1", "three")
181
+
182
+ expect(@client.rpop("key1")).to eq("three")
183
+ expect(@client.lrange("key1", 0, -1)).to eq(["one", "two"])
184
+ end
185
+
186
+ it "should remove the last element in a list, append it to another list and return it" do
187
+ @client.rpush("key1", "one")
188
+ @client.rpush("key1", "two")
189
+ @client.rpush("key1", "three")
190
+
191
+ expect(@client.rpoplpush("key1", "key2")).to eq("three")
192
+
193
+ expect(@client.lrange("key1", 0, -1)).to eq(["one", "two"])
194
+ expect(@client.lrange("key2", 0, -1)).to eq(["three"])
195
+ end
196
+
197
+ context 'when the source list is empty' do
198
+ it 'rpoplpush does not add anything to the destination list' do
199
+ @client.rpoplpush("source", "destination")
200
+
201
+ expect(@client.lrange("destination", 0, -1)).to eq([])
202
+ end
203
+ end
204
+
205
+ it "should append a value to a list" do
206
+ @client.rpush("key1", "one")
207
+ @client.rpush("key1", "two")
208
+
209
+ expect(@client.lrange("key1", 0, -1)).to eq(["one", "two"])
210
+ end
211
+
212
+ it "should append a value to a list, only if the list exists" do
213
+ @client.rpush("key1", "one")
214
+ @client.rpushx("key1", "two")
215
+ @client.rpushx("key2", "two")
216
+
217
+ expect(@client.lrange("key1", 0, -1)).to eq(["one", "two"])
218
+ expect(@client.lrange("key2", 0, -1)).to eq([])
219
+ end
220
+
221
+ it 'should not allow pushing empty list of objects' do
222
+ expect { @client.lpush("key1", []) }.to raise_error(Redis::CommandError, /lpush[^x]/)
223
+ expect { @client.lpush("key1", 1); @client.lpushx("key1", []) }.to raise_error(Redis::CommandError, /lpushx/)
224
+
225
+ expect { @client.rpush("key1", []) }.to raise_error(Redis::CommandError, /rpush[^x]/)
226
+ expect { @client.rpush("key1", 1); @client.rpushx("key1", []) }.to raise_error(Redis::CommandError, /rpushx/)
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module FakeRedis
4
+ describe 'time' do
5
+ before(:each) do
6
+ @client = Redis.new
7
+ allow(Time).to receive_message_chain(:now, :to_f).and_return(1397845595.5139461)
8
+ end
9
+
10
+ it 'is an array' do
11
+ expect(@client.time).to be_an_instance_of(Array)
12
+ end
13
+
14
+ it 'has two elements' do
15
+ expect(@client.time.count).to eql 2
16
+ end
17
+
18
+ if fakeredis?
19
+ it 'has the current time in seconds' do
20
+ expect(@client.time.first).to eql 1397845595
21
+ end
22
+
23
+ it 'has the current leftover microseconds' do
24
+ expect(@client.time.last).to eql 513946
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module FakeRedis
4
+ describe "ServerMethods" do
5
+
6
+ before(:each) do
7
+ @client = Redis.new
8
+ end
9
+
10
+ it "should return the number of keys in the selected database" do
11
+ @client.set("key1", "1")
12
+ @client.set("key2", "2")
13
+ @client.set("key2", "two")
14
+
15
+ expect(@client.dbsize).to eq(2)
16
+ end
17
+
18
+ it "should get information and statistics about the server" do
19
+ expect(@client.info.key?("redis_version")).to eq(true)
20
+ end
21
+
22
+ it "should handle non-existent methods" do
23
+ expect { @client.idontexist }.to raise_error(Redis::CommandError, "ERR unknown command 'idontexist'")
24
+ end
25
+
26
+ describe "multiple databases" do
27
+ it "should default to database 0" do
28
+ expect(@client.inspect).to match(%r#/0>$#)
29
+ end
30
+
31
+ it "should select another database" do
32
+ @client.select(1)
33
+ expect(@client.inspect).to match(%r#/1>$#)
34
+ end
35
+
36
+ it "should store keys separately in each database" do
37
+ expect(@client.select(0)).to eq("OK")
38
+ @client.set("key1", "1")
39
+ @client.set("key2", "2")
40
+
41
+ @client.select(1)
42
+ @client.set("key3", "3")
43
+ @client.set("key4", "4")
44
+ @client.set("key5", "5")
45
+
46
+ @client.select(0)
47
+ expect(@client.dbsize).to eq(2)
48
+ expect(@client.exists("key1")).to be true
49
+ expect(@client.exists("key3")).to be false
50
+
51
+ @client.select(1)
52
+ expect(@client.dbsize).to eq(3)
53
+ expect(@client.exists("key4")).to be true
54
+ expect(@client.exists("key2")).to be false
55
+
56
+ @client.flushall
57
+ expect(@client.dbsize).to eq(0)
58
+
59
+ @client.select(0)
60
+ expect(@client.dbsize).to eq(0)
61
+ end
62
+
63
+ it "should flush a database" do
64
+ @client.select(0)
65
+ @client.set("key1", "1")
66
+ @client.set("key2", "2")
67
+ expect(@client.dbsize).to eq(2)
68
+
69
+ @client.select(1)
70
+ @client.set("key3", "3")
71
+ @client.set("key4", "4")
72
+ expect(@client.dbsize).to eq(2)
73
+
74
+ expect(@client.flushdb).to eq("OK")
75
+
76
+ expect(@client.dbsize).to eq(0)
77
+ @client.select(0)
78
+ expect(@client.dbsize).to eq(2)
79
+ end
80
+
81
+ it "should flush all databases" do
82
+ @client.select(0)
83
+ @client.set("key3", "3")
84
+ @client.set("key4", "4")
85
+ expect(@client.dbsize).to eq(2)
86
+
87
+ @client.select(1)
88
+ @client.set("key3", "3")
89
+ @client.set("key4", "4")
90
+ expect(@client.dbsize).to eq(2)
91
+
92
+ expect(@client.flushall).to eq("OK")
93
+
94
+ expect(@client.dbsize).to eq(0)
95
+ @client.select(0)
96
+ expect(@client.dbsize).to eq(0)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,280 @@
1
+ require 'spec_helper'
2
+
3
+ module FakeRedis
4
+ describe "SetsMethods" do
5
+ before(:each) do
6
+ @client = Redis.new
7
+ end
8
+
9
+ it "should add a member to a set" do
10
+ expect(@client.sadd("key", "value")).to eq(true)
11
+ expect(@client.sadd("key", "value")).to eq(false)
12
+
13
+ expect(@client.smembers("key")).to eq(["value"])
14
+ end
15
+
16
+ it "should raise error if command arguments count is not enough" do
17
+ expect { @client.sadd("key", []) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'sadd' command")
18
+ expect { @client.sinter(*[]) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'sinter' command")
19
+ expect { @client.sinter([]) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'sinter' command")
20
+ expect { @client.sunion(*[]) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'sunion' command")
21
+ expect { @client.sunion([]) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'sunion' command")
22
+
23
+ expect(@client.smembers("key")).to be_empty
24
+ end
25
+
26
+ it "should add multiple members to a set" do
27
+ expect(@client.sadd("key", %w(value other something more))).to eq(4)
28
+ expect(@client.sadd("key", %w(and additional values))).to eq(3)
29
+ expect(@client.smembers("key")).to match_array(["value", "other", "something", "more", "and", "additional", "values"])
30
+ end
31
+
32
+ it "should get the number of members in a set" do
33
+ @client.sadd("key", "val1")
34
+ @client.sadd("key", "val2")
35
+
36
+ expect(@client.scard("key")).to eq(2)
37
+ end
38
+
39
+ it "should subtract multiple sets" do
40
+ @client.sadd("key1", "a")
41
+ @client.sadd("key1", "b")
42
+ @client.sadd("key1", "c")
43
+ @client.sadd("key1", "d")
44
+ @client.sadd("key2", "c")
45
+ @client.sadd("key3", "a")
46
+ @client.sadd("key3", "c")
47
+ @client.sadd("key3", "e")
48
+
49
+ expect(@client.sdiff("key1", "key2", "key3")).to match_array(["b", "d"])
50
+ expect(@client.sdiff("key1", ["key2", "key3"])).to match_array(["b", "d"])
51
+ end
52
+
53
+ it "should subtract from a nonexistent set" do
54
+ @client.sadd("key2", "a")
55
+ @client.sadd("key2", "b")
56
+
57
+ expect(@client.sdiff("key1", "key2")).to eq([])
58
+ expect(@client.sdiff(["key1", "key2"])).to eq([])
59
+ end
60
+
61
+ it "should subtract multiple sets and store the resulting set in a key" do
62
+ @client.sadd("key1", "a")
63
+ @client.sadd("key1", "b")
64
+ @client.sadd("key1", "c")
65
+ @client.sadd("key1", "d")
66
+ @client.sadd("key2", "c")
67
+ @client.sadd("key3", "a")
68
+ @client.sadd("key3", "c")
69
+ @client.sadd("key3", "e")
70
+ @client.sdiffstore("key", "key1", "key2", "key3")
71
+ @client.sdiffstore("new_key", "key1", ["key2", "key3"])
72
+
73
+ expect(@client.smembers("key")).to match_array(["b", "d"])
74
+ expect(@client.smembers("new_key")).to match_array(["b", "d"])
75
+ end
76
+
77
+ it "should intersect multiple sets" do
78
+ @client.sadd("key1", "a")
79
+ @client.sadd("key1", "b")
80
+ @client.sadd("key1", "c")
81
+ @client.sadd("key1", "d")
82
+ @client.sadd("key2", "c")
83
+ @client.sadd("key3", "a")
84
+ @client.sadd("key3", "c")
85
+ @client.sadd("key3", "e")
86
+
87
+ expect(@client.sinter("key1", "key2", "key3")).to eq(["c"])
88
+ expect(@client.sinter(["key1", "key2", "key3"])).to eq(["c"])
89
+ end
90
+
91
+ it "should intersect multiple sets and store the resulting set in a key" do
92
+ @client.sadd("key1", "a")
93
+ @client.sadd("key1", "b")
94
+ @client.sadd("key1", "c")
95
+ @client.sadd("key1", "d")
96
+ @client.sadd("key2", "c")
97
+ @client.sadd("key3", "a")
98
+ @client.sadd("key3", "c")
99
+ @client.sadd("key3", "e")
100
+ @client.sinterstore("key", "key1", "key2", "key3")
101
+ @client.sinterstore("new_key", ["key1", "key2", "key3"])
102
+
103
+ expect(@client.smembers("key")).to eq(["c"])
104
+ expect(@client.smembers("new_key")).to eq(["c"])
105
+ end
106
+
107
+ it "should determine if a given value is a member of a set" do
108
+ @client.sadd("key1", "a")
109
+
110
+ expect(@client.sismember("key1", "a")).to eq(true)
111
+ expect(@client.sismember("key1", "b")).to eq(false)
112
+ expect(@client.sismember("key2", "a")).to eq(false)
113
+ end
114
+
115
+ it "should get all the members in a set" do
116
+ @client.sadd("key", "a")
117
+ @client.sadd("key", "b")
118
+ @client.sadd("key", "c")
119
+ @client.sadd("key", "d")
120
+
121
+ expect(@client.smembers("key")).to match_array(["a", "b", "c", "d"])
122
+ end
123
+
124
+ it "should move a member from one set to another" do
125
+ @client.sadd("key1", "a")
126
+ @client.sadd("key1", "b")
127
+ @client.sadd("key2", "c")
128
+ expect(@client.smove("key1", "key2", "a")).to eq(true)
129
+ expect(@client.smove("key1", "key2", "a")).to eq(false)
130
+
131
+ expect(@client.smembers("key1")).to eq(["b"])
132
+ expect(@client.smembers("key2")).to match_array(["c", "a"])
133
+ end
134
+
135
+ it "should remove and return a random member from a set" do
136
+ @client.sadd("key1", "a")
137
+ @client.sadd("key1", "b")
138
+
139
+ expect(["a", "b"].include?(@client.spop("key1"))).to be true
140
+ expect(["a", "b"].include?(@client.spop("key1"))).to be true
141
+ expect(@client.spop("key1")).to be_nil
142
+ end
143
+
144
+ it "should get a random member from a set" do
145
+ @client.sadd("key1", "a")
146
+ @client.sadd("key1", "b")
147
+
148
+ expect(["a", "b"].include?(@client.spop("key1"))).to be true
149
+ end
150
+
151
+ it "should remove a member from a set" do
152
+ @client.sadd("key1", "a")
153
+ @client.sadd("key1", "b")
154
+ expect(@client.srem("key1", "a")).to eq(true)
155
+ expect(@client.srem("key1", "a")).to eq(false)
156
+
157
+ expect(@client.smembers("key1")).to eq(["b"])
158
+ end
159
+
160
+ it "should remove multiple members from a set" do
161
+ @client.sadd("key1", "a")
162
+ @client.sadd("key1", "b")
163
+
164
+ expect(@client.srem("key1", [ "a", "b"])).to eq(2)
165
+ expect(@client.smembers("key1")).to be_empty
166
+ end
167
+
168
+ it "should remove the set's key once it's empty" do
169
+ @client.sadd("key1", "a")
170
+ @client.sadd("key1", "b")
171
+ @client.srem("key1", "b")
172
+ @client.srem("key1", "a")
173
+
174
+ expect(@client.exists("key1")).to eq(false)
175
+ end
176
+
177
+ it "should add multiple sets" do
178
+ @client.sadd("key1", "a")
179
+ @client.sadd("key1", "b")
180
+ @client.sadd("key1", "c")
181
+ @client.sadd("key1", "d")
182
+ @client.sadd("key2", "c")
183
+ @client.sadd("key3", "a")
184
+ @client.sadd("key3", "c")
185
+ @client.sadd("key3", "e")
186
+
187
+ expect(@client.sunion("key1", "key2", "key3")).to match_array(["a", "b", "c", "d", "e"])
188
+ end
189
+
190
+ it "should add multiple sets and store the resulting set in a key" do
191
+ @client.sadd("key1", "a")
192
+ @client.sadd("key1", "b")
193
+ @client.sadd("key1", "c")
194
+ @client.sadd("key1", "d")
195
+ @client.sadd("key2", "c")
196
+ @client.sadd("key3", "a")
197
+ @client.sadd("key3", "c")
198
+ @client.sadd("key3", "e")
199
+ @client.sunionstore("key", "key1", "key2", "key3")
200
+
201
+ expect(@client.smembers("key")).to match_array(["a", "b", "c", "d", "e"])
202
+ end
203
+ end
204
+
205
+ describe 'srandmember' do
206
+ before(:each) do
207
+ @client = Redis.new
208
+ end
209
+
210
+ context 'with a set that has three elements' do
211
+ before do
212
+ @client.sadd("key1", "a")
213
+ @client.sadd("key1", "b")
214
+ @client.sadd("key1", "c")
215
+ end
216
+
217
+ context 'when called without the optional number parameter' do
218
+ it 'is a random element from the set' do
219
+ random_element = @client.srandmember("key1")
220
+
221
+ expect(['a', 'b', 'c'].include?(random_element)).to be true
222
+ end
223
+ end
224
+
225
+ context 'when called with the optional number parameter of 1' do
226
+ it 'is an array of one random element from the set' do
227
+ random_elements = @client.srandmember("key1", 1)
228
+
229
+ expect([['a'], ['b'], ['c']].include?(@client.srandmember("key1", 1))).to be true
230
+ end
231
+ end
232
+
233
+ context 'when called with the optional number parameter of 2' do
234
+ it 'is an array of two unique, random elements from the set' do
235
+ random_elements = @client.srandmember("key1", 2)
236
+
237
+ expect(random_elements.count).to eq(2)
238
+ expect(random_elements.uniq.count).to eq(2)
239
+ random_elements.all? do |element|
240
+ expect(['a', 'b', 'c'].include?(element)).to be true
241
+ end
242
+ end
243
+ end
244
+
245
+ context 'when called with an optional parameter of -100' do
246
+ it 'is an array of 100 random elements from the set, some of which are repeated' do
247
+ random_elements = @client.srandmember("key1", -100)
248
+
249
+ expect(random_elements.count).to eq(100)
250
+ expect(random_elements.uniq.count).to be <= 3
251
+ random_elements.all? do |element|
252
+ expect(['a', 'b', 'c'].include?(element)).to be true
253
+ end
254
+ end
255
+ end
256
+
257
+ context 'when called with an optional parameter of 100' do
258
+ it 'is an array of all of the elements from the set, none of which are repeated' do
259
+ random_elements = @client.srandmember("key1", 100)
260
+
261
+ expect(random_elements.count).to eq(3)
262
+ expect(random_elements.uniq.count).to eq(3)
263
+ expect(random_elements).to match_array(['a', 'b', 'c'])
264
+ end
265
+ end
266
+ end
267
+
268
+ context 'with an empty set' do
269
+ before { @client.del("key1") }
270
+
271
+ it 'is nil without the extra parameter' do
272
+ expect(@client.srandmember("key1")).to be_nil
273
+ end
274
+
275
+ it 'is an empty array with an extra parameter' do
276
+ expect(@client.srandmember("key1", 1)).to eq([])
277
+ end
278
+ end
279
+ end
280
+ end