fakeredis 0.5.0 → 0.8.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 +5 -5
  2. data/.gitignore +3 -0
  3. data/.travis.yml +14 -5
  4. data/LICENSE +1 -1
  5. data/README.md +42 -24
  6. data/fakeredis.gemspec +1 -1
  7. data/lib/fakeredis.rb +28 -0
  8. data/lib/fakeredis/bitop_command.rb +56 -0
  9. data/lib/fakeredis/command_executor.rb +6 -9
  10. data/lib/fakeredis/expiring_hash.rb +3 -5
  11. data/lib/fakeredis/geo_commands.rb +142 -0
  12. data/lib/fakeredis/geo_set.rb +84 -0
  13. data/lib/fakeredis/minitest.rb +24 -0
  14. data/lib/fakeredis/rspec.rb +1 -0
  15. data/lib/fakeredis/sort_method.rb +3 -3
  16. data/lib/fakeredis/sorted_set_store.rb +1 -1
  17. data/lib/fakeredis/transaction_commands.rb +2 -2
  18. data/lib/fakeredis/version.rb +1 -1
  19. data/lib/fakeredis/zset.rb +8 -2
  20. data/lib/redis/connection/memory.rb +650 -82
  21. data/spec/bitop_command_spec.rb +209 -0
  22. data/spec/command_executor_spec.rb +15 -0
  23. data/spec/compatibility_spec.rb +1 -1
  24. data/spec/connection_spec.rb +21 -21
  25. data/spec/fakeredis_spec.rb +73 -0
  26. data/spec/geo_set_spec.rb +164 -0
  27. data/spec/hashes_spec.rb +138 -57
  28. data/spec/hyper_log_logs_spec.rb +50 -0
  29. data/spec/keys_spec.rb +232 -90
  30. data/spec/lists_spec.rb +91 -35
  31. data/spec/memory_spec.rb +80 -7
  32. data/spec/server_spec.rb +38 -24
  33. data/spec/sets_spec.rb +112 -46
  34. data/spec/sort_method_spec.rb +6 -0
  35. data/spec/sorted_sets_spec.rb +482 -150
  36. data/spec/spec_helper.rb +9 -18
  37. data/spec/spec_helper_live_redis.rb +4 -4
  38. data/spec/strings_spec.rb +113 -79
  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 +20 -16
  42. data/spec/transactions_spec.rb +34 -13
  43. data/spec/upcase_method_name_spec.rb +2 -2
  44. metadata +23 -6
data/spec/sets_spec.rb CHANGED
@@ -7,30 +7,34 @@ module FakeRedis
7
7
  end
8
8
 
9
9
  it "should add a member to a set" do
10
- @client.sadd("key", "value").should be == true
11
- @client.sadd("key", "value").should be == false
10
+ expect(@client.sadd("key", "value")).to eq(true)
11
+ expect(@client.sadd("key", "value")).to eq(false)
12
12
 
13
- @client.smembers("key").should be == ["value"]
13
+ expect(@client.smembers("key")).to eq(["value"])
14
14
  end
15
15
 
16
16
  it "should raise error if command arguments count is not enough" do
