mirror of
https://github.com/thoughtbot/factory_bot.git
synced 2022-11-09 11:43:51 -05:00
Fix self referencing trait error (#1294)
If a new trait is defined with attributes, check if attributes matches the name of the trait. Raise an error if so, to avoid a recursive call to the trait. Co-authored-by: Daniel Colsen <daniel.j.colson@thoughtbot.com> Co-authored-by: Paras Sanghavi <sanghaviparas@gmail.com>
This commit is contained in:
parent
831dcef717
commit
5ccc564923
4 changed files with 45 additions and 2 deletions
|
@ -25,6 +25,9 @@ module FactoryBot
|
|||
[Attribute::Association.new(name, name, {})]
|
||||
elsif FactoryBot::Internal.sequences.registered?(name)
|
||||
[Attribute::Sequence.new(name, name, @ignored)]
|
||||
elsif @factory.name.to_s == name.to_s
|
||||
message = "Self-referencing trait '#{@name}'"
|
||||
raise TraitDefinitionError, message
|
||||
else
|
||||
@factory.inherit_traits([name])
|
||||
[]
|
||||
|
|
|
@ -2,6 +2,9 @@ module FactoryBot
|
|||
# Raised when a factory is defined that attempts to instantiate itself.
|
||||
class AssociationDefinitionError < RuntimeError; end
|
||||
|
||||
# Raised when a trait is defined that references itself.
|
||||
class TraitDefinitionError < RuntimeError; end
|
||||
|
||||
# Raised when a callback is defined that has an invalid name
|
||||
class InvalidCallbackNameError < RuntimeError; end
|
||||
|
||||
|
|
|
@ -7,9 +7,11 @@ module FactoryBot
|
|||
@name = name.to_s
|
||||
@block = block
|
||||
@definition = Definition.new(@name)
|
||||
|
||||
proxy = FactoryBot::DefinitionProxy.new(@definition)
|
||||
proxy.instance_eval(&@block) if block_given?
|
||||
|
||||
if block_given?
|
||||
proxy.instance_eval(&@block)
|
||||
end
|
||||
end
|
||||
|
||||
delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
|
||||
|
|
|
@ -798,3 +798,38 @@ describe "traits used in associations" do
|
|||
expect(creator.name).to eq "Joe Creator"
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a self-referential trait is defined" do
|
||||
it "raises a TraitDefinitionError" do
|
||||
define_model("User", name: :string)
|
||||
FactoryBot.define do
|
||||
factory :user do
|
||||
trait :admin do
|
||||
admin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
expect { FactoryBot.build(:user, :admin) }.to raise_error(
|
||||
FactoryBot::TraitDefinitionError,
|
||||
"Self-referencing trait 'admin'",
|
||||
)
|
||||
end
|
||||
|
||||
it "raises a TraitDefinitionError" do
|
||||
define_model("User", name: :string)
|
||||
FactoryBot.define do
|
||||
factory :user do
|
||||
trait :admin do
|
||||
admin
|
||||
name { "name" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
expect { FactoryBot.build(:user, :admin) }.to raise_error(
|
||||
FactoryBot::TraitDefinitionError,
|
||||
"Self-referencing trait 'admin'",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue