redis-objects 0.6.1 → 0.7.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.
@@ -14,7 +14,7 @@ class Redis
14
14
  # Define a new simple value. It will function like a regular instance
15
15
  # method, so it can be used alongside ActiveRecord, DataMapper, etc.
16
16
  def value(name, options={})
17
- @redis_objects[name.to_sym] = options.merge(:type => :value)
17
+ redis_objects[name.to_sym] = options.merge(:type => :value)
18
18
  klass_name = '::' + self.name
19
19
  if options[:global]
20
20
  instance_eval <<-EndMethods
@@ -43,13 +43,13 @@ class Redis
43
43
  end
44
44
  EndMethods
45
45
  end
46
-
46
+
47
47
  end
48
48
  end
49
-
49
+
50
50
  # Instance methods that appear in your class when you include Redis::Objects.
51
51
  module InstanceMethods
52
52
  end
53
53
  end
54
54
  end
55
- end
55
+ end
data/lib/redis/set.rb CHANGED
@@ -12,7 +12,7 @@ class Redis
12
12
  require 'redis/helpers/serialize'
13
13
  include Redis::Helpers::Serialize
14
14
 
15
- attr_reader :key, :options, :redis
15
+ attr_reader :key, :options
16
16
 
17
17
  # Works like add. Can chain together: list << 'a' << 'b'
18
18
  def <<(value)
@@ -12,7 +12,7 @@ class Redis
12
12
  require 'redis/helpers/serialize'
13
13
  include Redis::Helpers::Serialize
14
14
 
15
- attr_reader :key, :options, :redis
15
+ attr_reader :key, :options
16
16
 
17
17
  # How to add values using a sorted set. The key is the member, eg,
18
18
  # "Peter", and the value is the score, eg, 163. So:
data/lib/redis/value.rb CHANGED
@@ -10,10 +10,10 @@ class Redis
10
10
  require 'redis/helpers/serialize'
11
11
  include Redis::Helpers::Serialize
12
12
 
13
- attr_reader :key, :options, :redis
13
+ attr_reader :key, :options
14
14
  def initialize(key, *args)
15
15
  super(key, *args)
16
- @redis.setnx(key, to_redis(@options[:default])) if @options[:default]
16
+ redis.setnx(key, to_redis(@options[:default])) if @options[:default]
17
17
  end
18
18
 
19
19
  def value=(val)
@@ -5,24 +5,24 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "redis-objects"
8
- s.version = "0.6.1"
8
+ s.version = "0.7.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nate Wiger"]
12
- s.date = "2012-10-24"
12
+ s.date = "2013-02-27"
13
13
  s.description = "Map Redis types directly to Ruby objects. Works with any class or ORM."
14
- s.email = "nate@wiger.org"
14
+ s.email = "nwiger@gmail.com"
15
15
  s.extra_rdoc_files = [
16
- "README.rdoc"
16
+ "README.md"
17
17
  ]