17
17
  expect { @client.sadd("key", []) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'sadd' command")
18
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
+ expect { @client.srem("key", []) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'srem' command")
19
23
 
20
- @client.smembers("key").should be_empty
24
+ expect(@client.smembers("key")).to be_empty
21
25
  end
22
26
 
23
27
  it "should add multiple members to a set" do
24
- @client.sadd("key", %w(value other something more)).should be == 4
25
- @client.sadd("key", %w(and additional values)).should be == 3
26
- @client.smembers("key").should =~ ["value", "other", "something", "more", "and", "additional", "values"]
28
+ expect(@client.sadd("key", %w(value other something more))).to eq(4)
29
+ expect(@client.sadd("key", %w(and additional values))).to eq(3)
30
+ expect(@client.smembers("key")).to match_array(["value", "other", "something", "more", "and", "additional", "values"])
27
31
  end
28
32
 
29
33
  it "should get the number of members in a set" do
30
34
  @client.sadd("key", "val1")
31
35
  @client.sadd("key", "val2")
32
36
 
33
- @client.scard("key").should be == 2
37
+ expect(@client.scard("key")).to eq(2)
34
38
  end
35
39
 
36
40
  it "should subtract multiple sets" do
@@ -43,14 +47,16 @@ module FakeRedis
43
47
  @client.sadd("key3", "c")
44
48
  @client.sadd("key3", "e")
45
49
 
46
- @client.sdiff("key1", "key2", "key3").should =~ ["b", "d"]
50
+ expect(@client.sdiff("key1", "key2", "key3")).to match_array(["b", "d"])
51
+ expect(@client.sdiff("key1", ["key2", "key3"])).to match_array(["b", "d"])
47
52
  end
48
53
 
49
54
  it "should subtract from a nonexistent set" do
50
55
  @client.sadd("key2", "a")
51
56
  @client.sadd("key2", "b")
52
57
 
53
- @client.sdiff("key1", "key2").should == []
58
+ expect(@client.sdiff("key1", "key2")).to eq([])
59
+ expect(@client.sdiff(["key1", "key2"])).to eq([])
54
60
  end
55
61
 
56
62
  it "should subtract multiple sets and store the resulting set in a key" do
@@ -63,8 +69,10 @@ module FakeRedis
63
69
  @client.sadd("key3", "c")
64
70
  @client.sadd("key3", "e")
65
71
  @client.sdiffstore("key", "key1", "key2", "key3")
72
+ @client.sdiffstore("new_key", "key1", ["key2", "key3"])
66
73
 
67
- @client.smembers("key").should =~ ["b", "d"]
74
+ expect(@client.smembers("key")).to match_array(["b", "d"])
75
+ expect(@client.smembers("new_key")).to match_array(["b", "d"])
68
76
  end
69
77
 
70
78
  it "should intersect multiple sets" do
@@ -77,7 +85,8 @@ module FakeRedis
77
85
  @client.sadd("key3", "c")
78
86
  @client.sadd("key3", "e")
79
87
 
80
- @client.sinter("key1", "key2", "key3").should be == ["c"]
88
+ expect(@client.sinter("key1", "key2", "key3")).to eq(["c"])
89
+ expect(@client.sinter(["key1", "key2", "key3"])).to eq(["c"])
81
90
  end
82
91
 
83
92
  it "should intersect multiple sets and store the resulting set in a key" do
@@ -90,15 +99,18 @@ module FakeRedis
90
99
  @client.sadd("key3", "c")
91
100
  @client.sadd("key3", "e")
92
101
  @client.sinterstore("key", "key1", "key2", "key3")
93
- @client.smembers("key").should be == ["c"]
102
+ @client.sinterstore("new_key", ["key1", "key2", "key3"])
103
+
104
+ expect(@client.smembers("key")).to eq(["c"])
105
+ expect(@client.smembers("new_key")).to eq(["c"])
94
106
  end
95
107
 
96
108
  it "should determine if a given value is a member of a set" do
97
109
  @client.sadd("key1", "a")
98
110
 
99
- @client.sismember("key1", "a").should be == true
100
- @client.sismember("key1", "b").should be == false
101
- @client.sismember("key2", "a").should be == false
111
+ expect(@client.sismember("key1", "a")).to eq(true)
112
+ expect(@client.sismember("key1", "b")).to eq(false)
113
+ expect(@client.sismember("key2", "a")).to eq(false)
102
114
  end
103
115
 
104
116
  it "should get all the members in a set" do
@@ -107,51 +119,67 @@ module FakeRedis
107
119
  @client.sadd("key", "c")
108
120
  @client.sadd("key", "d")
109
121
 
110
- @client.smembers("key").should =~ ["a", "b", "c", "d"]
122
+ expect(@client.smembers("key")).to match_array(["a", "b", "c", "d"])
111
123
  end
112
124
 
113
125
  it "should move a member from one set to another" do
114
126
  @client.sadd("key1", "a")
115
127
  @client.sadd("key1", "b")
116
128
  @client.sadd("key2", "c")
117
- @client.smove("key1", "key2", "a").should be == true
118
- @client.smove("key1", "key2", "a").should be == false
129
+ expect(@client.smove("key1", "key2", "a")).to eq(true)
130
+ expect(@client.smove("key1", "key2", "a")).to eq(false)
119
131
 
120
- @client.smembers("key1").should be == ["b"]
121
- @client.smembers("key2").should =~ ["c", "a"]
132
+ expect(@client.smembers("key1")).to eq(["b"])
133
+ expect(@client.smembers("key2")).to match_array(["c", "a"])
122
134
  end
123
135
 
124
136
  it "should remove and return a random member from a set" do
125
137
  @client.sadd("key1", "a")
126
138
  @client.sadd("key1", "b")
127
139
 
128
- ["a", "b"].include?(@client.spop("key1")).should be true
129
- ["a", "b"].include?(@client.spop("key1")).should be true
130
- @client.spop("key1").should be_nil
140
+ expect(["a", "b"].include?(@client.spop("key1"))).to be true
141
+ expect(["a", "b"].include?(@client.spop("key1"))).to be true
142
+ expect(@client.spop("key1")).to be_nil
131
143
  end
132
144
 
133
145
  it "should get a random member from a set" do
134
146
  @client.sadd("key1", "a")
135
147
  @client.sadd("key1", "b")
136
148
 
137
- ["a", "b"].include?(@client.spop("key1")).should be true
149
+ expect(["a", "b"].include?(@client.spop("key1"))).to be true
150
+ end
151
+
152
+ it "should pop multiple members from a set" do
153
+ @client.sadd("key1", "a")
154
+ @client.sadd("key1", "b")
155
+ @client.sadd("key1", "c")
156
+
157
+ vals = @client.spop("key1", 2)
158
+ expect(vals.count).to eq(2)
159
+ vals.each { |v| expect(["a", "b", "c"].include?(v)).to be true }
160
+
161
+ new_vals = @client.spop("key1", 2)
162
+ expect(new_vals.count).to eq(1)
163
+ expect(["a", "b", "c"].include?(new_vals.first)).to be true
164
+
165
+ expect(["a", "b", "c"]).to eq((vals + new_vals).sort)
138
166
  end
139
167
 
140
168
  it "should remove a member from a set" do
141
169
  @client.sadd("key1", "a")
142
170
  @client.sadd("key1", "b")
143
- @client.srem("key1", "a").should be == true
144
- @client.srem("key1", "a").should be == false
171
+ expect(@client.srem("key1", "a")).to eq(true)
172
+ expect(@client.srem("key1", "a")).to eq(false)
145
173
 
146
- @client.smembers("key1").should be == ["b"]
174
+ expect(@client.smembers("key1")).to eq(["b"])
147
175
  end
148
176
 
149
177
  it "should remove multiple members from a set" do
150
178
  @client.sadd("key1", "a")
151
179
  @client.sadd("key1", "b")
152
180
 
153
- @client.srem("key1", [ "a", "b"]).should == 2
154
- @client.smembers("key1").should be_empty
181
+ expect(@client.srem("key1", [ "a", "b"])).to eq(2)
182
+ expect(@client.smembers("key1")).to be_empty
155
183
  end
156
184
 
157
185
  it "should remove the set's key once it's empty" do
@@ -160,7 +188,7 @@ module FakeRedis
160
188
  @client.srem("key1", "b")
161
189
  @client.srem("key1", "a")
162
190
 
163
- @client.exists("key1").should be == false
191
+ expect(@client.exists("key1")).to eq(false)
164
192
  end
165
193
 
166
194
  it "should add multiple sets" do
@@ -173,7 +201,7 @@ module FakeRedis
173
201
  @client.sadd("key3", "c")
174
202
  @client.sadd("key3", "e")
175
203
 
176
- @client.sunion("key1", "key2", "key3").should =~ ["a", "b", "c", "d", "e"]
204
+ expect(@client.sunion("key1", "key2", "key3")).to match_array(["a", "b", "c", "d", "e"])
177
205
  end
178
206
 
179
207
  it "should add multiple sets and store the resulting set in a key" do
@@ -187,7 +215,7 @@ module FakeRedis
187
215
  @client.sadd("key3", "e")
188
216
  @client.sunionstore("key", "key1", "key2", "key3")
189
217
 
190
- @client.smembers("key").should =~ ["a", "b", "c", "d", "e"]
218
+ expect(@client.smembers("key")).to match_array(["a", "b", "c", "d", "e"])
191
219
  end
192
220
  end
193
221
 
@@ -207,7 +235,7 @@ module FakeRedis
207
235
  it 'is a random element from the set' do
208
236
  random_element = @client.srandmember("key1")
209
237
 
210
- ['a', 'b', 'c'].include?(random_element).should be true
238
+ expect(['a', 'b', 'c'].include?(random_element)).to be true
211
239
  end
212
240
  end
213
241
 
@@ -215,7 +243,7 @@ module FakeRedis
215
243
  it 'is an array of one random element from the set' do
216
244
  random_elements = @client.srandmember("key1", 1)
217
245
 
218
- [['a'], ['b'], ['c']].include?(@client.srandmember("key1", 1)).should be true
246
+ expect([['a'], ['b'], ['c']].include?(random_elements)).to be true
219
247
  end
220
248
  end
221
249
 
@@ -223,10 +251,10 @@ module FakeRedis
223
251
  it 'is an array of two unique, random elements from the set' do
224
252
  random_elements = @client.srandmember("key1", 2)
225
253
 
226
- random_elements.count.should == 2
227
- random_elements.uniq.count.should == 2
254
+ expect(random_elements.count).to eq(2)
255
+ expect(random_elements.uniq.count).to eq(2)
228
256
  random_elements.all? do |element|
229
- ['a', 'b', 'c'].include?(element).should be true
257
+ expect(['a', 'b', 'c'].include?(element)).to be true
230
258
  end
231
259
  end
232
260
  end
@@ -235,10 +263,10 @@ module FakeRedis
235
263
  it 'is an array of 100 random elements from the set, some of which are repeated' do
236
264
  random_elements = @client.srandmember("key1", -100)
237
265
 
238
- random_elements.count.should == 100
239
- random_elements.uniq.count.should <= 3
266
+ expect(random_elements.count).to eq(100)
267
+ expect(random_elements.uniq.count).to be <= 3
240
268
  random_elements.all? do |element|
241
- ['a', 'b', 'c'].include?(element).should be true
269
+ expect(['a', 'b', 'c'].include?(element)).to be true
242
270
  end
243
271
  end
244
272
  end
@@ -247,9 +275,9 @@ module FakeRedis
247
275
  it 'is an array of all of the elements from the set, none of which are repeated' do
248
276
  random_elements = @client.srandmember("key1", 100)
249
277
 
250
- random_elements.count.should == 3
251
- random_elements.uniq.count.should == 3
252
- random_elements.should =~ ['a', 'b', 'c']
278
+ expect(random_elements.count).to eq(3)
279
+ expect(random_elements.uniq.count).to eq(3)
280
+ expect(random_elements).to match_array(['a', 'b', 'c'])
253
281
  end
254
282
  end
255
283
  end
@@ -258,11 +286,49 @@ module FakeRedis
258
286
  before { @client.del("key1") }
259
287
 
260
288
  it 'is nil without the extra parameter' do
261
- @client.srandmember("key1").should be_nil
289
+ expect(@client.srandmember("key1")).to be_nil
262
290
  end
263
291
 
264
292
  it 'is an empty array with an extra parameter' do
265
- @client.srandmember("key1", 1).should == []
293
+ expect(@client.srandmember("key1", 1)).to eq([])
294
+ end
295
+ end
296
+
297
+ describe "#sscan" do
298
+ it 'with no arguments and few items, returns all items' do
299
+ @client.sadd('set', ['name', 'Jack', 'age', '33'])
300
+ result = @client.sscan('set', 0)
301
+
302
+ expect(result[0]).to eq('0')
303
+ expect(result[1]).to eq(['name', 'Jack', 'age', '33'])
304
+ end
305
+
306
+ it 'with a count should return that number of members or more' do
307
+ @client.sadd('set', ['a', '1', 'b', '2', 'c', '3', 'd', '4', 'e', '5', 'f', '6', 'g', '7'])
308
+ result = @client.sscan('set', 0, count: 3)
309
+ expect(result[0]).to eq('3')
310
+ expect(result[1]).to eq([ 'a', '1', 'b'])
311
+ end
312
+
313
+ it 'returns items starting at the provided cursor' do
314
+ @client.sadd('set', ['a', '1', 'b', '2', 'c', '3', 'd', '4', 'e', '5', 'f', '6', 'g', '7'])
315
+ result = @client.sscan('set', 2, count: 3)
316
+ expect(result[0]).to eq('5')
317
+ expect(result[1]).to eq(['b', '2', 'c'])
318
+ end
319
+
320
+ it 'with match, returns items matching the given pattern' do
321
+ @client.sadd('set', ['aa', '1', 'b', '2', 'cc', '3', 'd', '4', 'ee', '5', 'f', '6', 'gg', '7'])
322
+ result = @client.sscan('set', 2, count: 7, match: '??')
323
+ expect(result[0]).to eq('9')
324
+ expect(result[1]).to eq(['cc','ee'])
325
+ end
326
+
327
+ it 'returns an empty result if the key is not found' do
328
+ result = @client.sscan('set', 0)
329
+
330
+ expect(result[0]).to eq('0')
331
+ expect(result[1]).to eq([])
266
332
  end
267
333
  end
268
334
  end
@@ -32,6 +32,12 @@ module FakeRedis
32
32
  end
33
33
  end
34
34
 
35
+ context "none" do
36
+ it "should return empty array" do
37
+ expect(@client.sort("key")).to eq []
38
+ end
39
+ end
40
+
35
41
  context "list" do
36
42
  before do
37
43
  @key = "fake-redis-test:list_sort"
@@ -9,84 +9,126 @@ module FakeRedis
9
9
  end
10
10
 
11
11
  it "should add a member to a sorted set, or update its score if it already exists" do
12
- @client.zadd("key", 1, "val").should be(true)
13
- @client.zscore("key", "val").should be == 1.0
12
+ expect(@client.zadd("key", 1, "val")).to be(true)
13
+ expect(@client.zscore("key", "val")).to eq(1.0)
14
14
 
15
- @client.zadd("key", 2, "val").should be(false)
16
- @client.zscore("key", "val").should be == 2.0
15
+ expect(@client.zadd("key", 2, "val")).to be(false)
16
+ expect(@client.zscore("key", "val")).to eq(2.0)
17
17
 
18
18
  # These assertions only work in redis-rb v3.0.2 or higher
19
- @client.zadd("key2", "inf", "val").should be == true
20
- @client.zscore("key2", "val").should be == Infinity
19
+ expect(@client.zadd("key2", "inf", "val")).to eq(true)
20
+ expect(@client.zscore("key2", "val")).to eq(Infinity)
21
21
 
22
- @client.zadd("key3", "+inf", "val").should be == true
23
- @client.zscore("key3", "val").should be == Infinity
22
+ expect(@client.zadd("key3", "+inf", "val")).to eq(true)
23
+ expect(@client.zscore("key3", "val")).to eq(Infinity)
24
24
 
25
- @client.zadd("key4", "-inf", "val").should be == true
26
- @client.zscore("key4", "val").should be == -Infinity
25
+ expect(@client.zadd("key4", "-inf", "val")).to eq(true)
26
+ expect(@client.zscore("key4", "val")).to eq(-Infinity)
27
27
  end
28
28
 
29
29
  it "should return a nil score for value not in a sorted set or empty key" do
30
30
  @client.zadd "key", 1, "val"
31
31
 
32
- @client.zscore("key", "val").should be == 1.0
33
- @client.zscore("key", "val2").should be_nil
34
- @client.zscore("key2", "val").should be_nil
32
+ expect(@client.zscore("key", "val")).to eq(1.0)
33
+ expect(@client.zscore("key", "val2")).to be_nil
34
+ expect(@client.zscore("key2", "val")).to be_nil
35
35
  end
36
36
 
37
37
  it "should add multiple members to a sorted set, or update its score if it already exists" do
38
- @client.zadd("key", [1, "val", 2, "val2"]).should be == 2
39
- @client.zscore("key", "val").should be == 1
40
- @client.zscore("key", "val2").should be == 2
41
-
42
- @client.zadd("key", [[5, "val"], [3, "val3"], [4, "val4"]]).should be == 2
43
- @client.zscore("key", "val").should be == 5
44
- @client.zscore("key", "val2").should be == 2
45
- @client.zscore("key", "val3").should be == 3
46
- @client.zscore("key", "val4").should be == 4
47
-
48
- @client.zadd("key", [[5, "val5"], [3, "val6"]]).should be == 2
49
- @client.zscore("key", "val5").should be == 5
50
- @client.zscore("key", "val6").should be == 3
38
+ expect(@client.zadd("key", [1, "val", 2, "val2"])).to eq(2)
39
+ expect(@client.zscore("key", "val")).to eq(1)
40
+ expect(@client.zscore("key", "val2")).to eq(2)
41
+
42
+ expect(@client.zadd("key", [[5, "val"], [3, "val3"], [4, "val4"]])).to eq(2)
43
+ expect(@client.zscore("key", "val")).to eq(5)
44
+ expect(@client.zscore("key", "val2")).to eq(2)
45
+ expect(@client.zscore("key", "val3")).to eq(3)
46
+ expect(@client.zscore("key", "val4")).to eq(4)
47
+
48
+ expect(@client.zadd("key", [[5, "val5"], [3, "val6"]])).to eq(2)
49
+ expect(@client.zscore("key", "val5")).to eq(5)
50
+ expect(@client.zscore("key", "val6")).to eq(3)
51
51
  end
52
52
 
53
53
  it "should error with wrong number of arguments when adding members" do
54
- lambda { @client.zadd("key") }.should raise_error(ArgumentError, "wrong number of arguments")
55
- lambda { @client.zadd("key", 1) }.should raise_error(ArgumentError, "wrong number of arguments")
56
- lambda { @client.zadd("key", [1]) }.should raise_error(Redis::CommandError, "ERR wrong number of arguments for 'zadd' command")
57
- lambda { @client.zadd("key", [1, "val", 2]) }.should raise_error(Redis::CommandError, "ERR syntax error")
58
- lambda { @client.zadd("key", [[1, "val"], [2]]) }.should raise_error(Redis::CommandError, "ERR syntax error")
54
+ expect { @client.zadd("key") }.to raise_error(ArgumentError, "wrong number of arguments")
55
+ expect { @client.zadd("key", 1) }.to raise_error(ArgumentError, "wrong number of arguments")
56
+ expect { @client.zadd("key", [1]) }.to raise_error(Redis::CommandError, "ERR wrong number of arguments for 'zadd' command")
57
+ expect { @client.zadd("key", [1, "val", 2]) }.to raise_error(Redis::CommandError, "ERR syntax error")
58
+ expect { @client.zadd("key", [[1, "val"], [2]]) }.to raise_error(Redis::CommandError, "ERR syntax error")
59
59
  end
60
60
 
61
61
  it "should allow floats as scores when adding or updating" do
62
- @client.zadd("key", 4.321, "val").should be(true)
63
- @client.zscore("key", "val").should be == 4.321
62
+ expect(@client.zadd("key", 4.321, "val")).to be(true)
63
+ expect(@client.zscore("key", "val")).to eq(4.321)
64
+
65
+ expect(@client.zadd("key", 54.3210, "val")).to be(false)
66
+ expect(@client.zscore("key", "val")).to eq(54.321)
67
+ end
64
68
 
65
- @client.zadd("key", 54.3210, "val").should be(false)
66
- @client.zscore("key", "val").should be == 54.321
69
+ it "should allow strings that can be parsed as float when adding or updating" do
70
+ expect(@client.zadd("key", "4.321", "val")).to be(true)
71
+ expect(@client.zscore("key", "val")).to eq(4.321)
72
+
73
+ expect(@client.zadd("key", "54.3210", "val")).to be(false)
74
+ expect(@client.zscore("key", "val")).to eq(54.321)
75
+ end
76
+
77
+ it "should error when the score is not a valid float" do
78
+ expect { @client.zadd("key", "score", "val") }.to raise_error(Redis::CommandError, "ERR value is not a valid float")
79
+ expect { @client.zadd("key", {}, "val") }.to raise_error(Redis::CommandError, "ERR value is not a valid float")
80
+ expect { @client.zadd("key", Time.now, "val") }.to raise_error(Redis::CommandError, "ERR value is not a valid float")
67
81
  end
68
82
 
69
83
  it "should remove members from sorted sets" do
70
- @client.zrem("key", "val").should be(false)
71
- @client.zadd("key", 1, "val").should be(true)
72
- @client.zrem("key", "val").should be(true)
84
+ expect(@client.zrem("key", "val")).to be(false)
85
+ expect(@client.zadd("key", 1, "val")).to be(true)
86
+ expect(@client.zrem("key", "val")).to be(true)
73
87
  end
74
88
 
75
89
  it "should remove multiple members from sorted sets" do
76
- @client.zrem("key2", %w(val)).should be == 0
77
- @client.zrem("key2", %w(val val2 val3)).should be == 0
90
+ expect(@client.zrem("key2", %w(val))).to eq(0)
91
+ expect(@client.zrem("key2", %w(val val2 val3))).to eq(0)
78
92
 
79
93
  @client.zadd("key2", 1, "val")
80
94
  @client.zadd("key2", 1, "val2")
81
95
  @client.zadd("key2", 1, "val3")
82
96
 
83
- @client.zrem("key2", %w(val val2 val3 val4)).should be == 3
97
+ expect(@client.zrem("key2", %w(val val2 val3 val4))).to eq(3)
84
98
  end
85
99
 
86
100
  it "should remove sorted set's key when it is empty" do
87
101
  @client.zadd("key", 1, "val")
88
102
  @client.zrem("key", "val")
89
- @client.exists("key").should be == false
103
+ expect(@client.exists("key")).to eq(false)
104
+ end
105
+
106
+ it "should pop members with the highest scores from sorted set" do
107
+ @client.zadd("key", [1, "val1", 2, "val2", 3, "val3"])
108
+ expect(@client.zpopmax("key")).to eq(["val3", 3.0])
109
+ expect(@client.zpopmax("key", 3)).to eq([["val2", 2.0], ["val1", 1.0]])
110
+ expect(@client.zpopmax("nonexistent")).to eq(nil)
111
+ end
112
+
113
+ it "should pop members with the lowest scores from sorted set" do
114
+ @client.zadd("key", [1, "val1", 2, "val2", 3, "val3"])
115
+ expect(@client.zpopmin("key")).to eq(["val1", 1.0])
116
+ expect(@client.zpopmin("key", 3)).to eq([["val2", 2.0], ["val3", 3.0]])
117
+ expect(@client.zpopmin("nonexistent")).to eq(nil)
118
+ end
119
+
120
+ it "should pop members with the highest score from first sorted set that is non-empty" do
121
+ @client.zadd("key1", [1, "val1", 2, "val2"])
122
+ @client.zadd("key2", [3, "val3"])
123
+ expect(@client.bzpopmax("nonexistent", "key1", "key2", 0)).to eq(["key1", "val2", 2.0])
124
+ expect(@client.bzpopmax("nonexistent")).to eq(nil)
125
+ end
126
+
127
+ it "should pop members with the lowest score from first sorted set that is non-empty" do
128
+ @client.zadd("key1", [1, "val1", 2, "val2"])
129
+ @client.zadd("key2", [3, "val3"])
130
+ expect(@client.bzpopmin("nonexistent", "key1", "key2", 0)).to eq(["key1", "val1", 1.0])
131
+ expect(@client.bzpopmin("nonexistent")).to eq(nil)
90
132
  end
91
133
 
92
134
  it "should get the number of members in a sorted set" do
@@ -94,7 +136,7 @@ module FakeRedis
94
136
  @client.zadd("key", 2, "val1")
95
137
  @client.zadd("key", 5, "val3")
96
138
 
97
- @client.zcard("key").should be == 3
139
+ expect(@client.zcard("key")).to eq(3)
98
140
  end
99
141
 
100
142
  it "should count the members in a sorted set with scores within the given values" do
@@ -102,28 +144,28 @@ module FakeRedis
102
144
  @client.zadd("key", 2, "val2")
103
145
  @client.zadd("key", 3, "val3")
104
146
 
105
- @client.zcount("key", 2, 3).should be == 2
147
+ expect(@client.zcount("key", 2, 3)).to eq(2)
106
148
  end
107
149
 
108
150
  it "should increment the score of a member in a sorted set" do
109
151
  @client.zadd("key", 1, "val1")
110
- @client.zincrby("key", 2, "val1").should be == 3
111
- @client.zscore("key", "val1").should be == 3
152
+ expect(@client.zincrby("key", 2, "val1")).to eq(3)
153
+ expect(@client.zscore("key", "val1")).to eq(3)
112
154
  end
113
155
 
114
156
  it "initializes the sorted set if the key wasnt already set" do
115
- @client.zincrby("key", 1, "val1").should be == 1
157
+ expect(@client.zincrby("key", 1, "val1")).to eq(1)
116
158
  end
117
159
 
118
160
  it "should convert the key to a string for zscore" do
119
161
  @client.zadd("key", 1, 1)
120
- @client.zscore("key", 1).should be == 1
162
+ expect(@client.zscore("key", 1)).to eq(1)
121
163
  end
122
164
 
123
165
  # These won't pass until redis-rb releases v3.0.2
124
166
  it "should handle infinity values when incrementing a sorted set key" do
125
- @client.zincrby("bar", "+inf", "s2").should be == Infinity
126
- @client.zincrby("bar", "-inf", "s1").should be == -Infinity
167
+ expect(@client.zincrby("bar", "+inf", "s2")).to eq(Infinity)
168
+ expect(@client.zincrby("bar", "-inf", "s1")).to eq(-Infinity)
127
169
  end
128
170
 
129
171
  it "should return a range of members in a sorted set, by index" do
@@ -131,10 +173,11 @@ module FakeRedis
131
173
  @client.zadd("key", 2, "two")
132
174
  @client.zadd("key", 3, "three")
133
175
 
134
- @client.zrange("key", 0, -1).should be == ["one", "two", "three"]
135
- @client.zrange("key", 1, 2).should be == ["two", "three"]
136
- @client.zrange("key", 0, -1, :withscores => true).should be == [["one", 1], ["two", 2], ["three", 3]]
137
- @client.zrange("key", 1, 2, :with_scores => true).should be == [["two", 2], ["three", 3]]
176
+ expect(@client.zrange("key", 0, -1)).to eq(["one", "two", "three"])
177
+ expect(@client.zrange("key", 1, 2)).to eq(["two", "three"])
178
+ expect(@client.zrange("key", -50, -2)).to eq(["one", "two"])
179
+ expect(@client.zrange("key", 0, -1, :withscores => true)).to eq([["one", 1], ["two", 2], ["three", 3]])
180
+ expect(@client.zrange("key", 1, 2, :with_scores => true)).to eq([["two", 2], ["three", 3]])
138
181
  end
139
182
 
140
183
  it "should sort zrange results logically" do
@@ -142,8 +185,8 @@ module FakeRedis
142
185
  @client.zadd("key", 5, "val3")
143
186
  @client.zadd("key", 5, "val1")
144
187
 
145
- @client.zrange("key", 0, -1).should be == %w(val1 val2 val3)
146
- @client.zrange("key", 0, -1, :with_scores => true).should be == [["val1", 5], ["val2", 5], ["val3", 5]]
188
+ expect(@client.zrange("key", 0, -1)).to eq(%w(val1 val2 val3))
189
+ expect(@client.zrange("key", 0, -1, :with_scores => true)).to eq([["val1", 5], ["val2", 5], ["val3", 5]])
147
190
  end
148
191
 
149
192
  it "should return a reversed range of members in a sorted set, by index" do
@@ -151,10 +194,10 @@ module FakeRedis
151
194
  @client.zadd("key", 2, "two")
152
195
  @client.zadd("key", 3, "three")
153
196
 
154
- @client.zrevrange("key", 0, -1).should be == ["three", "two", "one"]
155
- @client.zrevrange("key", 1, 2).should be == ["two", "one"]
156
- @client.zrevrange("key", 0, -1, :withscores => true).should be == [["three", 3], ["two", 2], ["one", 1]]
157
- @client.zrevrange("key", 0, -1, :with_scores => true).should be == [["three", 3], ["two", 2], ["one", 1]]
197
+ expect(@client.zrevrange("key", 0, -1)).to eq(["three", "two", "one"])
198
+ expect(@client.zrevrange("key", 1, 2)).to eq(["two", "one"])
199
+ expect(@client.zrevrange("key", 0, -1, :withscores => true)).to eq([["three", 3], ["two", 2], ["one", 1]])
200
+ expect(@client.zrevrange("key", 0, -1, :with_scores => true)).to eq([["three", 3], ["two", 2], ["one", 1]])
158
201
  end
159
202
 
160
203
  it "should return a range of members in a sorted set, by score" do
@@ -162,21 +205,21 @@ module FakeRedis
162
205
  @client.zadd("key", 2, "two")
163
206
  @client.zadd("key", 3, "three")
164
207
 
165
- @client.zrangebyscore("key", 0, 100).should be == ["one", "two", "three"]
166
- @client.zrangebyscore("key", 1, 2).should be == ["one", "two"]
167
- @client.zrangebyscore("key", 1, '(2').should be == ['one']
168
- @client.zrangebyscore("key", '(1', 2).should be == ['two']
169
- @client.zrangebyscore("key", '(1', '(2').should be == []
170
- @client.zrangebyscore("key", 0, 100, :withscores => true).should be == [["one", 1], ["two", 2], ["three", 3]]
171
- @client.zrangebyscore("key", 1, 2, :with_scores => true).should be == [["one", 1], ["two", 2]]
172
- @client.zrangebyscore("key", 0, 100, :limit => [0, 1]).should be == ["one"]
173
- @client.zrangebyscore("key", 0, 100, :limit => [0, -1]).should be == ["one", "two", "three"]
174
- @client.zrangebyscore("key", 0, 100, :limit => [1, -1], :with_scores => true).should be == [["two", 2], ["three", 3]]
175
- @client.zrangebyscore("key", '-inf', '+inf').should be == ["one", "two", "three"]
176
- @client.zrangebyscore("key", 2, '+inf').should be == ["two", "three"]
177
- @client.zrangebyscore("key", '-inf', 2).should be == ['one', "two"]
178
-
179
- @client.zrangebyscore("badkey", 1, 2).should be == []
208
+ expect(@client.zrangebyscore("key", 0, 100)).to eq(["one", "two", "three"])
209
+ expect(@client.zrangebyscore("key", 1, 2)).to eq(["one", "two"])
210
+ expect(@client.zrangebyscore("key", 1, '(2')).to eq(['one'])
211
+ expect(@client.zrangebyscore("key", '(1', 2)).to eq(['two'])
212
+ expect(@client.zrangebyscore("key", '(1', '(2')).to eq([])
213
+ expect(@client.zrangebyscore("key", 0, 100, :withscores => true)).to eq([["one", 1], ["two", 2], ["three", 3]])
214
+ expect(@client.zrangebyscore("key", 1, 2, :with_scores => true)).to eq([["one", 1], ["two", 2]])
215
+ expect(@client.zrangebyscore("key", 0, 100, :limit => [0, 1])).to eq(["one"])
216
+ expect(@client.zrangebyscore("key", 0, 100, :limit => [0, -1])).to eq(["one", "two", "three"])
217
+ expect(@client.zrangebyscore("key", 0, 100, :limit => [1, -1], :with_scores => true)).to eq([["two", 2], ["three", 3]])
218
+ expect(@client.zrangebyscore("key", '-inf', '+inf')).to eq(["one", "two", "three"])
219
+ expect(@client.zrangebyscore("key", 2, '+inf')).to eq(["two", "three"])
220
+ expect(@client.zrangebyscore("key", '-inf', 2)).to eq(['one', "two"])
221
+
222
+ expect(@client.zrangebyscore("badkey", 1, 2)).to eq([])
180
223
  end
181
224
 
182
225
  it "should return a reversed range of members in a sorted set, by score" do
@@ -184,13 +227,13 @@ module FakeRedis
184
227
  @client.zadd("key", 2, "two")
185
228
  @client.zadd("key", 3, "three")
186
229
 
187
- @client.zrevrangebyscore("key", 100, 0).should be == ["three", "two", "one"]
188
- @client.zrevrangebyscore("key", 2, 1).should be == ["two", "one"]
189
- @client.zrevrangebyscore("key", 1, 2).should be == []
190
- @client.zrevrangebyscore("key", 2, 1, :with_scores => true).should be == [["two", 2.0], ["one", 1.0]]
191
- @client.zrevrangebyscore("key", 100, 0, :limit => [0, 1]).should be == ["three"]
192
- @client.zrevrangebyscore("key", 100, 0, :limit => [0, -1]).should be == ["three", "two", "one"]
193
- @client.zrevrangebyscore("key", 100, 0, :limit => [1, -1], :with_scores => true).should be == [["two", 2.0], ["one", 1.0]]
230
+ expect(@client.zrevrangebyscore("key", 100, 0)).to eq(["three", "two", "one"])
231
+ expect(@client.zrevrangebyscore("key", 2, 1)).to eq(["two", "one"])
232
+ expect(@client.zrevrangebyscore("key", 1, 2)).to eq([])
233
+ expect(@client.zrevrangebyscore("key", 2, 1, :with_scores => true)).to eq([["two", 2.0], ["one", 1.0]])
234
+ expect(@client.zrevrangebyscore("key", 100, 0, :limit => [0, 1])).to eq(["three"])
235
+ expect(@client.zrevrangebyscore("key", 100, 0, :limit => [0, -1])).to eq(["three", "two", "one"])
236
+ expect(@client.zrevrangebyscore("key", 100, 0, :limit => [1, -1], :with_scores => true)).to eq([["two", 2.0], ["one", 1.0]])
194
237
  end
195
238
 
196
239
  it "should determine the index of a member in a sorted set" do
@@ -198,8 +241,8 @@ module FakeRedis
198
241
  @client.zadd("key", 2, "two")
199
242
  @client.zadd("key", 3, "three")
200
243
 
201
- @client.zrank("key", "three").should be == 2
202
- @client.zrank("key", "four").should be_nil
244
+ expect(@client.zrank("key", "three")).to eq(2)
245
+ expect(@client.zrank("key", "four")).to be_nil
203
246
  end
204
247
 
205
248
  it "should determine the reversed index of a member in a sorted set" do
@@ -207,16 +250,16 @@ module FakeRedis
207
250
  @client.zadd("key", 2, "two")
208
251
  @client.zadd("key", 3, "three")
209
252
 
210
- @client.zrevrank("key", "three").should be == 0
211
- @client.zrevrank("key", "four").should be_nil
253
+ expect(@client.zrevrank("key", "three")).to eq(0)
254
+ expect(@client.zrevrank("key", "four")).to be_nil
212
255
  end
213
256
 
214
257
  it "should not raise errors for zrank() on accessing a non-existing key in a sorted set" do
215
- @client.zrank("no_such_key", "no_suck_id").should be_nil
258
+ expect(@client.zrank("no_such_key", "no_suck_id")).to be_nil
216
259
  end
217
260
 
218
261
  it "should not raise errors for zrevrank() on accessing a non-existing key in a sorted set" do
219
- @client.zrevrank("no_such_key", "no_suck_id").should be_nil
262
+ expect(@client.zrevrank("no_such_key", "no_suck_id")).to be_nil
220
263
  end
221
264
 
222
265
  describe "#zinterstore" do
@@ -231,66 +274,82 @@ module FakeRedis
231
274
  end
232
275
 
233
276
  it "should intersect two keys with custom scores" do
234
- @client.zinterstore("out", ["key1", "key2"]).should be == 2
235
- @client.zrange("out", 0, -1, :with_scores => true).should be == [['two', (2 + 5)], ['three', (3 + 7)]]
277
+ expect(@client.zinterstore("out", ["key1", "key2"])).to eq(2)
278
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([['two', (2 + 5)], ['three', (3 + 7)]])
236
279
  end
237
280
 
238
281
  it "should intersect two keys with a default score" do
239
- @client.zinterstore("out", ["key1", "key3"]).should be == 2
240
- @client.zrange("out", 0, -1, :with_scores => true).should be == [['one', (1 + 1)], ['two', (2 + 1)]]
282
+ expect(@client.zinterstore("out", ["key1", "key3"])).to eq(2)
283
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([['one', (1 + 1)], ['two', (2 + 1)]])
241
284
  end
242
285
 
243
286
  it "should intersect more than two keys" do
244
- @client.zinterstore("out", ["key1", "key2", "key3"]).should be == 1
245
- @client.zrange("out", 0, -1, :with_scores => true).should be == [['two', (2 + 5 + 1)]]
287
+ expect(@client.zinterstore("out", ["key1", "key2", "key3"])).to eq(1)
288
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([['two', (2 + 5 + 1)]])
246
289
  end
247
290
 
248
291
  it "should not intersect an unknown key" do
249
- @client.zinterstore("out", ["key1", "no_key"]).should be == 0
250
- @client.zrange("out", 0, -1, :with_scores => true).should be == []
292
+ expect(@client.zinterstore("out", ["key1", "no_key"])).to eq(0)
293
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([])
251
294
  end
252
295
 
253
296
  it "should intersect two keys by minimum values" do
254
- @client.zinterstore("out", ["key1", "key2"], :aggregate => :min).should be == 2
255
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["two", 2], ["three", 3]]
297
+ expect(@client.zinterstore("out", ["key1", "key2"], :aggregate => :min)).to eq(2)
298
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["two", 2], ["three", 3]])
256
299
  end
