Skip to content

Commit

Permalink
Added ability to specify finding models with a table
Browse files Browse the repository at this point in the history
  • Loading branch information
ianwhite committed Nov 24, 2009
1 parent 6846976 commit 51c6805
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
18 changes: 17 additions & 1 deletion features/pickle/create_from_active_record.feature
Expand Up @@ -24,4 +24,20 @@ Feature: I can easily create models from my blueprints
And another user exists with name: "Ethel", attitude_score: -1.46
Then 2 users should exist
And the 1st user should be a positive person
And the 2nd user should not be a positive person
And the 2nd user should not be a positive person

Scenario: create and find using tables
Given the following users exist:
| name | status |
| Jim | married |
| Ethel | in a relationship with x |
Then the following users should exist:
| name |
| Jim |
| Ethel |
And the following users should exist:
| status |
| married |
| in a relationship with x |
And the 1st user should be the 3rd user
And the 2nd user should be the last user
9 changes: 7 additions & 2 deletions lib/pickle/session.rb
Expand Up @@ -32,11 +32,16 @@ def find_model(a_model_name, fields = nil)
factory, name = *parse_model(a_model_name)
raise ArgumentError, "Can't find a model with an ordinal (e.g. 1st user)" if name.is_a?(Integer)
model_class = pickle_config.factories[factory].klass
if record = model_class.find(:first, :conditions => convert_models_to_attributes(model_class, parse_fields(fields)))
fields = fields.instance_of?(Hash) ? fields.dup : parse_fields(fields)
if record = model_class.find(:first, :conditions => convert_models_to_attributes(model_class, fields))
store_model(factory, name, record)
end
end

def find_model!(a_model_name, fields = nil)
find_model(a_model_name, fields) or raise "Can't find pickle model: '#{name}' in this scenario"
end

def find_models(factory, fields = nil)
models_by_index(factory).clear
model_class = pickle_config.factories[factory].klass
Expand All @@ -53,7 +58,7 @@ def created_model(name)
elsif name_or_index.is_a?(Integer)
models_by_index(factory)[name_or_index]
else
models_by_name(factory)[name_or_index] or raise "model: #{name} does not refer to known model in this scenario"
models_by_name(factory)[name_or_index] or raise "Can't find pickle model: '#{name}' in this scenario"
end
end

Expand Down
13 changes: 12 additions & 1 deletion rails_generators/pickle/templates/pickle_steps.rb
Expand Up @@ -11,7 +11,7 @@
end

# create models from a table
Given /^the following #{capture_plural_factory} exist:?$/ do |plural_factory, table|
Given(/^the following #{capture_plural_factory} exists?:?$/) do |plural_factory, table|
name = plural_factory.singularize
table.hashes.each { |hash| create_model(name, hash) }
end
Expand All @@ -26,11 +26,22 @@
find_model(name, fields).should be_nil
end

# find models with a table
Then(/^the following #{capture_plural_factory} should exists?:?$/) do |plural_factory, table|
name = plural_factory.singularize
table.hashes.each { |hash| find_model!(name, hash)}
end

# find exactly n models
Then(/^(\d+) #{capture_plural_factory} should exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields|
find_models(plural_factory.singularize, fields).size.should == count.to_i
end

# assert equality of models
Then(/^#{capture_model} should be #{capture_model}$/) do |a, b|
model!(a).should == model!(b)
end

# assert model is in another model's has_many assoc
Then(/^#{capture_model} should be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
model(owner).send(association).should include(model(target))
Expand Down
29 changes: 29 additions & 0 deletions spec/lib/pickle_session_spec.rb
Expand Up @@ -188,6 +188,35 @@ def do_find_model

it_should_behave_like "after storing a single user"
end

describe "with hash" do
def do_create_model
find_model('a user', {'foo' => 'bar'})
end

it "should call User.find('user', {'foo' => 'bar'})" do
User.should_receive(:find).with(:first, :conditions => {'foo' => 'bar'}).and_return(@user)
do_create_model
end

describe "after find," do
before { do_find_model }

it_should_behave_like "after storing a single user"
end
end
end

describe "#find_model!" do
it "should call find_model" do
should_receive(:find_model).with('name', 'fields').and_return(mock('User'))
find_model!('name', 'fields')
end

it "should call raise error if find_model returns nil" do
should_receive(:find_model).with('name', 'fields').and_return(nil)
lambda { find_model!('name', 'fields') }.should raise_error
end
end

describe "#find_models" do
Expand Down

0 comments on commit 51c6805

Please sign in to comment.