rediska 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,175 @@
1
+ shared_examples 'sets' do
2
+ it 'should add a member to a set' do
3
+ subject.sadd('key', 'value').should be_true
4
+ subject.sadd('key', 'value').should be_false
5
+
6
+ subject.smembers('key').should =~ ['value']
7
+ end
8
+
9
+ it 'should raise error if command arguments count is not enough' do
10
+ expect {
11
+ subject.sadd('key', [])
12
+ }.to raise_error(Redis::CommandError)
13
+
14
+ expect {
15
+ subject.sinter(*[])
16
+ }.to raise_error(Redis::CommandError)
17
+
18
+ subject.smembers('key').should be_empty
19
+ end
20
+
21
+ it 'should add multiple members to a set' do
22
+ subject.sadd('key', %w(value other something more)).should eq(4)
23
+ subject.sadd('key', %w(and additional values)).should eq(3)
24
+ subject.smembers('key').should =~ ['value', 'other', 'something', 'more', 'and', 'additional', 'values']
25
+ end
26
+
27
+ it 'should get the number of members in a set' do
28
+ subject.sadd('key', 'val1')
29
+ subject.sadd('key', 'val2')
30
+
31
+ subject.scard('key').should eq(2)
32
+ end
33
+
34
+ it 'should subtract multiple sets' do
35
+ subject.sadd('key1', 'a')
36
+ subject.sadd('key1', 'b')
37
+ subject.sadd('key1', 'c')
38
+ subject.sadd('key1', 'd')
39
+ subject.sadd('key2', 'c')
40
+ subject.sadd('key3', 'a')
41
+ subject.sadd('key3', 'c')
42
+ subject.sadd('key3', 'e')
43
+
44
+ subject.sdiff('key1', 'key2', 'key3').should =~ ['b', 'd']
45
+ end
46
+
47
+ it 'should subtract multiple sets and store the resulting set in a key' do
48
+ subject.sadd('key1', 'a')
49
+ subject.sadd('key1', 'b')
50
+ subject.sadd('key1', 'c')
51
+ subject.sadd('key1', 'd')
52
+ subject.sadd('key2', 'c')
53
+ subject.sadd('key3', 'a')
54
+ subject.sadd('key3', 'c')
55
+ subject.sadd('key3', 'e')
56
+ subject.sdiffstore('key', 'key1', 'key2', 'key3')
57
+
58
+ subject.smembers('key').should =~ ['b', 'd']
59
+ end
60
+
61
+ it 'should intersect multiple sets' do
62
+ subject.sadd('key1', 'a')
63
+ subject.sadd('key1', 'b')
64
+ subject.sadd('key1', 'c')
65
+ subject.sadd('key1', 'd')
66
+ subject.sadd('key2', 'c')
67
+ subject.sadd('key3', 'a')
68
+ subject.sadd('key3', 'c')
69
+ subject.sadd('key3', 'e')
70
+
71
+ subject.sinter('key1', 'key2', 'key3').should =~ ['c']
72
+ end
73
+
74
+ it 'should intersect multiple sets and store the resulting set in a key' do
75
+ subject.sadd('key1', 'a')
76
+ subject.sadd('key1', 'b')
77
+ subject.sadd('key1', 'c')
78
+ subject.sadd('key1', 'd')
79
+ subject.sadd('key2', 'c')
80
+ subject.sadd('key3', 'a')
81
+ subject.sadd('key3', 'c')
82
+ subject.sadd('key3', 'e')
83
+ subject.sinterstore('key', 'key1', 'key2', 'key3')
84
+ subject.smembers('key').should =~ ['c']
85
+ end
86
+
87
+ it 'should determine if a given value is a member of a set' do
88
+ subject.sadd('key1', 'a')
89
+
90
+ subject.sismember('key1', 'a').should be_true
91
+ subject.sismember('key1', 'b').should be_false
92
+ subject.sismember('key2', 'a').should be_false
93
+ end
94
+
95
+ it 'should get all the members in a set' do
96
+ subject.sadd('key', 'a')
97
+ subject.sadd('key', 'b')
98
+ subject.sadd('key', 'c')
99
+ subject.sadd('key', 'd')
100
+
101
+ subject.smembers('key').should =~ ['a', 'b', 'c', 'd']
102
+ end
103
+
104
+ it 'should move a member from one set to another' do
105
+ subject.sadd('key1', 'a')
106
+ subject.sadd('key1', 'b')
107
+ subject.sadd('key2', 'c')
108
+ subject.smove('key1', 'key2', 'a').should be_true
109
+ subject.smove('key1', 'key2', 'a').should be_false
110
+
111
+ subject.smembers('key1').should =~ ['b']
112
+ subject.smembers('key2').should =~ ['c', 'a']
113
+ end
114
+
115
+ it 'should remove and return a random member from a set' do
116
+ subject.sadd('key1', 'a')
117
+ subject.sadd('key1', 'b')
118
+
119
+ ['a', 'b'].include?(subject.spop('key1')).should be_true
120
+ ['a', 'b'].include?(subject.spop('key1')).should be_true
121
+ subject.spop('key1').should be_nil
122
+ end
123
+
124
+ it 'should get a random member from a set' do
125
+ subject.sadd('key1', 'a')
126
+ subject.sadd('key1', 'b')
127
+
128
+ ['a', 'b'].include?(subject.spop('key1')).should be_true
129
+ end
130
+
131
+ it 'should remove a member from a set' do
132
+ subject.sadd('key1', 'a')
133
+ subject.sadd('key1', 'b')
134
+ subject.srem('key1', 'a').should be_true
135
+ subject.srem('key1', 'a').should be_false
136
+
137
+ subject.smembers('key1').should =~ ['b']
138
+ end
139
+
140
+ it "should remove the set's key once it's empty" do
141
+ subject.sadd('key1', 'a')
142
+ subject.sadd('key1', 'b')
143
+ subject.srem('key1', 'b')
144
+ subject.srem('key1', 'a')
145
+
146
+ subject.exists('key1').should be_false
147
+ end
148
+
149
+ it 'should add multiple sets' do
150
+ subject.sadd('key1', 'a')
151
+ subject.sadd('key1', 'b')
152
+ subject.sadd('key1', 'c')
153
+ subject.sadd('key1', 'd')
154
+ subject.sadd('key2', 'c')
155
+ subject.sadd('key3', 'a')
156
+ subject.sadd('key3', 'c')
157
+ subject.sadd('key3', 'e')
158
+
159
+ subject.sunion('key1', 'key2', 'key3').should =~ ['a', 'b', 'c', 'd', 'e']
160
+ end
161
+
162
+ it 'should add multiple sets and store the resulting set in a key' do
163
+ subject.sadd('key1', 'a')
164
+ subject.sadd('key1', 'b')
165
+ subject.sadd('key1', 'c')
166
+ subject.sadd('key1', 'd')
167
+ subject.sadd('key2', 'c')
168
+ subject.sadd('key3', 'a')
169
+ subject.sadd('key3', 'c')
170
+ subject.sadd('key3', 'e')
171
+ subject.sunionstore('key', 'key1', 'key2', 'key3')
172
+
173
+ subject.smembers('key').should =~ ['a', 'b', 'c', 'd', 'e']
174
+ end
175
+ end
@@ -0,0 +1,447 @@
1
+ shared_examples 'sorted sets' do
2
+ let(:infinity) { 1.0 / 0.0 }
3
+
4
+ before(:each) do
5
+ subject = Redis.new
6
+ end
7
+
8
+ it 'should add a member to a sorted set, or update its score if it already exists' do
9
+ subject.zadd('key', 1, 'val').should be_true
10
+ subject.zscore('key', 'val').should eq(1.0)
11
+
12
+ subject.zadd('key', 2, 'val').should be_false
13
+ subject.zscore('key', 'val').should eq(2.0)
14
+
15
+ subject.zadd('key2', 'inf', 'val').should be_true
16
+ subject.zscore('key2', 'val').should eq(infinity)
17
+
18
+ subject.zadd('key3', '+inf', 'val').should be_true
19
+ subject.zscore('key3', 'val').should eq(infinity)
20
+
21
+ subject.zadd('key4', '-inf', 'val').should be_true
22
+ subject.zscore('key4', 'val').should eq(-infinity)
23
+ end
24
+
25
+ it 'should return a nil score for value not in a sorted set or empty key' do
26
+ subject.zadd('key', 1, 'val')
27
+
28
+ subject.zscore('key', 'val').should eq(1.0)
29
+ subject.zscore('key', 'val2').should be_nil
30
+ subject.zscore('key2', 'val').should be_nil
31
+ end
32
+
33
+ it 'should add multiple members to a sorted set, or update its score if it already exists' do
34
+ subject.zadd('key', [1, 'val', 2, 'val2']).should eq(2)
35
+ subject.zscore('key', 'val').should eq(1)
36
+ subject.zscore('key', 'val2').should eq(2)
37
+
38
+ subject.zadd('key', [[5, 'val'], [3, 'val3'], [4, 'val4']]).should eq(2)
39
+ subject.zscore('key', 'val').should eq(5)
40
+ subject.zscore('key', 'val2').should eq(2)
41
+ subject.zscore('key', 'val3').should eq(3)
42
+ subject.zscore('key', 'val4').should eq(4)
43
+
44
+ subject.zadd('key', [[5, 'val5'], [3, 'val6']]).should eq(2)
45
+ subject.zscore('key', 'val5').should eq(5)
46
+ subject.zscore('key', 'val6').should eq(3)
47
+ end
48
+
49
+ it 'should error with wrong number of arguments when adding members' do
50
+ expect {
51
+ subject.zadd('key')
52
+ }.to raise_error(ArgumentError)
53
+
54
+ expect {
55
+ subject.zadd('key', 1)
56
+ }.to raise_error(ArgumentError)
57
+
58
+ expect {
59
+ subject.zadd('key', [1])
60
+ }.to raise_error(Redis::CommandError)
61
+
62
+ expect {
63
+ subject.zadd('key', [1, 'val', 2])
64
+ }.to raise_error(Redis::CommandError)
65
+
66
+ expect {
67
+ subject.zadd('key', [[1, 'val'], [2]])
68
+ }.to raise_error(Redis::CommandError)
69
+ end
70
+
71
+ it 'should allow floats as scores when adding or updating' do
72
+ subject.zadd('key', 4.321, 'val').should be_true
73
+ subject.zscore('key', 'val').should eq(4.321)
74
+
75
+ subject.zadd('key', 54.3210, 'val').should be_false
76
+ subject.zscore('key', 'val').should eq(54.321)
77
+ end
78
+
79
+ it 'should remove members from sorted sets' do
80
+ subject.zrem('key', 'val').should be_false
81
+ subject.zadd('key', 1, 'val').should be_true
82
+ subject.zrem('key', 'val').should be_true
83
+ end
84
+
85
+ it 'should remove multiple members from sorted sets' do
86
+ subject.zrem('key2', %w(val)).should eq(0)
87
+ subject.zrem('key2', %w(val val2 val3)).should eq(0)
88
+
89
+ subject.zadd('key2', 1, 'val')
90
+ subject.zadd('key2', 1, 'val2')
91
+ subject.zadd('key2', 1, 'val3')
92
+
93
+ subject.zrem('key2', %w(val val2 val3 val4)).should eq(3)
94
+ end
95
+
96
+ it "should remove sorted set's key when it is empty" do
97
+ subject.zadd('key', 1, 'val')
98
+ subject.zrem('key', 'val')
99
+ subject.exists('key').should be_false
100
+ end
101
+
102
+ it 'should get the number of members in a sorted set' do
103
+ subject.zadd('key', 1, 'val2')
104
+ subject.zadd('key', 2, 'val1')
105
+ subject.zadd('key', 5, 'val3')
106
+
107
+ subject.zcard('key').should eq(3)
108
+ end
109
+
110
+ it 'should count the members in a sorted set with scores within the given values' do
111
+ subject.zadd('key', 1, 'val1')
112
+ subject.zadd('key', 2, 'val2')
113
+ subject.zadd('key', 3, 'val3')
114
+
115
+ subject.zcount('key', 2, 3).should eq(2)
116
+ end
117
+
118
+ it 'should increment the score of a member in a sorted set' do
119
+ subject.zadd('key', 1, 'val1')
120
+ subject.zincrby('key', 2, 'val1').should eq(3)
121
+ subject.zscore('key', 'val1').should eq(3)
122
+ end
123
+
124
+ it 'initializes the sorted set if the key wasnt already set' do
125
+ subject.zincrby('key', 1, 'val1').should eq(1)
126
+ end
127
+
128
+ it 'should convert the key to a string for zscore' do
129
+ subject.zadd('key', 1, 1)
130
+ subject.zscore('key', 1).should eq(1)
131
+ end
132
+
133
+ # These won't pass until redis-rb releases v3.0.2
134
+ it 'should handle infinity values when incrementing a sorted set key' do
135
+ subject.zincrby('bar', '+inf', 's2').should eq(infinity)
136
+ subject.zincrby('bar', '-inf', 's1').should eq(-infinity)
137
+ end
138
+
139
+ it 'should return a range of members in a sorted set, by index' do
140
+ subject.zadd('key', 1, 'one')
141
+ subject.zadd('key', 2, 'two')
142
+ subject.zadd('key', 3, 'three')
143
+
144
+ subject.zrange('key', 0, -1).should eq(['one', 'two', 'three'])
145
+ subject.zrange('key', 1, 2).should eq(['two', 'three'])
146
+ subject.zrange('key', 0, -1, with_scores: true).should eq([['one', 1], ['two', 2], ['three', 3]])
147
+ subject.zrange('key', 1, 2, with_scores: true).should eq([['two', 2], ['three', 3]])
148
+ end
149
+
150
+ it 'should sort zrange results logically' do
151
+ subject.zadd('key', 5, 'val2')
152
+ subject.zadd('key', 5, 'val3')
153
+ subject.zadd('key', 5, 'val1')
154
+
155
+ subject.zrange('key', 0, -1).should eq(%w(val1 val2 val3))
156
+ subject.zrange('key', 0, -1, with_scores: true).should eq([['val1', 5], ['val2', 5], ['val3', 5]])
157
+ end
158
+
159
+ it 'should return a reversed range of members in a sorted set, by index' do
160
+ subject.zadd('key', 1, 'one')
161
+ subject.zadd('key', 2, 'two')
162
+ subject.zadd('key', 3, 'three')
163
+
164
+ subject.zrevrange('key', 0, -1).should eq(['three', 'two', 'one'])
165
+ subject.zrevrange('key', 1, 2).should eq(['two', 'one'])
166
+ subject.zrevrange('key', 0, -1, with_scores: true).should eq([['three', 3], ['two', 2], ['one', 1]])
167
+ subject.zrevrange('key', 0, -1, with_scores: true).should eq([['three', 3], ['two', 2], ['one', 1]])
168
+ end
169
+
170
+ it 'should return a range of members in a sorted set, by score' do
171
+ subject.zadd('key', 1, 'one')
172
+ subject.zadd('key', 2, 'two')
173
+ subject.zadd('key', 3, 'three')
174
+
175
+ subject.zrangebyscore('key', 0, 100).should eq(['one', 'two', 'three'])
176
+ subject.zrangebyscore('key', 1, 2).should eq(['one', 'two'])
177
+ subject.zrangebyscore('key', 0, 100, with_scores: true).should eq([['one', 1], ['two', 2], ['three', 3]])
178
+ subject.zrangebyscore('key', 1, 2, with_scores: true).should eq([['one', 1], ['two', 2]])
179
+ subject.zrangebyscore('key', 0, 100, limit: [0, 1]).should eq(['one'])
180
+ subject.zrangebyscore('key', 0, 100, limit: [0, -1]).should eq(['one', 'two', 'three'])
181
+ subject.zrangebyscore('key', 0, 100, limit: [1, -1], with_scores: true).should eq([['two', 2], ['three', 3]])
182
+ subject.zrangebyscore('key', '-inf', '+inf').should eq(['one', 'two', 'three'])
183
+ subject.zrangebyscore('key', 2, '+inf').should eq(['two', 'three'])
184
+ subject.zrangebyscore('key', '-inf', 2).should eq(['one', 'two'])
185
+ end
186
+
187
+ it 'should return a reversed range of members in a sorted set, by score' do
188
+ subject.zadd('key', 1, 'one')
189
+ subject.zadd('key', 2, 'two')
190
+ subject.zadd('key', 3, 'three')
191
+
192
+ subject.zrevrangebyscore('key', 100, 0).should eq(['three', 'two', 'one'])
193
+ subject.zrevrangebyscore('key', 2, 1).should eq(['two', 'one'])
194
+ subject.zrevrangebyscore('key', 1, 2).should be_empty
195
+ subject.zrevrangebyscore('key', 2, 1, with_scores: true).should eq([['two', 2], ['one', 1]])
196
+ subject.zrevrangebyscore('key', 100, 0, limit: [0, 1]).should eq(['three'])
197
+ subject.zrevrangebyscore('key', 100, 0, limit: [0, -1]).should eq(['three', 'two', 'one'])
198
+ subject.zrevrangebyscore('key', 100, 0, limit: [1, -1], with_scores: true).should eq([['two', 2], ['one', 1]])
199
+ end
200
+
201
+ it 'should determine the index of a member in a sorted set' do
202
+ subject.zadd('key', 1, 'one')
203
+ subject.zadd('key', 2, 'two')
204
+ subject.zadd('key', 3, 'three')
205
+
206
+ subject.zrank('key', 'three').should eq(2)
207
+ subject.zrank('key', 'four').should be_nil
208
+ end
209
+
210
+ it 'should determine the reversed index of a member in a sorted set' do
211
+ subject.zadd('key', 1, 'one')
212
+ subject.zadd('key', 2, 'two')
213
+ subject.zadd('key', 3, 'three')
214
+
215
+ subject.zrevrank('key', 'three').should eq(0)
216
+ subject.zrevrank('key', 'four').should be_nil
217
+ end
218
+
219
+ it 'should not raise errors for zrank() on accessing a non-existing key in a sorted set' do
220
+ subject.zrank('no_such_key', 'no_suck_id').should be_nil
221
+ end
222
+
223
+ it 'should not raise errors for zrevrank() on accessing a non-existing key in a sorted set' do
224
+ subject.zrevrank('no_such_key', 'no_suck_id').should be_nil
225
+ end
226
+
227
+ describe '#zinterstore' do
228
+ before do
229
+ subject.zadd('key1', 1, 'one')
230
+ subject.zadd('key1', 2, 'two')
231
+ subject.zadd('key1', 3, 'three')
232
+ subject.zadd('key2', 5, 'two')
233
+ subject.zadd('key2', 7, 'three')
234
+ subject.sadd('key3', 'one')
235
+ subject.sadd('key3', 'two')
236
+ end
237
+
238
+ it 'should intersect two keys with custom scores' do
239
+ subject.zinterstore('out', ['key1', 'key2']).should eq(2)
240
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', (2 + 5)], ['three', (3 + 7)]])
241
+ end
242
+
243
+ it 'should intersect two keys with a default score' do
244
+ subject.zinterstore('out', ['key1', 'key3']).should eq(2)
245
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['one', (1 + 1)], ['two', (2 + 1)]])
246
+ end
247
+
248
+ it 'should intersect more than two keys' do
249
+ subject.zinterstore('out', ['key1', 'key2', 'key3']).should eq(1)
250
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', (2 + 5 + 1)]])
251
+ end
252
+
253
+ it 'should not intersect an unknown key' do
254
+ subject.zinterstore('out', ['key1', 'no_key']).should eq(0)
255
+ subject.zrange('out', 0, -1, with_scores: true).should be_empty
256
+ end
257
+
258
+ it 'should intersect two keys by minimum values' do
259
+ subject.zinterstore('out', ['key1', 'key2'], aggregate: :min).should eq(2)
260
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', 2], ['three', 3]])
261
+ end
262
+
263
+ it 'should intersect two keys by maximum values' do
264
+ subject.zinterstore('out', ['key1', 'key2'], aggregate: :max).should eq(2)
265
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', 5], ['three', 7]])
266
+ end
267
+
268
+ it 'should intersect two keys by explicitly summing values' do
269
+ subject.zinterstore('out', %w(key1 key2), aggregate: :sum).should eq(2)
270
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', (2 + 5)], ['three', (3 + 7)]])
271
+ end
272
+
273
+ it 'should intersect two keys with weighted values' do
274
+ subject.zinterstore('out', %w(key1 key2), weights: [10, 1]).should eq(2)
275
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', (2 * 10 + 5)], ['three', (3 * 10 + 7)]])
276
+ end
277
+
278
+ it 'should intersect two keys with weighted minimum values' do
279
+ subject.zinterstore('out', %w(key1 key2), weights: [10, 1], aggregate: :min).should eq(2)
280
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', 5], ['three', 7]])
281
+ end
282
+
283
+ it 'should intersect two keys with weighted maximum values' do
284
+ subject.zinterstore('out', %w(key1 key2), weights: [10, 1], aggregate: :max).should eq(2)
285
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['two', (2 * 10)], ['three', (3 * 10)]])
286
+ end
287
+
288
+ it 'should error without enough weights given' do
289
+ expect {
290
+ subject.zinterstore('out', %w(key1 key2), weights: [])
291
+ }.to raise_error(Redis::CommandError)
292
+
293
+ expect {
294
+ subject.zinterstore('out', %w(key1 key2), weights: [10])
295
+ }.to raise_error(Redis::CommandError)
296
+ end
297
+
298
+ it 'should error with too many weights given' do
299
+ expect {
300
+ subject.zinterstore('out', %w(key1 key2), weights: [10, 1, 1])
301
+ }.to raise_error(Redis::CommandError)
302
+ end
303
+
304
+ it 'should error with an invalid aggregate' do
305
+ expect {
306
+ subject.zinterstore('out', %w(key1 key2), aggregate: :invalid)
307
+ }.to raise_error(Redis::CommandError)
308
+ end
309
+ end
310
+
311
+ context 'zremrangebyscore' do
312
+ it 'should remove items by score' do
313
+ subject.zadd('key', 1, 'one')
314
+ subject.zadd('key', 2, 'two')
315
+ subject.zadd('key', 3, 'three')
316
+
317
+ subject.zremrangebyscore('key', 0, 2).should eq(2)
318
+ subject.zcard('key').should eq(1)
319
+ end
320
+
321
+ it 'should remove items by score with infinity' do # Issue #50
322
+ subject.zadd('key', 10.0, 'one')
323
+ subject.zadd('key', 20.0, 'two')
324
+ subject.zadd('key', 30.0, 'three')
325
+ subject.zremrangebyscore('key', '-inf', '+inf').should eq(3)
326
+ subject.zcard('key').should eq(0)
327
+ subject.zscore('key', 'one').should be_nil
328
+ subject.zscore('key', 'two').should be_nil
329
+ subject.zscore('key', 'three').should be_nil
330
+ end
331
+
332
+ it 'should return 0 if the key did not exist' do
333
+ subject.zremrangebyscore('key', 0, 2).should eq(0)
334
+ end
335
+ end
336
+
337
+ context '#zremrangebyrank' do
338
+ it 'removes all elements with in the given range' do
339
+ subject.zadd('key', 1, 'one')
340
+ subject.zadd('key', 2, 'two')
341
+ subject.zadd('key', 3, 'three')
342
+
343
+ subject.zremrangebyrank('key', 0, 1).should eq(2)
344
+ subject.zcard('key').should eq(1)
345
+ end
346
+
347
+ it 'handles out of range requests' do
348
+ subject.zadd('key', 1, 'one')
349
+ subject.zadd('key', 2, 'two')
350
+ subject.zadd('key', 3, 'three')
351
+
352
+ subject.zremrangebyrank('key', 25, -1).should eq(0)
353
+ subject.zcard('key').should eq(3)
354
+ end
355
+ end
356
+
357
+ describe '#zunionstore' do
358
+ before do
359
+ subject.zadd('key1', 1, 'val1')
360
+ subject.zadd('key1', 2, 'val2')
361
+ subject.zadd('key1', 3, 'val3')
362
+ subject.zadd('key2', 5, 'val2')
363
+ subject.zadd('key2', 7, 'val3')
364
+ subject.sadd('key3', 'val1')
365
+ subject.sadd('key3', 'val2')
366
+ end
367
+
368
+ it 'should union two keys with custom scores' do
369
+ subject.zunionstore('out', %w(key1 key2)).should eq(3)
370
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', 1], ['val2', (2 + 5)], ['val3', (3 + 7)]])
371
+ end
372
+
373
+ it 'should union two keys with a default score' do
374
+ subject.zunionstore('out', %w(key1 key3)).should eq(3)
375
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', (1 + 1)], ['val2', (2 + 1)], ['val3', 3]])
376
+ end
377
+
378
+ it 'should union more than two keys' do
379
+ subject.zunionstore('out', %w(key1 key2 key3)).should eq(3)
380
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', (1 + 1)], ['val2', (2 + 5 + 1)], ['val3', (3 + 7)]])
381
+ end
382
+
383
+ it 'should union with an unknown key' do
384
+ subject.zunionstore('out', %w(key1 no_key)).should eq(3)
385
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', 1], ['val2', 2], ['val3', 3]])
386
+ end
387
+
388
+ it 'should union two keys by minimum values' do
389
+ subject.zunionstore('out', %w(key1 key2), aggregate: :min).should eq(3)
390
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', 1], ['val2', 2], ['val3', 3]])
391
+ end
392
+
393
+ it 'should union two keys by maximum values' do
394
+ subject.zunionstore('out', %w(key1 key2), aggregate: :max).should eq(3)
395
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', 1], ['val2', 5], ['val3', 7]])
396
+ end
397
+
398
+ it 'should union two keys by explicitly summing values' do
399
+ subject.zunionstore('out', %w(key1 key2), aggregate: :sum).should eq(3)
400
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', 1], ['val2', (2 + 5)], ['val3', (3 + 7)]])
401
+ end
402
+
403
+ it 'should union two keys with weighted values' do
404
+ subject.zunionstore('out', %w(key1 key2), :weights => [10, 1]).should eq(3)
405
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', (1 * 10)], ['val2', (2 * 10 + 5)], ['val3', (3 * 10 + 7)]])
406
+ end
407
+
408
+ it 'should union two keys with weighted minimum values' do
409
+ subject.zunionstore('out', %w(key1 key2), weights: [10, 1], aggregate: :min).should eq(3)
410
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val2', 5], ['val3', 7], ['val1', (1 * 10)]])
411
+ end
412
+
413
+ it 'should union two keys with weighted maximum values' do
414
+ subject.zunionstore('out', %w(key1 key2), weights: [10, 1], aggregate: :max).should eq(3)
415
+ subject.zrange('out', 0, -1, with_scores: true).should eq([['val1', (1 * 10)], ['val2', (2 * 10)], ['val3', (3 * 10)]])
416
+ end
417
+
418
+ it 'should error without enough weights given' do
419
+ expect {
420
+ subject.zunionstore('out', %w(key1 key2), weights: [])
421
+ }.to raise_error(Redis::CommandError)
422
+
423
+ expect {
424
+ subject.zunionstore('out', %w(key1 key2), weights: [10])
425
+ }.to raise_error(Redis::CommandError)
426
+ end
427
+
428
+ it 'should error with too many weights given' do
429
+ expect {
430
+ subject.zunionstore('out', %w(key1 key2), weights: [10, 1, 1])
431
+ }.to raise_error(Redis::CommandError)
432
+ end
433
+
434
+ it 'should error with an invalid aggregate' do
435
+ expect {
436
+ subject.zunionstore('out', %w(key1 key2), aggregate: :invalid)
437
+ }.to raise_error(Redis::CommandError)
438
+ end
439
+ end
440
+
441
+ #it 'should remove all members in a sorted set within the given indexes'
442
+ #it 'should return a range of members in a sorted set, by index, with scores ordered from high to low'
443
+ #it 'should return a range of members in a sorted set, by score, with scores ordered from high to low'
444
+ #it 'should determine the index of a member in a sorted set, with scores ordered from high to low'
445
+ #it 'should get the score associated with the given member in a sorted set'
446
+ #it 'should add multiple sorted sets and store the resulting sorted set in a new key'
447
+ end