257
300
 
258
301
  it "should intersect two keys by maximum values" do
259
- @client.zinterstore("out", ["key1", "key2"], :aggregate => :max).should be == 2
260
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["two", 5], ["three", 7]]
302
+ expect(@client.zinterstore("out", ["key1", "key2"], :aggregate => :max)).to eq(2)
303
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["two", 5], ["three", 7]])
261
304
  end
262
305
 
263
306
  it "should intersect two keys by explicitly summing values" do
264
- @client.zinterstore("out", %w(key1 key2), :aggregate => :sum).should be == 2
265
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["two", (2 + 5)], ["three", (3 + 7)]]
307
+ expect(@client.zinterstore("out", %w(key1 key2), :aggregate => :sum)).to eq(2)
308
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["two", (2 + 5)], ["three", (3 + 7)]])
266
309
  end
267
310
 
268
311
  it "should intersect two keys with weighted values" do
269
- @client.zinterstore("out", %w(key1 key2), :weights => [10, 1]).should be == 2
270
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["two", (2 * 10 + 5)], ["three", (3 * 10 + 7)]]
312
+ expect(@client.zinterstore("out", %w(key1 key2), :weights => [10, 1])).to eq(2)
313
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["two", (2 * 10 + 5)], ["three", (3 * 10 + 7)]])
271
314
  end
