From 52b5d3e5100675ba63f58c2946aab466567b266b Mon Sep 17 00:00:00 2001 From: Brendan Thomas Date: Thu, 8 Mar 2018 15:25:46 -0500 Subject: [PATCH 1/4] add index_errors association matcher --- .../active_record/association_matcher.rb | 37 +++++++++++++++++++ .../active_record/association_matcher_spec.rb | 22 +++++++++++ 2 files changed, 59 insertions(+) diff --git a/lib/shoulda/matchers/active_record/association_matcher.rb b/lib/shoulda/matchers/active_record/association_matcher.rb index 5b2b3faa9..ed86bd53f 100644 --- a/lib/shoulda/matchers/active_record/association_matcher.rb +++ b/lib/shoulda/matchers/active_record/association_matcher.rb @@ -524,6 +524,24 @@ def belong_to(name) # 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 +1040,11 @@ def autosave(autosave) 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 +1119,7 @@ def matches?(subject) class_name_correct? && join_table_correct? && autosave_correct? && + index_errors_correct? && conditions_correct? && validate_correct? && touch_correct? && @@ -1257,6 +1281,19 @@ def autosave_correct? end end + def index_errors_correct? + if 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 + else + true + end + end + def conditions_correct? if options.key?(:conditions) if option_verifier.correct_for_relation_clause?(:conditions, options[:conditions]) 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 3db2c28b1..2d35ddfec 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,28 @@ def belonging_to_non_existent_class(model_name, assoc_name, options = {}) }.to fail_with_message(message) end + 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 + context 'validate' do it 'accepts when the :validate option matches' do expect(having_many_children(validate: false)).to have_many(:children).validate(false) From 0ab8115bc9157efb7e49f18594f34d9f28cb57f2 Mon Sep 17 00:00:00 2001 From: Brendan Thomas Date: Thu, 8 Mar 2018 15:34:43 -0500 Subject: [PATCH 2/4] fix hound warnings --- .../matchers/active_record/association_matcher.rb | 9 ++++++--- .../matchers/active_record/association_matcher_spec.rb | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/shoulda/matchers/active_record/association_matcher.rb b/lib/shoulda/matchers/active_record/association_matcher.rb index ed86bd53f..761ab537f 100644 --- a/lib/shoulda/matchers/active_record/association_matcher.rb +++ b/lib/shoulda/matchers/active_record/association_matcher.rb @@ -526,7 +526,8 @@ def belong_to(name) # # ##### index_errors # - # Use `index_errors` to assert that the `:index_errors` option was specified. + # Use `index_errors` to assert that the `:index_errors` option was + # specified. # # class Player < ActiveRecord::Base # has_many :games, index_errors: true @@ -1283,10 +1284,12 @@ def autosave_correct? def index_errors_correct? if options.key?(:index_errors) - if option_verifier.correct_for_boolean?(:index_errors, options[: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]}" + @missing = "#{name} should have index_errors set to "\ + "#{options[:index_errors]}" false end else 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 2d35ddfec..56b2df539 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb @@ -810,16 +810,18 @@ def belonging_to_non_existent_class(model_name, assoc_name, options = {}) 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 + 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 { + message = 'Expected Parent to have a has_many association called '\ + 'children (children should have index_errors set to true)' + expect do expect(Parent.new).to have_many(:children).index_errors(true) - }.to fail_with_message(message) + end.to fail_with_message(message) end end From 4d1fbaeddef1425a70e99c16b9839ad36d3e639a Mon Sep 17 00:00:00 2001 From: Brendan Thomas Date: Fri, 9 Mar 2018 13:12:25 -0500 Subject: [PATCH 3/4] only run specs for >= rails 5 --- .../active_record/association_matcher.rb | 5 ++- spec/support/unit/helpers/rails_versions.rb | 4 ++ .../active_record/association_matcher_spec.rb | 38 ++++++++++--------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/lib/shoulda/matchers/active_record/association_matcher.rb b/lib/shoulda/matchers/active_record/association_matcher.rb index 761ab537f..120427239 100644 --- a/lib/shoulda/matchers/active_record/association_matcher.rb +++ b/lib/shoulda/matchers/active_record/association_matcher.rb @@ -1284,8 +1284,9 @@ def autosave_correct? def index_errors_correct? if options.key?(:index_errors) - if option_verifier.correct_for_boolean?(:index_errors, - options[:index_errors]) + if option_verifier.correct_for_boolean?( + :index_errors, options[:index_errors] + ) true else @missing = "#{name} should have index_errors set to "\ diff --git a/spec/support/unit/helpers/rails_versions.rb b/spec/support/unit/helpers/rails_versions.rb index d555378e8..2b578739f 100644 --- a/spec/support/unit/helpers/rails_versions.rb +++ b/spec/support/unit/helpers/rails_versions.rb @@ -34,5 +34,9 @@ def rails_gte_4_2? 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 56b2df539..c5fba1f1e 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb @@ -801,27 +801,29 @@ def belonging_to_non_existent_class(model_name, assoc_name, options = {}) }.to fail_with_message(message) end - 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 + 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 - 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 + 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 do - expect(Parent.new).to have_many(:children).index_errors(true) - end.to fail_with_message(message) + message = 'Expected Parent to have a has_many association called '\ + 'children (children should have index_errors set to true)' + expect do + expect(Parent.new).to have_many(:children).index_errors(true) + end.to fail_with_message(message) + end end end From aa4aacc2ff46441c7aa2768e70886ea2ade6ec43 Mon Sep 17 00:00:00 2001 From: Brendan Thomas Date: Fri, 9 Mar 2018 13:21:12 -0500 Subject: [PATCH 4/4] fix method to long hound warning in index_errors_correct --- .../active_record/association_matcher.rb | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/shoulda/matchers/active_record/association_matcher.rb b/lib/shoulda/matchers/active_record/association_matcher.rb index 120427239..e4a269875 100644 --- a/lib/shoulda/matchers/active_record/association_matcher.rb +++ b/lib/shoulda/matchers/active_record/association_matcher.rb @@ -1283,18 +1283,16 @@ def autosave_correct? end def index_errors_correct? - if 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 - else + 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