redis 3.3.5 → 4.0.3
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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis/Gemfile +8 -1
- data/.travis.yml +34 -62
- data/CHANGELOG.md +45 -2
- data/Gemfile +5 -1
- data/README.md +32 -76
- data/benchmarking/logging.rb +1 -1
- data/bin/build +71 -0
- data/bors.toml +14 -0
- data/lib/redis/client.rb +38 -20
- data/lib/redis/cluster/command.rb +81 -0
- data/lib/redis/cluster/command_loader.rb +32 -0
- data/lib/redis/cluster/key_slot_converter.rb +72 -0
- data/lib/redis/cluster/node.rb +104 -0
- data/lib/redis/cluster/node_key.rb +35 -0
- data/lib/redis/cluster/node_loader.rb +35 -0
- data/lib/redis/cluster/option.rb +76 -0
- data/lib/redis/cluster/slot.rb +69 -0
- data/lib/redis/cluster/slot_loader.rb +47 -0
- data/lib/redis/cluster.rb +285 -0
- data/lib/redis/connection/command_helper.rb +2 -8
- data/lib/redis/connection/hiredis.rb +2 -2
- data/lib/redis/connection/ruby.rb +13 -30
- data/lib/redis/connection/synchrony.rb +12 -4
- data/lib/redis/connection.rb +2 -2
- data/lib/redis/distributed.rb +29 -8
- data/lib/redis/errors.rb +46 -0
- data/lib/redis/hash_ring.rb +20 -64
- data/lib/redis/pipeline.rb +9 -7
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +287 -52
- data/makefile +74 -0
- data/redis.gemspec +9 -10
- data/test/bitpos_test.rb +13 -19
- data/test/blocking_commands_test.rb +3 -5
- data/test/client_test.rb +18 -1
- data/test/cluster_abnormal_state_test.rb +38 -0
- data/test/cluster_blocking_commands_test.rb +15 -0
- data/test/cluster_client_internals_test.rb +77 -0
- data/test/cluster_client_key_hash_tags_test.rb +88 -0
- data/test/cluster_client_options_test.rb +147 -0
- data/test/cluster_client_pipelining_test.rb +59 -0
- data/test/cluster_client_replicas_test.rb +36 -0
- data/test/cluster_client_slots_test.rb +94 -0
- data/test/cluster_client_transactions_test.rb +71 -0
- data/test/cluster_commands_on_cluster_test.rb +165 -0
- data/test/cluster_commands_on_connection_test.rb +40 -0
- data/test/cluster_commands_on_geo_test.rb +74 -0
- data/test/cluster_commands_on_hashes_test.rb +11 -0
- data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
- data/test/cluster_commands_on_keys_test.rb +134 -0
- data/test/cluster_commands_on_lists_test.rb +15 -0
- data/test/cluster_commands_on_pub_sub_test.rb +101 -0
- data/test/cluster_commands_on_scripting_test.rb +56 -0
- data/test/cluster_commands_on_server_test.rb +221 -0
- data/test/cluster_commands_on_sets_test.rb +39 -0
- data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
- data/test/cluster_commands_on_streams_test.rb +196 -0
- data/test/cluster_commands_on_strings_test.rb +15 -0
- data/test/cluster_commands_on_transactions_test.rb +41 -0
- data/test/cluster_commands_on_value_types_test.rb +14 -0
- data/test/command_map_test.rb +3 -5
- data/test/commands_on_geo_test.rb +116 -0
- data/test/commands_on_hashes_test.rb +2 -16
- data/test/commands_on_hyper_log_log_test.rb +3 -17
- data/test/commands_on_lists_test.rb +2 -15
- data/test/commands_on_sets_test.rb +2 -72
- data/test/commands_on_sorted_sets_test.rb +2 -132
- data/test/commands_on_strings_test.rb +2 -96
- data/test/commands_on_value_types_test.rb +80 -6
- data/test/connection_handling_test.rb +5 -7
- data/test/distributed_blocking_commands_test.rb +10 -4
- data/test/distributed_commands_on_hashes_test.rb +16 -5
- data/test/distributed_commands_on_hyper_log_log_test.rb +8 -15
- data/test/distributed_commands_on_lists_test.rb +4 -7
- data/test/distributed_commands_on_sets_test.rb +58 -36
- data/test/distributed_commands_on_sorted_sets_test.rb +51 -10
- data/test/distributed_commands_on_strings_test.rb +30 -10
- data/test/distributed_commands_on_value_types_test.rb +38 -4
- data/test/distributed_commands_requiring_clustering_test.rb +1 -3
- data/test/distributed_connection_handling_test.rb +1 -3
- data/test/distributed_internals_test.rb +8 -19
- data/test/distributed_key_tags_test.rb +4 -6
- data/test/distributed_persistence_control_commands_test.rb +1 -3
- data/test/distributed_publish_subscribe_test.rb +1 -3
- data/test/distributed_remote_server_control_commands_test.rb +1 -3
- data/test/distributed_scripting_test.rb +1 -3
- data/test/distributed_sorting_test.rb +1 -3
- data/test/distributed_test.rb +12 -14
- data/test/distributed_transactions_test.rb +1 -3
- data/test/encoding_test.rb +4 -8
- data/test/error_replies_test.rb +2 -4
- data/test/fork_safety_test.rb +1 -6
- data/test/helper.rb +179 -66
- data/test/helper_test.rb +1 -3
- data/test/internals_test.rb +47 -56
- data/test/lint/blocking_commands.rb +40 -16
- data/test/lint/hashes.rb +41 -0
- data/test/lint/hyper_log_log.rb +15 -1
- data/test/lint/lists.rb +16 -0
- data/test/lint/sets.rb +142 -0
- data/test/lint/sorted_sets.rb +183 -2
- data/test/lint/strings.rb +108 -20
- data/test/lint/value_types.rb +8 -0
- data/test/persistence_control_commands_test.rb +1 -3
- data/test/pipelining_commands_test.rb +12 -8
- data/test/publish_subscribe_test.rb +1 -3
- data/test/remote_server_control_commands_test.rb +60 -3
- data/test/scanning_test.rb +1 -7
- data/test/scripting_test.rb +1 -3
- data/test/sentinel_command_test.rb +1 -3
- data/test/sentinel_test.rb +1 -3
- data/test/sorting_test.rb +1 -3
- data/test/ssl_test.rb +45 -49
- data/test/support/cluster/orchestrator.rb +199 -0
- data/test/support/connection/hiredis.rb +1 -1
- data/test/support/connection/ruby.rb +1 -1
- data/test/support/connection/synchrony.rb +1 -1
- data/test/support/redis_mock.rb +1 -1
- data/test/synchrony_driver.rb +6 -9
- data/test/thread_safety_test.rb +1 -3
- data/test/transactions_test.rb +11 -3
- data/test/unknown_commands_test.rb +1 -3
- data/test/url_param_test.rb +44 -46
- metadata +109 -16
- data/Rakefile +0 -87
data/test/lint/hashes.rb
CHANGED
@@ -30,6 +30,21 @@ module Lint
|
|
30
30
|
assert_equal nil, r.hget("foo", "f1")
|
31
31
|
end
|
32
32
|
|
33
|
+
def test_splat_hdel
|
34
|
+
target_version "2.3.9" do
|
35
|
+
r.hset("foo", "f1", "s1")
|
36
|
+
r.hset("foo", "f2", "s2")
|
37
|
+
|
38
|
+
assert_equal "s1", r.hget("foo", "f1")
|
39
|
+
assert_equal "s2", r.hget("foo", "f2")
|
40
|
+
|
41
|
+
assert_equal 2, r.hdel("foo", "f1", "f2")
|
42
|
+
|
43
|
+
assert_equal nil, r.hget("foo", "f1")
|
44
|
+
assert_equal nil, r.hget("foo", "f2")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
33
48
|
def test_variadic_hdel
|
34
49
|
target_version "2.3.9" do
|
35
50
|
r.hset("foo", "f1", "s1")
|
@@ -129,6 +144,17 @@ module Lint
|
|
129
144
|
assert({"f1" => "s1", "f2" => "s2"} == r.mapped_hmget("foo", "f1", "f2"))
|
130
145
|
end
|
131
146
|
|
147
|
+
def test_mapped_hmget_in_a_pipeline_returns_hash
|
148
|
+
r.hset("foo", "f1", "s1")
|
149
|
+
r.hset("foo", "f2", "s2")
|
150
|
+
|
151
|
+
result = r.pipelined do
|
152
|
+
r.mapped_hmget("foo", "f1", "f2")
|
153
|
+
end
|
154
|
+
|
155
|
+
assert_equal result[0], { "f1" => "s1", "f2" => "s2" }
|
156
|
+
end
|
157
|
+
|
132
158
|
def test_hincrby
|
133
159
|
r.hincrby("foo", "f1", 1)
|
134
160
|
|
@@ -158,5 +184,20 @@ module Lint
|
|
158
184
|
assert_equal "1.9", r.hget("foo", "f1")
|
159
185
|
end
|
160
186
|
end
|
187
|
+
|
188
|
+
def test_hstrlen
|
189
|
+
target_version('3.2.0') do
|
190
|
+
redis.hmset('foo', 'f1', 'HelloWorld', 'f2', 99, 'f3', -256)
|
191
|
+
assert_equal 10, r.hstrlen('foo', 'f1')
|
192
|
+
assert_equal 2, r.hstrlen('foo', 'f2')
|
193
|
+
assert_equal 4, r.hstrlen('foo', 'f3')
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_hscan
|
198
|
+
redis.hmset('foo', 'f1', 'Jack', 'f2', 33)
|
199
|
+
expected = ['0', [%w[f1 Jack], %w[f2 33]]]
|
200
|
+
assert_equal expected, redis.hscan('foo', 0)
|
201
|
+
end
|
161
202
|
end
|
162
203
|
end
|
data/test/lint/hyper_log_log.rb
CHANGED
@@ -55,6 +55,20 @@ module Lint
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
def test_pfmerge
|
59
|
+
target_version '2.8.9' do
|
60
|
+
r.pfadd 'foo', 's1'
|
61
|
+
r.pfadd 'bar', 's2'
|
62
|
+
|
63
|
+
assert_equal true, r.pfmerge('res', 'foo', 'bar')
|
64
|
+
assert_equal 2, r.pfcount('res')
|
65
|
+
end
|
66
|
+
end
|
59
67
|
|
68
|
+
def test_variadic_pfmerge_expanded
|
69
|
+
redis.pfadd('{1}foo', %w[foo bar zap a])
|
70
|
+
redis.pfadd('{1}bar', %w[a b c foo])
|
71
|
+
assert_equal true, redis.pfmerge('{1}baz', '{1}foo', '{1}bar')
|
72
|
+
end
|
73
|
+
end
|
60
74
|
end
|
data/test/lint/lists.rb
CHANGED
@@ -139,5 +139,21 @@ module Lint
|
|
139
139
|
r.linsert "foo", :anywhere, "s3", "s2"
|
140
140
|
end
|
141
141
|
end
|
142
|
+
|
143
|
+
def test_rpoplpush
|
144
|
+
r.rpush 'foo', 's1'
|
145
|
+
r.rpush 'foo', 's2'
|
146
|
+
|
147
|
+
assert_equal 's2', r.rpoplpush('foo', 'bar')
|
148
|
+
assert_equal ['s2'], r.lrange('bar', 0, -1)
|
149
|
+
assert_equal 's1', r.rpoplpush('foo', 'bar')
|
150
|
+
assert_equal %w[s1 s2], r.lrange('bar', 0, -1)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_variadic_rpoplpush_expand
|
154
|
+
redis.rpush('{1}foo', %w[a b c])
|
155
|
+
redis.rpush('{1}bar', %w[d e f])
|
156
|
+
assert_equal 'c', redis.rpoplpush('{1}foo', '{1}bar')
|
157
|
+
end
|
142
158
|
end
|
143
159
|
end
|
data/test/lint/sets.rb
CHANGED
@@ -136,5 +136,147 @@ module Lint
|
|
136
136
|
|
137
137
|
assert_equal 4, r.scard("foo")
|
138
138
|
end
|
139
|
+
|
140
|
+
def test_smove
|
141
|
+
r.sadd 'foo', 's1'
|
142
|
+
r.sadd 'bar', 's2'
|
143
|
+
|
144
|
+
assert r.smove('foo', 'bar', 's1')
|
145
|
+
assert r.sismember('bar', 's1')
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_sinter
|
149
|
+
r.sadd 'foo', 's1'
|
150
|
+
r.sadd 'foo', 's2'
|
151
|
+
r.sadd 'bar', 's2'
|
152
|
+
|
153
|
+
assert_equal ['s2'], r.sinter('foo', 'bar')
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_variadic_smove_expand
|
157
|
+
r.sadd('{1}foo', 's1')
|
158
|
+
r.sadd('{1}foo', 's2')
|
159
|
+
r.sadd('{1}foo', 's3')
|
160
|
+
r.sadd('{1}bar', 's3')
|
161
|
+
r.sadd('{1}bar', 's4')
|
162
|
+
r.sadd('{1}bar', 's5')
|
163
|
+
assert_equal true, r.smove('{1}foo', '{1}bar', 's2')
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_variadic_sinter_expand
|
167
|
+
r.sadd('{1}foo', 's1')
|
168
|
+
r.sadd('{1}foo', 's2')
|
169
|
+
r.sadd('{1}foo', 's3')
|
170
|
+
r.sadd('{1}bar', 's3')
|
171
|
+
r.sadd('{1}bar', 's4')
|
172
|
+
r.sadd('{1}bar', 's5')
|
173
|
+
assert_equal %w[s3], r.sinter('{1}foo', '{1}bar')
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_sinterstore
|
177
|
+
r.sadd 'foo', 's1'
|
178
|
+
r.sadd 'foo', 's2'
|
179
|
+
r.sadd 'bar', 's2'
|
180
|
+
|
181
|
+
r.sinterstore('baz', 'foo', 'bar')
|
182
|
+
|
183
|
+
assert_equal ['s2'], r.smembers('baz')
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_variadic_sinterstore_expand
|
187
|
+
r.sadd('{1}foo', 's1')
|
188
|
+
r.sadd('{1}foo', 's2')
|
189
|
+
r.sadd('{1}foo', 's3')
|
190
|
+
r.sadd('{1}bar', 's3')
|
191
|
+
r.sadd('{1}bar', 's4')
|
192
|
+
r.sadd('{1}bar', 's5')
|
193
|
+
assert_equal 1, r.sinterstore('{1}baz', '{1}foo', '{1}bar')
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_sunion
|
197
|
+
r.sadd 'foo', 's1'
|
198
|
+
r.sadd 'foo', 's2'
|
199
|
+
r.sadd 'bar', 's2'
|
200
|
+
r.sadd 'bar', 's3'
|
201
|
+
|
202
|
+
assert_equal %w[s1 s2 s3], r.sunion('foo', 'bar').sort
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_variadic_sunion_expand
|
206
|
+
r.sadd('{1}foo', 's1')
|
207
|
+
r.sadd('{1}foo', 's2')
|
208
|
+
r.sadd('{1}foo', 's3')
|
209
|
+
r.sadd('{1}bar', 's3')
|
210
|
+
r.sadd('{1}bar', 's4')
|
211
|
+
r.sadd('{1}bar', 's5')
|
212
|
+
assert_equal %w[s1 s2 s3 s4 s5], r.sunion('{1}foo', '{1}bar').sort
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_sunionstore
|
216
|
+
r.sadd 'foo', 's1'
|
217
|
+
r.sadd 'foo', 's2'
|
218
|
+
r.sadd 'bar', 's2'
|
219
|
+
r.sadd 'bar', 's3'
|
220
|
+
|
221
|
+
r.sunionstore('baz', 'foo', 'bar')
|
222
|
+
|
223
|
+
assert_equal %w[s1 s2 s3], r.smembers('baz').sort
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_variadic_sunionstore_expand
|
227
|
+
r.sadd('{1}foo', 's1')
|
228
|
+
r.sadd('{1}foo', 's2')
|
229
|
+
r.sadd('{1}foo', 's3')
|
230
|
+
r.sadd('{1}bar', 's3')
|
231
|
+
r.sadd('{1}bar', 's4')
|
232
|
+
r.sadd('{1}bar', 's5')
|
233
|
+
assert_equal 5, r.sunionstore('{1}baz', '{1}foo', '{1}bar')
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_sdiff
|
237
|
+
r.sadd 'foo', 's1'
|
238
|
+
r.sadd 'foo', 's2'
|
239
|
+
r.sadd 'bar', 's2'
|
240
|
+
r.sadd 'bar', 's3'
|
241
|
+
|
242
|
+
assert_equal ['s1'], r.sdiff('foo', 'bar')
|
243
|
+
assert_equal ['s3'], r.sdiff('bar', 'foo')
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_variadic_sdiff_expand
|
247
|
+
r.sadd('{1}foo', 's1')
|
248
|
+
r.sadd('{1}foo', 's2')
|
249
|
+
r.sadd('{1}foo', 's3')
|
250
|
+
r.sadd('{1}bar', 's3')
|
251
|
+
r.sadd('{1}bar', 's4')
|
252
|
+
r.sadd('{1}bar', 's5')
|
253
|
+
assert_equal %w[s1 s2], r.sdiff('{1}foo', '{1}bar').sort
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_sdiffstore
|
257
|
+
r.sadd 'foo', 's1'
|
258
|
+
r.sadd 'foo', 's2'
|
259
|
+
r.sadd 'bar', 's2'
|
260
|
+
r.sadd 'bar', 's3'
|
261
|
+
|
262
|
+
r.sdiffstore('baz', 'foo', 'bar')
|
263
|
+
|
264
|
+
assert_equal ['s1'], r.smembers('baz')
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_variadic_sdiffstore_expand
|
268
|
+
r.sadd('{1}foo', 's1')
|
269
|
+
r.sadd('{1}foo', 's2')
|
270
|
+
r.sadd('{1}foo', 's3')
|
271
|
+
r.sadd('{1}bar', 's3')
|
272
|
+
r.sadd('{1}bar', 's4')
|
273
|
+
r.sadd('{1}bar', 's5')
|
274
|
+
assert_equal 2, r.sdiffstore('{1}baz', '{1}foo', '{1}bar')
|
275
|
+
end
|
276
|
+
|
277
|
+
def test_sscan
|
278
|
+
r.sadd('foo', %w[1 2 3 foo foobar feelsgood])
|
279
|
+
assert_equal %w[0 feelsgood foo foobar], r.sscan('foo', 0, match: 'f*').flatten.sort
|
280
|
+
end
|
139
281
|
end
|
140
282
|
end
|
data/test/lint/sorted_sets.rb
CHANGED
@@ -41,7 +41,8 @@ module Lint
|
|
41
41
|
assert_equal 11.0, r.zadd("foo", 10, "s1", :incr => true)
|
42
42
|
assert_equal(-Infinity, r.zadd("bar", "-inf", "s1", :incr => true))
|
43
43
|
assert_equal(+Infinity, r.zadd("bar", "+inf", "s2", :incr => true))
|
44
|
-
r.del
|
44
|
+
r.del 'foo'
|
45
|
+
r.del 'bar'
|
45
46
|
|
46
47
|
# Incompatible options combination
|
47
48
|
assert_raise(Redis::CommandError) { r.zadd("foo", 1, "s1", :xx => true, :nx => true) }
|
@@ -104,7 +105,8 @@ module Lint
|
|
104
105
|
assert_equal(-Infinity, r.zadd("bar", ["-inf", "s1"], :incr => true))
|
105
106
|
assert_equal(+Infinity, r.zadd("bar", ["+inf", "s2"], :incr => true))
|
106
107
|
assert_raise(Redis::CommandError) { r.zadd("foo", [1, "s1", 2, "s2"], :incr => true) }
|
107
|
-
r.del
|
108
|
+
r.del 'foo'
|
109
|
+
r.del 'bar'
|
108
110
|
|
109
111
|
# Incompatible options combination
|
110
112
|
assert_raise(Redis::CommandError) { r.zadd("foo", [1, "s1"], :xx => true, :nx => true) }
|
@@ -312,5 +314,184 @@ module Lint
|
|
312
314
|
assert_equal 3, r.zremrangebyscore("foo", 2, 4)
|
313
315
|
assert_equal ["s1"], r.zrange("foo", 0, -1)
|
314
316
|
end
|
317
|
+
|
318
|
+
def test_zpopmax
|
319
|
+
target_version('4.9.0') do
|
320
|
+
r.zadd('foo', %w[0 a 1 b 2 c])
|
321
|
+
assert_equal %w[c 2], r.zpopmax('foo')
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_zpopmin
|
326
|
+
target_version('4.9.0') do
|
327
|
+
r.zadd('foo', %w[0 a 1 b 2 c])
|
328
|
+
assert_equal %w[a 0], r.zpopmin('foo')
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_zremrangebylex
|
333
|
+
r.zadd('foo', %w[0 a 0 b 0 c 0 d 0 e 0 f 0 g])
|
334
|
+
assert_equal 5, r.zremrangebylex('foo', '(b', '[g')
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_zlexcount
|
338
|
+
target_version '2.8.9' do
|
339
|
+
r.zadd 'foo', 0, 'aaren'
|
340
|
+
r.zadd 'foo', 0, 'abagael'
|
341
|
+
r.zadd 'foo', 0, 'abby'
|
342
|
+
r.zadd 'foo', 0, 'abbygail'
|
343
|
+
|
344
|
+
assert_equal 4, r.zlexcount('foo', '[a', "[a\xff")
|
345
|
+
assert_equal 4, r.zlexcount('foo', '[aa', "[ab\xff")
|
346
|
+
assert_equal 3, r.zlexcount('foo', '(aaren', "[ab\xff")
|
347
|
+
assert_equal 2, r.zlexcount('foo', '[aba', '(abbygail')
|
348
|
+
assert_equal 1, r.zlexcount('foo', '(aaren', '(abby')
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def test_zrangebylex
|
353
|
+
target_version '2.8.9' do
|
354
|
+
r.zadd 'foo', 0, 'aaren'
|
355
|
+
r.zadd 'foo', 0, 'abagael'
|
356
|
+
r.zadd 'foo', 0, 'abby'
|
357
|
+
r.zadd 'foo', 0, 'abbygail'
|
358
|
+
|
359
|
+
assert_equal %w[aaren abagael abby abbygail], r.zrangebylex('foo', '[a', "[a\xff")
|
360
|
+
assert_equal %w[aaren abagael], r.zrangebylex('foo', '[a', "[a\xff", limit: [0, 2])
|
361
|
+
assert_equal %w[abby abbygail], r.zrangebylex('foo', '(abb', "(abb\xff")
|
362
|
+
assert_equal %w[abbygail], r.zrangebylex('foo', '(abby', "(abby\xff")
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
def test_zrevrangebylex
|
367
|
+
target_version '2.9.9' do
|
368
|
+
r.zadd 'foo', 0, 'aaren'
|
369
|
+
r.zadd 'foo', 0, 'abagael'
|
370
|
+
r.zadd 'foo', 0, 'abby'
|
371
|
+
r.zadd 'foo', 0, 'abbygail'
|
372
|
+
|
373
|
+
assert_equal %w[abbygail abby abagael aaren], r.zrevrangebylex('foo', "[a\xff", '[a')
|
374
|
+
assert_equal %w[abbygail abby], r.zrevrangebylex('foo', "[a\xff", '[a', limit: [0, 2])
|
375
|
+
assert_equal %w[abbygail abby], r.zrevrangebylex('foo', "(abb\xff", '(abb')
|
376
|
+
assert_equal %w[abbygail], r.zrevrangebylex('foo', "(abby\xff", '(abby')
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def test_zcount
|
381
|
+
r.zadd 'foo', 1, 's1'
|
382
|
+
r.zadd 'foo', 2, 's2'
|
383
|
+
r.zadd 'foo', 3, 's3'
|
384
|
+
|
385
|
+
assert_equal 2, r.zcount('foo', 2, 3)
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_zunionstore
|
389
|
+
r.zadd 'foo', 1, 's1'
|
390
|
+
r.zadd 'bar', 2, 's2'
|
391
|
+
r.zadd 'foo', 3, 's3'
|
392
|
+
r.zadd 'bar', 4, 's4'
|
393
|
+
|
394
|
+
assert_equal 4, r.zunionstore('foobar', %w[foo bar])
|
395
|
+
assert_equal %w[s1 s2 s3 s4], r.zrange('foobar', 0, -1)
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_zunionstore_with_weights
|
399
|
+
r.zadd 'foo', 1, 's1'
|
400
|
+
r.zadd 'foo', 3, 's3'
|
401
|
+
r.zadd 'bar', 20, 's2'
|
402
|
+
r.zadd 'bar', 40, 's4'
|
403
|
+
|
404
|
+
assert_equal 4, r.zunionstore('foobar', %w[foo bar])
|
405
|
+
assert_equal %w[s1 s3 s2 s4], r.zrange('foobar', 0, -1)
|
406
|
+
|
407
|
+
assert_equal 4, r.zunionstore('foobar', %w[foo bar], weights: [10, 1])
|
408
|
+
assert_equal %w[s1 s2 s3 s4], r.zrange('foobar', 0, -1)
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_zunionstore_with_aggregate
|
412
|
+
r.zadd 'foo', 1, 's1'
|
413
|
+
r.zadd 'foo', 2, 's2'
|
414
|
+
r.zadd 'bar', 4, 's2'
|
415
|
+
r.zadd 'bar', 3, 's3'
|
416
|
+
|
417
|
+
assert_equal 3, r.zunionstore('foobar', %w[foo bar])
|
418
|
+
assert_equal %w[s1 s3 s2], r.zrange('foobar', 0, -1)
|
419
|
+
|
420
|
+
assert_equal 3, r.zunionstore('foobar', %w[foo bar], aggregate: :min)
|
421
|
+
assert_equal %w[s1 s2 s3], r.zrange('foobar', 0, -1)
|
422
|
+
|
423
|
+
assert_equal 3, r.zunionstore('foobar', %w[foo bar], aggregate: :max)
|
424
|
+
assert_equal %w[s1 s3 s2], r.zrange('foobar', 0, -1)
|
425
|
+
end
|
426
|
+
|
427
|
+
def test_zunionstore_expand
|
428
|
+
r.zadd('{1}foo', %w[0 a 1 b 2 c])
|
429
|
+
r.zadd('{1}bar', %w[0 c 1 d 2 e])
|
430
|
+
assert_equal 5, r.zunionstore('{1}baz', %w[{1}foo {1}bar])
|
431
|
+
end
|
432
|
+
|
433
|
+
def test_zinterstore
|
434
|
+
r.zadd 'foo', 1, 's1'
|
435
|
+
r.zadd 'bar', 2, 's1'
|
436
|
+
r.zadd 'foo', 3, 's3'
|
437
|
+
r.zadd 'bar', 4, 's4'
|
438
|
+
|
439
|
+
assert_equal 1, r.zinterstore('foobar', %w[foo bar])
|
440
|
+
assert_equal ['s1'], r.zrange('foobar', 0, -1)
|
441
|
+
end
|
442
|
+
|
443
|
+
def test_zinterstore_with_weights
|
444
|
+
r.zadd 'foo', 1, 's1'
|
445
|
+
r.zadd 'foo', 2, 's2'
|
446
|
+
r.zadd 'foo', 3, 's3'
|
447
|
+
r.zadd 'bar', 20, 's2'
|
448
|
+
r.zadd 'bar', 30, 's3'
|
449
|
+
r.zadd 'bar', 40, 's4'
|
450
|
+
|
451
|
+
assert_equal 2, r.zinterstore('foobar', %w[foo bar])
|
452
|
+
assert_equal %w[s2 s3], r.zrange('foobar', 0, -1)
|
453
|
+
|
454
|
+
assert_equal 2, r.zinterstore('foobar', %w[foo bar], weights: [10, 1])
|
455
|
+
assert_equal %w[s2 s3], r.zrange('foobar', 0, -1)
|
456
|
+
|
457
|
+
assert_equal 40.0, r.zscore('foobar', 's2')
|
458
|
+
assert_equal 60.0, r.zscore('foobar', 's3')
|
459
|
+
end
|
460
|
+
|
461
|
+
def test_zinterstore_with_aggregate
|
462
|
+
r.zadd 'foo', 1, 's1'
|
463
|
+
r.zadd 'foo', 2, 's2'
|
464
|
+
r.zadd 'foo', 3, 's3'
|
465
|
+
r.zadd 'bar', 20, 's2'
|
466
|
+
r.zadd 'bar', 30, 's3'
|
467
|
+
r.zadd 'bar', 40, 's4'
|
468
|
+
|
469
|
+
assert_equal 2, r.zinterstore('foobar', %w[foo bar])
|
470
|
+
assert_equal %w[s2 s3], r.zrange('foobar', 0, -1)
|
471
|
+
assert_equal 22.0, r.zscore('foobar', 's2')
|
472
|
+
assert_equal 33.0, r.zscore('foobar', 's3')
|
473
|
+
|
474
|
+
assert_equal 2, r.zinterstore('foobar', %w[foo bar], aggregate: :min)
|
475
|
+
assert_equal %w[s2 s3], r.zrange('foobar', 0, -1)
|
476
|
+
assert_equal 2.0, r.zscore('foobar', 's2')
|
477
|
+
assert_equal 3.0, r.zscore('foobar', 's3')
|
478
|
+
|
479
|
+
assert_equal 2, r.zinterstore('foobar', %w[foo bar], aggregate: :max)
|
480
|
+
assert_equal %w[s2 s3], r.zrange('foobar', 0, -1)
|
481
|
+
assert_equal 20.0, r.zscore('foobar', 's2')
|
482
|
+
assert_equal 30.0, r.zscore('foobar', 's3')
|
483
|
+
end
|
484
|
+
|
485
|
+
def test_zinterstore_expand
|
486
|
+
r.zadd '{1}foo', %w[0 s1 1 s2 2 s3]
|
487
|
+
r.zadd '{1}bar', %w[0 s3 1 s4 2 s5]
|
488
|
+
assert_equal 1, r.zinterstore('{1}baz', %w[{1}foo {1}bar], weights: [2.0, 3.0])
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_zscan
|
492
|
+
r.zadd('foo', %w[0 a 1 b 2 c])
|
493
|
+
expected = ['0', [['a', 0.0], ['b', 1.0], ['c', 2.0]]]
|
494
|
+
assert_equal expected, r.zscan('foo', 0)
|
495
|
+
end
|
315
496
|
end
|
316
497
|
end
|
data/test/lint/strings.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module Lint
|
2
2
|
|
3
3
|
module Strings
|
4
|
+
def mock(*args, &block)
|
5
|
+
redis_mock(*args, &block)
|
6
|
+
end
|
4
7
|
|
5
8
|
def test_set_and_get
|
6
9
|
r.set("foo", "s1")
|
@@ -8,18 +11,6 @@ module Lint
|
|
8
11
|
assert_equal "s1", r.get("foo")
|
9
12
|
end
|
10
13
|
|
11
|
-
def test_set_and_get_with_brackets
|
12
|
-
r["foo"] = "s1"
|
13
|
-
|
14
|
-
assert_equal "s1", r["foo"]
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_set_and_get_with_brackets_and_symbol
|
18
|
-
r[:foo] = "s1"
|
19
|
-
|
20
|
-
assert_equal "s1", r[:foo]
|
21
|
-
end
|
22
|
-
|
23
14
|
def test_set_and_get_with_newline_characters
|
24
15
|
r.set("foo", "1\n")
|
25
16
|
|
@@ -35,14 +26,12 @@ module Lint
|
|
35
26
|
end
|
36
27
|
|
37
28
|
def test_set_and_get_with_ascii_characters
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
assert_equal str, r.get("foo")
|
45
|
-
end
|
29
|
+
with_external_encoding("ASCII-8BIT") do
|
30
|
+
(0..255).each do |i|
|
31
|
+
str = "#{i.chr}---#{i.chr}"
|
32
|
+
r.set("foo", str)
|
33
|
+
|
34
|
+
assert_equal str, r.get("foo")
|
46
35
|
end
|
47
36
|
end
|
48
37
|
end
|
@@ -256,5 +245,104 @@ module Lint
|
|
256
245
|
|
257
246
|
assert_equal 5, r.strlen("foo")
|
258
247
|
end
|
248
|
+
|
249
|
+
def test_bitfield
|
250
|
+
target_version('3.2.0') do
|
251
|
+
mock(bitfield: ->(*_) { "*2\r\n:1\r\n:0\r\n" }) do |redis|
|
252
|
+
assert_equal [1, 0], redis.bitfield('foo', 'INCRBY', 'i5', 100, 1, 'GET', 'u4', 0)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_mget
|
258
|
+
r.set('{1}foo', 's1')
|
259
|
+
r.set('{1}bar', 's2')
|
260
|
+
|
261
|
+
assert_equal %w[s1 s2], r.mget('{1}foo', '{1}bar')
|
262
|
+
assert_equal ['s1', 's2', nil], r.mget('{1}foo', '{1}bar', '{1}baz')
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_mget_mapped
|
266
|
+
r.set('{1}foo', 's1')
|
267
|
+
r.set('{1}bar', 's2')
|
268
|
+
|
269
|
+
response = r.mapped_mget('{1}foo', '{1}bar')
|
270
|
+
|
271
|
+
assert_equal 's1', response['{1}foo']
|
272
|
+
assert_equal 's2', response['{1}bar']
|
273
|
+
|
274
|
+
response = r.mapped_mget('{1}foo', '{1}bar', '{1}baz')
|
275
|
+
|
276
|
+
assert_equal 's1', response['{1}foo']
|
277
|
+
assert_equal 's2', response['{1}bar']
|
278
|
+
assert_equal nil, response['{1}baz']
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_mapped_mget_in_a_pipeline_returns_hash
|
282
|
+
r.set('{1}foo', 's1')
|
283
|
+
r.set('{1}bar', 's2')
|
284
|
+
|
285
|
+
result = r.pipelined do
|
286
|
+
r.mapped_mget('{1}foo', '{1}bar')
|
287
|
+
end
|
288
|
+
|
289
|
+
assert_equal({ '{1}foo' => 's1', '{1}bar' => 's2' }, result[0])
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_mset
|
293
|
+
r.mset('{1}foo', 's1', '{1}bar', 's2')
|
294
|
+
|
295
|
+
assert_equal 's1', r.get('{1}foo')
|
296
|
+
assert_equal 's2', r.get('{1}bar')
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_mset_mapped
|
300
|
+
r.mapped_mset('{1}foo' => 's1', '{1}bar' => 's2')
|
301
|
+
|
302
|
+
assert_equal 's1', r.get('{1}foo')
|
303
|
+
assert_equal 's2', r.get('{1}bar')
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_msetnx
|
307
|
+
r.set('{1}foo', 's1')
|
308
|
+
assert_equal false, r.msetnx('{1}foo', 's2', '{1}bar', 's3')
|
309
|
+
assert_equal 's1', r.get('{1}foo')
|
310
|
+
assert_equal nil, r.get('{1}bar')
|
311
|
+
|
312
|
+
r.del('{1}foo')
|
313
|
+
assert_equal true, r.msetnx('{1}foo', 's2', '{1}bar', 's3')
|
314
|
+
assert_equal 's2', r.get('{1}foo')
|
315
|
+
assert_equal 's3', r.get('{1}bar')
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_msetnx_mapped
|
319
|
+
r.set('{1}foo', 's1')
|
320
|
+
assert_equal false, r.mapped_msetnx('{1}foo' => 's2', '{1}bar' => 's3')
|
321
|
+
assert_equal 's1', r.get('{1}foo')
|
322
|
+
assert_equal nil, r.get('{1}bar')
|
323
|
+
|
324
|
+
r.del('{1}foo')
|
325
|
+
assert_equal true, r.mapped_msetnx('{1}foo' => 's2', '{1}bar' => 's3')
|
326
|
+
assert_equal 's2', r.get('{1}foo')
|
327
|
+
assert_equal 's3', r.get('{1}bar')
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_bitop
|
331
|
+
with_external_encoding('UTF-8') do
|
332
|
+
target_version '2.5.10' do
|
333
|
+
r.set('foo{1}', 'a')
|
334
|
+
r.set('bar{1}', 'b')
|
335
|
+
|
336
|
+
r.bitop(:and, 'foo&bar{1}', 'foo{1}', 'bar{1}')
|
337
|
+
assert_equal "\x60", r.get('foo&bar{1}')
|
338
|
+
r.bitop(:or, 'foo|bar{1}', 'foo{1}', 'bar{1}')
|
339
|
+
assert_equal "\x63", r.get('foo|bar{1}')
|
340
|
+
r.bitop(:xor, 'foo^bar{1}', 'foo{1}', 'bar{1}')
|
341
|
+
assert_equal "\x03", r.get('foo^bar{1}')
|
342
|
+
r.bitop(:not, '~foo{1}', 'foo{1}')
|
343
|
+
assert_equal "\x9E", r.get('~foo{1}')
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
259
347
|
end
|
260
348
|
end
|
data/test/lint/value_types.rb
CHANGED
@@ -93,6 +93,14 @@ module Lint
|
|
93
93
|
assert r.restore("bar", 1000, w)
|
94
94
|
assert_equal ["b", "c", "d"], r.lrange("bar", 0, -1)
|
95
95
|
assert [0, 1].include? r.ttl("bar")
|
96
|
+
|
97
|
+
r.set("bar", "somethingelse")
|
98
|
+
assert_raises(Redis::CommandError) { r.restore("bar", 1000, w) } # ensure by default replace is false
|
99
|
+
assert_raises(Redis::CommandError) { r.restore("bar", 1000, w, :replace => false) }
|
100
|
+
assert_equal "somethingelse", r.get("bar")
|
101
|
+
assert r.restore("bar", 1000, w, :replace => true)
|
102
|
+
assert_equal ["b", "c", "d"], r.lrange("bar", 0, -1)
|
103
|
+
assert [0, 1].include? r.ttl("bar")
|
96
104
|
end
|
97
105
|
end
|
98
106
|
|
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.expand_path("helper", File.dirname(__FILE__))
|
1
|
+
require_relative "helper"
|
4
2
|
|
5
3
|
class TestPipeliningCommands < Test::Unit::TestCase
|
6
4
|
|
@@ -130,15 +128,21 @@ class TestPipeliningCommands < Test::Unit::TestCase
|
|
130
128
|
end
|
131
129
|
end
|
132
130
|
|
131
|
+
def test_futures_raise_when_command_errors_and_needs_transformation
|
132
|
+
assert_raise(Redis::CommandError) do
|
133
|
+
r.pipelined do
|
134
|
+
@result = r.zrange("a", "b", 5, :with_scores => true)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
133
139
|
def test_futures_can_be_identified
|
134
140
|
r.pipelined do
|
135
141
|
@result = r.sadd("foo", 1)
|
136
142
|
end
|
137
143
|
|
138
144
|
assert_equal true, @result.is_a?(Redis::Future)
|
139
|
-
|
140
|
-
assert_equal true, @result.is_a?(::BasicObject)
|
141
|
-
end
|
145
|
+
assert_equal true, @result.is_a?(::BasicObject)
|
142
146
|
assert_equal Redis::Future, @result.class
|
143
147
|
end
|
144
148
|
|
@@ -225,7 +229,7 @@ class TestPipeliningCommands < Test::Unit::TestCase
|
|
225
229
|
p2.select 2
|
226
230
|
end
|
227
231
|
|
228
|
-
assert_equal 2, r.
|
232
|
+
assert_equal 2, r._client.db
|
229
233
|
end
|
230
234
|
|
231
235
|
def test_nested_pipeline_select_client_db
|
@@ -237,6 +241,6 @@ class TestPipeliningCommands < Test::Unit::TestCase
|
|
237
241
|
end
|
238
242
|
end
|
239
243
|
|
240
|
-
assert_equal 3, r.
|
244
|
+
assert_equal 3, r._client.db
|
241
245
|
end
|
242
246
|
end
|