em-redis 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,761 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/test_helper.rb")
2
- require 'logger'
3
-
4
- EM.describe EM::Protocols::Redis do
5
- default_timeout 1
6
-
7
- before do
8
- @r = EM::Protocols::Redis.connect :db => 14
9
- @r.flushdb
10
- @r['foo'] = 'bar'
11
- end
12
-
13
- after { @r.close_connection }
14
-
15
- should "be able to provide a logger" do
16
- log = StringIO.new
17
- r = EM::Protocols::Redis.connect :db => 14, :logger => Logger.new(log)
18
- r.ping do
19
- log.string.should.include "ping"
20
- done
21
- end
22
- end
23
-
24
- it "should be able to PING" do
25
- @r.ping { |r| r.should == 'PONG'; done }
26
- end
27
-
28
- it "should be able to GET a key" do
29
- @r.get('foo') { |r| r.should == 'bar'; done }
30
- end
31
-
32
- it "should be able to SET a key" do
33
- @r['foo'] = 'nik'
34
- @r.get('foo') { |r| r.should == 'nik'; done }
35
- end
36
-
37
- it "should properly handle trailing newline characters" do
38
- @r['foo'] = "bar\n"
39
- @r.get('foo') { |r| r.should == "bar\n"; done }
40
- end
41
-
42
- it "should store and retrieve all possible characters at the beginning and the end of a string" do
43
- (0..255).each do |char_idx|
44
- string = "#{char_idx.chr}---#{char_idx.chr}"
45
- @r['foo'] = string
46
- @r.get('foo') { |r| r.should == string }
47
- end
48
- @r.ping { done }
49
- end
50
-
51
- it "should be able to SET a key with an expiry" do
52
- timeout(3)
53
-
54
- @r.set('foo', 'bar', 1)
55
- @r.get('foo') { |r| r.should == 'bar' }
56
- EM.add_timer(2) do
57
- @r.get('foo') { |r| r.should == nil }
58
- @r.ping { done }
59
- end
60
- end
61
-
62
- it "should be able to return a TTL for a key" do
63
- @r.set('foo', 'bar', 1)
64
- @r.ttl('foo') { |r| r.should == 1; done }
65
- end
66
-
67
- it "should be able to SETNX" do
68
- @r['foo'] = 'nik'
69
- @r.get('foo') { |r| r.should == 'nik' }
70
- @r.setnx 'foo', 'bar'
71
- @r.get('foo') { |r| r.should == 'nik' }
72
-
73
- @r.ping { done }
74
- end
75
- #
76
- it "should be able to GETSET" do
77
- @r.getset('foo', 'baz') { |r| r.should == 'bar' }
78
- @r.get('foo') { |r| r.should == 'baz'; done }
79
- end
80
- #
81
- it "should be able to INCR a key" do
82
- @r.del('counter')
83
- @r.incr('counter') { |r| r.should == 1 }
84
- @r.incr('counter') { |r| r.should == 2 }
85
- @r.incr('counter') { |r| r.should == 3 }
86
-
87
- @r.ping { done }
88
- end
89
- #
90
- it "should be able to INCRBY a key" do
91
- @r.del('counter')
92
- @r.incrby('counter', 1) { |r| r.should == 1 }
93
- @r.incrby('counter', 2) { |r| r.should == 3 }
94
- @r.incrby('counter', 3) { |r| r.should == 6 }
95
-
96
- @r.ping { done }
97
- end
98
- #
99
- it "should be able to DECR a key" do
100
- @r.del('counter')
101
- @r.incr('counter') { |r| r.should == 1 }
102
- @r.incr('counter') { |r| r.should == 2 }
103
- @r.incr('counter') { |r| r.should == 3 }
104
- @r.decr('counter') { |r| r.should == 2 }
105
- @r.decr('counter', 2) { |r| r.should == 0; done }
106
- end
107
- #
108
- it "should be able to RANDKEY" do
109
- @r.randkey { |r| r.should.not == nil; done }
110
- end
111
- #
112
- it "should be able to RENAME a key" do
113
- @r.del 'foo'
114
- @r.del 'bar'
115
- @r['foo'] = 'hi'
116
- @r.rename 'foo', 'bar'
117
- @r.get('bar') { |r| r.should == 'hi' ; done }
118
- end
119
- #
120
- it "should be able to RENAMENX a key" do
121
- @r.del 'foo'
122
- @r.del 'bar'
123
- @r['foo'] = 'hi'
124
- @r['bar'] = 'ohai'
125
- @r.renamenx 'foo', 'bar'
126
- @r.get('bar') { |r| r.should == 'ohai' ; done }
127
- end
128
- #
129
- it "should be able to get DBSIZE of the database" do
130
- dbsize_without_foo, dbsize_with_foo = nil
131
- @r.delete 'foo'
132
- @r.dbsize { |r| dbsize_without_foo = r }
133
- @r['foo'] = 0
134
- @r.dbsize { |r| dbsize_with_foo = r }
135
-
136
- @r.ping do
137
- dbsize_with_foo.should == dbsize_without_foo + 1
138
- done
139
- end
140
- end
141
- #
142
- it "should be able to EXPIRE a key" do
143
- timeout(3)
144
-
145
- @r['foo'] = 'bar'
146
- @r.expire 'foo', 1
147
- @r.get('foo') { |r| r.should == "bar" }
148
- EM.add_timer(2) do
149
- @r.get('foo') { |r| r.should == nil }
150
- @r.ping { done }
151
- end
152
- end
153
- #
154
- it "should be able to EXISTS" do
155
- @r['foo'] = 'nik'
156
- @r.exists('foo') { |r| r.should == true }
157
- @r.del 'foo'
158
- @r.exists('foo') { |r| r.should == false ; done }
159
- end
160
- #
161
- it "should be able to KEYS" do
162
- @r.keys("f*") { |keys| keys.each { |key| @r.del key } }
163
- @r['f'] = 'nik'
164
- @r['fo'] = 'nak'
165
- @r['foo'] = 'qux'
166
- @r.keys("f*") { |r| r.sort.should == ['f', 'fo', 'foo'].sort }
167
-
168
- @r.ping { done }
169
- end
170
- #
171
- it "should be able to return a random key (RANDOMKEY)" do
172
- 3.times do |i|
173
- @r.randomkey do |r|
174
- @r.exists(r) do |e|
175
- e.should == true
176
- done if i == 2
177
- end
178
- end
179
- end
180
- end
181
- #
182
- it "should be able to check the TYPE of a key" do
183
- @r['foo'] = 'nik'
184
- @r.type('foo') { |r| r.should == "string" }
185
- @r.del 'foo'
186
- @r.type('foo') { |r| r.should == "none" ; done }
187
- end
188
- #
189
- it "should be able to push to the head of a list (LPUSH)" do
190
- @r.lpush "list", 'hello'
191
- @r.lpush "list", 42
192
- @r.type('list') { |r| r.should == "list" }
193
- @r.llen('list') { |r| r.should == 2 }
194
- @r.lpop('list') { |r| r.should == '42'; done }
195
- end
196
- #
197
- it "should be able to push to the tail of a list (RPUSH)" do
198
- @r.rpush "list", 'hello'
199
- @r.type('list') { |r| r.should == "list" }
200
- @r.llen('list') { |r| r.should == 1 ; done }
201
- end
202
- #
203
- it "should be able to pop the tail of a list (RPOP)" do
204
- @r.rpush "list", 'hello'
205
- @r.rpush"list", 'goodbye'
206
- @r.type('list') { |r| r.should == "list" }
207
- @r.llen('list') { |r| r.should == 2 }
208
- @r.rpop('list') { |r| r.should == 'goodbye'; done }
209
- end
210
- #
211
- it "should be able to pop the head of a list (LPOP)" do
212
- @r.rpush "list", 'hello'
213
- @r.rpush "list", 'goodbye'
214
- @r.type('list') { |r| r.should == "list" }
215
- @r.llen('list') { |r| r.should == 2 }
216
- @r.lpop('list') { |r| r.should == 'hello'; done }
217
- end
218
- #
219
- it "should be able to get the length of a list (LLEN)" do
220
- @r.rpush "list", 'hello'
221
- @r.rpush "list", 'goodbye'
222
- @r.type('list') { |r| r.should == "list" }
223
- @r.llen('list') { |r| r.should == 2 ; done }
224
- end
225
- #
226
- it "should be able to get a range of values from a list (LRANGE)" do
227
- @r.rpush "list", 'hello'
228
- @r.rpush "list", 'goodbye'
229
- @r.rpush "list", '1'
230
- @r.rpush "list", '2'
231
- @r.rpush "list", '3'
232
- @r.type('list') { |r| r.should == "list" }
233
- @r.llen('list') { |r| r.should == 5 }
234
- @r.lrange('list', 2, -1) { |r| r.should == ['1', '2', '3']; done }
235
- end
236
- #
237
- it "should be able to trim a list (LTRIM)" do
238
- @r.rpush "list", 'hello'
239
- @r.rpush "list", 'goodbye'
240
- @r.rpush "list", '1'
241
- @r.rpush "list", '2'
242
- @r.rpush "list", '3'
243
- @r.type('list') { |r| r.should == "list" }
244
- @r.llen('list') { |r| r.should == 5 }
245
- @r.ltrim 'list', 0, 1
246
- @r.llen('list') { |r| r.should == 2 }
247
- @r.lrange('list', 0, -1) { |r| r.should == ['hello', 'goodbye']; done }
248
- end
249
- #
250
- it "should be able to get a value by indexing into a list (LINDEX)" do
251
- @r.rpush "list", 'hello'
252
- @r.rpush "list", 'goodbye'
253
- @r.type('list') { |r| r.should == "list" }
254
- @r.llen('list') { |r| r.should == 2 }
255
- @r.lindex('list', 1) { |r| r.should == 'goodbye'; done }
256
- end
257
- #
258
- it "should be able to set a value by indexing into a list (LSET)" do
259
- @r.rpush "list", 'hello'
260
- @r.rpush "list", 'hello'
261
- @r.type('list') { |r| r.should == "list" }
262
- @r.llen('list') { |r| r.should == 2 }
263
- @r.lset('list', 1, 'goodbye') { |r| r.should == 'OK' }
264
- @r.lindex('list', 1) { |r| r.should == 'goodbye'; done }
265
- end
266
- #
267
- it "should be able to remove values from a list (LREM)" do
268
- @r.rpush "list", 'hello'
269
- @r.rpush "list", 'goodbye'
270
- @r.type('list') { |r| r.should == "list" }
271
- @r.llen('list') { |r| r.should == 2 }
272
- @r.lrem('list', 1, 'hello') { |r| r.should == 1 }
273
- @r.lrange('list', 0, -1) { |r| r.should == ['goodbye']; done }
274
- end
275
-
276
- it "should be able to pop values from a list and push them onto a temp list(RPOPLPUSH)" do
277
- @r.rpush "list", 'one'
278
- @r.rpush "list", 'two'
279
- @r.rpush "list", 'three'
280
- @r.type('list') { |r| r.should == "list" }
281
- @r.llen('list') { |r| r.should == 3 }
282
- @r.lrange('list', 0, -1) { |r| r.should == ['one', 'two', 'three'] }
283
- @r.lrange('tmp', 0, -1) { |r| r.should == [] }
284
- @r.rpoplpush('list', 'tmp') { |r| r.should == 'three' }
285
- @r.lrange('tmp', 0, -1) { |r| r.should == ['three'] }
286
- @r.rpoplpush('list', 'tmp') { |r| r.should == 'two' }
287
- @r.lrange('tmp', 0, -1) { |r| r.should == ['two', 'three'] }
288
- @r.rpoplpush('list', 'tmp') { |r| r.should == 'one' }
289
- @r.lrange('tmp', 0, -1) { |r| r.should == ['one', 'two', 'three']; done }
290
- end
291
- #
292
- it "should be able add members to a set (SADD)" do
293
- @r.sadd "set", 'key1'
294
- @r.sadd "set", 'key2'
295
- @r.type('set') { |r| r.should == "set" }
296
- @r.scard('set') { |r| r.should == 2 }
297
- @r.smembers('set') { |r| r.sort.should == ['key1', 'key2'].sort; done }
298
- end
299
- #
300
- it "should be able delete members to a set (SREM)" do
301
- @r.sadd "set", 'key1'
302
- @r.sadd "set", 'key2'
303
- @r.type('set') { |r| r.should == "set" }
304
- @r.scard('set') { |r| r.should == 2 }
305
- @r.smembers('set') { |r| r.sort.should == ['key1', 'key2'].sort }
306
- @r.srem('set', 'key1')
307
- @r.scard('set') { |r| r.should == 1 }
308
- @r.smembers('set') { |r| r.should == ['key2']; done }
309
- end
310
- #
311
- it "should be able to return and remove random key from set (SPOP)" do
312
- @r.sadd "set_pop", "key1"
313
- @r.sadd "set_pop", "key2"
314
- @r.spop("set_pop") { |r| r.should.not == nil }
315
- @r.scard("set_pop") { |r| r.should == 1; done }
316
- end
317
- #
318
- it "should be able to return random key without delete the key from a set (SRANDMEMBER)" do
319
- @r.sadd "set_srandmember", "key1"
320
- @r.sadd "set_srandmember", "key2"
321
- @r.srandmember("set_srandmember") { |r| r.should.not == nil }
322
- @r.scard("set_srandmember") { |r| r.should == 2; done }
323
- end
324
- #
325
- it "should be able count the members of a set (SCARD)" do
326
- @r.sadd "set", 'key1'
327
- @r.sadd "set", 'key2'
328
- @r.type('set') { |r| r.should == "set" }
329
- @r.scard('set') { |r| r.should == 2; done }
330
- end
331
- #
332
- it "should be able test for set membership (SISMEMBER)" do
333
- @r.sadd "set", 'key1'
334
- @r.sadd "set", 'key2'
335
- @r.type('set') { |r| r.should == "set" }
336
- @r.scard('set') { |r| r.should == 2 }
337
- @r.sismember('set', 'key1') { |r| r.should == true }
338
- @r.sismember('set', 'key2') { |r| r.should == true }
339
- @r.sismember('set', 'notthere') { |r| r.should == false; done }
340
- end
341
- #
342
- it "should be able to do set intersection (SINTER)" do
343
- @r.sadd "set", 'key1'
344
- @r.sadd "set", 'key2'
345
- @r.sadd "set2", 'key2'
346
- @r.sinter('set', 'set2') { |r| r.should == ['key2']; done }
347
- end
348
- #
349
- it "should be able to do set intersection and store the results in a key (SINTERSTORE)" do
350
- @r.sadd "set", 'key1'
351
- @r.sadd "set", 'key2'
352
- @r.sadd "set2", 'key2'
353
- @r.sinterstore('newone', 'set', 'set2') { |r| r.should == 1 }
354
- @r.smembers('newone') { |r| r.should == ['key2']; done }
355
- end
356
- #
357
- it "should be able to do set union (SUNION)" do
358
- @r.sadd "set", 'key1'
359
- @r.sadd "set", 'key2'
360
- @r.sadd "set2", 'key2'
361
- @r.sadd "set2", 'key3'
362
- @r.sunion('set', 'set2') { |r| r.sort.should == ['key1','key2','key3'].sort; done }
363
- end
364
- #
365
- it "should be able to do set union and store the results in a key (SUNIONSTORE)" do
366
- @r.sadd "set", 'key1'
367
- @r.sadd "set", 'key2'
368
- @r.sadd "set2", 'key2'
369
- @r.sadd "set2", 'key3'
370
- @r.sunionstore('newone', 'set', 'set2') { |r| r.should == 3 }
371
- @r.smembers('newone') { |r| r.sort.should == ['key1','key2','key3'].sort; done }
372
- end
373
- #
374
- it "should be able to do set difference (SDIFF)" do
375
- @r.sadd "set", 'a'
376
- @r.sadd "set", 'b'
377
- @r.sadd "set2", 'b'
378
- @r.sadd "set2", 'c'
379
- @r.sdiff('set', 'set2') { |r| r.should == ['a']; done }
380
- end
381
- #
382
- it "should be able to do set difference and store the results in a key (SDIFFSTORE)" do
383
- @r.sadd "set", 'a'
384
- @r.sadd "set", 'b'
385
- @r.sadd "set2", 'b'
386
- @r.sadd "set2", 'c'
387
- @r.sdiffstore('newone', 'set', 'set2')
388
- @r.smembers('newone') { |r| r.should == ['a']; done }
389
- end
390
- #
391
- it "should be able move elements from one set to another (SMOVE)" do
392
- @r.sadd 'set1', 'a'
393
- @r.sadd 'set1', 'b'
394
- @r.sadd 'set2', 'x'
395
- @r.smove('set1', 'set2', 'a') { |r| r.should == true }
396
- @r.sismember('set2', 'a') { |r| r.should == true }
397
- @r.delete('set1') { done }
398
- end
399
- #
400
- it "should be able to do crazy SORT queries" do
401
- # The 'Dogs' is capitialized on purpose
402
- @r['dog_1'] = 'louie'
403
- @r.rpush 'Dogs', 1
404
- @r['dog_2'] = 'lucy'
405
- @r.rpush 'Dogs', 2
406
- @r['dog_3'] = 'max'
407
- @r.rpush 'Dogs', 3
408
- @r['dog_4'] = 'taj'
409
- @r.rpush 'Dogs', 4
410
- @r.sort('Dogs', :get => 'dog_*', :limit => [0,1]) { |r| r.should == ['louie'] }
411
- @r.sort('Dogs', :get => 'dog_*', :limit => [0,1], :order => 'desc alpha') { |r| r.should == ['taj'] }
412
- @r.ping { done }
413
- end
414
-
415
- it "should be able to handle array of :get using SORT" do
416
- @r['dog:1:name'] = 'louie'
417
- @r['dog:1:breed'] = 'mutt'
418
- @r.rpush 'dogs', 1
419
- @r['dog:2:name'] = 'lucy'
420
- @r['dog:2:breed'] = 'poodle'
421
- @r.rpush 'dogs', 2
422
- @r['dog:3:name'] = 'max'
423
- @r['dog:3:breed'] = 'hound'
424
- @r.rpush 'dogs', 3
425
- @r['dog:4:name'] = 'taj'
426
- @r['dog:4:breed'] = 'terrier'
427
- @r.rpush 'dogs', 4
428
- @r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1]) { |r| r.should == ['louie', 'mutt'] }
429
- @r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1], :order => 'desc alpha') { |r| r.should == ['taj', 'terrier'] }
430
- @r.ping { done }
431
- end
432
- #
433
- it "should be able count the members of a zset" do
434
- @r.set_add "set", 'key1'
435
- @r.set_add "set", 'key2'
436
- @r.zset_add 'zset', 1, 'set'
437
- @r.zset_count('zset') { |r| r.should == 1 }
438
- @r.delete('set')
439
- @r.delete('zset') { done }
440
- end
441
- #
442
- it "should be able add members to a zset" do
443
- @r.set_add "set", 'key1'
444
- @r.set_add "set", 'key2'
445
- @r.zset_add 'zset', 1, 'set'
446
- @r.zset_range('zset', 0, 1) { |r| r.should == ['set'] }
447
- @r.zset_count('zset') { |r| r.should == 1 }
448
- @r.delete('set')
449
- @r.delete('zset') { done }
450
- end
451
- #
452
- it "should be able delete members to a zset" do
453
- @r.set_add "set", 'key1'
454
- @r.set_add "set", 'key2'
455
- @r.type?('set') { |r| r.should == "set" }
456
- @r.set_add "set2", 'key3'
457
- @r.set_add "set2", 'key4'
458
- @r.type?('set2') { |r| r.should == "set" }
459
- @r.zset_add 'zset', 1, 'set'
460
- @r.zset_count('zset') { |r| r.should == 1 }
461
- @r.zset_add 'zset', 2, 'set2'
462
- @r.zset_count('zset') { |r| r.should == 2 }
463
- @r.zset_delete 'zset', 'set'
464
- @r.zset_count('zset') { |r| r.should == 1 }
465
- @r.delete('set')
466
- @r.delete('set2')
467
- @r.delete('zset') { done }
468
- end
469
- #
470
- it "should be able to get a range of values from a zset" do
471
- @r.set_add "set", 'key1'
472
- @r.set_add "set", 'key2'
473
- @r.set_add "set2", 'key3'
474
- @r.set_add "set2", 'key4'
475
- @r.set_add "set3", 'key1'
476
- @r.type?('set') { |r| r.should == 'set' }
477
- @r.type?('set2') { |r| r.should == 'set' }
478
- @r.type?('set3') { |r| r.should == 'set' }
479
- @r.zset_add 'zset', 1, 'set'
480
- @r.zset_add 'zset', 2, 'set2'
481
- @r.zset_add 'zset', 3, 'set3'
482
- @r.zset_count('zset') { |r| r.should == 3 }
483
- @r.zset_range('zset', 0, 3) { |r| r.should == ['set', 'set2', 'set3'] }
484
- @r.delete('set')
485
- @r.delete('set2')
486
- @r.delete('set3')
487
- @r.delete('zset') { done }
488
- end
489
- #
490
- it "should be able to get a reverse range of values from a zset" do
491
- @r.set_add "set", 'key1'
492
- @r.set_add "set", 'key2'
493
- @r.set_add "set2", 'key3'
494
- @r.set_add "set2", 'key4'
495
- @r.set_add "set3", 'key1'
496
- @r.type?('set') { |r| r.should == 'set' }
497
- @r.type?('set2') { |r| r.should == 'set' }
498
- @r.type?('set3') { |r| r.should == 'set' }
499
- @r.zset_add 'zset', 1, 'set'
500
- @r.zset_add 'zset', 2, 'set2'
501
- @r.zset_add 'zset', 3, 'set3'
502
- @r.zset_count('zset') { |r| r.should == 3 }
503
- @r.zset_reverse_range('zset', 0, 3) { |r| r.should == ['set3', 'set2', 'set'] }
504
- @r.delete('set')
505
- @r.delete('set2')
506
- @r.delete('set3')
507
- @r.delete('zset') { done }
508
- end
509
- #
510
- it "should be able to get a range by score of values from a zset" do
511
- @r.set_add "set", 'key1'
512
- @r.set_add "set", 'key2'
513
- @r.set_add "set2", 'key3'
514
- @r.set_add "set2", 'key4'
515
- @r.set_add "set3", 'key1'
516
- @r.set_add "set4", 'key4'
517
- @r.zset_add 'zset', 1, 'set'
518
- @r.zset_add 'zset', 2, 'set2'
519
- @r.zset_add 'zset', 3, 'set3'
520
- @r.zset_add 'zset', 4, 'set4'
521
- @r.zset_count('zset') { |r| r.should == 4 }
522
- @r.zset_range_by_score('zset', 2, 3) { |r| r.should == ['set2', 'set3'] }
523
- @r.delete('set')
524
- @r.delete('set2')
525
- @r.delete('set3')
526
- @r.delete('set4')
527
- @r.delete('zset') { done }
528
- end
529
- #
530
- it "should be able to get a score for a specific value in a zset (ZSCORE)" do
531
- @r.zset_add "zset", 23, "value"
532
- @r.zset_score("zset", "value") { |r| r.should == "23" }
533
-
534
- @r.zset_score("zset", "value2") { |r| r.should == nil }
535
- @r.zset_score("unknown_zset", "value") { |r| r.should == nil }
536
-
537
- @r.delete("zset") { done }
538
- end
539
- #
540
- it "should be able to increment a range score of a zset (ZINCRBY)" do
541
- # create a new zset
542
- @r.zset_increment_by "hackers", 1965, "Yukihiro Matsumoto"
543
- @r.zset_score("hackers", "Yukihiro Matsumoto") { |r| r.should == "1965" }
544
-
545
- # add a new element
546
- @r.zset_increment_by "hackers", 1912, "Alan Turing"
547
- @r.zset_score("hackers", "Alan Turing") { |r| r.should == "1912" }
548
-
549
- # update the score
550
- @r.zset_increment_by "hackers", 100, "Alan Turing" # yeah, we are making Turing a bit younger
551
- @r.zset_score("hackers", "Alan Turing") { |r| r.should == "2012" }
552
-
553
- # attempt to update a key that's not a zset
554
- @r["i_am_not_a_zet"] = "value"
555
- # should raise error
556
- @r.on_error { true.should == true }
557
- @r.zset_incr_by("i_am_not_a_zet", 23, "element") { false.should == true }
558
-
559
- @r.delete("hackers")
560
- @r.delete("i_am_not_a_zet") { done }
561
- end
562
- #
563
- it "should provide info (INFO)" do
564
- @r.info do |r|
565
- [: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|
566
- r.keys.include?(x).should == true
567
- end
568
- done
569
- end
570
- end
571
- #
572
- it "should be able to flush the database (FLUSHDB)" do
573
- @r['key1'] = 'keyone'
574
- @r['key2'] = 'keytwo'
575
- @r.keys('*') { |r| r.sort.should == ['foo', 'key1', 'key2'].sort } #foo from before
576
- @r.flushdb
577
- @r.keys('*') { |r| r.should == []; done }
578
- end
579
- #
580
- it "should be able to SELECT database" do
581
- @r.select(15)
582
- @r.get('foo') { |r| r.should == nil; done }
583
- end
584
- #
585
- it "should be able to provide the last save time (LASTSAVE)" do
586
- @r.lastsave do |savetime|
587
- Time.at(savetime).class.should == Time
588
- Time.at(savetime).should <= Time.now
589
- done
590
- end
591
- end
592
-
593
- it "should be able to MGET keys" do
594
- @r['foo'] = 1000
595
- @r['bar'] = 2000
596
- @r.mget('foo', 'bar') { |r| r.should == ['1000', '2000'] }
597
- @r.mget('foo', 'bar', 'baz') { |r| r.should == ['1000', '2000', nil] }
598
- @r.ping { done }
599
- end
600
-
601
- it "should be able to mapped MGET keys" do
602
- @r['foo'] = 1000
603
- @r['bar'] = 2000
604
- @r.mapped_mget('foo', 'bar') { |r| r.should == { 'foo' => '1000', 'bar' => '2000'} }
605
- @r.mapped_mget('foo', 'baz', 'bar') { |r| r.should == { 'foo' => '1000', 'bar' => '2000'} }
606
- @r.ping { done }
607
- end
608
-
609
- it "should be able to MSET values" do
610
- @r.mset :key1 => "value1", :key2 => "value2"
611
- @r.get('key1') { |r| r.should == "value1" }
612
- @r.get('key2') { |r| r.should == "value2"; done }
613
- end
614
-
615
- it "should be able to MSETNX values" do
616
- @r.msetnx :keynx1 => "valuenx1", :keynx2 => "valuenx2"
617
- @r.mget('keynx1', 'keynx2') { |r| r.should == ["valuenx1", "valuenx2"] }
618
-
619
- @r["keynx1"] = "value1"
620
- @r["keynx2"] = "value2"
621
- @r.msetnx :keynx1 => "valuenx1", :keynx2 => "valuenx2"
622
- @r.mget('keynx1', 'keynx2') { |r| r.should == ["value1", "value2"]; done }
623
- end
624
-
625
- it "should bgsave" do
626
- @r.bgsave do |r|
627
- ['OK', 'Background saving started'].include?(r).should == true
628
- done
629
- end
630
- end
631
-
632
- it "should be able to ECHO" do
633
- @r.echo("message in a bottle\n") { |r| r.should == "message in a bottle\n"; done }
634
- end
635
-
636
- # Tests are disabled due uncatchable exceptions. We should use on_error callback,
637
- # intead of raising exceptions in random places.
638
- #
639
- # it "should raise error when invoke MONITOR" do
640
- # # lambda { @r.monitor }.should.raise
641
- # done
642
- # end
643
- #
644
- # it "should raise error when invoke SYNC" do
645
- # # lambda { @r.sync }.should.raise
646
- # done
647
- # end
648
-
649
- it "should run MULTI without a block" do
650
- @r.multi
651
- @r.get("key1") { |r| r.should == "QUEUED" }
652
- @r.discard { done }
653
- end
654
-
655
- it "should run MULTI/EXEC with a block" do
656
- @r.multi do
657
- @r.set "key1", "value1"
658
- end
659
-
660
- @r.get("key1") { |r| r.should == "value1" }
661
-
662
- begin
663
- @r.multi do
664
- @r.set "key2", "value2"
665
- raise "Some error"
666
- @r.set "key3", "value3"
667
- end
668
- rescue
669
- end
670
-
671
- @r.get("key2") { |r| r.should == nil }
672
- @r.get("key3") { |r| r.should == nil; done}
673
- end
674
-
675
- it "should yield the Redis object when using #multi with a block" do
676
- @r.multi do |multi|
677
- multi.set "key1", "value1"
678
- end
679
-
680
- @r.get("key1") { |r| r.should == "value1"; done }
681
- end
682
-
683
- it "can set and get hash values" do
684
- @r.hset("rush", "signals", "1982") { |r| r.should == true }
685
- @r.hexists("rush", "signals") { |r| r.should == true }
686
- @r.hget("rush", "signals") { |r| r.should == "1982"; done }
687
- end
688
-
689
- it "can delete hash values" do
690
- @r.hset("rush", "YYZ", "1981")
691
- @r.hdel("rush", "YYZ") { |r| r.should == true }
692
- @r.hexists("rush", "YYZ") { |r| r.should == false; done }
693
- end
694
- end
695
-
696
- # Yup, bacon can't handle nested describe blocks properly
697
- EM.describe EM::Protocols::Redis, "with some hash values" do
698
- default_timeout 1
699
-
700
- before do
701
- @r = EM::Protocols::Redis.connect :db => 14
702
- @r.flushdb
703
- @r['foo'] = 'bar'
704
- @r.hset("rush", "permanent waves", "1980")
705
- @r.hset("rush", "moving pictures", "1981")
706
- @r.hset("rush", "signals", "1982")
707
- end
708
-
709
- after { @r.close_connection }
710
-
711
- it "can get the length of the hash" do
712
- @r.hlen("rush") { |r| r.should == 3 }
713
- @r.hlen("yyz") { |r| r.should == 0; done }
714
- end
715
-
716
- it "can get the keys and values of the hash" do
717
- @r.hkeys("rush") { |r| r.should == ["permanent waves", "moving pictures", "signals"] }
718
- @r.hvals("rush") { |r| r.should == %w[1980 1981 1982] }
719
- @r.hvals("yyz") { |r| r.should == []; done }
720
- end
721
-
722
- it "returns a hash for HGETALL" do
723
- @r.hgetall("rush") do |r|
724
- r.should == {
725
- "permanent waves" => "1980",
726
- "moving pictures" => "1981",
727
- "signals" => "1982"
728
- }
729
- end
730
- @r.hgetall("yyz") { |r| r.should == {}; done }
731
- end
732
- end
733
-
734
- EM.describe EM::Protocols::Redis, "with nested multi-bulk response" do
735
- default_timeout 1
736
-
737
- before do
738
- @r = EM::Protocols::Redis.connect :db => 14
739
- @r.flushdb
740
- @r.set 'user:one:id', 'id-one'
741
- @r.set 'user:two:id', 'id-two'
742
- @r.sadd "user:one:interests", "first-interest"
743
- @r.sadd "user:one:interests", "second-interest"
744
- @r.sadd "user:two:interests", "third-interest"
745
- end
746
-
747
- after { @r.close_connection }
748
-
749
- it "returns array of arrays" do
750
- @r.multi
751
- @r.smembers "user:one:interests"
752
- @r.smembers "user:two:interests"
753
- @r.exec do |user_interests|
754
- user_interests.should == [["second-interest", "first-interest"], ['third-interest']]
755
- end
756
- @r.mget("user:one:id", "user:two:id") do |user_ids|
757
- user_ids.should == ['id-one', 'id-two']
758
- done
759
- end
760
- end
761
- end