18
18
  s.files = [
19
19
  "ATOMICITY.rdoc",
20
20
  "CHANGELOG.rdoc",
21
21
  "Gemfile",
22
- "Gemfile.lock",
23
- "README.rdoc",
22
+ "README.md",
24
23
  "Rakefile",
25
24
  "VERSION",
25
+ "lib/redis-objects.rb",
26
26
  "lib/redis/base_object.rb",
27
27
  "lib/redis/counter.rb",
28
28
  "lib/redis/hash_key.rb",
@@ -42,8 +42,10 @@ Gem::Specification.new do |s|
42
42
  "lib/redis/sorted_set.rb",
43
43
  "lib/redis/value.rb",
44
44
  "redis-objects.gemspec",
45
+ "spec/redis_autoload_objects_spec.rb",
45
46
  "spec/redis_namespace_compat_spec.rb",
46
47
  "spec/redis_objects_active_record_spec.rb",
48
+ "spec/redis_objects_conn_spec.rb",
47
49
  "spec/redis_objects_instance_spec.rb",
48
50
  "spec/redis_objects_model_spec.rb",
49
51
  "spec/spec_helper.rb"
@@ -0,0 +1,46 @@
1
+
2
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
+
4
+ # tests whether autoload functionality works correctly; had issues previously
5
+
6
+ require 'redis/objects'
7
+ # $redis used automatically
8
+
9
+ describe 'Redis::Objects' do
10
+ it "should autoload everything" do
11
+ defined?(::Redis::Counter).should == "constant"
12
+ x = Redis::Counter.new('x')
13
+ x.class.name.should == "Redis::Counter"
14
+ x.redis.should == REDIS_HANDLE
15
+
16
+ defined?(::Redis::HashKey).should == "constant"
17
+ x = Redis::HashKey.new('x')
18
+ x.class.name.should == "Redis::HashKey"
19
+ x.redis.should == REDIS_HANDLE
20
+
21
+ defined?(::Redis::List).should == "constant"
22
+ x = Redis::List.new('x')
23
+ x.class.name.should == "Redis::List"
24
+ x.redis.should == REDIS_HANDLE
25
+
26
+ defined?(::Redis::Lock).should == "constant"
27
+ x = Redis::Lock.new('x')
28
+ x.class.name.should == "Redis::Lock"
29
+ x.redis.should == REDIS_HANDLE
30
+
31
+ defined?(::Redis::Set).should == "constant"
32
+ x = Redis::Set.new('x')
33
+ x.class.name.should == "Redis::Set"
34
+ x.redis.should == REDIS_HANDLE
35
+
36
+ defined?(::Redis::SortedSet).should == "constant"
37
+ x = Redis::SortedSet.new('x')
38
+ x.class.name.should == "Redis::SortedSet"
39
+ x.redis.should == REDIS_HANDLE
40
+
41
+ defined?(::Redis::Value).should == "constant"
42
+ x = Redis::Value.new('x')
43
+ x.class.name.should == "Redis::Value"
44
+ x.redis.should == REDIS_HANDLE
45
+ end
46
+ end
@@ -1,7 +1,7 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  require 'redis/objects'
4
- Redis::Objects.redis = $redis
4
+ Redis::Objects.redis = REDIS_HANDLE
5
5
 
6
6
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../../redis-namespace/lib')
7
7
  begin
@@ -9,7 +9,7 @@ begin
9
9
 
10
10
  describe 'Redis::Namespace compat' do
11
11
  it "tests the compatibility of Hash and ::Hash conflicts" do
12
- ns = Redis::Namespace.new("resque", :redis => $redis)
12
+ ns = Redis::Namespace.new("resque", :redis => REDIS_HANDLE)
13
13
  ns.instance_eval { rem_namespace({"resque:x" => nil}) }.should == {"x"=>nil}
14
14
  class Foo
15
15
  include Redis::Objects
@@ -2,7 +2,7 @@
2
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
 
4
4
  require 'redis/objects'
5
- Redis::Objects.redis = $redis
5
+ # $redis used automatically
6
6
 
7
7
  begin
8
8
  require 'active_record'
@@ -0,0 +1,104 @@
1
+ #
2
+ # Connection tests - a bit ugly but important
3
+ #
4
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
5
+
6
+ require 'redis/objects'
7
+
8
+ BAD_REDIS = "totally bad bogus redis handle"
9
+
10
+ # Grab a global handle
11
+ describe 'Connection tests' do
12
+ it "should support local handles" do
13
+ Redis.current = nil # reset from other tests
14
+ Redis::Objects.redis = nil
15
+ @redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
16
+
17
+ # Redis.current is lazily auto-populated to touch 6379
18
+ # This why we choose the weird 9212 port to avoid
19
+ Redis.current.inspect.should == Redis.new.inspect
20
+ Redis::Objects.redis.inspect.should == Redis.new.inspect
21
+
22
+ v = Redis::Value.new('conn/value', @redis_handle)
23
+ v.clear
24
+ v.value = 'yay'
25
+ v.value.should == 'yay'
26
+
27
+ h = Redis::HashKey.new('conn/hash', @redis_handle)
28
+ h.clear
29
+ h['k'] = 'v'
30
+
31
+ l = Redis::List.new('conn/list', @redis_handle)
32
+ l.clear
33
+ l << 3
34
+ l << 4
35
+ l << 5
36
+
37
+ s = Redis::Set.new('conn/set', @redis_handle)
38
+ s.clear
39
+ s << 5
40
+ s << 5
41
+ s << 6
42
+ s << 7
43
+
44
+ z = Redis::SortedSet.new('conn/zset', @redis_handle)
45
+ z.clear
46
+ z['a'] = 8
47
+ z['b'] = 7
48
+ z['c'] = 9
49
+ z['d'] = 6
50
+
51
+ c = Redis::Counter.new('conn/counter', @redis_handle)
52
+ c.reset
53
+ c.incr(3)
54
+ c.decr(1)
55
+ end
56
+
57
+ it "should support Redis.current" do
58
+ Redis.current = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
59
+
60
+ Redis::Value.new('conn/value').should == 'yay'
61
+ Redis::HashKey.new('conn/hash').keys.should == ['k']
62
+ Redis::List.new('conn/list').sort.should == ['3', '4', '5']
63
+ Redis::Set.new('conn/set').sort.should == ['5', '6', '7']
64
+ Redis::SortedSet.new('conn/zset').should == ['d', 'b', 'a', 'c']
65
+ Redis::Counter.new('conn/counter').should == 2
66
+ end
67
+
68
+ it "should support Redis::Objects.redis=" do
69
+ @redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT)
70
+
71
+ # Redis.current is lazily auto-populated to touch 6379
72
+ # This why we choose the weird 9212 port to avoid
73
+ Redis.current = BAD_REDIS
74
+ Redis::Objects.redis.should == BAD_REDIS
75
+
76
+ # This set of tests sucks, it fucks up the per-data-type handles
77
+ # because Redis.current is then set to a BS value, and the lazy
78
+ # init code in redis-rb will keep that value until we clear it.
79
+ # This ends up fucking any sequential tests.
80
+ raises_exception{ Redis::Value.new('conn/value').should.be.nil }
81
+ raises_exception{ Redis::HashKey.new('conn/hash').keys.should == [] }
82
+ raises_exception{ Redis::List.new('conn/list').sort.should == [] }
83
+ raises_exception{ Redis::Set.new('conn/set').sort.should == [] }
84
+ raises_exception{ Redis::SortedSet.new('conn/zset').should == [] }
85
+ raises_exception{ Redis::Counter.new('conn/counter').get.should == 0 }
86
+
87
+ Redis::Objects.redis = @redis_handle
88
+ Redis::Value.new('fart').redis.should == @redis_handle
89
+
90
+ # These should now get the correct handle
91
+ Redis::Value.new('conn/value').should == 'yay'
92
+ Redis::HashKey.new('conn/hash').keys.should == ['k']
93
+ Redis::List.new('conn/list').sort.should == ['3', '4', '5']
94
+ Redis::Set.new('conn/set').sort.should == ['5', '6', '7']
95
+ Redis::SortedSet.new('conn/zset').should == ['d', 'b', 'a', 'c']
96
+ Redis::Counter.new('conn/counter').should == 2
97
+
98
+ # Fix for future tests
99
+ Redis.current = @redis_handle
100
+ end
101
+
102
+ end
103
+
104
+
@@ -1,13 +1,7 @@
1
1
 
