redis 4.0.1 → 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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +17 -29
  4. data/.travis/Gemfile +5 -0
  5. data/CHANGELOG.md +29 -0
  6. data/Gemfile +5 -0
  7. data/README.md +1 -1
  8. data/bin/build +71 -0
  9. data/lib/redis.rb +198 -12
  10. data/lib/redis/client.rb +26 -12
  11. data/lib/redis/cluster.rb +285 -0
  12. data/lib/redis/cluster/command.rb +81 -0
  13. data/lib/redis/cluster/command_loader.rb +32 -0
  14. data/lib/redis/cluster/key_slot_converter.rb +72 -0
  15. data/lib/redis/cluster/node.rb +104 -0
  16. data/lib/redis/cluster/node_key.rb +35 -0
  17. data/lib/redis/cluster/node_loader.rb +35 -0
  18. data/lib/redis/cluster/option.rb +76 -0
  19. data/lib/redis/cluster/slot.rb +69 -0
  20. data/lib/redis/cluster/slot_loader.rb +47 -0
  21. data/lib/redis/connection/ruby.rb +5 -2
  22. data/lib/redis/distributed.rb +10 -2
  23. data/lib/redis/errors.rb +46 -0
  24. data/lib/redis/pipeline.rb +9 -1
  25. data/lib/redis/version.rb +1 -1
  26. data/makefile +54 -22
  27. data/redis.gemspec +2 -1
  28. data/test/client_test.rb +17 -0
  29. data/test/cluster_abnormal_state_test.rb +38 -0
  30. data/test/cluster_blocking_commands_test.rb +15 -0
  31. data/test/cluster_client_internals_test.rb +77 -0
  32. data/test/cluster_client_key_hash_tags_test.rb +88 -0
  33. data/test/cluster_client_options_test.rb +147 -0
  34. data/test/cluster_client_pipelining_test.rb +59 -0
  35. data/test/cluster_client_replicas_test.rb +36 -0
  36. data/test/cluster_client_slots_test.rb +94 -0
  37. data/test/cluster_client_transactions_test.rb +71 -0
  38. data/test/cluster_commands_on_cluster_test.rb +165 -0
  39. data/test/cluster_commands_on_connection_test.rb +40 -0
  40. data/test/cluster_commands_on_geo_test.rb +74 -0
  41. data/test/cluster_commands_on_hashes_test.rb +11 -0
  42. data/test/cluster_commands_on_hyper_log_log_test.rb +17 -0
  43. data/test/cluster_commands_on_keys_test.rb +134 -0
  44. data/test/cluster_commands_on_lists_test.rb +15 -0
  45. data/test/cluster_commands_on_pub_sub_test.rb +101 -0
  46. data/test/cluster_commands_on_scripting_test.rb +56 -0
  47. data/test/cluster_commands_on_server_test.rb +221 -0
  48. data/test/cluster_commands_on_sets_test.rb +39 -0
  49. data/test/cluster_commands_on_sorted_sets_test.rb +35 -0
  50. data/test/cluster_commands_on_streams_test.rb +196 -0
  51. data/test/cluster_commands_on_strings_test.rb +15 -0
  52. data/test/cluster_commands_on_transactions_test.rb +41 -0
  53. data/test/cluster_commands_on_value_types_test.rb +14 -0
  54. data/test/commands_on_geo_test.rb +116 -0
  55. data/test/commands_on_hashes_test.rb +2 -14
  56. data/test/commands_on_hyper_log_log_test.rb +2 -14
  57. data/test/commands_on_lists_test.rb +2 -13
  58. data/test/commands_on_sets_test.rb +2 -70
  59. data/test/commands_on_sorted_sets_test.rb +2 -145
  60. data/test/commands_on_strings_test.rb +2 -94
  61. data/test/commands_on_value_types_test.rb +36 -0
  62. data/test/distributed_blocking_commands_test.rb +8 -0
  63. data/test/distributed_commands_on_hashes_test.rb +16 -3
  64. data/test/distributed_commands_on_hyper_log_log_test.rb +8 -13
  65. data/test/distributed_commands_on_lists_test.rb +4 -5
  66. data/test/distributed_commands_on_sets_test.rb +45 -46
  67. data/test/distributed_commands_on_sorted_sets_test.rb +51 -8
  68. data/test/distributed_commands_on_strings_test.rb +10 -0
  69. data/test/distributed_commands_on_value_types_test.rb +36 -0
  70. data/test/helper.rb +176 -32
  71. data/test/internals_test.rb +20 -1
  72. data/test/lint/blocking_commands.rb +40 -16
  73. data/test/lint/hashes.rb +41 -0
  74. data/test/lint/hyper_log_log.rb +15 -1
  75. data/test/lint/lists.rb +16 -0
  76. data/test/lint/sets.rb +142 -0
  77. data/test/lint/sorted_sets.rb +183 -2
  78. data/test/lint/strings.rb +102 -0
  79. data/test/pipelining_commands_test.rb +8 -0
  80. data/test/support/cluster/orchestrator.rb +199 -0
  81. data/test/support/redis_mock.rb +1 -1
  82. data/test/transactions_test.rb +10 -0
  83. metadata +81 -2
@@ -55,6 +55,20 @@ module Lint
55
55
  end
56
56
  end
57
57
 
58
- end
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
@@ -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
@@ -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
@@ -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 "foo", "bar"
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 "foo", "bar"
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
@@ -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")
@@ -242,5 +245,104 @@ module Lint
242
245
 
243
246
  assert_equal 5, r.strlen("foo")
244
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
245
347
  end
246
348
  end