272
315
 
273
316
  it "should intersect two keys with weighted minimum values" do
274
- @client.zinterstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :min).should be == 2
275
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["two", 5], ["three", 7]]
317
+ expect(@client.zinterstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :min)).to eq(2)
318
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["two", 5], ["three", 7]])
276
319
  end
277
320
 
278
321
  it "should intersect two keys with weighted maximum values" do
279
- @client.zinterstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :max).should be == 2
280
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["two", (2 * 10)], ["three", (3 * 10)]]
322
+ expect(@client.zinterstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :max)).to eq(2)
323
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["two", (2 * 10)], ["three", (3 * 10)]])
281
324
  end
282
325
 
283
326
  it "should error without enough weights given" do
284
- lambda { @client.zinterstore("out", %w(key1 key2), :weights => []) }.should raise_error(Redis::CommandError, "ERR syntax error")
285
- lambda { @client.zinterstore("out", %w(key1 key2), :weights => [10]) }.should raise_error(Redis::CommandError, "ERR syntax error")
327
+ expect { @client.zinterstore("out", %w(key1 key2), :weights => []) }.to raise_error(Redis::CommandError, "ERR syntax error")
328
+ expect { @client.zinterstore("out", %w(key1 key2), :weights => [10]) }.to raise_error(Redis::CommandError, "ERR syntax error")
286
329
  end
