mirror of
https://github.com/thoughtbot/factory_bot.git
synced 2022-11-09 11:43:51 -05:00
Support *_list for all (including custom) strategies
This commit is contained in:
parent
1325da5174
commit
95a4626daa
5 changed files with 127 additions and 47 deletions
|
@ -3,6 +3,7 @@ require "active_support/notifications"
|
|||
|
||||
require 'factory_girl/errors'
|
||||
require 'factory_girl/factory_runner'
|
||||
require 'factory_girl/strategy_syntax_method_registrar'
|
||||
require 'factory_girl/strategy_calculator'
|
||||
require "factory_girl/strategy/build"
|
||||
require "factory_girl/strategy/create"
|
||||
|
@ -87,16 +88,7 @@ module FactoryGirl
|
|||
|
||||
def self.register_strategy(strategy_name, strategy_class)
|
||||
strategies.register(strategy_name, strategy_class)
|
||||
|
||||
FactoryGirl::Syntax::Methods.module_exec do
|
||||
define_method(strategy_name) do |name, *traits_and_overrides, &block|
|
||||
instrumentation_payload = { name: name, strategy: strategy_name }
|
||||
|
||||
ActiveSupport::Notifications.instrument("factory_girl.run_factory", instrumentation_payload) do
|
||||
FactoryRunner.new(name, strategy_name, traits_and_overrides).run(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
StrategySyntaxMethodRegistrar.new(strategy_name).define_strategy_methods
|
||||
end
|
||||
|
||||
def self.strategy_by_name(name)
|
||||
|
|
|
@ -17,7 +17,11 @@ module FactoryGirl
|
|||
factory = factory.with_traits(@traits)
|
||||
end
|
||||
|
||||
factory.run(runner_strategy, @overrides, &block)
|
||||
instrumentation_payload = { name: @name, strategy: runner_strategy }
|
||||
|
||||
ActiveSupport::Notifications.instrument("factory_girl.run_factory", instrumentation_payload) do
|
||||
factory.run(runner_strategy, @overrides, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
36
lib/factory_girl/strategy_syntax_method_registrar.rb
Normal file
36
lib/factory_girl/strategy_syntax_method_registrar.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
module FactoryGirl
|
||||
class StrategySyntaxMethodRegistrar
|
||||
def initialize(strategy_name)
|
||||
@strategy_name = strategy_name
|
||||
end
|
||||
|
||||
def define_strategy_methods
|
||||
define_singular_strategy_method
|
||||
define_list_strategy_method
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def define_singular_strategy_method
|
||||
strategy_name = @strategy_name
|
||||
|
||||
define_syntax_method(strategy_name) do |name, *traits_and_overrides, &block|
|
||||
FactoryRunner.new(name, strategy_name, traits_and_overrides).run(&block)
|
||||
end
|
||||
end
|
||||
|
||||
def define_list_strategy_method
|
||||
strategy_name = @strategy_name
|
||||
|
||||
define_syntax_method("#{strategy_name}_list") do |name, amount, *traits_and_overrides|
|
||||
amount.times.map { send(strategy_name, name, *traits_and_overrides) }
|
||||
end
|
||||
end
|
||||
|
||||
def define_syntax_method(name, &block)
|
||||
FactoryGirl::Syntax::Methods.module_exec do
|
||||
define_method(name, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,43 +1,83 @@
|
|||
module FactoryGirl
|
||||
module Syntax
|
||||
## This module is a container for all strategy methods provided by
|
||||
## FactoryGirl. This includes all the default strategies provided ({Methods#build},
|
||||
## {Methods#create}, {Methods#build_stubbed}, and {Methods#attributes_for}), as well as
|
||||
## the complementary *_list methods.
|
||||
## @example singular factory execution
|
||||
## # basic use case
|
||||
## build(:completed_order)
|
||||
##
|
||||
## # factory yielding its result to a block
|
||||
## create(:post) do |post|
|
||||
## create(:comment, post: post)
|
||||
## end
|
||||
##
|
||||
## # factory with attribute override
|
||||
## attributes_for(:post, title: "I love Ruby!")
|
||||
##
|
||||
## # factory with traits and attribute override
|
||||
## build_stubbed(:user, :admin, :male, name: "John Doe")
|
||||
##
|
||||
## @example multiple factory execution
|
||||
## # basic use case
|
||||
## build_list(:completed_order, 2)
|
||||
## create_list(:completed_order, 2)
|
||||
##
|
||||
## # factory with attribute override
|
||||
## attributes_for_list(:post, 4, title: "I love Ruby!")
|
||||
##
|
||||
## # factory with traits and attribute override
|
||||
## build_stubbed_list(:user, 15, :admin, :male, name: "John Doe")
|
||||
module Methods
|
||||
# Builds and returns multiple instances from this factory as an array. Attributes can be
|
||||
# individually overridden by passing in a Hash of attribute => value pairs.
|
||||
#
|
||||
# Arguments:
|
||||
# * name: +Symbol+ or +String+
|
||||
# The name of the factory to be used.
|
||||
# * amount: +Integer+
|
||||
# number of instances to be built.
|
||||
# * traits_and_overrides: +Array+
|
||||
# [+*Array+] Traits to be applied
|
||||
# [+Hash+] Attributes to overwrite for this instance.
|
||||
#
|
||||
# Returns: +Array+
|
||||
# An array of instances of the class this factory generates, with generated attributes
|
||||
# assigned.
|
||||
def build_list(name, amount, *traits_and_overrides)
|
||||
amount.times.map { build(name, *traits_and_overrides) }
|
||||
end
|
||||
# @!parse FactoryGirl.register_default_strategies
|
||||
# @!method build(name, *traits_and_overrides, &block)
|
||||
# (see #strategy_method)
|
||||
# Builds a registered factory by name.
|
||||
# @return [Object] instantiated object defined by the factory
|
||||
|
||||
# Creates and returns multiple instances from this factory as an array. Attributes can be
|
||||
# individually overridden by passing in a Hash of attribute => value pairs.
|
||||
#
|
||||
# Arguments:
|
||||
# * name: +Symbol+ or +String+
|
||||
# The name of the factory to be used.
|
||||
# * amount: +Integer+
|
||||
# number of instances to be created.
|
||||
# * traits_and_overrides: +Array+
|
||||
# [+*Array+] Traits to be applied
|
||||
# [+Hash+] Attributes to overwrite for this instance.
|
||||
#
|
||||
# Returns: +Array+
|
||||
# An array of instances of the class this factory generates, with generated attributes
|
||||
# assigned.
|
||||
def create_list(name, amount, *traits_and_overrides)
|
||||
amount.times.map { create(name, *traits_and_overrides) }
|
||||
end
|
||||
# @!method create(name, *traits_and_overrides, &block)
|
||||
# (see #strategy_method)
|
||||
# Creates a registered factory by name.
|
||||
# @return [Object] instantiated object defined by the factory
|
||||
|
||||
# @!method build_stubbed(name, *traits_and_overrides, &block)
|
||||
# (see #strategy_method)
|
||||
# Builds a stubbed registered factory by name.
|
||||
# @return [Object] instantiated object defined by the factory
|
||||
|
||||
# @!method attributes_for(name, *traits_and_overrides, &block)
|
||||
# (see #strategy_method)
|
||||
# Generates a hash of attributes for a registered factory by name.
|
||||
# @return [Hash] hash of attributes for the factory
|
||||
|
||||
# @!method build_list(name, amount, *traits_and_overrides)
|
||||
# (see #strategy_method_list)
|
||||
# @return [Array] array of built objects defined by the factory
|
||||
|
||||
# @!method create_list(name, amount, *traits_and_overrides)
|
||||
# (see #strategy_method_list)
|
||||
# @return [Array] array of created objects defined by the factory
|
||||
|
||||
# @!method build_stubbed_list(name, amount, *traits_and_overrides)
|
||||
# (see #strategy_method_list)
|
||||
# @return [Array] array of stubbed objects defined by the factory
|
||||
|
||||
# @!method attributes_for_list(name, amount, *traits_and_overrides)
|
||||
# (see #strategy_method_list)
|
||||
# @return [Array<Hash>] array of attribute hashes for the factory
|
||||
|
||||
# @!method strategy_method
|
||||
# @!visibility private
|
||||
# @param [Symbol] name name of the factory to build
|
||||
# @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
|
||||
# @param [Proc] block block to be executed
|
||||
|
||||
# @!method strategy_method_list
|
||||
# @!visibility private
|
||||
# @param [Symbol] name name of the factory to execute
|
||||
# @param [Integer] amount the number of instances to execute
|
||||
# @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
|
||||
|
||||
# Generates and returns the next value in a sequence.
|
||||
#
|
||||
|
|
|
@ -41,6 +41,14 @@ describe "register custom strategies" do
|
|||
FactoryGirl.build(:named_object).name.should == "Great"
|
||||
FactoryGirl.insert(:named_object).name.should == "Custom strategy"
|
||||
end
|
||||
|
||||
it "allows using the *_list method to build a list using a custom strategy" do
|
||||
FactoryGirl.register_strategy(:insert, custom_strategy)
|
||||
|
||||
inserted_items = FactoryGirl.insert_list(:named_object, 2)
|
||||
inserted_items.length.should == 2
|
||||
inserted_items.map(&:name).should == ["Custom strategy", "Custom strategy"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "including FactoryGirl::Syntax::Methods when custom strategies have been declared" do
|
||||
|
|
Loading…
Reference in a new issue