rediska 0.0.2

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