Raise helpful error block given to association

Closes #1033

> Arguably, association should raise and let the developer know
> they're using it in an unexpected way. I'd love to see a PR for
> that (with a test!), so if you're interested in contributing that,
> please do!
> https://github.com/thoughtbot/factory_girl/issues/1032#issuecomment-329297006

Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
This commit is contained in:
Jared Beck 2018-10-28 19:12:34 -04:00 committed by Daniel Colson
parent 31e833bdd1
commit bfeec78f29
3 changed files with 35 additions and 6 deletions

View File

@ -131,7 +131,15 @@ module FactoryBot
# name of the factory. For example, a "user" association will by
# default use the "user" factory.
def association(name, *options)
@definition.declare_attribute(Declaration::Association.new(name, *options))
if block_given?
raise AssociationDefinitionError.new(
"Unexpected block passed to '#{name}' association "\
"in '#{@definition.name}' factory",
)
else
declaration = Declaration::Association.new(name, *options)
@definition.declare_attribute(declaration)
end
end
def to_create(&block)

View File

@ -14,6 +14,9 @@ module FactoryBot
# Raised when defining an attribute twice in the same factory
class AttributeDefinitionError < RuntimeError; end
# Raised when attempting to pass a block to an association definition
class AssociationDefinitionError < RuntimeError; end
# Raised when a method is defined in a factory or trait with arguments
class MethodDefinitionError < RuntimeError; end

View File

@ -131,19 +131,37 @@ describe FactoryBot::DefinitionProxy, "#sequence" do
end
describe FactoryBot::DefinitionProxy, "#association" do
subject { FactoryBot::Definition.new(:name) }
let(:proxy) { FactoryBot::DefinitionProxy.new(subject) }
it "declares an association" do
definition = FactoryBot::Definition.new(:definition_name)
proxy = FactoryBot::DefinitionProxy.new(definition)
proxy.association(:association_name)
expect(subject).to have_association_declaration(:association_name)
expect(definition).to have_association_declaration(:association_name)
end
it "declares an association with options" do
definition = FactoryBot::Definition.new(:definition_name)
proxy = FactoryBot::DefinitionProxy.new(definition)
proxy.association(:association_name, name: "Awesome")
expect(subject).to have_association_declaration(:association_name).
expect(definition).to have_association_declaration(:association_name).
with_options(name: "Awesome")
end
context "when passing a block" do
it "raises an error" do
definition = FactoryBot::Definition.new(:post)
proxy = FactoryBot::DefinitionProxy.new(definition)
expect { proxy.association(:author) {} }.
to raise_error(
FactoryBot::AssociationDefinitionError,
"Unexpected block passed to 'author' association in 'post' factory",
)
end
end
end
describe FactoryBot::DefinitionProxy, "adding callbacks" do