287
330
 
288
331
  it "should error with too many weights given" do
289
- lambda { @client.zinterstore("out", %w(key1 key2), :weights => [10, 1, 1]) }.should raise_error(Redis::CommandError, "ERR syntax error")
332
+ expect { @client.zinterstore("out", %w(key1 key2), :weights => [10, 1, 1]) }.to raise_error(Redis::CommandError, "ERR syntax error")
290
333
  end
291
334
 
292
335
  it "should error with an invalid aggregate" do
293
- lambda { @client.zinterstore("out", %w(key1 key2), :aggregate => :invalid) }.should raise_error(Redis::CommandError, "ERR syntax error")
336
+ expect { @client.zinterstore("out", %w(key1 key2), :aggregate => :invalid) }.to raise_error(Redis::CommandError, "ERR syntax error")
337
+ end
338
+
339
+ it 'stores nothing when there are no members in common' do
340
+ @client.zadd("k1", 1, "1")
341
+ @client.zadd("k1", 1, "2")
342
+ @client.sadd("k2", "a")
343
+ @client.sadd("k3", "b")
344
+
345
+ expect(@client.zinterstore("out", %w(k1 k2 k3))).to eq(0)
346
+ expect(@client.zrange("out", 0, -1)).to eq([])
347
+ end
348
+
349
+ it 'handles range start being higher than number of members' do
350
+ @client.zadd("key", 1, "1")
351
+
352
+ expect(@client.zrange("key", 10, 10)).to eq([])
294
353
  end
