em-hiredis 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,910 @@
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
+ [:last_save_time, :redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days, :changes_since_last_save].each do |x|
615
+ r.keys.include?(x).should == true
616
+ end
617
+ done
618
+ end
619
+ end
620
+ end
621
+
622
+ it "flushes the database (FLUSHDB)" do
623
+ connect do |redis|
624
+ redis.set('key1', 'keyone')
625
+ redis.set('key2', 'keytwo')
626
+ redis.keys('*') { |r| r.sort.should == ['key1', 'key2'].sort }
627
+ redis.flushdb
628
+ redis.keys('*') { |r| r.should == []; done }
629
+ end
630
+ end
631
+
632
+ it "SELECTs database" do
633
+ connect do |redis|
634
+ redis.set("foo", "bar") do |set_response|
635
+ redis.select("9") do |select_response|
636
+ redis.get("foo") do |get_response|
637
+ get_response.should == nil; done
638
+ end
639
+ end
640
+ end
641
+ end
642
+ end
643
+
644
+ it "SELECTs database without a callback" do
645
+ connect do |redis|
646
+ redis.select("9")
647
+ redis.incr("foo") do |response|
648
+ response.should == 1
649
+ done
650
+ end
651
+ end
652
+ end
653
+
654
+ it "provides the last save time (LASTSAVE)" do
655
+ connect do |redis|
656
+ redis.lastsave do |savetime|
657
+ Time.at(savetime).class.should == Time
658
+ Time.at(savetime).should <= Time.now
659
+ done
660
+ end
661
+ end
662
+ end
663
+
664
+ it "can MGET keys" do
665
+ connect do |redis|
666
+ redis.set('foo', 1000)
667
+ redis.set('bar', 2000)
668
+ redis.mget('foo', 'bar') { |r| r.should == ['1000', '2000'] }
669
+ redis.mget('foo', 'bar', 'baz') { |r| r.should == ['1000', '2000', nil] }
670
+ redis.ping { done }
671
+ end
672
+ end
673
+
674
+ it "can MSET values" do
675
+ connect do |redis|
676
+ redis.mset "key1", "value1", "key2", "value2"
677
+ redis.get('key1') { |r| r.should == "value1" }
678
+ redis.get('key2') { |r| r.should == "value2"; done }
679
+ end
680
+ end
681
+
682
+ it "can MSETNX values" do
683
+ connect do |redis|
684
+ redis.msetnx "keynx1", "valuenx1", "keynx2", "valuenx2"
685
+ redis.mget('keynx1', 'keynx2') { |r| r.should == ["valuenx1", "valuenx2"] }
686
+
687
+ redis.set("keynx1", "value1")
688
+ redis.set("keynx2", "value2")
689
+ redis.msetnx "keynx1", "valuenx1", "keynx2", "valuenx2"
690
+ redis.mget('keynx1', 'keynx2') { |r| r.should == ["value1", "value2"]; done }
691
+ end
692
+ end
693
+
694
+ it "can BGSAVE" do
695
+ connect do |redis|
696
+ redis.bgsave do |r|
697
+ ['OK', 'Background saving started'].include?(r).should == true
698
+ done
699
+ end
700
+ end
701
+ end
702
+
703
+ it "can ECHO" do
704
+ connect do |redis|
705
+ redis.echo("message in a bottle\n") { |r| r.should == "message in a bottle\n"; done }
706
+ end
707
+ end
708
+
709
+ it "runs MULTI without a block" do
710
+ connect do |redis|
711
+ redis.multi
712
+ redis.get("key1") { |r| r.should == "QUEUED" }
713
+ redis.discard { done }
714
+ end
715
+ end
716
+
717
+ it "runs MULTI/EXEC" do
718
+ connect do |redis|
719
+ redis.multi
720
+ redis.set "key1", "value1"
721
+ redis.exec
722
+
723
+ redis.get("key1") { |r| r.should == "value1" }
724
+
725
+ begin
726
+ redis.multi
727
+ redis.set "key2", "value2"
728
+ raise "Some error"
729
+ redis.set "key3", "value3"
730
+ redis.exec
731
+ rescue
732
+ redis.discard
733
+ end
734
+
735
+ redis.get("key2") { |r| r.should == nil }
736
+ redis.get("key3") { |r| r.should == nil; done}
737
+ end
738
+ end
739
+
740
+ it "sets and get hash values" do
741
+ connect do |redis|
742
+ redis.hset("rush", "signals", "1982") { |r| r.should == 1 }
743
+ redis.hexists("rush", "signals") { |r| r.should == 1 }
744
+ redis.hget("rush", "signals") { |r| r.should == "1982"; done }
745
+ end
746
+ end
747
+
748
+ it "deletes hash values" do
749
+ connect do |redis|
750
+ redis.hset("rush", "YYZ", "1981")
751
+ redis.hdel("rush", "YYZ") { |r| r.should == 1 }
752
+ redis.hexists("rush", "YYZ") { |r| r.should == 0; done }
753
+ end
754
+ end
755
+ end
756
+
757
+ describe EventMachine::Hiredis, "with hash values" do
758
+ def set(&blk)
759
+ connect do |redis|
760
+ redis.hset("rush", "permanent waves", "1980")
761
+ redis.hset("rush", "moving pictures", "1981")
762
+ redis.hset("rush", "signals", "1982")
763
+ blk.call(redis)
764
+ end
765
+ end
766
+
767
+ it "gets the length of the hash" do
768
+ set do |redis|
769
+ redis.hlen("rush") { |r| r.should == 3 }
770
+ redis.hlen("yyz") { |r| r.should == 0; done }
771
+ end
772
+ end
773
+
774
+ it "gets the keys and values of the hash" do
775
+ set do |redis|
776
+ redis.hkeys("rush") { |r| r.should == ["permanent waves", "moving pictures", "signals"] }
777
+ redis.hvals("rush") { |r| r.should == %w[1980 1981 1982] }
778
+ redis.hvals("yyz") { |r| r.should == []; done }
779
+ end
780
+ end
781
+
782
+ it "returns all hash values" do
783
+ set do |redis|
784
+ redis.hgetall("rush") do |r|
785
+ r.should == [
786
+ "permanent waves", "1980",
787
+ "moving pictures", "1981",
788
+ "signals" , "1982"
789
+ ]
790
+ end
791
+ redis.hgetall("yyz") { |r| r.should == []; done }
792
+ end
793
+ end
794
+ end
795
+
796
+ describe EventMachine::Hiredis, "with nested multi-bulk response" do
797
+ def set(&blk)
798
+ connect do |redis|
799
+ redis.set 'user:one:id', 'id-one'
800
+ redis.set 'user:two:id', 'id-two'
801
+ redis.sadd "user:one:interests", "first-interest"
802
+ redis.sadd "user:one:interests", "second-interest"
803
+ redis.sadd "user:two:interests", "third-interest"
804
+ blk.call(redis)
805
+ end
806
+ end
807
+
808
+ it "returns array of arrays" do
809
+ set do |redis|
810
+ redis.multi
811
+ redis.smembers "user:one:interests"
812
+ redis.smembers "user:two:interests"
813
+ redis.exec do |user_interests|
814
+ user_interests.should == [["second-interest", "first-interest"], ['third-interest']]
815
+ end
816
+ redis.mget("user:one:id", "user:two:id") do |user_ids|
817
+ user_ids.should == ['id-one', 'id-two']
818
+ done
819
+ end
820
+ end
821
+ end
822
+ end
823
+
824
+ describe EventMachine::Hiredis, "monitor" do
825
+ it "returns monitored commands" do
826
+ connect do |redis|
827
+ redis.monitor do |reply|
828
+ reply.should == "OK"
829
+ end
830
+ redis.on(:monitor) do |line|
831
+ line.should =~ /monitor/
832
+ done
833
+ end
834
+ end
835
+ end
836
+ end
837
+
838
+ describe EventMachine::Hiredis, "sorting" do
839
+ context "with some simple sorting data" do
840
+ def set(&blk)
841
+ connect do |redis|
842
+ redis.set('dog_1', 'louie')
843
+ redis.rpush 'Dogs', 1
844
+ redis.set('dog_2', 'lucy')
845
+ redis.rpush 'Dogs', 2
846
+ redis.set('dog_3', 'max')
847
+ redis.rpush 'Dogs', 3
848
+ redis.set('dog_4', 'taj')
849
+ redis.rpush 'Dogs', 4
850
+ blk.call(redis)
851
+ end
852
+ end
853
+
854
+ it "sorts with a limit" do
855
+ set do |redis|
856
+ redis.sort('Dogs', "GET", 'dog_*', "LIMIT", "0", "1") do |r|
857
+ r.should == ['louie']
858
+ done
859
+ end
860
+ end
861
+ end
862
+
863
+ it "sorts with a limit and order" do
864
+ set do |redis|
865
+ redis.sort('Dogs', "GET", 'dog_*', "LIMIT", "0", "1", "desc", "alpha") do |r|
866
+ r.should == ['taj']
867
+ done
868
+ end
869
+ end
870
+ end
871
+ end
872
+
873
+ context "with more complex sorting data" do
874
+ def set(&blk)
875
+ connect do |redis|
876
+ redis.set('dog:1:name', 'louie')
877
+ redis.set('dog:1:breed', 'mutt')
878
+ redis.rpush 'dogs', 1
879
+ redis.set('dog:2:name', 'lucy')
880
+ redis.set('dog:2:breed', 'poodle')
881
+ redis.rpush 'dogs', 2
882
+ redis.set('dog:3:name', 'max')
883
+ redis.set('dog:3:breed', 'hound')
884
+ redis.rpush 'dogs', 3
885
+ redis.set('dog:4:name', 'taj')
886
+ redis.set('dog:4:breed', 'terrier')
887
+ redis.rpush 'dogs', 4
888
+ blk.call(redis)
889
+ end
890
+ end
891
+
892
+ it "handles multiple GETs" do
893
+ set do |redis|
894
+ redis.sort('dogs', 'GET', 'dog:*:name', 'GET', 'dog:*:breed', 'LIMIT', '0', '1') do |r|
895
+ r.should == ['louie', 'mutt']
896
+ done
897
+ end
898
+ end
899
+ end
900
+
901
+ it "handles multiple GETs with an order" do
902
+ set do |redis|
903
+ redis.sort('dogs', 'GET', 'dog:*:name', 'GET', 'dog:*:breed', 'LIMIT', '0', '1', 'desc', 'alpha') do |r|
904
+ r.should == ['taj', 'terrier']
905
+ done
906
+ end
907
+ end
908
+ end
909
+ end
910
+ end