2
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
 
4
- require 'redis/counter'
5
- require 'redis/list'
6
- require 'redis/value'
7
- require 'redis/lock'
8
- require 'redis/set'
9
- require 'redis/sorted_set'
10
- require 'redis/hash_key'
4
+ require 'redis/objects'
11
5
 
12
6
  describe Redis::Value do
13
7
  before do
@@ -27,6 +21,8 @@ describe Redis::Value do
27
21
  @value.get.should == 'Trevor Hoffman'
28
22
  @value.del.should == 1
29
23
  @value.should.be.nil
24
+ @value.value = 42
25
+ @value.value.should == '42'
30
26
  end
31
27
 
32
28
  it "should handle complex marshaled values" do
@@ -100,7 +96,6 @@ describe Redis::List do
100
96
  describe "as a bounded list" do
101
97
  before do
102
98
  @list = Redis::List.new('spec/bounded_list',
103
- $redis,
104
99
  :maxlength => 10)
105
100
  1.upto(10) do |i|
106
101
  @list << i
@@ -330,7 +325,7 @@ end
330
325
 
331
326
  describe Redis::Lock do
332
327
  before do
333
- $redis.flushall
328
+ REDIS_HANDLE.flushall
334
329
  end
335
330
 
336
331
  it "should set the value to the expiration" do
@@ -338,7 +333,7 @@ describe Redis::Lock do
338
333
  expiry = 15
