From bfeec78f297e2f1b796568d3bba0f4ee7320454c Mon Sep 17 00:00:00 2001 From: Jared Beck Date: Sun, 28 Oct 2018 19:12:34 -0400 Subject: [PATCH] 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 --- lib/factory_bot/definition_proxy.rb | 10 +++++++- lib/factory_bot/errors.rb | 3 +++ spec/factory_bot/definition_proxy_spec.rb | 28 +++++++++++++++++++---- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/factory_bot/definition_proxy.rb b/lib/factory_bot/definition_proxy.rb index 0b5e6ba..5855177 100644 --- a/lib/factory_bot/definition_proxy.rb +++ b/lib/factory_bot/definition_proxy.rb @@ -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) diff --git a/lib/factory_bot/errors.rb b/lib/factory_bot/errors.rb index 9452bce..bcab0ba 100644 --- a/lib/factory_bot/errors.rb +++ b/lib/factory_bot/errors.rb @@ -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 diff --git a/spec/factory_bot/definition_proxy_spec.rb b/spec/factory_bot/definition_proxy_spec.rb index 9a13498..f846e0f 100644 --- a/spec/factory_bot/definition_proxy_spec.rb +++ b/spec/factory_bot/definition_proxy_spec.rb @@ -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