From 795ca688bff08590dbd2ab6f2b51ea415e0c7473 Mon Sep 17 00:00:00 2001 From: Brendan Thomas Date: Thu, 8 Mar 2018 15:25:46 -0500 Subject: [PATCH] add index_errors association matcher --- .../active_record/association_matcher.rb | 41 +++++++++++++++++++ spec/support/unit/helpers/rails_versions.rb | 4 ++ .../active_record/association_matcher_spec.rb | 27 ++++++++++++ 3 files changed, 72 insertions(+) diff --git a/lib/shoulda/matchers/active_record/association_matcher.rb b/lib/shoulda/matchers/active_record/association_matcher.rb index 5b2b3faa..527dc57d 100644 --- a/lib/shoulda/matchers/active_record/association_matcher.rb +++ b/lib/shoulda/matchers/active_record/association_matcher.rb @@ -524,6 +524,25 @@ module Shoulda # should have_many(:games).autosave(true) # end # + # ##### index_errors + # + # Use `index_errors` to assert that the `:index_errors` option was + # specified. + # + # class Player < ActiveRecord::Base + # has_many :games, index_errors: true + # end + # + # # RSpec + # RSpec.describe Player, type: :model do + # it { should have_many(:games).index_errors(true) } + # end + # + # # Minitest (Shoulda) + # class PlayerTest < ActiveSupport::TestCase + # should have_many(:games).index_errors(true) + # end + # # ##### inverse_of # # Use `inverse_of` to assert that the `:inverse_of` option was specified. @@ -1022,6 +1041,11 @@ module Shoulda self end + def index_errors(index_errors) + @options[:index_errors] = index_errors + self + end + def class_name(class_name) @options[:class_name] = class_name self @@ -1096,6 +1120,7 @@ module Shoulda class_name_correct? && join_table_correct? && autosave_correct? && + index_errors_correct? && conditions_correct? && validate_correct? && touch_correct? && @@ -1257,6 +1282,22 @@ module Shoulda end end + def index_errors_correct? + return true unless options.key?(:index_errors) + + if option_verifier.correct_for_boolean?( + :index_errors, + options[:index_errors] + ) + true + else + @missing = + "#{name} should have index_errors set to " + + "#{options[:index_errors]}" + false + end + end + def conditions_correct? if options.key?(:conditions) if option_verifier.correct_for_relation_clause?(:conditions, options[:conditions]) diff --git a/spec/support/unit/helpers/rails_versions.rb b/spec/support/unit/helpers/rails_versions.rb index d555378e..2b578739 100644 --- a/spec/support/unit/helpers/rails_versions.rb +++ b/spec/support/unit/helpers/rails_versions.rb @@ -34,5 +34,9 @@ module UnitTests def rails_lt_5? rails_version < 5 end + + def rails_5_x? + rails_version =~ '~> 5.0' + 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 3db2c28b..361e011c 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb @@ -801,6 +801,33 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher, type: :model do }.to fail_with_message(message) end + if rails_5_x? + context 'index_errors' do + it 'accepts an association with a matching :index_errors option' do + define_model :child, parent_id: :integer + define_model :parent do + has_many :children, index_errors: true + end + expect(Parent.new).to have_many(:children).index_errors(true) + end + + it 'rejects an association with a non-matching :index_errors option and returns the correct message' do + define_model :child, parent_id: :integer + define_model :parent do + has_many :children, autosave: false + end + + message = + 'Expected Parent to have a has_many association called children ' + + '(children should have index_errors set to true)' + + expect { + expect(Parent.new).to have_many(:children).index_errors(true) + }.to fail_with_message(message) + end + end + end + context 'validate' do it 'accepts when the :validate option matches' do expect(having_many_children(validate: false)).to have_many(:children).validate(false)