339
334
  lock = Redis::Lock.new(:test_lock, :expiration => expiry)
340
335
  lock.lock do
341
- expiration = $redis.get("test_lock").to_f
336
+ expiration = REDIS_HANDLE.get("test_lock").to_f
342
337
 
343
338
  # The expiration stored in redis should be 15 seconds from when we started
344
339
  # or a little more
@@ -346,17 +341,17 @@ describe Redis::Lock do
346
341
  end
347
342
 
348
343
  # key should have been cleaned up
349
- $redis.get("test_lock").should.be.nil
344
+ REDIS_HANDLE.get("test_lock").should.be.nil
350
345
  end
351
346
 
352
347
  it "should set value to 1 when no expiration is set" do
353
348
  lock = Redis::Lock.new(:test_lock)
354
349
  lock.lock do
355
- $redis.get('test_lock').should == '1'
350
+ REDIS_HANDLE.get('test_lock').should == '1'
356
351
  end
357
352
 
358
353
  # key should have been cleaned up
359
- $redis.get("test_lock").should.be.nil
354
+ REDIS_HANDLE.get("test_lock").should.be.nil
360
355
  end
361
356
 
362
357
  it "should let lock be gettable when lock is expired" do
@@ -364,7 +359,7 @@ describe Redis::Lock do
364
359
  lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
365
360
 
366
361
  # create a fake lock in the past
367
- $redis.set("test_lock", Time.now-(expiry + 60))
362
+ REDIS_HANDLE.set("test_lock", Time.now-(expiry + 60))
368
363
 
369
364
  gotit = false
370
365
  lock.lock do
@@ -373,7 +368,7 @@ describe Redis::Lock do
373
368
 
374
369
  # should get the lock because it has expired
375
370
  gotit.should.be.true
376
- $redis.get("test_lock").should.be.nil
371
+ REDIS_HANDLE.get("test_lock").should.be.nil
377
372
  end
378
373
 
379
374
  it "should not let non-expired locks be gettable" do
@@ -381,7 +376,7 @@ describe Redis::Lock do
381
376
  lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
382
377
 
383
378
  # create a fake lock
384
- $redis.set("test_lock", (Time.now + expiry).to_f)
379
+ REDIS_HANDLE.set("test_lock", (Time.now + expiry).to_f)
385
380
 
386
381
  gotit = false
387
382
  error = nil
@@ -398,7 +393,7 @@ describe Redis::Lock do
398
393
  gotit.should.not.be.true
399
394
 
400
395
  # lock value should still be set
401
- $redis.get("test_lock").should.not.be.nil
396
+ REDIS_HANDLE.get("test_lock").should.not.be.nil
402
397
  end
403
398
 
404
399
  it "should not remove the key if lock is held past expiration" do
@@ -409,7 +404,7 @@ describe Redis::Lock do
409
404
  end
410
405
 
411
406
  # lock value should still be set since the lock was held for more than the expiry
412
- $redis.get("test_lock").should.not.be.nil
407
+ REDIS_HANDLE.get("test_lock").should.not.be.nil
413
408
  end
414
409
  end
415
410
 
@@ -417,8 +412,7 @@ end
417
412
  describe Redis::HashKey do
418
413
  describe "With Marshal" do
419
414
  before do
420
- @hash = Redis::HashKey.new('test_hash', $redis,
421
- {:marshal_keys=>{'created_at'=>true}})
415
+ @hash = Redis::HashKey.new('test_hash', {:marshal_keys=>{'created_at'=>true}})
422
416
  @hash.clear
423
417
  end
424
418
 
@@ -449,7 +443,7 @@ describe Redis::HashKey do
449
443
  end
450
444
 
451
445
  before do
452
- @hash = Redis::HashKey.new('test_hash')
446
+ @hash = Redis::HashKey.new('test_hash')
453
447
  @hash.clear
454
448
  end
455
449
 
@@ -2,7 +2,6 @@
2
2
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
 
4
4
  require 'redis/objects'
5
- Redis::Objects.redis = $redis
6
5
 
7
6
  class Roster
8
7
  include Redis::Objects
@@ -20,7 +19,7 @@ class Roster
20
19
  counter :total_players_online, :global => true
21
20
  set :all_players_online, :global => true
22
21
  value :last_player, :global => true
23
-
22
+
24
23
  # custom keys
