1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
module FactoryBot
# @api private
class StrategySyntaxMethodRegistrar
def initialize(strategy_name)
@strategy_name = strategy_name
end
def define_strategy_methods
define_singular_strategy_method
define_list_strategy_method
define_pair_strategy_method
end
def self.with_index(block, index)
if block&.arity == 2
->(instance) { block.call(instance, index) }
else
block
end
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, &block|
unless amount.respond_to?(:times)
raise ArgumentError, "count missing for #{strategy_name}_list"
end
Array.new(amount) do |i|
block_with_index = StrategySyntaxMethodRegistrar.with_index(block, i)
send(strategy_name, name, *traits_and_overrides, &block_with_index)
end
end
end
def define_pair_strategy_method
strategy_name = @strategy_name
define_syntax_method("#{strategy_name}_pair") do |name, *traits_and_overrides, &block|
Array.new(2) { send(strategy_name, name, *traits_and_overrides, &block) }
end
end
def define_syntax_method(name, &block)
FactoryBot::Syntax::Methods.module_exec do
if method_defined?(name) || private_method_defined?(name)
undef_method(name)
end
define_method(name, &block)
end
end
end
end
|