Permalink
Browse files

let Twitter::Base#fetch accept a block

  • Loading branch information...
stve committed Jul 10, 2012
1 parent ca8e285 commit 5b549e39bc2450f31080467e97b4c1701691ef82
Showing with 35 additions and 8 deletions.
  1. +12 −4 lib/twitter/base.rb
  2. +3 −0 lib/twitter/identity_map.rb
  3. +20 −4 spec/twitter/base_spec.rb
View
@@ -31,17 +31,22 @@ def self.attr_reader(*attrs)
# @return [Twitter::Base]
def self.fetch(attrs)
@@identity_map[self] ||= {}
- @@identity_map[self][Marshal.dump(attrs)]
+ if object = @@identity_map[self][Marshal.dump(attrs)]
+ return object
+ end
+
+ return yield if block_given?
+ raise Twitter::IdentityMapKeyError, 'key not found'
end
# Stores an object in the identity map and returns the newly created
# object.
#
# @param attrs [Hash]
# @return [Twitter::Base]
- def self.store(attrs)
+ def self.store(object)
@@identity_map[self] ||= {}
- @@identity_map[self][Marshal.dump(attrs)] = self.new(attrs)
+ @@identity_map[self][Marshal.dump(object.attrs)] = object
end
# Returns a new object based on the response hash
@@ -58,7 +63,10 @@ def self.from_response(response={})
# @param attrs [Hash]
# @return [Twitter::Base]
def self.fetch_or_store(attrs={})
- self.fetch(attrs) || self.store(attrs)
+ self.fetch(attrs) do
+ object = self.new(attrs)
+ self.store(object)
+ end
end
# Initializes a new object
@@ -5,4 +5,7 @@ module Twitter
class IdentityMap < Hash
end
+ class IdentityMapKeyError < ::StandardError
+ end
+
end
View
@@ -3,7 +3,8 @@
describe Twitter::Base do
before do
- @base = Twitter::Base.store(:id => 1)
+ object = Twitter::Base.new(:id => 1)
+ @base = Twitter::Base.store(object)
end
describe "#[]" do
@@ -37,14 +38,29 @@
Twitter::Base.fetch(:id => 1).should be
end
- it "retuns nil for objects that don't exist" do
- Twitter::Base.fetch(:id => 2).should_not be
+ it "raises an error on objects that don't exist" do
+ lambda {
+ Twitter::Base.fetch(:id => 6)
+ }.should raise_error(Twitter::IdentityMapKeyError)
end
end
describe '.store' do
it 'stores Twitter::Base objects' do
- Twitter::Base.store(:id => 1).should be_a Twitter::Base
+ object = Twitter::Base.new(:id => 4)
+ Twitter::Base.store(object).should be_a Twitter::Base
+ end
+ end
+
+ describe '.fetch_or_store' do
+ it 'returns existing objects' do
+ Twitter::Base.fetch_or_store(:id => 1).should be
+ end
+
+ it 'creates new objects and stores them' do
+ Twitter::Base.fetch_or_store(:id => 2).should be
+
+ Twitter::Base.fetch(:id => 2).should be
end
end
end

0 comments on commit 5b549e3

Please sign in to comment.