diff --git a/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb b/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb index 7aa641093..ecf7818b1 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb @@ -6,6 +6,11 @@ module AssociationMatchers class OptionVerifier delegate :reflection, to: :reflector + DEFAULT_VALUE_OF_OPTIONS = { + has_many: { + validate: true, + }, + }.freeze RELATION_OPTIONS = [:conditions, :order].freeze def initialize(reflector) @@ -55,7 +60,7 @@ def actual_value_for(name) if respond_to?(method_name, true) __send__(method_name) else - reflection.options[name] + actual_value_for_option(name) end end end @@ -116,6 +121,16 @@ def actual_value_for_relation_clause(name) def actual_value_for_class_name reflector.associated_class end + + def actual_value_for_option(name) + option_value = reflection.options[name] + + if option_value.nil? + DEFAULT_VALUE_OF_OPTIONS.dig(reflection.macro, name) + else + option_value + end + end end end end diff --git a/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb b/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb index 5fe336a70..920dcd32b 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb @@ -1177,20 +1177,40 @@ def belonging_to_non_existent_class(model_name, assoc_name, options = {}) end context 'validate' do - it 'accepts when the :validate option matches' do + it 'accepts validate(false) when the :validate option is false' do expect(having_many_children(validate: false)).to have_many(:children).validate(false) end - it 'rejects when the :validate option does not match' do + it 'accepts validate(true) when the :validate option is true' do + expect(having_many_children(validate: true)).to have_many(:children).validate(true) + end + + it 'rejects validate(false) when the :validate option is true' do expect(having_many_children(validate: true)).not_to have_many(:children).validate(false) end + it 'rejects validate(true) when the :validate option is false' do + expect(having_many_children(validate: false)).not_to have_many(:children).validate(true) + end + it 'assumes validate() means validate(true)' do + expect(having_many_children(validate: true)).to have_many(:children).validate + end + + it 'rejects validate() when :validate option is false' do expect(having_many_children(validate: false)).not_to have_many(:children).validate end - it 'matches validate(false) to having no validate option specified' do - expect(having_many_children).to have_many(:children).validate(false) + it 'rejects validate(false) when no :validate option was specified' do + expect(having_many_children).not_to have_many(:children).validate(false) + end + + it 'accepts validate(true) when no :validate option was specified' do + expect(having_many_children).to have_many(:children).validate(true) + end + + it 'accepts validate() when no :validate option was specified' do + expect(having_many_children).to have_many(:children).validate end end