295
354
  end
296
355
 
@@ -300,23 +359,23 @@ module FakeRedis
300
359
  @client.zadd("key", 2, "two")
301
360
  @client.zadd("key", 3, "three")
302
361
 
303
- @client.zremrangebyscore("key", 0, 2).should be == 2
304
- @client.zcard("key").should be == 1
362
+ expect(@client.zremrangebyscore("key", 0, 2)).to eq(2)
363
+ expect(@client.zcard("key")).to eq(1)
305
364
  end
306
365
 
307
366
  it "should remove items by score with infinity" do # Issue #50
308
367
  @client.zadd("key", 10.0, "one")
309
368
  @client.zadd("key", 20.0, "two")
310
369
  @client.zadd("key", 30.0, "three")
311
- @client.zremrangebyscore("key", "-inf", "+inf").should be == 3
312
- @client.zcard("key").should be == 0
313
- @client.zscore("key", "one").should be_nil
314
- @client.zscore("key", "two").should be_nil
315
- @client.zscore("key", "three").should be_nil
370
+ expect(@client.zremrangebyscore("key", "-inf", "+inf")).to eq(3)
371
+ expect(@client.zcard("key")).to eq(0)
372
+ expect(@client.zscore("key", "one")).to be_nil
373
+ expect(@client.zscore("key", "two")).to be_nil
374
+ expect(@client.zscore("key", "three")).to be_nil
316
375
  end
317
376
 
318
377
  it "should return 0 if the key didn't exist" do
319
- @client.zremrangebyscore("key", 0, 2).should be == 0
378
+ expect(@client.zremrangebyscore("key", 0, 2)).to eq(0)
320
379
  end
321
380
  end
322
381
 
@@ -326,8 +385,8 @@ module FakeRedis
326
385
  @client.zadd("key", 2, "two")
327
386
  @client.zadd("key", 3, "three")
328
387
 
329
- @client.zremrangebyrank("key", 0, 1).should be == 2
330
- @client.zcard('key').should be == 1
388
+ expect(@client.zremrangebyrank("key", 0, 1)).to eq(2)
389
+ expect(@client.zcard('key')).to eq(1)
331
390
  end
332
391
 
333
392
  it 'handles out of range requests' do
@@ -335,12 +394,12 @@ module FakeRedis
335
394
  @client.zadd("key", 2, "two")
336
395
  @client.zadd("key", 3, "three")
337
396
 
338
- @client.zremrangebyrank("key", 25, -1).should be == 0
339
- @client.zcard('key').should be == 3
397
+ expect(@client.zremrangebyrank("key", 25, -1)).to eq(0)
398
+ expect(@client.zcard('key')).to eq(3)
340
399
  end
341
400
 
342
401
  it "should return 0 if the key didn't exist" do
343
- @client.zremrangebyrank("key", 0, 1).should be == 0
402
+ expect(@client.zremrangebyrank("key", 0, 1)).to eq(0)
344
403
  end
345
404
  end
346
405
 
@@ -356,66 +415,66 @@ module FakeRedis
356
415
  end
357
416
 
358
417
  it "should union two keys with custom scores" do
359
- @client.zunionstore("out", %w(key1 key2)).should be == 3
360
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", 1], ["val2", (2 + 5)], ["val3", (3 + 7)]]
418
+ expect(@client.zunionstore("out", %w(key1 key2))).to eq(3)
419
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", 1], ["val2", (2 + 5)], ["val3", (3 + 7)]])
361
420
  end
362
421
 
363
422
  it "should union two keys with a default score" do
364
- @client.zunionstore("out", %w(key1 key3)).should be == 3
365
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", (1 + 1)], ["val2", (2 + 1)], ["val3", 3]]
423
+ expect(@client.zunionstore("out", %w(key1 key3))).to eq(3)
424
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", (1 + 1)], ["val2", (2 + 1)], ["val3", 3]])
366
425
  end
367
426
 
368
427
  it "should union more than two keys" do
369
- @client.zunionstore("out", %w(key1 key2 key3)).should be == 3
370
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", (1 + 1)], ["val2", (2 + 5 + 1)], ["val3", (3 + 7)]]
428
+ expect(@client.zunionstore("out", %w(key1 key2 key3))).to eq(3)
429
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", (1 + 1)], ["val2", (2 + 5 + 1)], ["val3", (3 + 7)]])
371
430
  end
372
431
 
373
432
  it "should union with an unknown key" do
374
- @client.zunionstore("out", %w(key1 no_key)).should be == 3
375
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", 1], ["val2", 2], ["val3", 3]]
433
+ expect(@client.zunionstore("out", %w(key1 no_key))).to eq(3)
434
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", 1], ["val2", 2], ["val3", 3]])
376
435
  end
377
436
 
378
437
  it "should union two keys by minimum values" do
