diff --git a/lib/factory_girl.rb b/lib/factory_girl.rb index 18f191a..8da549d 100644 --- a/lib/factory_girl.rb +++ b/lib/factory_girl.rb @@ -17,7 +17,7 @@ require 'factory_girl/aliases' # Example: # Factory(:user, :name => 'Joe') def Factory (name, attrs = {}) - Factory.create(name, attrs) + Factory.default_strategy(name, attrs) end if defined? Rails diff --git a/lib/factory_girl/factory.rb b/lib/factory_girl/factory.rb index 3db1c0d..c772459 100644 --- a/lib/factory_girl/factory.rb +++ b/lib/factory_girl/factory.rb @@ -48,6 +48,10 @@ class Factory def build_class #:nodoc: @build_class ||= class_for(class_name) end + + def default_strategy #:nodoc: + @options[:default_strategy] || :create + end def initialize (name, options = {}) #:nodoc: assert_valid_options(options) @@ -170,7 +174,7 @@ class Factory s = Sequence.new(&block) add_attribute(name) { s.next } end - + # Generates and returns a Hash of attributes from this factory. Attributes # can be individually overridden by passing in a Hash of attribute => value # pairs. @@ -230,7 +234,11 @@ class Factory # A mock object with generated attributes stubbed out (Object) def self.stub (name, overrides = {}) factory_by_name(name).run(Proxy::Stub, overrides) - end + end + + def self.default_strategy (name, overrides = {}) + self.send(factory_by_name(name).default_strategy, name, overrides) + end def self.find_definitions #:nodoc: definition_file_paths.each do |path| @@ -284,10 +292,17 @@ class Factory end def assert_valid_options(options) - invalid_keys = options.keys - [:class, :parent] + invalid_keys = options.keys - [:class, :parent, :default_strategy] unless invalid_keys == [] raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}" end + assert_valid_strategy(options[:default_strategy]) if options[:default_strategy] + end + + def assert_valid_strategy(strategy) + unless Factory::Proxy.const_defined? variable_name_to_class_name(strategy) + raise ArgumentError, "Unknown strategy: #{strategy}" + end end # Based on ActiveSupport's underscore inflector diff --git a/test/factory_test.rb b/test/factory_test.rb index 47b904e..8ce2966 100644 --- a/test/factory_test.rb +++ b/test/factory_test.rb @@ -46,13 +46,17 @@ factory = Factory.new(:post) should "have a build class" do assert_equal @class, @factory.build_class end + + should "have a default strategy" do + assert_equal :create, @factory.default_strategy + end should "not allow the same attribute to be added twice" do assert_raise(Factory::AttributeDefinitionError) do 2.times { @factory.add_attribute :first_name } end end - + should "add a static attribute when an attribute is defined with a value" do attribute = mock('attribute', :name => :name) Factory::Attribute::Static. @@ -238,7 +242,7 @@ factory = Factory.new(:post) assert_nil @result[:test] end end - + should "guess the build class from the factory name" do assert_equal User, @factory.build_class end @@ -362,8 +366,18 @@ factory = Factory.new(:post) returns('result') assert_equal 'result', Factory.stub(@name, :attr => 'value') end + + should "use default strategy option as Factory.default_strategy" do + @factory.stubs(:default_strategy).returns(:create) + @factory. + expects(:run). + with(Factory::Proxy::Create, :attr => 'value'). + returns('result') + assert_equal 'result', Factory.default_strategy(@name, :attr => 'value') + end - should "use Proxy::Create for the global Factory method" do + should "use the default strategy for the global Factory method" do + @factory.stubs(:default_strategy).returns(:create) @factory. expects(:run). with(Factory::Proxy::Create, :attr => 'value'). @@ -384,7 +398,7 @@ factory = Factory.new(:post) end end - context 'defining a factory using a parent attribute' do + context 'defining a factory with a parent parameter' do setup do @parent = Factory.define :object do |f| f.name 'Name' @@ -422,6 +436,17 @@ factory = Factory.new(:post) end end + context 'defining a factory with a default strategy parameter' do + should 'raise an ArgumentError when trying to use a non-existent factory' do + assert_raise(ArgumentError) { Factory.define(:object, :default_strategy => :nonexistent) {} } + end + + should 'create a new factory with a specified default strategy' do + factory = Factory.define(:object, :default_strategy => :stub) {} + assert_equal :stub, factory.default_strategy + end + end + def self.context_in_directory_with_files(*files) context "in a directory with #{files.to_sentence}" do setup do diff --git a/test/integration_test.rb b/test/integration_test.rb index 8c94368..b564fdc 100644 --- a/test/integration_test.rb +++ b/test/integration_test.rb @@ -10,7 +10,7 @@ class IntegrationTest < Test::Unit::TestCase f.email {|a| "#{a.first_name}.#{a.last_name}@example.com".downcase } end - Factory.define Post do |f| + Factory.define Post, :default_strategy => :attributes_for do |f| f.name 'Test Post' f.association :author, :factory => :user end @@ -131,7 +131,7 @@ class IntegrationTest < Test::Unit::TestCase end end - + context "an instance generated by a factory with a custom class name" do setup do @@ -225,5 +225,11 @@ class IntegrationTest < Test::Unit::TestCase end end + + context "a factory with a default strategy specified" do + should "generate instances according to the strategy" do + assert_kind_of Hash, Factory(:post) + end + end end