Skip to content

Commit

Permalink
Document Pickle::Session::Adapters, and allow adapter_map overriding
Browse files Browse the repository at this point in the history
  • Loading branch information
ianwhite committed Aug 28, 2010
1 parent 7b49bd8 commit af34072
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 32 deletions.
32 changes: 5 additions & 27 deletions features/pickle_api/example_code.feature
Expand Up @@ -5,44 +5,25 @@ Feature: Example of the pickle api, testing that it works with different combina
And I am using <FACTORY> (<ORM>) for generating test data
And I am writing a test using the pickle dsl, with <FACTORY> (<ORM>)

Then I can make and store a user (code):
Then I can make and store a user, and the result is a user made by <FACTORY> (code):
"""
user = pickle.make_and_store 'a user'
"""

And the result is a user made by <FACTORY> (code):
"""
user.should be_a User
user.name.should == "made by <FACTORY>"
"""

Then the exact user object can be retrieved from the session (code):
And I can retrieve (exact object) or retrieve_and_reload (aliased as model) the object using a pickle ref (code):
"""
pickle.retrieve('the user').object_id.should == user.object_id
"""

And the reloaded user can be retrieved from the db (code):
"""
pickle.retrieve_and_reload('the user').should == user
"""

And pickle.model does the same thing as pickle.retrieve_and_reload (code):
"""
pickle.model('the user').should == user
"""

When something happens that changes the db (code):
When something happens that changes the db, then pickle can find and store the expected changes (code):
"""
user.create_welcome_note
"""
Then pickle can find and store the expected changes (code):
"""
welcome_note = pickle.find_and_store 'note: "welcome note"', 'owner: the user'
"""

Then it should be a note, lets use the adapter to find and compare it (code):
"""
welcome_note.should be_a Note
# adapter_for will find with the <ORM> orm_adpater in this case
Expand All @@ -60,14 +41,11 @@ Feature: Example of the pickle api, testing that it works with different combina
pickle.model(:factory => 'note', :index => 0).should == welcome_note
"""

When we create another note, we can store it in pickle ourselves (code):
When we create another note, we can store it in pickle ourselves, then retrieve in the order they were mentioned, just like a conversation (code):
"""
another_note = user.create_note("another note")
pickle.store another_note
"""

Then we can get the notes back in the order they were mentioned, just like a conversation (code):
"""
pickle.model('the 1st note').should == welcome_note
pickle.model('the 2nd note').should == another_note
"""
Expand Down
20 changes: 19 additions & 1 deletion lib/pickle/session/adapters.rb
Expand Up @@ -2,6 +2,19 @@ module Pickle
module Session
# single entry for making and finding models, based on Pickle::Refs
#
# make 'user' # make a user model
# find_first 'user', 'age: 23' # find first user model with conditions :age => 23
# find_all 'user', :big => true # find all user models with conditions :big => true
# reload <user model> # reloads the given model
#
# The way it works is to find a Pickle::Adapter instance 'user', and use that. Adapter
# instances are usually auto-discovered when Pickle is loaded, but can be set simply by
# setting the adapter_map, e.g. adapter_map['user'] = <My adapter instance>
#
# to include this, you need to implement either
# #adapter_map - returns hash of adapters, or
# #config - returns a Pickle::Config
#
# included into Pickle::Session
module Adapters
include Conversion
Expand All @@ -25,7 +38,12 @@ def reload(model, ref = model.class.name)
def adapter_for(pickle_ref)
pickle_ref = ref(pickle_ref)
raise InvalidPickleRefError, "#{pickle_ref.inspect} must have a :factory when finding an adapter" unless pickle_ref.factory
config.adapter_map[pickle_ref.factory] or raise NoAdapterError, "can't find an adapter for #{pickle_ref.factory.inspect}"
adapter_map[pickle_ref.factory] or raise NoAdapterError, "can't find an adapter for #{pickle_ref.factory.inspect}"
end

protected
def adapter_map
@adapter_map ||= config.adapter_map
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions spec/pickle/session/adapters_spec.rb
Expand Up @@ -2,7 +2,7 @@

describe Pickle::Session::Adapters do
include Pickle::Session::Adapters
before { stub!(:config).and_return(Pickle::Config.new) }
before { stub!(:adapter_map).and_return(Pickle::AdapterMap.new) }

describe "#adapter_for(<ref>)" do
specify "converts <ref> to a Pickle::Ref" do
Expand All @@ -15,8 +15,8 @@
lambda { adapter_for(:index => 1) }.should raise_error(Pickle::InvalidPickleRefError)
end

it "should return config.adapter_map[<ref.factory>]" do
config.adapter_map.should_receive(:[]).with('the_user_factory').and_return(adapter = mock)
it "should return adapter_map[<ref.factory>]" do
adapter_map.should_receive(:[]).with('the_user_factory').and_return(adapter = mock)
adapter_for('The::User::Factory').should == adapter
end

Expand All @@ -29,7 +29,7 @@
let(:user) { mock('user') }
let(:user_adapter) { mock('user adapter') }

before { config.adapter_map['user'] = user_adapter }
before { adapter_map['user'] = user_adapter }

it "#make('user') should return the result of <user adapter>.make({})" do
user_adapter.should_receive(:make).with({}).and_return(user)
Expand Down

0 comments on commit af34072

Please sign in to comment.