379
- @client.zunionstore("out", %w(key1 key2), :aggregate => :min).should be == 3
380
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", 1], ["val2", 2], ["val3", 3]]
438
+ expect(@client.zunionstore("out", %w(key1 key2), :aggregate => :min)).to eq(3)
439
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", 1], ["val2", 2], ["val3", 3]])
381
440
  end
382
441
 
383
442
  it "should union two keys by maximum values" do
384
- @client.zunionstore("out", %w(key1 key2), :aggregate => :max).should be == 3
385
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", 1], ["val2", 5], ["val3", 7]]
443
+ expect(@client.zunionstore("out", %w(key1 key2), :aggregate => :max)).to eq(3)
444
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", 1], ["val2", 5], ["val3", 7]])
386
445
  end
387
446
 
388
447
  it "should union two keys by explicitly summing values" do
389
- @client.zunionstore("out", %w(key1 key2), :aggregate => :sum).should be == 3
390
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", 1], ["val2", (2 + 5)], ["val3", (3 + 7)]]
448
+ expect(@client.zunionstore("out", %w(key1 key2), :aggregate => :sum)).to eq(3)
449
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", 1], ["val2", (2 + 5)], ["val3", (3 + 7)]])
391
450
  end
392
451
 
393
452
  it "should union two keys with weighted values" do
394
- @client.zunionstore("out", %w(key1 key2), :weights => [10, 1]).should be == 3
395
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", (1 * 10)], ["val2", (2 * 10 + 5)], ["val3", (3 * 10 + 7)]]
453
+ expect(@client.zunionstore("out", %w(key1 key2), :weights => [10, 1])).to eq(3)
454
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", (1 * 10)], ["val2", (2 * 10 + 5)], ["val3", (3 * 10 + 7)]])
396
455
  end
397
456
 
398
457
  it "should union two keys with weighted minimum values" do
399
- @client.zunionstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :min).should be == 3
400
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val2", 5], ["val3", 7], ["val1", (1 * 10)]]
458
+ expect(@client.zunionstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :min)).to eq(3)
459
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val2", 5], ["val3", 7], ["val1", (1 * 10)]])
401
460
  end
402
461
 
403
462
  it "should union two keys with weighted maximum values" do
404
- @client.zunionstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :max).should be == 3
405
- @client.zrange("out", 0, -1, :with_scores => true).should be == [["val1", (1 * 10)], ["val2", (2 * 10)], ["val3", (3 * 10)]]
463
+ expect(@client.zunionstore("out", %w(key1 key2), :weights => [10, 1], :aggregate => :max)).to eq(3)
464
+ expect(@client.zrange("out", 0, -1, :with_scores => true)).to eq([["val1", (1 * 10)], ["val2", (2 * 10)], ["val3", (3 * 10)]])
406
465
  end
407
466
 
408
467
  it "should error without enough weights given" do
409
- lambda { @client.zunionstore("out", %w(key1 key2), :weights => []) }.should raise_error(Redis::CommandError, "ERR syntax error")
410
- lambda { @client.zunionstore("out", %w(key1 key2), :weights => [10]) }.should raise_error(Redis::CommandError, "ERR syntax error")
468
+ expect { @client.zunionstore("out", %w(key1 key2), :weights => []) }.to raise_error(Redis::CommandError, "ERR syntax error")
469
+ expect { @client.zunionstore("out", %w(key1 key2), :weights => [10]) }.to raise_error(Redis::CommandError, "ERR syntax error")
411
470
  end
412
471
 
413
472
  it "should error with too many weights given" do
414
- lambda { @client.zunionstore("out", %w(key1 key2), :weights => [10, 1, 1]) }.should raise_error(Redis::CommandError, "ERR syntax error")
473
+ expect { @client.zunionstore("out", %w(key1 key2), :weights => [10, 1, 1]) }.to raise_error(Redis::CommandError, "ERR syntax error")
415
474
  end
416
475
 
417
476
  it "should error with an invalid aggregate" do
418
- lambda { @client.zunionstore("out", %w(key1 key2), :aggregate => :invalid) }.should raise_error(Redis::CommandError, "ERR syntax error")
477
+ expect { @client.zunionstore("out", %w(key1 key2), :aggregate => :invalid) }.to raise_error(Redis::CommandError, "ERR syntax error")
419
478
  end
420
479
  end
421
480
 
@@ -434,7 +493,280 @@ module FakeRedis
434
493
  it "zrem should remove members add by zadd" do
435
494
  @client.zadd("key1", 1, 3)
436
495
  @client.zrem("key1", 3)
