diff --git a/lib/factory_bot/internal/strategies.rb b/lib/factory_bot/internal/strategies.rb index df3588841..5beaccdb1 100644 --- a/lib/factory_bot/internal/strategies.rb +++ b/lib/factory_bot/internal/strategies.rb @@ -9,11 +9,6 @@ def self.reset @strategies&.reset end - def self.register_strategy(strategy_name, strategy_class) - strategies.register(strategy_name, strategy_class) - StrategySyntaxMethodRegistrar.new(strategy_name).define_strategy_methods - end - def self.strategy_by_name(name) strategies.find(name) end @@ -25,6 +20,11 @@ def self.register_default_strategies register_strategy(:build_stubbed, FactoryBot::Strategy::Stub) register_strategy(:null, FactoryBot::Strategy::Null) end + + def self.register_strategy(strategy_name, strategy_class) + strategies.register(strategy_name, strategy_class) + StrategySyntaxMethodRegistrar.define_strategy_methods(strategy_name) + end end end end diff --git a/lib/factory_bot/strategy_syntax_method_registrar.rb b/lib/factory_bot/strategy_syntax_method_registrar.rb index 5813c9d85..64ad2d829 100644 --- a/lib/factory_bot/strategy_syntax_method_registrar.rb +++ b/lib/factory_bot/strategy_syntax_method_registrar.rb @@ -1,37 +1,20 @@ module FactoryBot # @api private - class StrategySyntaxMethodRegistrar - def initialize(strategy_name) - @strategy_name = strategy_name + module StrategySyntaxMethodRegistrar + def self.define_strategy_methods(strategy_name) + define_singular_strategy_method(strategy_name) + define_list_strategy_method(strategy_name) + define_pair_strategy_method(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 - + def self.define_singular_strategy_method(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 + private_class_method :define_singular_strategy_method - def define_list_strategy_method - strategy_name = @strategy_name - + def self.define_list_strategy_method(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" @@ -43,16 +26,16 @@ def define_list_strategy_method end end end + private_class_method :define_list_strategy_method - def define_pair_strategy_method - strategy_name = @strategy_name - + def self.define_pair_strategy_method(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 + private_class_method :define_pair_strategy_method - def define_syntax_method(name, &block) + def self.define_syntax_method(name, &block) FactoryBot::Syntax::Methods.module_exec do if method_defined?(name) || private_method_defined?(name) undef_method(name) @@ -61,5 +44,14 @@ def define_syntax_method(name, &block) define_method(name, &block) end end + private_class_method :define_syntax_method + + def self.with_index(block, index) + if block&.arity == 2 + ->(instance) { block.call(instance, index) } + else + block + end + end end end