Fix strategy tracking through associations

What?
=====

Within FactoryBot::Evaluator, the build strategy was reported either as
a class OR symbol.

A side-effect of this is misreporting within
ActiveSupport::Notifications hooks, since the instrumentation payload
may have strategies listed as e.g. `:create` or
`FactoryBot::Strategy::Create`, even though they semantically represent
the same information.

This introduces a new instance method for all strategies, `to_sym`,
to be called rather than `class`.
This commit is contained in:
Josh Clayton 2022-02-03 21:41:09 -05:00
parent 8f766ef25d
commit 1b81d5dc25
No known key found for this signature in database
GPG Key ID: 5B6558F77E9A8118
7 changed files with 35 additions and 1 deletions

View File

@ -24,7 +24,7 @@ module FactoryBot
def association(factory_name, *traits_and_overrides)
overrides = traits_and_overrides.extract_options!
strategy_override = overrides.fetch(:strategy) {
FactoryBot.use_parent_strategy ? @build_strategy.class : :create
FactoryBot.use_parent_strategy ? @build_strategy.to_sym : :create
}
traits_and_overrides += [overrides.except(:strategy)]

View File

@ -8,6 +8,10 @@ module FactoryBot
def result(evaluation)
evaluation.hash
end
def to_sym
:attributes_for
end
end
end
end

View File

@ -10,6 +10,10 @@ module FactoryBot
evaluation.notify(:after_build, instance)
end
end
def to_sym
:build
end
end
end
end

View File

@ -13,6 +13,10 @@ module FactoryBot
evaluation.notify(:after_create, instance)
end
end
def to_sym
:create
end
end
end
end

View File

@ -6,6 +6,10 @@ module FactoryBot
def result(evaluation)
end
def to_sym
:null
end
end
end
end

View File

@ -41,6 +41,10 @@ module FactoryBot
end
end
def to_sym
:stub
end
private
def next_id

View File

@ -16,6 +16,10 @@ describe "using ActiveSupport::Instrumentation to track factory interaction" do
let(:user_factory) { FactoryBot::Internal.factory_by_name("user") }
before do
define_model("User", email: :string)
define_model("Post", user_id: :integer) do
belongs_to :user
end
FactoryBot.define do
factory :user do
email { "john@example.com" }
@ -24,6 +28,12 @@ describe "using ActiveSupport::Instrumentation to track factory interaction" do
after(:build) { Kernel.sleep(0.1) }
end
end
factory :post do
trait :with_user do
user
end
end
end
end
@ -55,6 +65,9 @@ describe "using ActiveSupport::Instrumentation to track factory interaction" do
FactoryBot.build_list(:user, 5)
FactoryBot.create_list(:user, 2)
FactoryBot.attributes_for(:slow_user)
user = FactoryBot.create(:user)
FactoryBot.create(:post, user: user)
FactoryBot.create_list(:post, 2, :with_user)
end
expect(tracked_invocations[:slow_user][:build]).to eq(2)
@ -62,5 +75,6 @@ describe "using ActiveSupport::Instrumentation to track factory interaction" do
expect(tracked_invocations[:slow_user][:factory]).to eq(slow_user_factory)
expect(tracked_invocations[:user][:build]).to eq(5)
expect(tracked_invocations[:user][:factory]).to eq(user_factory)
expect(tracked_invocations[:user][:create]).to eq(5)
end
end