25
24
  counter :player_totals, :key => 'players/#{username}/total'
26
25
  list :all_player_stats, :key => 'players:all_stats', :global => true
@@ -52,14 +51,14 @@ class MethodRoster
52
51
  def increment(attribute, by=1)
53
52
  42
54
53
  end
55
-
54
+
56
55
  def initialize(id=1) @id = id end
57
56
  def id; @id; end
58
57
  end
59
58
 
60
59
  class CustomMethodRoster < MethodRoster
61
60
  include Redis::Objects
62
-
61
+
63
62
  attr_accessor :counter
64
63
  counter :basic
65
64
  end
@@ -68,7 +67,7 @@ describe Redis::Objects do
68
67
  before do
69
68
  @roster = Roster.new
70
69
  @roster2 = Roster.new
71
-
70
+
72
71
  @roster_1 = Roster.new(1)
73
72
  @roster_2 = Roster.new(2)
74
73
  @roster_3 = Roster.new(3)
@@ -96,7 +95,7 @@ describe Redis::Objects do
96
95
  Roster.all_players_online.clear
97
96
  Roster.last_player.delete
98
97
  Roster.weird_key.clear
99
-
98
+
100
99
  @roster.player_totals.clear
101
100
  @roster.all_player_stats.clear
102
101
  @roster.total_wins.clear
@@ -173,11 +172,11 @@ describe Redis::Objects do
173
172
  @roster.respond_to?(m).should == true
174
173
  end
175
174
  end
176
-
175
+
177
176
  it "should support increment/decrement of counters" do
178
177
  @roster.available_slots.key.should == 'roster:1:available_slots'
179
178
  @roster.available_slots.should == 10
180
-
179
+
181
180
  # math proxy ops
182
181
  (@roster.available_slots == 10).should.be.true
183
182
  (@roster.available_slots <= 10).should.be.true
@@ -204,7 +203,7 @@ describe Redis::Objects do
204
203
  @roster2.basic.decrement.should == 0
205
204
  @roster.basic.get.should == 0
206
205
  end
207
-
206
+
208
207
  it "should support class-level increment/decrement of counters" do
209
208
  Roster.get_counter(:available_slots, @roster.id).should == 10
210
209
  Roster.increment_counter(:available_slots, @roster.id).should == 11
@@ -225,7 +224,7 @@ describe Redis::Objects do
225
224
  Roster.total_players_online.decrement(2).should == 1
226
225
  Roster.total_players_online.reset.should.be.true
227
226
  Roster.total_players_online.should == 0
228
-
227
+
229
228
  Roster.get_counter(:total_players_online).should == 0
230
229
  Roster.increment_counter(:total_players_online).should == 1
231
230
  Roster.increment_counter(:total_players_online, nil, 3).should == 4
@@ -247,21 +246,28 @@ describe Redis::Objects do
247
246
  end
248
247
  @roster.available_slots.should == 9
249
248
  a.should.be.true
250
-
249
+
251
250
  @roster.available_slots.should == 9
252
251
  @roster.available_slots.decr do |cnt|
253
252
  @roster.available_slots.should == 8
254
253
  false
255
254
  end
256
255
  @roster.available_slots.should == 8
257
-
256
+
258
257
  @roster.available_slots.should == 8
259
258
  @roster.available_slots.decr do |cnt|
260
259
  @roster.available_slots.should == 7
261
260
  nil # should rewind
262
261
  end
263
262
  @roster.available_slots.should == 8
264
-
263
+
264
+ @roster.available_slots.should == 8
265
+ @roster.available_slots.decr(4) do |cnt|
266
+ @roster.available_slots.should == 4
267
+ nil # should rewind
268
+ end
269
+ @roster.available_slots.should == 8
270
+
265
271
  @roster.available_slots.should == 8
266
272
  @roster.available_slots.incr do |cnt|
267
273
  if 1 == 2 # should rewind
@@ -270,6 +276,14 @@ describe Redis::Objects do
270
276
  end
271
277
  @roster.available_slots.should == 8
272
278
 
279
+ @roster.available_slots.should == 8
280
+ @roster.available_slots.incr(5) do |cnt|
281
+ if 1 == 2 # should rewind
282
+ true
283
+ end
284
+ end
285
+ @roster.available_slots.should == 8
286
+
273
287
  @roster.available_slots.should == 8
