From b593ce1062ab9cdc9c4fa3480ea04e7ffe3b987d Mon Sep 17 00:00:00 2001 From: Mohammed Nasser <135416851+mohammednasser-32@users.noreply.github.com> Date: Mon, 13 May 2024 20:04:22 +0300 Subject: [PATCH 1/2] Add hoc sequences in create_list --- lib/factory_bot/strategy_syntax_method_registrar.rb | 2 +- lib/factory_bot/syntax/methods.rb | 12 ++++++++++++ spec/acceptance/create_list_spec.rb | 10 ++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/factory_bot/strategy_syntax_method_registrar.rb b/lib/factory_bot/strategy_syntax_method_registrar.rb index 5813c9d85..a70ca0746 100644 --- a/lib/factory_bot/strategy_syntax_method_registrar.rb +++ b/lib/factory_bot/strategy_syntax_method_registrar.rb @@ -39,7 +39,7 @@ def define_list_strategy_method Array.new(amount) do |i| block_with_index = StrategySyntaxMethodRegistrar.with_index(block, i) - send(strategy_name, name, *traits_and_overrides, &block_with_index) + send(strategy_name, name, *evaluate_sequence_attributes(traits_and_overrides, i), &block_with_index) end end end diff --git a/lib/factory_bot/syntax/methods.rb b/lib/factory_bot/syntax/methods.rb index d03f63f28..cb7739397 100644 --- a/lib/factory_bot/syntax/methods.rb +++ b/lib/factory_bot/syntax/methods.rb @@ -129,6 +129,18 @@ def generate_list(name, count) Internal.sequence_by_name(name).next end end + + def build_sequence(&block) + block + end + + def evaluate_sequence_attributes(traits_and_overrides, i) + traits_and_overrides.map do |attribute| + next attribute unless attribute.is_a?(Hash) + + attribute.transform_values { |value| value.respond_to?(:call) ? value.call(i) : value } + end + end end end end diff --git a/spec/acceptance/create_list_spec.rb b/spec/acceptance/create_list_spec.rb index 891c00f83..591cc9a07 100644 --- a/spec/acceptance/create_list_spec.rb +++ b/spec/acceptance/create_list_spec.rb @@ -38,6 +38,16 @@ end end + context "with sequencial attributes" do + subject { FactoryBot.create_list(:post, 20, title: FactoryBot.build_sequence{|n| "title_#{n}"}) } + + it "create sequencial attribute values" do + subject.each_with_index do |record, i| + expect(record.title).to eq "title_#{i}" + end + end + end + context "with a block" do subject do FactoryBot.create_list(:post, 20, title: "The Listing of the Block") do |post| From 213bd29839d2826bc7dbc98d622c769bf8bf5b1b Mon Sep 17 00:00:00 2001 From: Mohammed Nasser <135416851+mohammednasser-32@users.noreply.github.com> Date: Mon, 13 May 2024 22:04:59 +0300 Subject: [PATCH 2/2] create AttributeSequence class --- lib/factory_bot.rb | 1 + lib/factory_bot/attribute_sequence.rb | 24 +++++++++++++++++++ .../strategy_syntax_method_registrar.rb | 4 +++- lib/factory_bot/syntax/methods.rb | 10 +------- spec/acceptance/create_list_spec.rb | 2 +- 5 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 lib/factory_bot/attribute_sequence.rb diff --git a/lib/factory_bot.rb b/lib/factory_bot.rb index 3d76cd9eb..ca9a1c5e3 100644 --- a/lib/factory_bot.rb +++ b/lib/factory_bot.rb @@ -47,6 +47,7 @@ require "factory_bot/decorator/new_constructor" require "factory_bot/linter" require "factory_bot/version" +require "factory_bot/attribute_sequence" module FactoryBot Deprecation = ActiveSupport::Deprecation.new("7.0", "factory_bot") diff --git a/lib/factory_bot/attribute_sequence.rb b/lib/factory_bot/attribute_sequence.rb new file mode 100644 index 000000000..e0e4f0720 --- /dev/null +++ b/lib/factory_bot/attribute_sequence.rb @@ -0,0 +1,24 @@ +module FactoryBot + # @api private + class AttributeSequence + attr_reader :expression + + def initialize(&block) + @expression = block + end + + def evaluate(index) + expression.call(index) + end + + def self.evaluate_attributes(traits_and_overrides, i) + traits_and_overrides.map do |attribute| + next attribute unless attribute.is_a?(Hash) + + attribute.transform_values do |value| + value.is_a?(self) ? value.evaluate(i) : value + end + 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 a70ca0746..6bc9e2390 100644 --- a/lib/factory_bot/strategy_syntax_method_registrar.rb +++ b/lib/factory_bot/strategy_syntax_method_registrar.rb @@ -39,7 +39,9 @@ def define_list_strategy_method Array.new(amount) do |i| block_with_index = StrategySyntaxMethodRegistrar.with_index(block, i) - send(strategy_name, name, *evaluate_sequence_attributes(traits_and_overrides, i), &block_with_index) + traits_and_evaluated_overrides = + FactoryBot::AttributeSequence.evaluate_attributes(traits_and_overrides, i) + send(strategy_name, name, *traits_and_evaluated_overrides, &block_with_index) end end end diff --git a/lib/factory_bot/syntax/methods.rb b/lib/factory_bot/syntax/methods.rb index cb7739397..8625e33a4 100644 --- a/lib/factory_bot/syntax/methods.rb +++ b/lib/factory_bot/syntax/methods.rb @@ -131,15 +131,7 @@ def generate_list(name, count) end def build_sequence(&block) - block - end - - def evaluate_sequence_attributes(traits_and_overrides, i) - traits_and_overrides.map do |attribute| - next attribute unless attribute.is_a?(Hash) - - attribute.transform_values { |value| value.respond_to?(:call) ? value.call(i) : value } - end + FactoryBot::AttributeSequence.new(&block) end end end diff --git a/spec/acceptance/create_list_spec.rb b/spec/acceptance/create_list_spec.rb index 591cc9a07..28ce8ea46 100644 --- a/spec/acceptance/create_list_spec.rb +++ b/spec/acceptance/create_list_spec.rb @@ -39,7 +39,7 @@ end context "with sequencial attributes" do - subject { FactoryBot.create_list(:post, 20, title: FactoryBot.build_sequence{|n| "title_#{n}"}) } + subject { FactoryBot.create_list(:post, 20, title: FactoryBot.build_sequence{ |n| "title_#{n}" }) } it "create sequencial attribute values" do subject.each_with_index do |record, i|