gilmour-em-hiredis 0.3.0

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,931 @@
1
+ require 'spec_helper'
2
+
3
+ describe EventMachine::Hiredis, "commands" do
4
+ it "pings" do
5
+ connect do |redis|
6
+ redis.ping { |r| r.should == 'PONG'; done }
7
+ end
8
+ end
9
+
10
+ it "SETs and GETs a key" do
11
+ connect do |redis|
12
+ redis.set('foo', 'nik')
13
+ redis.get('foo') { |r| r.should == 'nik'; done }
14
+ end
15
+ end
16
+
17
+ it "handles trailing newline characters" do
18
+ connect do |redis|
19
+ redis.set('foo', "bar\n")
20
+ redis.get('foo') { |r| r.should == "bar\n"; done }
21
+ end
22
+ end
23
+
24
+ it "stores and retrieves all possible characters at the beginning and the end of a string" do
25
+ connect do |redis|
26
+ (0..255).each do |char_idx|
27
+ string = "#{char_idx.chr}---#{char_idx.chr}"
28
+ if RUBY_VERSION > "1.9"
29
+ string.force_encoding("UTF-8")
30
+ end
31
+ redis.set('foo', string)
32
+ redis.get('foo') { |r| r.should == string }
33
+ end
34
+ redis.ping { done }
35
+ end
36
+ end
37
+
38
+ it "SETs a key with an expiry" do
39
+ connect do |redis|
40
+ timeout(3)
41
+
42
+ redis.setex('foo', 1, 'bar')
43
+ redis.get('foo') { |r| r.should == 'bar' }
44
+ EventMachine.add_timer(2) do
45
+ redis.get('foo') { |r| r.should == nil }
46
+ redis.ping { done }
47
+ end
48
+ end
49
+ end
50
+
51
+ it "gets TTL for a key" do
52
+ connect do |redis|
53
+ redis.setex('foo', 1, 'bar')
54
+ redis.ttl('foo') { |r| r.should == 1; done }
55
+ end
56
+ end
57
+
58
+ it "can SETNX" do
59
+ connect do |redis|
60
+ redis.set('foo', 'nik')
61
+ redis.get('foo') { |r| r.should == 'nik' }
62
+ redis.setnx 'foo', 'bar'
63
+ redis.get('foo') { |r| r.should == 'nik' }
64
+
65
+ redis.ping { done }
66
+ end
67
+ end
68
+
69
+ it "can GETSET" do
70
+ connect do |redis|
71
+ redis.set('foo', 'bar')
72
+ redis.getset('foo', 'baz') { |r| r.should == 'bar' }
73
+ redis.get('foo') { |r| r.should == 'baz'; done }
74
+ end
75
+ end
76
+
77
+ it "can INCR a key" do
78
+ connect do |redis|
79
+ redis.del('counter')
80
+ redis.incr('counter') { |r| r.should == 1 }
81
+ redis.incr('counter') { |r| r.should == 2 }
82
+ redis.incr('counter') { |r| r.should == 3 }
83
+
84
+ redis.ping { done }
85
+ end
86
+ end
87
+
88
+ it "can INCRBY a key" do
89
+ connect do |redis|
90
+ redis.del('counter')
91
+ redis.incrby('counter', 1) { |r| r.should == 1 }
92
+ redis.incrby('counter', 2) { |r| r.should == 3 }
93
+ redis.incrby('counter', 3) { |r| r.should == 6 }
94
+
95
+ redis.ping { done }
96
+ end
97
+ end
98
+
99
+ it "can DECR a key" do
100
+ connect do |redis|
101
+ redis.del('counter')
102
+ redis.incr('counter') { |r| r.should == 1 }
103
+ redis.incr('counter') { |r| r.should == 2 }
104
+ redis.incr('counter') { |r| r.should == 3 }
105
+ redis.decr('counter') { |r| r.should == 2 }
106
+ redis.decrby('counter', 2) { |r| r.should == 0; done }
107
+ end
108
+ end
109
+
110
+ it "can RANDOMKEY" do
111
+ connect do |redis|
112
+ redis.set('foo', 'bar')
113
+ redis.randomkey { |r| r.should_not == nil; done }
114
+ end
115
+ end
116
+
117
+ it "can RENAME a key" do
118
+ connect do |redis|
119
+ redis.del 'foo'
120
+ redis.del 'bar'
121
+ redis.set('foo', 'hi')
122
+ redis.rename 'foo', 'bar'
123
+ redis.get('bar') { |r| r.should == 'hi' ; done }
124
+ end
125
+ end
126
+
127
+ it "can RENAMENX a key" do
128
+ connect do |redis|
129
+ redis.del 'foo'
130
+ redis.del 'bar'
131
+ redis.set('foo', 'hi')
132
+ redis.set('bar', 'ohai')
133
+ redis.renamenx 'foo', 'bar'
134
+ redis.get('bar') { |r| r.should == 'ohai' ; done }
135
+ end
136
+ end
137
+
138
+ it "can get DBSIZE of the database" do
139
+ connect do |redis|
140
+ redis.set('foo1', 'bar')
141
+ redis.set('foo2', 'baz')
142
+ redis.set('foo3', 'bat')
143
+ redis.dbsize do |r|
144
+ r.should == 3
145
+ done
146
+ end
147
+ end
148
+ end
149
+
150
+ it "can EXPIRE a key" do
151
+ connect do |redis|
152
+ timeout(3)
153
+
154
+ redis.set('foo', 'bar')
155
+ redis.expire 'foo', 1
156
+ redis.get('foo') { |r| r.should == "bar" }
157
+ EventMachine.add_timer(2) do
158
+ redis.get('foo') { |r| r.should == nil }
159
+ redis.ping { done }
160
+ end
161
+ end
162
+ end
163
+
164
+
165
+ it "can check if a key EXISTS" do
166
+ connect do |redis|
167
+ redis.set 'foo', 'nik'
168
+ redis.exists('foo') { |r| r.should == 1 }
169
+ redis.del 'foo'
170
+ redis.exists('foo') { |r| r.should == 0 ; done }
171
+ end
172
+ end
173
+
174
+ it "can list KEYS" do
175
+ connect do |redis|
176
+ redis.keys("f*") { |keys| keys.each { |key| @r.del key } }
177
+ redis.set('f', 'nik')
178
+ redis.set('fo', 'nak')
179
+ redis.set('foo', 'qux')
180
+ redis.keys("f*") { |r| r.sort.should == ['f', 'fo', 'foo'].sort }
181
+
182
+ redis.ping { done }
183
+ end
184
+ end
185
+
186
+ it "returns a random key (RANDOMKEY)" do
187
+ connect do |redis|
188
+ redis.set("foo", "bar")
189
+ redis.randomkey do |r|
190
+ redis.exists(r) do |e|
191
+ e.should == 1
192
+ done
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ it "should be able to check the TYPE of a key" do
199
+ connect do |redis|
200
+ redis.set('foo', 'nik')
201
+ redis.type('foo') { |r| r.should == "string" }
202
+ redis.del 'foo'
203
+ redis.type('foo') { |r| r.should == "none" ; done }
204
+ end
205
+ end
206
+
207
+ it "pushes to the head of a list (LPUSH)" do
208
+ connect do |redis|
209
+ redis.lpush "list", 'hello'
210
+ redis.lpush "list", 42
211
+ redis.type('list') { |r| r.should == "list" }
212
+ redis.llen('list') { |r| r.should == 2 }
213
+ redis.lpop('list') { |r| r.should == '42'; done }
214
+ end
215
+ end
216
+
217
+ it "pushes to the tail of a list (RPUSH)" do
218
+ connect do |redis|
219
+ redis.rpush "list", 'hello'
220
+ redis.type('list') { |r| r.should == "list" }
221
+ redis.llen('list') { |r| r.should == 1 ; done }
222
+ end
223
+ end
224
+
225
+ it "pops the tail of a list (RPOP)" do
226
+ connect do |redis|
227
+ redis.rpush "list", 'hello'
228
+ redis.rpush"list", 'goodbye'
229
+ redis.type('list') { |r| r.should == "list" }
230
+ redis.llen('list') { |r| r.should == 2 }
231
+ redis.rpop('list') { |r| r.should == 'goodbye'; done }
232
+ end
233
+ end
234
+
235
+ it "pop the head of a list (LPOP)" do
236
+ connect do |redis|
237
+ redis.rpush "list", 'hello'
238
+ redis.rpush "list", 'goodbye'
239
+ redis.type('list') { |r| r.should == "list" }
240
+ redis.llen('list') { |r| r.should == 2 }
241
+ redis.lpop('list') { |r| r.should == 'hello'; done }
242
+ end
243
+ end
244
+
245
+ it "gets the length of a list (LLEN)" do
246
+ connect do |redis|
247
+ redis.rpush "list", 'hello'
248
+ redis.rpush "list", 'goodbye'
249
+ redis.type('list') { |r| r.should == "list" }
250
+ redis.llen('list') { |r| r.should == 2 ; done }
251
+ end
252
+ end
253
+
254
+ it "gets a range of values from a list (LRANGE)" do
255
+ connect do |redis|
256
+ redis.rpush "list", 'hello'
257
+ redis.rpush "list", 'goodbye'
258
+ redis.rpush "list", '1'
259
+ redis.rpush "list", '2'
260
+ redis.rpush "list", '3'
261
+ redis.type('list') { |r| r.should == "list" }
262
+ redis.llen('list') { |r| r.should == 5 }
263
+ redis.lrange('list', 2, -1) { |r| r.should == ['1', '2', '3']; done }
264
+ end
265
+ end
266
+
267
+ it "trims a list (LTRIM)" do
268
+ connect do |redis|
269
+ redis.rpush "list", 'hello'
270
+ redis.rpush "list", 'goodbye'
271
+ redis.rpush "list", '1'
272
+ redis.rpush "list", '2'
273
+ redis.rpush "list", '3'
274
+ redis.type('list') { |r| r.should == "list" }
275
+ redis.llen('list') { |r| r.should == 5 }
276
+ redis.ltrim 'list', 0, 1
277
+ redis.llen('list') { |r| r.should == 2 }
278
+ redis.lrange('list', 0, -1) { |r| r.should == ['hello', 'goodbye']; done }
279
+ end
280
+ end
281
+
282
+ it "gets a value by indexing into a list (LINDEX)" do
283
+ connect do |redis|
284
+ redis.rpush "list", 'hello'
285
+ redis.rpush "list", 'goodbye'
286
+ redis.type('list') { |r| r.should == "list" }
287
+ redis.llen('list') { |r| r.should == 2 }
288
+ redis.lindex('list', 1) { |r| r.should == 'goodbye'; done }
289
+ end
290
+ end
291
+
292
+ it "sets a value by indexing into a list (LSET)" do
293
+ connect do |redis|
294
+ redis.rpush "list", 'hello'
295
+ redis.rpush "list", 'hello'
296
+ redis.type('list') { |r| r.should == "list" }
297
+ redis.llen('list') { |r| r.should == 2 }
298
+ redis.lset('list', 1, 'goodbye') { |r| r.should == 'OK' }
299
+ redis.lindex('list', 1) { |r| r.should == 'goodbye'; done }
300
+ end
301
+ end
302
+
303
+ it "removes values from a list (LREM)" do
304
+ connect do |redis|
305
+ redis.rpush "list", 'hello'
306
+ redis.rpush "list", 'goodbye'
307
+ redis.type('list') { |r| r.should == "list" }
308
+ redis.llen('list') { |r| r.should == 2 }
309
+ redis.lrem('list', 1, 'hello') { |r| r.should == 1 }
310
+ redis.lrange('list', 0, -1) { |r| r.should == ['goodbye']; done }
311
+ end
312
+ end
313
+
314
+ it "pops values from a list and push them onto a temp list(RPOPLPUSH)" do
315
+ connect do |redis|
316
+ redis.rpush "list", 'one'
317
+ redis.rpush "list", 'two'
318
+ redis.rpush "list", 'three'
319
+ redis.type('list') { |r| r.should == "list" }
320
+ redis.llen('list') { |r| r.should == 3 }
321
+ redis.lrange('list', 0, -1) { |r| r.should == ['one', 'two', 'three'] }
322
+ redis.lrange('tmp', 0, -1) { |r| r.should == [] }
323
+ redis.rpoplpush('list', 'tmp') { |r| r.should == 'three' }
324
+ redis.lrange('tmp', 0, -1) { |r| r.should == ['three'] }
325
+ redis.rpoplpush('list', 'tmp') { |r| r.should == 'two' }
326
+ redis.lrange('tmp', 0, -1) { |r| r.should == ['two', 'three'] }
327
+ redis.rpoplpush('list', 'tmp') { |r| r.should == 'one' }
328
+ redis.lrange('tmp', 0, -1) { |r| r.should == ['one', 'two', 'three']; done }
329
+ end
330
+ end
331
+
332
+ it "adds members to a set (SADD)" do
333
+ connect do |redis|
334
+ redis.sadd "set", 'key1'
335
+ redis.sadd "set", 'key2'
336
+ redis.type('set') { |r| r.should == "set" }
337
+ redis.scard('set') { |r| r.should == 2 }
338
+ redis.smembers('set') { |r| r.sort.should == ['key1', 'key2'].sort; done }
339
+ end
340
+ end
341
+
342
+ it "deletes members to a set (SREM)" do
343
+ connect do |redis|
344
+ redis.sadd "set", 'key1'
345
+ redis.sadd "set", 'key2'
346
+ redis.type('set') { |r| r.should == "set" }
347
+ redis.scard('set') { |r| r.should == 2 }
348
+ redis.smembers('set') { |r| r.sort.should == ['key1', 'key2'].sort }
349
+ redis.srem('set', 'key1')
350
+ redis.scard('set') { |r| r.should == 1 }
351
+ redis.smembers('set') { |r| r.should == ['key2']; done }
352
+ end
353
+ end
354
+
355
+ it "returns and remove random key from set (SPOP)" do
356
+ connect do |redis|
357
+ redis.sadd "set_pop", "key1"
358
+ redis.sadd "set_pop", "key2"
359
+ redis.spop("set_pop") { |r| r.should_not == nil }
360
+ redis.scard("set_pop") { |r| r.should == 1; done }
361
+ end
362
+ end
363
+
364
+ it "returns random key without delete the key from a set (SRANDMEMBER)" do
365
+ connect do |redis|
366
+ redis.sadd "set_srandmember", "key1"
367
+ redis.sadd "set_srandmember", "key2"
368
+ redis.srandmember("set_srandmember") { |r| r.should_not == nil }
369
+ redis.scard("set_srandmember") { |r| r.should == 2; done }
370
+ end
371
+ end
372
+
373
+ it "counts the members of a set (SCARD)" do
374
+ connect do |redis|
375
+ redis.sadd "set", 'key1'
376
+ redis.sadd "set", 'key2'
377
+ redis.type('set') { |r| r.should == "set" }
378
+ redis.scard('set') { |r| r.should == 2; done }
379
+ end
380
+ end
381
+
382
+ it "tests for set membership (SISMEMBER)" do
383
+ connect do |redis|
384
+ redis.sadd "set", 'key1'
385
+ redis.sadd "set", 'key2'
386
+ redis.type('set') { |r| r.should == "set" }
387
+ redis.scard('set') { |r| r.should == 2 }
388
+ redis.sismember('set', 'key1') { |r| r.should == 1 }
389
+ redis.sismember('set', 'key2') { |r| r.should == 1 }
390
+ redis.sismember('set', 'notthere') { |r| r.should == 0; done }
391
+ end
392
+ end
393
+
394
+ it "intersects sets (SINTER)" do
395
+ connect do |redis|
396
+ redis.sadd "set", 'key1'
397
+ redis.sadd "set", 'key2'
398
+ redis.sadd "set2", 'key2'
399
+ redis.sinter('set', 'set2') { |r| r.should == ['key2']; done }
400
+ end
401
+ end
402
+
403
+ it "intersects set and stores the results in a key (SINTERSTORE)" do
404
+ connect do |redis|
405
+ redis.sadd "set", 'key1'
406
+ redis.sadd "set", 'key2'
407
+ redis.sadd "set2", 'key2'
408
+ redis.sinterstore('newone', 'set', 'set2') { |r| r.should == 1 }
409
+ redis.smembers('newone') { |r| r.should == ['key2']; done }
410
+ end
411
+ end
412
+
413
+ it "performs set unions (SUNION)" do
414
+ connect do |redis|
415
+ redis.sadd "set", 'key1'
416
+ redis.sadd "set", 'key2'
417
+ redis.sadd "set2", 'key2'
418
+ redis.sadd "set2", 'key3'
419
+ redis.sunion('set', 'set2') { |r| r.sort.should == ['key1','key2','key3'].sort; done }
420
+ end
421
+ end
422
+
423
+ it "performs a set union and store the results in a key (SUNIONSTORE)" do
424
+ connect do |redis|
425
+ redis.sadd "set", 'key1'
426
+ redis.sadd "set", 'key2'
427
+ redis.sadd "set2", 'key2'
428
+ redis.sadd "set2", 'key3'
429
+ redis.sunionstore('newone', 'set', 'set2') { |r| r.should == 3 }
430
+ redis.smembers('newone') { |r| r.sort.should == ['key1','key2','key3'].sort; done }
431
+ end
432
+ end
433
+
434
+ it "takes a set difference (SDIFF)" do
435
+ connect do |redis|
436
+ redis.sadd "set", 'a'
437
+ redis.sadd "set", 'b'
438
+ redis.sadd "set2", 'b'
439
+ redis.sadd "set2", 'c'
440
+ redis.sdiff('set', 'set2') { |r| r.should == ['a']; done }
441
+ end
442
+ end
443
+
444
+ it "takes set difference and store the results in a key (SDIFFSTORE)" do
445
+ connect do |redis|
446
+ redis.sadd "set", 'a'
447
+ redis.sadd "set", 'b'
448
+ redis.sadd "set2", 'b'
449
+ redis.sadd "set2", 'c'
450
+ redis.sdiffstore('newone', 'set', 'set2')
451
+ redis.smembers('newone') { |r| r.should == ['a']; done }
452
+ end
453
+ end
454
+
455
+ it "moves elements from one set to another (SMOVE)" do
456
+ connect do |redis|
457
+ redis.sadd 'set1', 'a'
458
+ redis.sadd 'set1', 'b'
459
+ redis.sadd 'set2', 'x'
460
+ redis.smove('set1', 'set2', 'a') { |r| r.should == 1 }
461
+ redis.sismember('set2', 'a') { |r| r.should == 1 }
462
+ redis.del('set1') { done }
463
+ end
464
+ end
465
+
466
+ it "counts the members of a zset" do
467
+ connect do |redis|
468
+ redis.sadd "set", 'key1'
469
+ redis.sadd "set", 'key2'
470
+ redis.zadd 'zset', 1, 'set'
471
+ redis.zcount('zset') { |r| r.should == 1 }
472
+ redis.del('set')
473
+ redis.del('zset') { done }
474
+ end
475
+ end
476
+
477
+ it "adds members to a zset" do
478
+ connect do |redis|
479
+ redis.sadd "set", 'key1'
480
+ redis.sadd "set", 'key2'
481
+ redis.zadd 'zset', 1, 'set'
482
+ redis.zrange('zset', 0, 1) { |r| r.should == ['set'] }
483
+ redis.zcount('zset') { |r| r.should == 1 }
484
+ redis.del('set')
485
+ redis.del('zset') { done }
486
+ end
487
+ end
488
+
489
+ it "deletes members to a zset" do
490
+ connect do |redis|
491
+ redis.sadd "set", 'key1'
492
+ redis.sadd "set", 'key2'
493
+ redis.type?('set') { |r| r.should == "set" }
494
+ redis.sadd "set2", 'key3'
495
+ redis.sadd "set2", 'key4'
496
+ redis.type?('set2') { |r| r.should == "set" }
497
+ redis.zadd 'zset', 1, 'set'
498
+ redis.zcount('zset') { |r| r.should == 1 }
499
+ redis.zadd 'zset', 2, 'set2'
500
+ redis.zcount('zset') { |r| r.should == 2 }
501
+ redis.zset_delete 'zset', 'set'
502
+ redis.zcount('zset') { |r| r.should == 1 }
503
+ redis.del('set')
504
+ redis.del('set2')
505
+ redis.del('zset') { done }
506
+ end
507
+ end
508
+
509
+ it "gets a range of values from a zset" do
510
+ connect do |redis|
511
+ redis.sadd "set", 'key1'
512
+ redis.sadd "set", 'key2'
513
+ redis.sadd "set2", 'key3'
514
+ redis.sadd "set2", 'key4'
515
+ redis.sadd "set3", 'key1'
516
+ redis.type?('set') { |r| r.should == 'set' }
517
+ redis.type?('set2') { |r| r.should == 'set' }
518
+ redis.type?('set3') { |r| r.should == 'set' }
519
+ redis.zadd 'zset', 1, 'set'
520
+ redis.zadd 'zset', 2, 'set2'
521
+ redis.zadd 'zset', 3, 'set3'
522
+ redis.zcount('zset') { |r| r.should == 3 }
523
+ redis.zrange('zset', 0, 3) { |r| r.should == ['set', 'set2', 'set3'] }
524
+ redis.del('set')
525
+ redis.del('set2')
526
+ redis.del('set3')
527
+ redis.del('zset') { done }
528
+ end
529
+ end
530
+
531
+ it "gets a reverse range of values from a zset" do
532
+ connect do |redis|
533
+ redis.sadd "set", 'key1'
534
+ redis.sadd "set", 'key2'
535
+ redis.sadd "set2", 'key3'
536
+ redis.sadd "set2", 'key4'
537
+ redis.sadd "set3", 'key1'
538
+ redis.type?('set') { |r| r.should == 'set' }
539
+ redis.type?('set2') { |r| r.should == 'set' }
540
+ redis.type?('set3') { |r| r.should == 'set' }
541
+ redis.zadd 'zset', 1, 'set'
542
+ redis.zadd 'zset', 2, 'set2'
543
+ redis.zadd 'zset', 3, 'set3'
544
+ redis.zcount('zset') { |r| r.should == 3 }
545
+ redis.zrevrange('zset', 0, 3) { |r| r.should == ['set3', 'set2', 'set'] }
546
+ redis.del('set')
547
+ redis.del('set2')
548
+ redis.del('set3')
549
+ redis.del('zset') { done }
550
+ end
551
+ end
552
+
553
+ it "gets a range by score of values from a zset" do
554
+ connect do |redis|
555
+ redis.sadd "set", 'key1'
556
+ redis.sadd "set", 'key2'
557
+ redis.sadd "set2", 'key3'
558
+ redis.sadd "set2", 'key4'
559
+ redis.sadd "set3", 'key1'
560
+ redis.sadd "set4", 'key4'
561
+ redis.zadd 'zset', 1, 'set'
562
+ redis.zadd 'zset', 2, 'set2'
563
+ redis.zadd 'zset', 3, 'set3'
564
+ redis.zadd 'zset', 4, 'set4'
565
+ redis.zcount('zset') { |r| r.should == 4 }
566
+ redis.zrangebyscore('zset', 2, 3) { |r| r.should == ['set2', 'set3'] }
567
+ redis.del('set')
568
+ redis.del('set2')
569
+ redis.del('set3')
570
+ redis.del('set4')
571
+ redis.del('zset') { done }
572
+ end
573
+ end
574
+
575
+ it "gets a score for a specific value in a zset (ZSCORE)" do
576
+ connect do |redis|
577
+ redis.zadd "zset", 23, "value"
578
+ redis.zscore("zset", "value") { |r| r.should == "23" }
579
+
580
+ redis.zscore("zset", "value2") { |r| r.should == nil }
581
+ redis.zscore("unknown_zset", "value") { |r| r.should == nil }
582
+
583
+ redis.del("zset") { done }
584
+ end
585
+ end
586
+
587
+ it "increments a range score of a zset (ZINCRBY)" do
588
+ connect do |redis|
589
+ # create a new zset
590
+ redis.zincrby "hackers", 1965, "Yukihiro Matsumoto"
591
+ redis.zscore("hackers", "Yukihiro Matsumoto") { |r| r.should == "1965" }
592
+
593
+ # add a new element
594
+ redis.zincrby "hackers", 1912, "Alan Turing"
595
+ redis.zscore("hackers", "Alan Turing") { |r| r.should == "1912" }
596
+
597
+ # update the score
598
+ redis.zincrby "hackers", 100, "Alan Turing" # yeah, we are making Turing a bit younger
599
+ redis.zscore("hackers", "Alan Turing") { |r| r.should == "2012" }
600
+
601
+ # attempt to update a key that's not a zset
602
+ redis.set("i_am_not_a_zet", "value")
603
+ # shouldn't raise error anymore
604
+ redis.zincrby("i_am_not_a_zet", 23, "element") { |r| r.should == nil }
605
+
606
+ redis.del("hackers")
607
+ redis.del("i_am_not_a_zet") { done }
608
+ end
609
+ end
610
+
611
+ it "provides info (INFO)" do
612
+ connect do |redis|
613
+ redis.info do |r|
614
+ [:redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days].each do |x|
615
+ r.keys.include?(x).should == true
616
+ end
617
+ done
618
+ end
619
+ end
620
+ end
621
+
622
+ it "provides commandstats (INFO COMMANDSTATS)" do
623
+ connect do |redis|
624
+ redis.info_commandstats do |r|
625
+ r[:get][:calls].should be_a_kind_of(Integer)
626
+ r[:get][:usec].should be_a_kind_of(Integer)
627
+ r[:get][:usec_per_call].should be_a_kind_of(Float)
628
+ done
629
+ end
630
+ end
631
+ end
632
+
633
+ it "flushes the database (FLUSHDB)" do
634
+ connect do |redis|
635
+ redis.set('key1', 'keyone')
636
+ redis.set('key2', 'keytwo')
637
+ redis.keys('*') { |r| r.sort.should == ['key1', 'key2'].sort }
638
+ redis.flushdb
639
+ redis.keys('*') { |r| r.should == []; done }
640
+ end
641
+ end
642
+
643
+ it "SELECTs database" do
644
+ connect do |redis|
645
+ redis.set("foo", "bar") do |set_response|
646
+ redis.select("10") do |select_response|
647
+ redis.get("foo") do |get_response|
648
+ get_response.should == nil; done
649
+ end
650
+ end
651
+ end
652
+ end
653
+ end
654
+
655
+ it "SELECTs database without a callback" do
656
+ connect do |redis|
657
+ redis.select("9")
658
+ redis.incr("foo") do |response|
659
+ response.should == 1
660
+ done
661
+ end
662
+ end
663
+ end
664
+
665
+ it "provides the last save time (LASTSAVE)" do
666
+ connect do |redis|
667
+ redis.lastsave do |savetime|
668
+ Time.at(savetime).class.should == Time
669
+ Time.at(savetime).should <= Time.now
670
+ done
671
+ end
672
+ end
673
+ end
674
+
675
+ it "can MGET keys" do
676
+ connect do |redis|
677
+ redis.set('foo', 1000)
678
+ redis.set('bar', 2000)
679
+ redis.mget('foo', 'bar') { |r| r.should == ['1000', '2000'] }
680
+ redis.mget('foo', 'bar', 'baz') { |r| r.should == ['1000', '2000', nil] }
681
+ redis.ping { done }
682
+ end
683
+ end
684
+
685
+ it "can MSET values" do
686
+ connect do |redis|
687
+ redis.mset "key1", "value1", "key2", "value2"
688
+ redis.get('key1') { |r| r.should == "value1" }
689
+ redis.get('key2') { |r| r.should == "value2"; done }
690
+ end
691
+ end
692
+
693
+ it "can MSETNX values" do
694
+ connect do |redis|
695
+ redis.msetnx "keynx1", "valuenx1", "keynx2", "valuenx2"
696
+ redis.mget('keynx1', 'keynx2') { |r| r.should == ["valuenx1", "valuenx2"] }
697
+
698
+ redis.set("keynx1", "value1")
699
+ redis.set("keynx2", "value2")
700
+ redis.msetnx "keynx1", "valuenx1", "keynx2", "valuenx2"
701
+ redis.mget('keynx1', 'keynx2') { |r| r.should == ["value1", "value2"]; done }
702
+ end
703
+ end
704
+
705
+ it "can BGSAVE" do
706
+ connect do |redis|
707
+ redis.bgsave do |r|
708
+ ['OK', 'Background saving started'].include?(r).should == true
709
+ done
710
+ end
711
+ end
712
+ end
713
+
714
+ it "can ECHO" do
715
+ connect do |redis|
716
+ redis.echo("message in a bottle\n") { |r| r.should == "message in a bottle\n"; done }
717
+ end
718
+ end
719
+
720
+ it "runs MULTI without a block" do
721
+ connect do |redis|
722
+ redis.multi
723
+ redis.get("key1") { |r| r.should == "QUEUED" }
724
+ redis.discard { done }
725
+ end
726
+ end
727
+
728
+ it "runs MULTI/EXEC" do
729
+ connect do |redis|
730
+ redis.multi
731
+ redis.set "key1", "value1"
732
+ redis.exec
733
+
734
+ redis.get("key1") { |r| r.should == "value1" }
735
+
736
+ begin
737
+ redis.multi
738
+ redis.set "key2", "value2"
739
+ raise "Some error"
740
+ redis.set "key3", "value3"
741
+ redis.exec
742
+ rescue
743
+ redis.discard
744
+ end
745
+
746
+ redis.get("key2") { |r| r.should == nil }
747
+ redis.get("key3") { |r| r.should == nil; done}
748
+ end
749
+ end
750
+
751
+ it "sets and get hash values" do
752
+ connect do |redis|
753
+ redis.hset("rush", "signals", "1982") { |r| r.should == 1 }
754
+ redis.hexists("rush", "signals") { |r| r.should == 1 }
755
+ redis.hget("rush", "signals") { |r| r.should == "1982"; done }
756
+ end
757
+ end
758
+
759
+ it "deletes hash values" do
760
+ connect do |redis|
761
+ redis.hset("rush", "YYZ", "1981")
762
+ redis.hdel("rush", "YYZ") { |r| r.should == 1 }
763
+ redis.hexists("rush", "YYZ") { |r| r.should == 0; done }
764
+ end
765
+ end
766
+ end
767
+
768
+ describe EventMachine::Hiredis, "with hash values" do
769
+ def set(&blk)
770
+ connect do |redis|
771
+ redis.hset("rush", "permanent waves", "1980")
772
+ redis.hset("rush", "moving pictures", "1981")
773
+ redis.hset("rush", "signals", "1982")
774
+ blk.call(redis)
775
+ end
776
+ end
777
+
778
+ it "gets the length of the hash" do
779
+ set do |redis|
780
+ redis.hlen("rush") { |r| r.should == 3 }
781
+ redis.hlen("yyz") { |r| r.should == 0; done }
782
+ end
783
+ end
784
+
785
+ it "gets the keys and values of the hash" do
786
+ set do |redis|
787
+ redis.hkeys("rush") { |r| r.should == ["permanent waves", "moving pictures", "signals"] }
788
+ redis.hvals("rush") { |r| r.should == %w[1980 1981 1982] }
789
+ redis.hvals("yyz") { |r| r.should == []; done }
790
+ end
791
+ end
792
+
793
+ it "returns all hash values" do
794
+ set do |redis|
795
+ redis.hgetall("rush") do |r|
796
+ r.should == [
797
+ "permanent waves", "1980",
798
+ "moving pictures", "1981",
799
+ "signals" , "1982"
800
+ ]
801
+ end
802
+ redis.hgetall("yyz") { |r| r.should == []; done }
803
+ end
804
+ end
805
+ end
806
+
807
+ describe EventMachine::Hiredis, "with nested multi-bulk response" do
808
+ def set(&blk)
809
+ connect do |redis|
810
+ redis.set 'user:one:id', 'id-one'
811
+ redis.set 'user:two:id', 'id-two'
812
+ redis.sadd "user:one:interests", "first-interest"
813
+ redis.sadd "user:one:interests", "second-interest"
814
+ redis.sadd "user:two:interests", "third-interest"
815
+ blk.call(redis)
816
+ end
817
+ end
818
+
819
+ it "returns array of arrays" do
820
+ set do |redis|
821
+ redis.multi
822
+ redis.smembers "user:one:interests"
823
+ redis.smembers "user:two:interests"
824
+ redis.exec do |interests_one, interests_two|
825
+ interests_one.sort.should == ["first-interest", "second-interest"]
826
+ interests_two.should == ['third-interest']
827
+ end
828
+ redis.mget("user:one:id", "user:two:id") do |user_ids|
829
+ user_ids.should == ['id-one', 'id-two']
830
+ done
831
+ end
832
+ end
833
+ end
834
+ end
835
+
836
+ describe EventMachine::Hiredis, "monitor" do
837
+ it "returns monitored commands" do
838
+ connect do |redis|
839
+ # 1. Create 2nd connection to send traffic to monitor
840
+ redis2 = EventMachine::Hiredis.connect("redis://localhost:6379/")
841
+ redis2.callback {
842
+ # 2. Monitor after command has connected
843
+ redis.monitor do |reply|
844
+ reply.should == "OK"
845
+
846
+ # 3. Command which should show up in monitor output
847
+ redis2.get('foo')
848
+ end
849
+ }
850
+
851
+ redis.on(:monitor) do |line|
852
+ line.should =~ /foo/
853
+ done
854
+ end
855
+ end
856
+ end
857
+ end
858
+
859
+ describe EventMachine::Hiredis, "sorting" do
860
+ context "with some simple sorting data" do
861
+ def set(&blk)
862
+ connect do |redis|
863
+ redis.set('dog_1', 'louie')
864
+ redis.rpush 'Dogs', 1
865
+ redis.set('dog_2', 'lucy')
866
+ redis.rpush 'Dogs', 2
867
+ redis.set('dog_3', 'max')
868
+ redis.rpush 'Dogs', 3
869
+ redis.set('dog_4', 'taj')
870
+ redis.rpush 'Dogs', 4
871
+ blk.call(redis)
872
+ end
873
+ end
874
+
875
+ it "sorts with a limit" do
876
+ set do |redis|
877
+ redis.sort('Dogs', "GET", 'dog_*', "LIMIT", "0", "1") do |r|
878
+ r.should == ['louie']
879
+ done
880
+ end
881
+ end
882
+ end
883
+
884
+ it "sorts with a limit and order" do
885
+ set do |redis|
886
+ redis.sort('Dogs', "GET", 'dog_*', "LIMIT", "0", "1", "desc", "alpha") do |r|
887
+ r.should == ['taj']
888
+ done
889
+ end
890
+ end
891
+ end
892
+ end
893
+
894
+ context "with more complex sorting data" do
895
+ def set(&blk)
896
+ connect do |redis|
897
+ redis.set('dog:1:name', 'louie')
898
+ redis.set('dog:1:breed', 'mutt')
899
+ redis.rpush 'dogs', 1
900
+ redis.set('dog:2:name', 'lucy')
901
+ redis.set('dog:2:breed', 'poodle')
902
+ redis.rpush 'dogs', 2
903
+ redis.set('dog:3:name', 'max')
904
+ redis.set('dog:3:breed', 'hound')
905
+ redis.rpush 'dogs', 3
906
+ redis.set('dog:4:name', 'taj')
907
+ redis.set('dog:4:breed', 'terrier')
908
+ redis.rpush 'dogs', 4
909
+ blk.call(redis)
910
+ end
911
+ end
912
+
913
+ it "handles multiple GETs" do
914
+ set do |redis|
915
+ redis.sort('dogs', 'GET', 'dog:*:name', 'GET', 'dog:*:breed', 'LIMIT', '0', '1') do |r|
916
+ r.should == ['louie', 'mutt']
917
+ done
918
+ end
919
+ end
920
+ end
921
+
922
+ it "handles multiple GETs with an order" do
923
+ set do |redis|
924
+ redis.sort('dogs', 'GET', 'dog:*:name', 'GET', 'dog:*:breed', 'LIMIT', '0', '1', 'desc', 'alpha') do |r|
925
+ r.should == ['taj', 'terrier']
926
+ done
927
+ end
928
+ end
929
+ end
930
+ end
931
+ end