274
288
  @roster.available_slots.incr do |cnt|
275
289
  @roster.available_slots.should == 9
@@ -286,7 +300,7 @@ describe Redis::Objects do
286
300
  rescue
287
301
  end
288
302
  @roster.available_slots.should == 9
289
-
303
+
290
304
  # check return value from the block
291
305
  value =
292
306
  @roster.available_slots.decr do |cnt|
@@ -322,6 +336,13 @@ describe Redis::Objects do
322
336
  end
323
337
  Roster.get_counter(:available_slots, @roster.id).should == 8
324
338
 
339
+ Roster.get_counter(:available_slots, @roster.id).should == 8
340
+ Roster.decrement_counter(:available_slots, @roster.id, 4) do |cnt|
341
+ Roster.get_counter(:available_slots, @roster.id).should == 4
342
+ nil # should rewind
343
+ end
344
+ Roster.get_counter(:available_slots, @roster.id).should == 8
345
+
325
346
  Roster.get_counter(:available_slots, @roster.id).should == 8
326
347
  Roster.increment_counter(:available_slots, @roster.id) do |cnt|
327
348
  if 1 == 2 # should rewind
@@ -330,6 +351,14 @@ describe Redis::Objects do
330
351
  end
331
352
  Roster.get_counter(:available_slots, @roster.id).should == 8
332
353
 
354
+ Roster.get_counter(:available_slots, @roster.id).should == 8
355
+ Roster.increment_counter(:available_slots, @roster.id, 4) do |cnt|
356
+ if 1 == 2 # should rewind
357
+ true
358
+ end
359
+ end
360
+ Roster.get_counter(:available_slots, @roster.id).should == 8
361
+
333
362
  Roster.get_counter(:available_slots, @roster.id).should == 8
334
363
  Roster.increment_counter(:available_slots, @roster.id) do |cnt|
335
364
  Roster.get_counter(:available_slots, @roster.id).should == 9
@@ -406,7 +435,7 @@ describe Redis::Objects do
406
435
  error.should.be.nil
407
436
  Roster.redis.get("roster:2:resort_lock").should.be.nil
408
437
  end
409
-
438
+
410
439
  it "should handle simple values" do
411
440
  @roster.starting_pitcher.should == nil
412
441
  @roster.starting_pitcher = 'Trevor Hoffman'
@@ -515,7 +544,7 @@ describe Redis::Objects do
515
544
  @roster.outfielders.get.sort.should == ['a','b']
516
545
  @roster.outfielders.length.should == 2
517
546
  @roster.outfielders.size.should == 2
518
-
547
+
519
548
  i = 0
520
549
  @roster.outfielders.each do |st|
521
550
  i += 1
@@ -535,7 +564,7 @@ describe Redis::Objects do
535
564
  coll.should == ['c']
536
565
  @roster.outfielders.sort.should == ['a','b','c']
537
566
  end
538
-
567
+
539
568
  it "should handle set intersections and unions" do
540
569
  @roster_1.outfielders << 'a' << 'b' << 'c' << 'd' << 'e'
541
570
  @roster_2.outfielders << 'c' << 'd' << 'e' << 'f' << 'g'
@@ -651,7 +680,7 @@ describe Redis::Objects do
651
680
  Roster.all_players_online.get.sort.should == ['a','b']
652
681
  Roster.all_players_online.length.should == 2
653
682
  Roster.all_players_online.size.should == 2
654
-
683
+
655
684
  i = 0
656
685
  Roster.all_players_online.each do |st|
657
686
  i += 1
@@ -671,7 +700,7 @@ describe Redis::Objects do
671
700
  coll.should == ['c']
672
701
  Roster.all_players_online.sort.should == ['a','b','c']
673
702
  end
674
-
703
+
675
704
  it "should handle class-level global values" do
676
705
  Roster.last_player.should == nil
677
706
  Roster.last_player = 'Trevor Hoffman'
@@ -705,7 +734,7 @@ describe Redis::Objects do
705
734
  @roster2.all_player_stats.should == ['b','a']
706
735
  @roster2.all_player_stats << 'b'
707
736
  @roster.all_player_stats.should == ['b','a','b']
708
-
737
+
709
738
  @roster.last_player.should == nil
710
739
  @roster.class.last_player = 'Trevor Hoffman'
