redis-objects 0.2.1 → 0.2.4
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.
- data/ChangeLog +23 -0
- data/README.rdoc +190 -97
- data/lib/redis/counter.rb +10 -12
- data/lib/redis/helpers/core_commands.rb +54 -0
- data/lib/redis/helpers/serialize.rb +25 -0
- data/lib/redis/list.rb +8 -10
- data/lib/redis/lock.rb +42 -5
- data/lib/redis/objects/counters.rb +41 -23
- data/lib/redis/objects/lists.rb +19 -9
- data/lib/redis/objects/locks.rb +21 -11
- data/lib/redis/objects/sets.rb +20 -9
- data/lib/redis/objects/sorted_sets.rb +45 -0
- data/lib/redis/objects/values.rb +29 -12
- data/lib/redis/objects.rb +10 -8
- data/lib/redis/set.rb +33 -11
- data/lib/redis/sorted_set.rb +275 -0
- data/lib/redis/value.rb +10 -12
- data/spec/redis_objects_instance_spec.rb +339 -32
- data/spec/redis_objects_model_spec.rb +203 -2
- data/spec/spec_helper.rb +1 -0
- metadata +28 -13
- data/lib/redis/objects/core.rb +0 -0
- data/lib/redis/serialize.rb +0 -23
|
@@ -3,8 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
|
3
3
|
|
|
4
4
|
require 'redis/counter'
|
|
5
5
|
require 'redis/list'
|
|
6
|
-
require 'redis/set'
|
|
7
6
|
require 'redis/value'
|
|
7
|
+
require 'redis/lock'
|
|
8
|
+
require 'redis/set'
|
|
9
|
+
require 'redis/sorted_set'
|
|
8
10
|
|
|
9
11
|
describe Redis::Value do
|
|
10
12
|
before :all do
|
|
@@ -36,6 +38,19 @@ describe Redis::Value do
|
|
|
36
38
|
@value.should be_nil
|
|
37
39
|
end
|
|
38
40
|
|
|
41
|
+
it "should support renaming values" do
|
|
42
|
+
@value.value = 'Peter Pan'
|
|
43
|
+
@value.key.should == 'spec/value'
|
|
44
|
+
@value.rename('spec/value2').should be_true
|
|
45
|
+
@value.key.should == 'spec/value2'
|
|
46
|
+
@value.should == 'Peter Pan'
|
|
47
|
+
old = Redis::Value.new('spec/value')
|
|
48
|
+
old.should be_nil
|
|
49
|
+
old.value = 'Tuff'
|
|
50
|
+
@value.renamenx('spec/value').should be_false
|
|
51
|
+
@value.value.should == 'Peter Pan'
|
|
52
|
+
end
|
|
53
|
+
|
|
39
54
|
after :all do
|
|
40
55
|
@value.delete
|
|
41
56
|
end
|
|
@@ -131,12 +146,164 @@ describe Redis::List do
|
|
|
131
146
|
@list.last.should == [1,2,3,[4,5]]
|
|
132
147
|
@list.shift.should == {:json => 'data'}
|
|
133
148
|
end
|
|
149
|
+
|
|
150
|
+
it "should support renaming lists" do
|
|
151
|
+
@list.should be_empty
|
|
152
|
+
@list << 'a' << 'b' << 'a' << 3
|
|
153
|
+
@list.should == ['a','b','a','3']
|
|
154
|
+
@list.key.should == 'spec/list'
|
|
155
|
+
@list.rename('spec/list3', false).should be_true
|
|
156
|
+
@list.key.should == 'spec/list'
|
|
157
|
+
@list.redis.del('spec/list3')
|
|
158
|
+
@list << 'a' << 'b' << 'a' << 3
|
|
159
|
+
@list.rename('spec/list2').should be_true
|
|
160
|
+
@list.key.should == 'spec/list2'
|
|
161
|
+
@list.redis.lrange(@list.key, 0, 3).should == ['a','b','a','3']
|
|
162
|
+
old = Redis::List.new('spec/list')
|
|
163
|
+
old.should be_empty
|
|
164
|
+
old << 'Tuff'
|
|
165
|
+
old.values.should == ['Tuff']
|
|
166
|
+
@list.renamenx('spec/list').should be_false
|
|
167
|
+
@list.renamenx(old).should be_false
|
|
168
|
+
@list.renamenx('spec/foo').should be_true
|
|
169
|
+
old.values.should == ['Tuff']
|
|
170
|
+
@list.clear
|
|
171
|
+
@list.redis.del('spec/list2')
|
|
172
|
+
end
|
|
134
173
|
|
|
135
174
|
after :all do
|
|
136
175
|
@list.clear
|
|
137
176
|
end
|
|
138
177
|
end
|
|
139
178
|
|
|
179
|
+
describe Redis::Counter do
|
|
180
|
+
before :all do
|
|
181
|
+
@counter = Redis::Counter.new('spec/counter')
|
|
182
|
+
@counter2 = Redis::Counter.new('spec/counter')
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
before :each do
|
|
186
|
+
@counter.reset
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "should support increment/decrement of counters" do
|
|
190
|
+
@counter.key.should == 'spec/counter'
|
|
191
|
+
@counter.incr(10)
|
|
192
|
+
@counter.should == 10
|
|
193
|
+
|
|
194
|
+
# math proxy ops
|
|
195
|
+
(@counter == 10).should be_true
|
|
196
|
+
(@counter <= 10).should be_true
|
|
197
|
+
(@counter < 11).should be_true
|
|
198
|
+
(@counter > 9).should be_true
|
|
199
|
+
(@counter >= 10).should be_true
|
|
200
|
+
"#{@counter}".should == "10"
|
|
201
|
+
|
|
202
|
+
@counter.increment.should == 11
|
|
203
|
+
@counter.increment.should == 12
|
|
204
|
+
@counter2.increment.should == 13
|
|
205
|
+
@counter2.increment(2).should == 15
|
|
206
|
+
@counter.decrement.should == 14
|
|
207
|
+
@counter2.decrement.should == 13
|
|
208
|
+
@counter.decrement.should == 12
|
|
209
|
+
@counter2.decrement(4).should == 8
|
|
210
|
+
@counter.should == 8
|
|
211
|
+
@counter.reset.should be_true
|
|
212
|
+
@counter.should == 0
|
|
213
|
+
@counter.reset(15).should be_true
|
|
214
|
+
@counter.should == 15
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
after :all do
|
|
218
|
+
@counter.delete
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
describe Redis::Lock do
|
|
223
|
+
before :each do
|
|
224
|
+
$redis.flushall
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it "should set the value to the expiration" do
|
|
228
|
+
start = Time.now
|
|
229
|
+
expiry = 15
|
|
230
|
+
lock = Redis::Lock.new(:test_lock, :expiration => expiry)
|
|
231
|
+
lock.lock do
|
|
232
|
+
expiration = $redis.get("test_lock").to_f
|
|
233
|
+
|
|
234
|
+
# The expiration stored in redis should be 15 seconds from when we started
|
|
235
|
+
# or a little more
|
|
236
|
+
expiration.should be_close((start + expiry).to_f, 2.0)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# key should have been cleaned up
|
|
240
|
+
$redis.get("test_lock").should be_nil
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it "should set value to 1 when no expiration is set" do
|
|
244
|
+
lock = Redis::Lock.new(:test_lock)
|
|
245
|
+
lock.lock do
|
|
246
|
+
$redis.get('test_lock').should == '1'
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# key should have been cleaned up
|
|
250
|
+
$redis.get("test_lock").should be_nil
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "should let lock be gettable when lock is expired" do
|
|
254
|
+
expiry = 15
|
|
255
|
+
lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
|
|
256
|
+
|
|
257
|
+
# create a fake lock in the past
|
|
258
|
+
$redis.set("test_lock", Time.now-(expiry + 60))
|
|
259
|
+
|
|
260
|
+
gotit = false
|
|
261
|
+
lock.lock do
|
|
262
|
+
gotit = true
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# should get the lock because it has expired
|
|
266
|
+
gotit.should be_true
|
|
267
|
+
$redis.get("test_lock").should be_nil
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "should not let non-expired locks be gettable" do
|
|
271
|
+
expiry = 15
|
|
272
|
+
lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
|
|
273
|
+
|
|
274
|
+
# create a fake lock
|
|
275
|
+
$redis.set("test_lock", (Time.now + expiry).to_f)
|
|
276
|
+
|
|
277
|
+
gotit = false
|
|
278
|
+
error = nil
|
|
279
|
+
begin
|
|
280
|
+
lock.lock do
|
|
281
|
+
gotit = true
|
|
282
|
+
end
|
|
283
|
+
rescue => error
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
error.should be_kind_of(Redis::Lock::LockTimeout)
|
|
287
|
+
|
|
288
|
+
# should not have the lock
|
|
289
|
+
gotit.should_not be_true
|
|
290
|
+
|
|
291
|
+
# lock value should still be set
|
|
292
|
+
$redis.get("test_lock").should_not be_nil
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it "should not remove the key if lock is held past expiration" do
|
|
296
|
+
lock = Redis::Lock.new(:test_lock, :expiration => 0.0)
|
|
297
|
+
|
|
298
|
+
lock.lock do
|
|
299
|
+
sleep 1.1
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# lock value should still be set since the lock was held for more than the expiry
|
|
303
|
+
$redis.get("test_lock").should_not be_nil
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
140
307
|
describe Redis::Set do
|
|
141
308
|
before :all do
|
|
142
309
|
@set = Redis::Set.new('spec/set')
|
|
@@ -191,7 +358,7 @@ describe Redis::Set do
|
|
|
191
358
|
@set.sort.should == ['a','b','c']
|
|
192
359
|
end
|
|
193
360
|
|
|
194
|
-
it "should handle set intersections and
|
|
361
|
+
it "should handle set intersections, unions, and diffs" do
|
|
195
362
|
@set_1 << 'a' << 'b' << 'c' << 'd' << 'e'
|
|
196
363
|
@set_2 << 'c' << 'd' << 'e' << 'f' << 'g'
|
|
197
364
|
@set_3 << 'a' << 'd' << 'g' << 'l' << 'm'
|
|
@@ -216,6 +383,34 @@ describe Redis::Set do
|
|
|
216
383
|
@set_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g']
|
|
217
384
|
@set_1.unionstore(UNIONSTORE_KEY, @set_2, @set_3).should == 9
|
|
218
385
|
@set_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g','l','m']
|
|
386
|
+
|
|
387
|
+
(@set_1 ^ @set_2).sort.should == ["a", "b"]
|
|
388
|
+
(@set_1 - @set_2).sort.should == ["a", "b"]
|
|
389
|
+
(@set_2 - @set_1).sort.should == ["f", "g"]
|
|
390
|
+
@set_1.difference(@set_2).sort.should == ["a", "b"]
|
|
391
|
+
@set_1.diff(@set_2).sort.should == ["a", "b"]
|
|
392
|
+
@set_1.difference(@set_2, @set_3).sort.should == ['b']
|
|
393
|
+
@set_1.diffstore(DIFFSTORE_KEY, @set_2).should == 2
|
|
394
|
+
@set_1.redis.smembers(DIFFSTORE_KEY).sort.should == ['a','b']
|
|
395
|
+
@set_1.diffstore(DIFFSTORE_KEY, @set_2, @set_3).should == 1
|
|
396
|
+
@set_1.redis.smembers(DIFFSTORE_KEY).sort.should == ['b']
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
it "should support renaming sets" do
|
|
400
|
+
@set.should be_empty
|
|
401
|
+
@set << 'a' << 'b' << 'a' << 3
|
|
402
|
+
@set.sort.should == ['3','a','b']
|
|
403
|
+
@set.key.should == 'spec/set'
|
|
404
|
+
@set.rename('spec/set2').should be_true
|
|
405
|
+
@set.key.should == 'spec/set2'
|
|
406
|
+
old = Redis::Set.new('spec/set')
|
|
407
|
+
old.should be_empty
|
|
408
|
+
old << 'Tuff'
|
|
409
|
+
@set.renamenx('spec/set').should be_false
|
|
410
|
+
@set.renamenx(old).should be_false
|
|
411
|
+
@set.renamenx('spec/foo').should be_true
|
|
412
|
+
@set.clear
|
|
413
|
+
@set.redis.del('spec/set2')
|
|
219
414
|
end
|
|
220
415
|
|
|
221
416
|
after :all do
|
|
@@ -226,45 +421,157 @@ describe Redis::Set do
|
|
|
226
421
|
end
|
|
227
422
|
end
|
|
228
423
|
|
|
229
|
-
describe Redis::
|
|
424
|
+
describe Redis::SortedSet do
|
|
230
425
|
before :all do
|
|
231
|
-
@
|
|
232
|
-
@
|
|
426
|
+
@set = Redis::SortedSet.new('spec/zset')
|
|
427
|
+
@set_1 = Redis::SortedSet.new('spec/zset_1')
|
|
428
|
+
@set_2 = Redis::SortedSet.new('spec/zset_2')
|
|
429
|
+
@set_3 = Redis::SortedSet.new('spec/zset_3')
|
|
233
430
|
end
|
|
234
431
|
|
|
235
432
|
before :each do
|
|
236
|
-
@
|
|
433
|
+
@set.clear
|
|
434
|
+
@set_1.clear
|
|
435
|
+
@set_2.clear
|
|
436
|
+
@set_3.clear
|
|
237
437
|
end
|
|
238
438
|
|
|
239
|
-
it "should
|
|
240
|
-
@
|
|
241
|
-
@
|
|
242
|
-
@
|
|
439
|
+
it "should handle sets of simple values" do
|
|
440
|
+
@set.should be_empty
|
|
441
|
+
@set['a'] = 11
|
|
442
|
+
@set['a'] = 21
|
|
443
|
+
@set.add('a', 5)
|
|
444
|
+
@set.score('a').should == 5
|
|
445
|
+
@set['a'] = 3
|
|
446
|
+
@set['b'] = 5
|
|
447
|
+
@set['c'] = 4
|
|
448
|
+
|
|
449
|
+
@set[0,-1].should == ['a','c','b']
|
|
450
|
+
@set.range(0,-1).should == ['a','c','b']
|
|
451
|
+
@set.revrange(0,-1).should == ['b','c','a']
|
|
452
|
+
@set[0..1].should == ['a','c']
|
|
453
|
+
@set[1].should == 'c'
|
|
454
|
+
@set.at(1).should == 'c'
|
|
455
|
+
@set.first.should == 'a'
|
|
456
|
+
@set.last.should == 'b'
|
|
457
|
+
|
|
458
|
+
@set.members.should == ['a','c','b']
|
|
459
|
+
@set.members(:withscores => true).should == [['a',3],['c',4],['b',5]]
|
|
460
|
+
|
|
461
|
+
@set['b'] = 5
|
|
462
|
+
@set['b'] = 6
|
|
463
|
+
@set.score('b').should == 6
|
|
464
|
+
@set.delete('c')
|
|
465
|
+
@set.to_s.should == 'a, b'
|
|
466
|
+
@set.should == ['a','b']
|
|
467
|
+
@set.members.should == ['a','b']
|
|
468
|
+
@set['d'] = 0
|
|
243
469
|
|
|
244
|
-
|
|
245
|
-
(
|
|
246
|
-
(
|
|
247
|
-
(
|
|
248
|
-
(@counter > 9).should be_true
|
|
249
|
-
(@counter >= 10).should be_true
|
|
250
|
-
"#{@counter}".should == "10"
|
|
470
|
+
@set.rangebyscore(0, 4).should == ['d','a']
|
|
471
|
+
@set.rangebyscore(0, 4, :count => 1).should == ['d']
|
|
472
|
+
@set.rangebyscore(0, 4, :count => 2).should == ['d','a']
|
|
473
|
+
@set.rangebyscore(0, 4, :limit => 2).should == ['d','a']
|
|
251
474
|
|
|
252
|
-
|
|
253
|
-
@
|
|
254
|
-
@
|
|
255
|
-
@
|
|
256
|
-
@
|
|
257
|
-
@
|
|
258
|
-
|
|
259
|
-
@
|
|
260
|
-
@
|
|
261
|
-
@
|
|
262
|
-
@
|
|
263
|
-
@
|
|
264
|
-
@
|
|
475
|
+
# Redis 1.3.5
|
|
476
|
+
# @set.rangebyscore(0,4, :withscores => true).should == [['d',4],['a',3]]
|
|
477
|
+
# @set.revrangebyscore(0,4).should == ['d','a']
|
|
478
|
+
# @set.revrangebyscore(0,4, :count => 2).should == ['a','d']
|
|
479
|
+
# @set.rank('b').should == 2
|
|
480
|
+
# @set.revrank('b').should == 3
|
|
481
|
+
|
|
482
|
+
@set['f'] = 100
|
|
483
|
+
@set['g'] = 110
|
|
484
|
+
@set['h'] = 120
|
|
485
|
+
@set['j'] = 130
|
|
486
|
+
@set.incr('h', 20)
|
|
487
|
+
@set.remrangebyscore(100, 120)
|
|
488
|
+
@set.members.should == ['d','a','b','j','h']
|
|
489
|
+
|
|
490
|
+
# Redis 1.3.5
|
|
491
|
+
# @set['h'] = 12
|
|
492
|
+
# @set['j'] = 13
|
|
493
|
+
# @set.remrangebyrank(4,-1)
|
|
494
|
+
# @set.members.should == ['d','a','b']
|
|
495
|
+
|
|
496
|
+
@set.delete('d')
|
|
497
|
+
@set['c'] = 200
|
|
498
|
+
@set.members.should == ['a','b','j','h','c']
|
|
499
|
+
@set.delete('c')
|
|
500
|
+
@set.length.should == 4
|
|
501
|
+
@set.size.should == 4
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
# Not until Redis 1.3.5 with hashes
|
|
505
|
+
xit "Redis 1.3.5: should handle set intersections, unions, and diffs" do
|
|
506
|
+
@set_1['a'] = 5
|
|
507
|
+
@set_2['b'] = 18
|
|
508
|
+
@set_2['c'] = 12
|
|
509
|
+
|
|
510
|
+
@set_2['a'] = 10
|
|
511
|
+
@set_2['b'] = 15
|
|
512
|
+
@set_2['c'] = 15
|
|
513
|
+
|
|
514
|
+
(@set_1 & @set_2).sort.should == ['c','d','e']
|
|
515
|
+
|
|
516
|
+
@set_1 << 'a' << 'b' << 'c' << 'd' << 'e'
|
|
517
|
+
@set_2 << 'c' << 'd' << 'e' << 'f' << 'g'
|
|
518
|
+
@set_3 << 'a' << 'd' << 'g' << 'l' << 'm'
|
|
519
|
+
@set_1.sort.should == %w(a b c d e)
|
|
520
|
+
@set_2.sort.should == %w(c d e f g)
|
|
521
|
+
@set_3.sort.should == %w(a d g l m)
|
|
522
|
+
(@set_1 & @set_2).sort.should == ['c','d','e']
|
|
523
|
+
@set_1.intersection(@set_2).sort.should == ['c','d','e']
|
|
524
|
+
@set_1.intersection(@set_2, @set_3).sort.should == ['d']
|
|
525
|
+
@set_1.intersect(@set_2).sort.should == ['c','d','e']
|
|
526
|
+
@set_1.inter(@set_2, @set_3).sort.should == ['d']
|
|
527
|
+
@set_1.interstore(INTERSTORE_KEY, @set_2).should == 3
|
|
528
|
+
@set_1.redis.smembers(INTERSTORE_KEY).sort.should == ['c','d','e']
|
|
529
|
+
@set_1.interstore(INTERSTORE_KEY, @set_2, @set_3).should == 1
|
|
530
|
+
@set_1.redis.smembers(INTERSTORE_KEY).sort.should == ['d']
|
|
531
|
+
|
|
532
|
+
(@set_1 | @set_2).sort.should == ['a','b','c','d','e','f','g']
|
|
533
|
+
(@set_1 + @set_2).sort.should == ['a','b','c','d','e','f','g']
|
|
534
|
+
@set_1.union(@set_2).sort.should == ['a','b','c','d','e','f','g']
|
|
535
|
+
@set_1.union(@set_2, @set_3).sort.should == ['a','b','c','d','e','f','g','l','m']
|
|
536
|
+
@set_1.unionstore(UNIONSTORE_KEY, @set_2).should == 7
|
|
537
|
+
@set_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g']
|
|
538
|
+
@set_1.unionstore(UNIONSTORE_KEY, @set_2, @set_3).should == 9
|
|
539
|
+
@set_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g','l','m']
|
|
540
|
+
|
|
541
|
+
(@set_1 ^ @set_2).sort.should == ["a", "b"]
|
|
542
|
+
(@set_1 - @set_2).sort.should == ["a", "b"]
|
|
543
|
+
(@set_2 - @set_1).sort.should == ["f", "g"]
|
|
544
|
+
@set_1.difference(@set_2).sort.should == ["a", "b"]
|
|
545
|
+
@set_1.diff(@set_2).sort.should == ["a", "b"]
|
|
546
|
+
@set_1.difference(@set_2, @set_3).sort.should == ['b']
|
|
547
|
+
@set_1.diffstore(DIFFSTORE_KEY, @set_2).should == 2
|
|
548
|
+
@set_1.redis.smembers(DIFFSTORE_KEY).sort.should == ['a','b']
|
|
549
|
+
@set_1.diffstore(DIFFSTORE_KEY, @set_2, @set_3).should == 1
|
|
550
|
+
@set_1.redis.smembers(DIFFSTORE_KEY).sort.should == ['b']
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
it "should support renaming sets" do
|
|
554
|
+
@set.should be_empty
|
|
555
|
+
@set['zynga'] = 151
|
|
556
|
+
@set['playfish'] = 202
|
|
557
|
+
@set.members.should == ['zynga','playfish']
|
|
558
|
+
@set.key.should == 'spec/zset'
|
|
559
|
+
@set.rename('spec/zset2').should be_true
|
|
560
|
+
@set.key.should == 'spec/zset2'
|
|
561
|
+
old = Redis::SortedSet.new('spec/zset')
|
|
562
|
+
old.should be_empty
|
|
563
|
+
old['tuff'] = 54
|
|
564
|
+
@set.renamenx('spec/zset').should be_false
|
|
565
|
+
@set.renamenx(old).should be_false
|
|
566
|
+
@set.renamenx('spec/zfoo').should be_true
|
|
567
|
+
@set.clear
|
|
568
|
+
@set.redis.del('spec/zset2')
|
|
265
569
|
end
|
|
266
570
|
|
|
267
571
|
after :all do
|
|
268
|
-
@
|
|
572
|
+
@set.clear
|
|
573
|
+
@set_1.clear
|
|
574
|
+
@set_2.clear
|
|
575
|
+
@set_3.clear
|
|
269
576
|
end
|
|
270
|
-
end
|
|
577
|
+
end
|
|
@@ -9,12 +9,17 @@ class Roster
|
|
|
9
9
|
counter :available_slots, :start => 10
|
|
10
10
|
counter :pitchers, :limit => :max_pitchers
|
|
11
11
|
counter :basic
|
|
12
|
-
counter :all_players_online, :global => true
|
|
13
12
|
lock :resort, :timeout => 2
|
|
14
13
|
value :starting_pitcher
|
|
15
14
|
list :player_stats
|
|
16
15
|
set :outfielders
|
|
17
16
|
|
|
17
|
+
# global class counters
|
|
18
|
+
counter :total_players_online, :global => true
|
|
19
|
+
list :all_player_stats, :global => true
|
|
20
|
+
set :all_players_online, :global => true
|
|
21
|
+
value :last_player, :global => true
|
|
22
|
+
|
|
18
23
|
def initialize(id=1) @id = id end
|
|
19
24
|
def id; @id; end
|
|
20
25
|
def max_pitchers; 3; end
|
|
@@ -43,11 +48,17 @@ describe Redis::Objects do
|
|
|
43
48
|
@roster_3.outfielders.clear
|
|
44
49
|
@roster.redis.del(UNIONSTORE_KEY)
|
|
45
50
|
@roster.redis.del(INTERSTORE_KEY)
|
|
51
|
+
@roster.redis.del(DIFFSTORE_KEY)
|
|
52
|
+
|
|
53
|
+
Roster.total_players_online.reset
|
|
54
|
+
Roster.all_player_stats.clear
|
|
55
|
+
Roster.all_players_online.clear
|
|
56
|
+
Roster.last_player.delete
|
|
46
57
|
end
|
|
47
58
|
|
|
48
59
|
it "should provide a connection method" do
|
|
49
60
|
Roster.redis.should == Redis::Objects.redis
|
|
50
|
-
Roster.redis.should be_kind_of(Redis)
|
|
61
|
+
# Roster.redis.should be_kind_of(Redis)
|
|
51
62
|
end
|
|
52
63
|
|
|
53
64
|
it "should create counter accessors" do
|
|
@@ -97,6 +108,24 @@ describe Redis::Objects do
|
|
|
97
108
|
Roster.get_counter(:available_slots, @roster.id).should == 10
|
|
98
109
|
end
|
|
99
110
|
|
|
111
|
+
it "should support class-level increment/decrement of global counters" do
|
|
112
|
+
Roster.total_players_online.should == 0
|
|
113
|
+
Roster.total_players_online.increment.should == 1
|
|
114
|
+
Roster.total_players_online.decrement.should == 0
|
|
115
|
+
Roster.total_players_online.increment(3).should == 3
|
|
116
|
+
Roster.total_players_online.decrement(2).should == 1
|
|
117
|
+
Roster.total_players_online.reset.should be_true
|
|
118
|
+
Roster.total_players_online.should == 0
|
|
119
|
+
|
|
120
|
+
Roster.get_counter(:total_players_online).should == 0
|
|
121
|
+
Roster.increment_counter(:total_players_online).should == 1
|
|
122
|
+
Roster.increment_counter(:total_players_online, nil, 3).should == 4
|
|
123
|
+
Roster.decrement_counter(:total_players_online, nil, 2).should == 2
|
|
124
|
+
Roster.decrement_counter(:total_players_online).should == 1
|
|
125
|
+
Roster.reset_counter(:total_players_online).should == true
|
|
126
|
+
Roster.get_counter(:total_players_online).should == 0
|
|
127
|
+
end
|
|
128
|
+
|
|
100
129
|
it "should take an atomic block for increment/decrement" do
|
|
101
130
|
a = false
|
|
102
131
|
@roster.available_slots.should == 10
|
|
@@ -253,12 +282,27 @@ describe Redis::Objects do
|
|
|
253
282
|
end
|
|
254
283
|
error.should be_kind_of(NoMethodError)
|
|
255
284
|
end
|
|
285
|
+
|
|
286
|
+
it "should support obtain_lock as a class method" do
|
|
287
|
+
error = nil
|
|
288
|
+
begin
|
|
289
|
+
Roster.obtain_lock(:resort, 2) do
|
|
290
|
+
Roster.redis.get("roster:2:resort_lock").should_not be_nil
|
|
291
|
+
end
|
|
292
|
+
rescue => error
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
error.should be_nil
|
|
296
|
+
Roster.redis.get("roster:2:resort_lock").should be_nil
|
|
297
|
+
end
|
|
256
298
|
|
|
257
299
|
it "should handle simple values" do
|
|
258
300
|
@roster.starting_pitcher.should == nil
|
|
259
301
|
@roster.starting_pitcher = 'Trevor Hoffman'
|
|
260
302
|
@roster.starting_pitcher.should == 'Trevor Hoffman'
|
|
261
303
|
@roster.starting_pitcher.get.should == 'Trevor Hoffman'
|
|
304
|
+
@roster.starting_pitcher = 'Tom Selleck'
|
|
305
|
+
@roster.starting_pitcher.should == 'Tom Selleck'
|
|
262
306
|
@roster.starting_pitcher.del.should be_true
|
|
263
307
|
@roster.starting_pitcher.should be_nil
|
|
264
308
|
end
|
|
@@ -409,6 +453,162 @@ describe Redis::Objects do
|
|
|
409
453
|
@roster_1.redis.smembers(UNIONSTORE_KEY).sort.should == ['a','b','c','d','e','f','g','l','m']
|
|
410
454
|
end
|
|
411
455
|
|
|
456
|
+
it "should handle class-level global lists of simple values" do
|
|
457
|
+
Roster.all_player_stats.should be_empty
|
|
458
|
+
Roster.all_player_stats << 'a'
|
|
459
|
+
Roster.all_player_stats.should == ['a']
|
|
460
|
+
Roster.all_player_stats.get.should == ['a']
|
|
461
|
+
Roster.all_player_stats.unshift 'b'
|
|
462
|
+
Roster.all_player_stats.to_s.should == 'b, a'
|
|
463
|
+
Roster.all_player_stats.should == ['b','a']
|
|
464
|
+
Roster.all_player_stats.get.should == ['b','a']
|
|
465
|
+
Roster.all_player_stats.push 'c'
|
|
466
|
+
Roster.all_player_stats.should == ['b','a','c']
|
|
467
|
+
Roster.all_player_stats.get.should == ['b','a','c']
|
|
468
|
+
Roster.all_player_stats.first.should == 'b'
|
|
469
|
+
Roster.all_player_stats.last.should == 'c'
|
|
470
|
+
Roster.all_player_stats << 'd'
|
|
471
|
+
Roster.all_player_stats.should == ['b','a','c','d']
|
|
472
|
+
Roster.all_player_stats[1].should == 'a'
|
|
473
|
+
Roster.all_player_stats[0].should == 'b'
|
|
474
|
+
Roster.all_player_stats[2].should == 'c'
|
|
475
|
+
Roster.all_player_stats[3].should == 'd'
|
|
476
|
+
Roster.all_player_stats.include?('c').should be_true
|
|
477
|
+
Roster.all_player_stats.include?('no').should be_false
|
|
478
|
+
Roster.all_player_stats.pop.should == 'd'
|
|
479
|
+
Roster.all_player_stats[0].should == Roster.all_player_stats.at(0)
|
|
480
|
+
Roster.all_player_stats[1].should == Roster.all_player_stats.at(1)
|
|
481
|
+
Roster.all_player_stats[2].should == Roster.all_player_stats.at(2)
|
|
482
|
+
Roster.all_player_stats.should == ['b','a','c']
|
|
483
|
+
Roster.all_player_stats.get.should == ['b','a','c']
|
|
484
|
+
Roster.all_player_stats.shift.should == 'b'
|
|
485
|
+
Roster.all_player_stats.should == ['a','c']
|
|
486
|
+
Roster.all_player_stats.get.should == ['a','c']
|
|
487
|
+
Roster.all_player_stats << 'e' << 'f' << 'e'
|
|
488
|
+
Roster.all_player_stats.should == ['a','c','e','f','e']
|
|
489
|
+
Roster.all_player_stats.get.should == ['a','c','e','f','e']
|
|
490
|
+
Roster.all_player_stats.delete('e').should == 2
|
|
491
|
+
Roster.all_player_stats.should == ['a','c','f']
|
|
492
|
+
Roster.all_player_stats.get.should == ['a','c','f']
|
|
493
|
+
Roster.all_player_stats << 'j'
|
|
494
|
+
Roster.all_player_stats.should == ['a','c','f','j']
|
|
495
|
+
Roster.all_player_stats[0..2].should == ['a','c','f']
|
|
496
|
+
Roster.all_player_stats[1, 3].should == ['c','f','j']
|
|
497
|
+
Roster.all_player_stats.length.should == 4
|
|
498
|
+
Roster.all_player_stats.size.should == 4
|
|
499
|
+
Roster.all_player_stats.should == ['a','c','f','j']
|
|
500
|
+
Roster.all_player_stats.get.should == ['a','c','f','j']
|
|
501
|
+
|
|
502
|
+
i = -1
|
|
503
|
+
Roster.all_player_stats.each do |st|
|
|
504
|
+
st.should == Roster.all_player_stats[i += 1]
|
|
505
|
+
end
|
|
506
|
+
Roster.all_player_stats.should == ['a','c','f','j']
|
|
507
|
+
Roster.all_player_stats.get.should == ['a','c','f','j']
|
|
508
|
+
|
|
509
|
+
Roster.all_player_stats.each_with_index do |st,i|
|
|
510
|
+
st.should == Roster.all_player_stats[i]
|
|
511
|
+
end
|
|
512
|
+
Roster.all_player_stats.should == ['a','c','f','j']
|
|
513
|
+
Roster.all_player_stats.get.should == ['a','c','f','j']
|
|
514
|
+
|
|
515
|
+
coll = Roster.all_player_stats.collect{|st| st}
|
|
516
|
+
coll.should == ['a','c','f','j']
|
|
517
|
+
Roster.all_player_stats.should == ['a','c','f','j']
|
|
518
|
+
Roster.all_player_stats.get.should == ['a','c','f','j']
|
|
519
|
+
|
|
520
|
+
Roster.all_player_stats << 'a'
|
|
521
|
+
coll = Roster.all_player_stats.select{|st| st == 'a'}
|
|
522
|
+
coll.should == ['a','a']
|
|
523
|
+
Roster.all_player_stats.should == ['a','c','f','j','a']
|
|
524
|
+
Roster.all_player_stats.get.should == ['a','c','f','j','a']
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
it "should handle class-level global sets of simple values" do
|
|
528
|
+
Roster.all_players_online.should be_empty
|
|
529
|
+
Roster.all_players_online << 'a' << 'a' << 'a'
|
|
530
|
+
Roster.all_players_online.should == ['a']
|
|
531
|
+
Roster.all_players_online.get.should == ['a']
|
|
532
|
+
Roster.all_players_online << 'b' << 'b'
|
|
533
|
+
Roster.all_players_online.to_s.should == 'a, b'
|
|
534
|
+
Roster.all_players_online.should == ['a','b']
|
|
535
|
+
Roster.all_players_online.members.should == ['a','b']
|
|
536
|
+
Roster.all_players_online.get.should == ['a','b']
|
|
537
|
+
Roster.all_players_online << 'c'
|
|
538
|
+
Roster.all_players_online.sort.should == ['a','b','c']
|
|
539
|
+
Roster.all_players_online.get.sort.should == ['a','b','c']
|
|
540
|
+
Roster.all_players_online.delete('c')
|
|
541
|
+
Roster.all_players_online.should == ['a','b']
|
|
542
|
+
Roster.all_players_online.get.sort.should == ['a','b']
|
|
543
|
+
Roster.all_players_online.length.should == 2
|
|
544
|
+
Roster.all_players_online.size.should == 2
|
|
545
|
+
|
|
546
|
+
i = 0
|
|
547
|
+
Roster.all_players_online.each do |st|
|
|
548
|
+
i += 1
|
|
549
|
+
end
|
|
550
|
+
i.should == Roster.all_players_online.length
|
|
551
|
+
|
|
552
|
+
coll = Roster.all_players_online.collect{|st| st}
|
|
553
|
+
coll.should == ['a','b']
|
|
554
|
+
Roster.all_players_online.should == ['a','b']
|
|
555
|
+
Roster.all_players_online.get.should == ['a','b']
|
|
556
|
+
|
|
557
|
+
Roster.all_players_online << 'c'
|
|
558
|
+
Roster.all_players_online.member?('c').should be_true
|
|
559
|
+
Roster.all_players_online.include?('c').should be_true
|
|
560
|
+
Roster.all_players_online.member?('no').should be_false
|
|
561
|
+
coll = Roster.all_players_online.select{|st| st == 'c'}
|
|
562
|
+
coll.should == ['c']
|
|
563
|
+
Roster.all_players_online.sort.should == ['a','b','c']
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
it "should handle class-level global values" do
|
|
567
|
+
Roster.last_player.should == nil
|
|
568
|
+
Roster.last_player = 'Trevor Hoffman'
|
|
569
|
+
Roster.last_player.should == 'Trevor Hoffman'
|
|
570
|
+
Roster.last_player.get.should == 'Trevor Hoffman'
|
|
571
|
+
Roster.last_player = 'Tom Selleck'
|
|
572
|
+
Roster.last_player.should == 'Tom Selleck'
|
|
573
|
+
Roster.last_player.del.should be_true
|
|
574
|
+
Roster.last_player.should be_nil
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
it "should easily enable @object.class.global_objects" do
|
|
578
|
+
@roster.class.all_players_online.should be_empty
|
|
579
|
+
@roster.class.all_players_online << 'a' << 'a' << 'a'
|
|
580
|
+
@roster.class.all_players_online.should == ['a']
|
|
581
|
+
@roster2.class.all_players_online.should == ['a']
|
|
582
|
+
|
|
583
|
+
@roster.all_players_online.should == ['a']
|
|
584
|
+
@roster2.all_players_online.should == ['a']
|
|
585
|
+
|
|
586
|
+
@roster.class.all_player_stats.should be_empty
|
|
587
|
+
@roster.class.all_player_stats << 'a'
|
|
588
|
+
@roster.class.all_player_stats.should == ['a']
|
|
589
|
+
@roster.class.all_player_stats.get.should == ['a']
|
|
590
|
+
@roster.class.all_player_stats.unshift 'b'
|
|
591
|
+
@roster.class.all_player_stats.to_s.should == 'b, a'
|
|
592
|
+
@roster.class.all_player_stats.should == ['b','a']
|
|
593
|
+
@roster2.class.all_player_stats.should == ['b','a']
|
|
594
|
+
|
|
595
|
+
@roster.all_player_stats.should == ['b','a']
|
|
596
|
+
@roster2.all_player_stats.should == ['b','a']
|
|
597
|
+
@roster2.all_player_stats << 'b'
|
|
598
|
+
@roster.all_player_stats.should == ['b','a','b']
|
|
599
|
+
|
|
600
|
+
@roster.last_player.should == nil
|
|
601
|
+
@roster.class.last_player = 'Trevor Hoffman'
|
|
602
|
+
@roster.last_player.should == 'Trevor Hoffman'
|
|
603
|
+
@roster.last_player.get.should == 'Trevor Hoffman'
|
|
604
|
+
@roster2.last_player.get.should == 'Trevor Hoffman'
|
|
605
|
+
@roster2.last_player = 'Tom Selleck'
|
|
606
|
+
@roster.last_player.should == 'Tom Selleck'
|
|
607
|
+
@roster.last_player.del.should be_true
|
|
608
|
+
@roster.last_player.should be_nil
|
|
609
|
+
@roster2.last_player.should be_nil
|
|
610
|
+
end
|
|
611
|
+
|
|
412
612
|
it "should handle lists of complex data types" do
|
|
413
613
|
@roster.player_stats << {:json => 'data'}
|
|
414
614
|
@roster.player_stats << {:json2 => 'data2'}
|
|
@@ -448,4 +648,5 @@ describe Redis::Objects do
|
|
|
448
648
|
error.should_not be_nil
|
|
449
649
|
error.should be_kind_of(Redis::Lock::LockTimeout)
|
|
450
650
|
end
|
|
651
|
+
|
|
451
652
|
end
|
data/spec/spec_helper.rb
CHANGED