437
- @client.zscore("key1", 3).should be_nil
496
+ expect(@client.zscore("key1", 3)).to be_nil
497
+ end
498
+
499
+ describe "#zscan" do
500
+ before { 50.times { |x| @client.zadd("key", x, "key #{x}") } }
501
+
502
+ it 'with no arguments should return 10 numbers in ascending order' do
503
+ result = @client.zscan("key", 0)[1]
504
+ expect(result).to eq(result.sort { |x, y| x[1] <=> y[1] })
505
+ expect(result.count).to eq(10)
506
+ end
507
+
508
+ it 'with a count should return that number of members' do
509
+ expect(@client.zscan("key", 0, count: 2)).to eq(["2", [["key 0", 0.0], ["key 1", 1.0]]])
510
+ end
511
+
512
+ it 'with a count greater than the number of members, returns all the members in asc order' do
513
+ result = @client.zscan("key", 0, count: 1000)[1]
514
+ expect(result).to eq(result.sort { |x, y| x[1] <=> y[1] })
515
+ expect(result.size).to eq(50)
516
+ end
517
+
518
+ it 'with match, should return key-values where the key matches' do
519
+ @client.zadd("key", 1.0, "blah")
520
+ @client.zadd("key", 2.0, "bluh")
521
+ result = @client.zscan("key", 0, count: 100, match: "key*")[1]
522
+ expect(result).to_not include(["blah", 1.0])
523
+ expect(result).to_not include(["bluh", 2.0])
524
+ end
525
+ end
526
+
527
+ describe "#zscan_each" do
528
+ before { 50.times { |x| @client.zadd("key", x, "key #{x}") } }
529
+
530
+ it 'enumerates over the items in the sorted set' do
531
+ expect(@client.zscan_each("key").to_a).to eq(@client.zscan("key", 0, count: 50)[1])
532
+ end
533
+ end
534
+
535
+ describe '#zrangebylex' do
536
+ before { @client.zadd "myzset", [0, 'a', 0, 'b', 0, 'd', 0, 'c'] }
537
+
538
+ it "should return empty list for '+'..'-' range" do
539
+ ranged = @client.zrangebylex "myzset", "+", "-"
540
+ expect(ranged).to be_empty
541
+ end
542
+
543
+ it "should return all elements for '-'..'+' range" do
544
+ ranged = @client.zrangebylex "myzset", "-", "+"
545
+ expect(ranged).to eq %w(a b c d)
546
+ end
547
+
548
+ it "should include values starting with [ symbol" do
549
+ ranged = @client.zrangebylex "myzset", "-", "[c"
550
+ expect(ranged).to eq %w(a b c)
551
+ end
552
+
553
+ it "should exclude values with ( symbol" do
554
+ ranged = @client.zrangebylex "myzset", "-", "(c"
555
+ expect(ranged).to eq %w(a b)
556
+ end
557
+
558
+ it "should work with both [ and ( properly" do
559
+ ranged = @client.zrangebylex "myzset", "[aaa", "(d"
560
+ expect(ranged).to eq %w(b c)
561
+ end
562
+
563
+ it "should return empty array if key is not exist" do
564
+ ranged = @client.zrangebylex "puppies", "-", "+"
565
+ expect(ranged).to be_empty
566
+ end
567
+
568
+ it 'should raise error for invalid range when range is invalid' do
569
+ expect{ @client.zrangebylex "myzset", "-", "d" }.to raise_error(Redis::CommandError, "ERR min or max not valid string range item")
570
+ end
571
+
572
+ it "should limit and offset values as 4th argument" do
573
+ ranged = @client.zrangebylex "myzset", "-", "+", limit: [1, 3]
574
+ expect(ranged).to eq %w(b c d)
575
+ end
576
+ end
577
+
578
+ describe "#zrevrangebylex" do
579
+ before { @client.zadd "myzset", [0, 'a', 0, 'b', 0, 'd', 0, 'c'] }
580
+
581
+ it "should return empty list for '-'..'+' range" do
582
+ ranged = @client.zrevrangebylex "myzset", "-", "+"
583
+ expect(ranged).to be_empty
584
+ end
585
+
586
+ it "should return all elements for '+'..'-' range in descending order" do
587
+ ranged = @client.zrevrangebylex "myzset", "+", "-"
588
+ expect(ranged).to eq %w(d c b a)
589
+ end
590
+
591
+ it "should include values starting with [ symbol" do
592
+ ranged = @client.zrevrangebylex "myzset", "[c", "-"
593
+ expect(ranged).to eq %w(c b a)
594
+ end
595
+
596
+ it "should exclude values with ( symbol" do
597
+ ranged = @client.zrevrangebylex "myzset", "+", "(c"
598
+ expect(ranged).to eq %w(d)
599
+ end
600
+
601
+ it "should work with both [ and ( properly" do
602
+ ranged = @client.zrevrangebylex "myzset", "(d", "[aaa"
603
+ expect(ranged).to eq %w(c b)
604
+ end
605
+
606
+ it "should return empty array if key does not exist" do
607
+ ranged = @client.zrevrangebylex "puppies", "+", "-"
608
+ expect(ranged).to be_empty
609
+ end
610
+
611
+ it 'should raise error for invalid range when range is invalid' do
612
+ expect { @client.zrevrangebylex "myzset", "-", "d" }.to raise_error(Redis::CommandError, "ERR min or max not valid string range item")
613
+ end
614
+
615
+ it "should limit and offset values as 4th argument" do
616
+ pending "current stable (3.2.0) redis-rb doesn't support limit option"
617
+
618
+ ranged = @client.zrevrangebylex "myzset", "+", "-", limit: [0, 3]
619
+ expect(ranged).to eq %w(d c b)
620
+ end
621
+ end
622
+
623
+ describe "#zadd" do
624
+ context "with {incr: true}" do
625
+ before { @client.zadd("key", 1, "existing") }
626
+ it "should increment the element's score with the provided value" do
627
+ @client.zadd("key", 99, "existing", incr: true)
628
+ expect(@client.zscore("key", "existing")).to eq(100.0)
629
+
630
+ @client.zadd("key", 2, "new", incr: true)
631
+ expect(@client.zscore("key", "new")).to eq(2.0)
632
+ end
633
+
634
+ it "should error when trying to add multiple increment-element pairs" do
635
+ expect {
636
+ @client.zadd("key", [1, "member1", 2, "member2"], incr: true)
637
+ }.to raise_error(Redis::CommandError, "ERR INCR option supports a single increment-element pair")
638
+ end
639
+ end
640
+
641
+ context "with {nx: true}" do
642
+ before { @client.zadd("key", [1, "existing1", 2, "existing2"]) }
643
+ it "should add new elements but not update the scores of existing elements" do
644
+ @client.zadd("key", [101, "existing1", 3, "new"], nx: true)
645
+
646
+ expect(@client.zscore("key", "existing1")).to eq(1.0)
647
+ expect(@client.zscore("key", "new")).to eq(3.0)
648
+
649
+ @client.zadd("key", 102, "existing2", nx: true)
650
+ expect(@client.zscore("key", "existing2")).to eq(2.0)
651
+ end
652
+ end
653
+
654
+ context "with {xx: true}" do
655
+ before { @client.zadd("key", 1, "existing") }
656
+ it "should not add new elements" do
657
+ expect(@client.zadd("key", 1, "new1", xx: true)).to eq(false)
658
+ expect(@client.zscore("key", "new1")).to be_nil
659
+
660
+ expect(@client.zadd("key", [11, "existing", 2, "new2"], xx: true)).to eq(0)
661
+ expect(@client.zscore("key", "existing")).to eq(11.0)
662
+ expect(@client.zscore("key", "new2")).to be_nil
663
+ end
664
+ end
665
+
666
+ context "with {ch: true}" do
667
+ it "should return the number of new elements added plus the number of existing elements for which the score was updated" do
668
+ expect(@client.zadd("key", 1, "first", ch: true)).to eq(true)
669
+
670
+ expect(@client.zadd("key", [1, "first", 2, "second"], ch: true)).to eq(1.0)
671
+ expect(@client.zadd("key", [11, "first", 2, "second"], ch: true)).to eq(1.0)
672
+ expect(@client.zadd("key", [99, "first", 99, "second"], ch: true)).to eq(2.0)
673
+ expect(@client.zadd("key", [111, "first", 22, "second", 3, "third"], ch: true)).to eq(3.0)
674
+ end
675
+ end
676
+
677
+ context "with {nx: true, xx: true}" do
678
+ it "should error" do
679
+ expect{
680
+ @client.zadd("key", 1, "value", nx: true, xx: true)
681
+ }.to raise_error(Redis::CommandError, "ERR XX and NX options at the same time are not compatible")
682
+ end
683
+ end
684
+
685
+ context "with {nx: true, incr: true}" do
686
+ let(:options) { {nx: true, incr: true} }
687
+ it "should increment to the provided score only if the element is new and return the element's score" do
688
+ expect(@client.zadd("key", 1, "first", options)).to eq(1.0)
689
+ expect(@client.zscore("key", "first")).to eq(1.0)
690
+
691
+ expect(@client.zadd("key", 2, "second", options)).to eq(2.0)
692
+ expect(@client.zscore("key", "second")).to eq(2.0)
693
+
694
+ expect(@client.zadd("key", 99, "first", options)).to be_nil
695
+ expect(@client.zscore("key", "first")).to eq(1.0)
696
+ end
697
+ end
698
+
699
+ context "with {nx: true, ch: true}" do
700
+ let(:options) { {nx: true, ch: true} }
701
+ it "should add only new elements, not update existing elements, and return the number of added elements" do
702
+ expect(@client.zadd("key", 1, "first", options)).to eq(true)
703
+ expect(@client.zadd("key", 1, "first", options)).to eq(false)
704
+
705
+ # add two new elements
706
+ expect(@client.zadd("key", [99, "first", 2, "second", 3, "third"], options)).to eq(2)
707
+ expect(@client.zscore("key", "first")).to eq(1.0)
708
+ end
709
+ end
710
+
711
+ context "with {nx: true, incr: true, ch: true}" do
712
+ let(:options) { {nx: true, incr: true, ch: true} }
713
+
714
+ it "should add only new elements" do
715
+ expect(@client.zadd("key", 1, "first", options)).to eq(1.0)
716
+ expect(@client.zadd("key", 99, "first", options)).to be_nil
717
+ expect(@client.zscore("key", "first")).to eq(1.0)
718
+ end
719
+
720
+ # when INCR is present, return value is always the new score of member
721
+ it "should return the score of the new member" do
722
+ expect(@client.zadd("key", 2, "second", options)).to eq(2.0)
723
+ end
724
+
725
+ it "should return nil when the member already exists" do
726
+ @client.zadd("key", 1, "first")
727
+ expect(@client.zadd("key", 99, "first", options)).to be_nil
728
+ end
729
+ end
730
+
731
+ context "with {xx: true, incr: true}" do
732
+ let(:options) { {xx: true, incr: true} }
733
+ before { @client.zadd("key", 1, "existing") }
734
+
735
+ it "should return nil if the member does not already exist" do
736
+ expect(@client.zadd("key", 1, "new1", options)).to be_nil
737
+ expect(@client.zscore("key", "new1")).to be_nil
738
+ end
739
+
740
+ it "should increment only existing elements" do
741
+ expect(@client.zadd("key", [11, "existing"], options)).to eq(12.0)
742
+ expect(@client.zscore("key", "existing")).to eq(12.0)
743
+ end
744
+ end
745
+
746
+ context "with {xx: true, ch: true}" do
747
+ let(:options) { {xx: true, ch: true} }
748
+ it "should return the number of updated elements and not add new members" do
749
+ @client.zadd("key", 1, "first")
750
+
751
+ expect(@client.zadd("key", 99, "first", options)).to eq(true)
752
+ expect(@client.zadd("key", [100, "first", 2, "second"], options)).to eq(1.0)
753
+ expect(@client.zscore("key", "second")).to be_nil
754
+ end
755
+ end
756
+
757
+ context "with {xx: true, incr: true, ch: true}" do
758
+ let(:options) { {xx: true, incr: true, ch: true} }
759
+ before { @client.zadd("key", 1, "existing") }
760
+
761
+ # when INCR is present, return value is always the new score of member
762
+ it "should return the new score of the inserted member" do
763
+ expect(@client.zadd("key", 2, "existing", options)).to eq(3.0)
764
+ end
765
+
766
+ it "should increment only existing elements" do
767
+ expect(@client.zadd("key", 1, "new", options)).to be_nil
768
+ end
769
+ end
438
770
  end
439
771
  end
440
772
  end