Permalink
Browse files

Merge branch 'method-build2-0-5' of https://github.com/jkingdon/facto…

  • Loading branch information...
2 parents 25affc7 + 9037481 commit 79a1d5e135091fac0521fed59ea8f4e2f664cd19 @mike-burns mike-burns committed Aug 26, 2011
View
@@ -194,13 +194,25 @@ The behavior of the association method varies depending on the build strategy us
# Builds and saves a User and a Post
post = FactoryGirl.create(:post)
- post.new_record? # => false
- post.author.new_record # => false
+ post.new_record? # => false
+ post.author.new_record? # => false
# Builds and saves a User, and then builds but does not save a Post
post = FactoryGirl.build(:post)
- post.new_record? # => true
- post.author.new_record # => false
+ post.new_record? # => true
+ post.author.new_record? # => false
+
+To not save the associated object, specify :method => :build in the factory:
+
+ factory :post do
+ # ...
+ association :author, :factory => :user, :method => :build
+ end
+
+ # Builds a User, and then builds a Post, but does not save either
+ post = FactoryGirl.build(:post)
+ post.new_record? # => true
+ post.author.new_record? # => true
Inheritance
-----------
@@ -23,19 +23,38 @@ def set(attribute, value, ignored = false)
end
def associate(name, factory_name, overrides)
+ method = get_method(overrides[:method])
factory = FactoryGirl.factory_by_name(factory_name)
- set(name, factory.run(Proxy::Create, overrides))
+ set(name, factory.run(method, remove_method(overrides)))
end
def association(factory_name, overrides = {})
+ method = get_method(overrides[:method])
factory = FactoryGirl.factory_by_name(factory_name)
- factory.run(Proxy::Create, overrides)
+ factory.run(method, remove_method(overrides))
+ end
+
+ def remove_method(overrides)
+ overrides.dup.delete_if {|key, value| key == :method}
end
def result(to_create)
run_callbacks(:after_build)
@instance
end
+
+ def parse_method(method)
+ method ||= :create
+ if :build == method
+ return Proxy::Build
+ elsif :create == method
+ return Proxy::Create
+ else
+ raise "unrecognized method #{method}"
+ end
+ end
+
+ alias_method :get_method, :parse_method
end
end
end
@@ -11,6 +11,12 @@ def result(to_create)
run_callbacks(:after_create)
@instance
end
+
+ def get_method(method_string)
+ # Leaving this as Proxy::Build in the :method => :build case
+ # is a bit strange, but does it have any user-visible behaviors?
+ parse_method(method_string)
+ end
end
end
end
@@ -60,12 +60,16 @@ def set(attribute, value, ignored = false)
def associate(name, factory_name, overrides)
factory = FactoryGirl.factory_by_name(factory_name)
- set(name, factory.run(Proxy::Stub, overrides))
+ set(name, factory.run(Proxy::Stub, remove_method(overrides)))
end
def association(factory_name, overrides = {})
factory = FactoryGirl.factory_by_name(factory_name)
- factory.run(Proxy::Stub, overrides)
+ factory.run(Proxy::Stub, remove_method(overrides))
+ end
+
+ def remove_method(overrides)
+ overrides.dup.delete_if {|key, value| key == :method}
end
def result(to_create)
@@ -31,3 +31,34 @@
end
end
+describe "a built instance with :method => :build" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('User')
+
+ define_model('Post', :user_id => :integer) do
+ belongs_to :user
+ end
+
+ FactoryGirl.define do
+ factory :user
+
+ factory :post do
+ association(:user, :method => :build)
+ end
+ end
+ end
+
+ subject { build(:post) }
+
+ it "isn't saved" do
+ should be_new_record
+ end
+
+ it "assigns but does not save associations" do
+ subject.user.should be_kind_of(User)
+ subject.user.should be_new_record
+ end
+
+end
@@ -31,6 +31,33 @@
end
end
+describe "a created instance, specifying :method => build" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('User')
+
+ define_model('Post', :user_id => :integer) do
+ belongs_to :user
+ end
+
+ FactoryGirl.define do
+ factory :user
+
+ factory :post do
+ association(:user, :method => :build)
+ end
+ end
+ end
+
+ subject { create('post') }
+
+ it "still saves associations (:method => :build only affects build, not create)" do
+ subject.user.should be_kind_of(User)
+ subject.user.should_not be_new_record
+ end
+end
+
describe "a custom create" do
include FactoryGirl::Syntax::Methods
@@ -0,0 +1,64 @@
+require 'spec_helper'
+
+describe "a stubbed instance" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('User')
+
+ define_model('Post', :user_id => :integer) do
+ belongs_to :user
+ end
+
+ FactoryGirl.define do
+ factory :user
+
+ factory :post do
+ user
+ end
+ end
+ end
+
+ subject { build_stubbed(:post) }
+
+ it "acts as if it came from the database" do
+ should_not be_new_record
+ end
+
+ it "assigns associations and acts as if it is saved" do
+ subject.user.should be_kind_of(User)
+ subject.user.should_not be_new_record
+ end
+end
+
+describe "a stubbed instance with :method => :build" do
+ include FactoryGirl::Syntax::Methods
+
+ before do
+ define_model('User')
+
+ define_model('Post', :user_id => :integer) do
+ belongs_to :user
+ end
+
+ FactoryGirl.define do
+ factory :user
+
+ factory :post do
+ association(:user, :method => :build)
+ end
+ end
+ end
+
+ subject { build_stubbed(:post) }
+
+ it "acts as if it is saved in the database" do
+ should_not be_new_record
+ end
+
+ it "assigns associations and acts as if it is saved" do
+ subject.user.should be_kind_of(User)
+ subject.user.should_not be_new_record
+ end
+
+end
@@ -9,4 +9,28 @@
it_should_behave_like "proxy with association support", FactoryGirl::Proxy::Create
it_should_behave_like "proxy with standard getters and setters", :attribute_name, "attribute value!"
it_should_behave_like "proxy with callbacks", :after_build
+ it_should_behave_like "proxy with :method => :build",
+ FactoryGirl::Proxy::Build
+
+ describe "specifying method" do
+ it "defaults to create" do
+ subject.send(:get_method, nil).should == FactoryGirl::Proxy::Create
+ end
+
+ it "can specify create explicitly" do
+ subject.send(:get_method, :create).should ==
+ FactoryGirl::Proxy::Create
+ end
+
+ it "can specify build explicitly" do
+ subject.send(:get_method, :build).should ==
+ FactoryGirl::Proxy::Build
+ end
+
+ it "complains if method is unrecognized" do
+ lambda { subject.send(:get_method, :froboznicate) }.
+ should raise_error("unrecognized method froboznicate")
+ end
+ end
+
end
@@ -9,6 +9,8 @@
it_should_behave_like "proxy with association support", FactoryGirl::Proxy::Stub
it_should_behave_like "proxy with standard getters and setters", :attribute_name, "attribute value!"
it_should_behave_like "proxy with callbacks", :after_stub
+ it_should_behave_like "proxy with :method => :build",
+ FactoryGirl::Proxy::Stub
context "asking for a result" do
it { subject.result(nil).should_not be_new_record }
@@ -49,6 +49,35 @@
end
end
+shared_examples_for "proxy with :method => :build" do |factory_girl_proxy_class|
+ let(:factory_name) { :user }
+ let(:association_name) { :owner }
+ let(:factory) { stub("associate_factory") }
+ let(:overrides) { { :method => :build } }
+
+ before do
+ FactoryGirl.stubs(:factory_by_name => factory)
+ instance.stubs(association_name => factory_name)
+ factory.stubs(:run => factory_name)
+ subject.stubs(:set)
+ end
+
+ it "sets a value for the association" do
+ subject.associate(association_name, factory_name, overrides)
+ subject.result(nil).send(association_name).should == factory_name
+ end
+
+ it "sets the association attribute as the factory" do
+ subject.associate(association_name, factory_name, overrides)
+ subject.should have_received(:set).with(association_name, factory_name)
+ end
+
+ it "runs the factory with the correct proxy class" do
+ subject.associate(association_name, factory_name, overrides)
+ factory.should have_received(:run).with(factory_girl_proxy_class, {})
+ end
+end
+
shared_examples_for "proxy with standard getters and setters" do |attribute, value|
before do
instance.stubs(:"#{attribute}=" => value, :"#{attribute}" => value)

0 comments on commit 79a1d5e

Please sign in to comment.