711
740
  @roster.last_player.should == 'Trevor Hoffman'
@@ -727,7 +756,7 @@ describe Redis::Objects do
727
756
  @roster.player_stats.last.should == [1,2,3,[4,5]]
728
757
  @roster.player_stats.shift.should == {:json => 'data'}
729
758
  end
730
-
759
+
731
760
  it "should handle sets of complex data types" do
732
761
  @roster.outfielders << {:a => 1}
733
762
  @roster.outfielders.members.should == [{:a => 1}]
@@ -747,7 +776,7 @@ describe Redis::Objects do
747
776
  end
748
777
  a.should.be.true
749
778
  end
750
-
779
+
751
780
  it "should raise an exception if the timeout is exceeded" do
752
781
  @roster.redis.set(@roster.resort_lock.key, 1)
753
782
  error = nil
@@ -799,7 +828,7 @@ describe Redis::Objects do
799
828
  it "should handle new subclass objects" do
800
829
  @custom_roster.special.increment.should == 1
801
830
  end
802
-
831
+
803
832
  it "should allow passing of increment/decrement to super class" do
804
833
  @custom_method_roster = CustomMethodRoster.new
805
834
  @custom_method_roster.counter.should.be.nil
@@ -814,4 +843,55 @@ describe Redis::Objects do
814
843
  @custom_method_roster.basic.should == 0
815
844
  @custom_method_roster.basic.should.be.kind_of(Redis::Counter)
816
845
  end
846
+
847
+ it "should pick up class methods from superclass automatically" do
848
+ CounterRoster = Class.new(Roster)
849
+ CounterRoster.counter :extended_counter
850
+ extended_roster = CounterRoster.new
851
+ extended_roster.basic.should.be.kind_of(Redis::Counter)
852
+ extended_roster.extended_counter.should.be.kind_of(Redis::Counter)
853
+ @roster.respond_to?(:extended_counter).should == false
854
+
855
+ HashKeyRoster = Class.new(Roster)
856
+ HashKeyRoster.hash_key :extended_hash_key
857
+ extended_roster = HashKeyRoster.new
858
+ extended_roster.contact_information.should.be.kind_of(Redis::HashKey)
859
+ extended_roster.extended_hash_key.should.be.kind_of(Redis::HashKey)
860
+ @roster.respond_to?(:extended_hash_key).should == false
861
+
862
+ LockRoster = Class.new(Roster)
863
+ LockRoster.lock :extended
864
+ extended_roster = LockRoster.new
865
+ extended_roster.resort_lock.should.be.kind_of(Redis::Lock)
866
+ extended_roster.extended_lock.should.be.kind_of(Redis::Lock)
867
+ @roster.respond_to?(:extended_lock).should == false
868
+
869
+ ValueRoster = Class.new(Roster)
870
+ ValueRoster.value :extended_value
871
+ extended_roster = ValueRoster.new
872
+ extended_roster.starting_pitcher.should.be.kind_of(Redis::Value)
873
+ extended_roster.extended_value.should.be.kind_of(Redis::Value)
874
+ @roster.respond_to?(:extended_value).should == false
875
+
876
+ ListRoster = Class.new(Roster)
877
+ ListRoster.list :extended_list
878
+ extended_roster = ListRoster.new
879
+ extended_roster.player_stats.should.be.kind_of(Redis::List)
880
+ extended_roster.extended_list.should.be.kind_of(Redis::List)
881
+ @roster.respond_to?(:extended_list).should == false
882
+
883
+ SetRoster = Class.new(Roster)
884
+ SetRoster.set :extended_set
885
+ extended_roster = SetRoster.new
886
+ extended_roster.outfielders.should.be.kind_of(Redis::Set)
887
+ extended_roster.extended_set.should.be.kind_of(Redis::Set)
888
+ @roster.respond_to?(:extended_set).should == false
889
+
890
+ SortedSetRoster = Class.new(Roster)
891
+ SortedSetRoster.sorted_set :extended_sorted_set
892
+ extended_roster = SortedSetRoster.new
893
+ extended_roster.rank.should.be.kind_of(Redis::SortedSet)
894
+ extended_roster.extended_sorted_set.should.be.kind_of(Redis::SortedSet)
895
+ @roster.respond_to?(:extended_sorted_set).should == false
896
+ end
817
897
  end