diff --git a/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb b/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb index 92e1f394b..a415d84cf 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb @@ -13,13 +13,7 @@ def initialize(reflection) end def associated_class - associated_class = reflection.klass - - if subject.strict_loading_by_default && !(reflection.options[:strict_loading] == false) - reflection.options[:strict_loading] = true - end - - associated_class + reflection.klass end def polymorphic? @@ -76,6 +70,10 @@ def has_and_belongs_to_many_name reflection.options[:through] end + def strict_loading? + reflection.options.fetch(:strict_loading, subject.strict_loading_by_default) + end + protected attr_reader :reflection, :subject 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 ecf7818b1..15cf0032d 100644 --- a/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +++ b/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb @@ -122,6 +122,10 @@ def actual_value_for_class_name reflector.associated_class end + def actual_value_for_strict_loading + reflection.strict_loading? + end + def actual_value_for_option(name) option_value = reflection.options[name] 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 a5754298e..9e995c156 100644 --- a/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb @@ -1199,403 +1199,405 @@ def belonging_to_non_existent_class(model_name, assoc_name, options = {}) expect(Parent.new).to have_many(:children) end - context 'when the application is configured with strict_loading disabled by default' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_disabled do - expect(having_many_children). - to have_many(:children).strict_loading(false) + describe "strict_loading" do + context 'when the application is configured with strict_loading disabled by default' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_disabled do + expect(having_many_children). + to have_many(:children).strict_loading(false) + end end - end - it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - expect { - expect(having_many_children). - to have_many(:children).strict_loading - }.to fail_with_message(message) + expect { + expect(having_many_children). + to have_many(:children).strict_loading + }.to fail_with_message(message) + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - expect { - expect(having_many_children). - to have_many(:children).strict_loading(true) - }.to fail_with_message(message) + expect { + expect(having_many_children). + to have_many(:children).strict_loading(true) + }.to fail_with_message(message) + end end - end - context 'when the association is configured with a strict_loading constraint' do - context 'when qualified with strict_loading(true)' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_disabled do - expect(having_many_children(strict_loading: true)). - to have_many(:children).strict_loading(true) + context 'when the association is configured with a strict_loading constraint' do + context 'when qualified with strict_loading(true)' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_disabled do + expect(having_many_children(strict_loading: true)). + to have_many(:children).strict_loading(true) + end end - end - it 'accepts an association with a matching :strict_loading option without explicit value' do - with_strict_loading_by_default_disabled do - expect(having_many_children(strict_loading: true)). - to have_many(:children).strict_loading + it 'accepts an association with a matching :strict_loading option without explicit value' do + with_strict_loading_by_default_disabled do + expect(having_many_children(strict_loading: true)). + to have_many(:children).strict_loading + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to false)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to false)', + ].join - expect { - expect(having_many_children(strict_loading: true)). - to have_many(:children).strict_loading(false) - }.to fail_with_message(message) + expect { + expect(having_many_children(strict_loading: true)). + to have_many(:children).strict_loading(false) + }.to fail_with_message(message) + end end end - end - context 'when qualified with strict_loading(false)' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_disabled do - expect(having_many_children(strict_loading: false)). - to have_many(:children).strict_loading(false) + context 'when qualified with strict_loading(false)' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_disabled do + expect(having_many_children(strict_loading: false)). + to have_many(:children).strict_loading(false) + end end - end - it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - expect { - expect(having_many_children(strict_loading: false)). - to have_many(:children).strict_loading - }.to fail_with_message(message) + expect { + expect(having_many_children(strict_loading: false)). + to have_many(:children).strict_loading + }.to fail_with_message(message) + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - expect { - expect(having_many_children(strict_loading: false)). - to have_many(:children).strict_loading(true) - }.to fail_with_message(message) + expect { + expect(having_many_children(strict_loading: false)). + to have_many(:children).strict_loading(true) + }.to fail_with_message(message) + end end end end - end - context 'when strict_loading is defined on the model level' do - context 'when it is set to true' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_disabled do - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = true - model.has_many :children - end.new + context 'when strict_loading is defined on the model level' do + context 'when it is set to true' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_disabled do + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = true + model.has_many :children + end.new - expect(parent).to have_many(:children).strict_loading(true) + expect(parent).to have_many(:children).strict_loading(true) + end end - end - it 'accepts an association with a matching :strict_loading option without explicit value' do - with_strict_loading_by_default_disabled do - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = true - model.has_many :children - end.new + it 'accepts an association with a matching :strict_loading option without explicit value' do + with_strict_loading_by_default_disabled do + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = true + model.has_many :children + end.new - expect(parent).to have_many(:children).strict_loading + expect(parent).to have_many(:children).strict_loading + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to false)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to false)', + ].join - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = true - model.has_many :children - end.new + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = true + model.has_many :children + end.new - expect { - expect(parent).to have_many(:children).strict_loading(false) - }.to fail_with_message(message) + expect { + expect(parent).to have_many(:children).strict_loading(false) + }.to fail_with_message(message) + end end end - end - context 'when it is set to false' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_disabled do - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = false - model.has_many :children - end.new + context 'when it is set to false' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_disabled do + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = false + model.has_many :children + end.new - expect(parent).to have_many(:children).strict_loading(false) + expect(parent).to have_many(:children).strict_loading(false) + end end - end - it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = false - model.has_many :children - end.new + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = false + model.has_many :children + end.new - expect { - expect(parent).to have_many(:children).strict_loading - }.to fail_with_message(message) + expect { + expect(parent).to have_many(:children).strict_loading + }.to fail_with_message(message) + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_disabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_disabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = false - model.has_many :children - end.new + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = false + model.has_many :children + end.new - expect { - expect(parent).to have_many(:children).strict_loading(true) - }.to fail_with_message(message) + expect { + expect(parent).to have_many(:children).strict_loading(true) + }.to fail_with_message(message) + end end end end end - end - context 'when the application is configured with strict_loading enabled by default' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_enabled do - expect(having_many_children). - to have_many(:children).strict_loading(true) + context 'when the application is configured with strict_loading enabled by default' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_enabled do + expect(having_many_children). + to have_many(:children).strict_loading(true) + end end - end - it 'accepts an association with a matching :strict_loading option without explicit value' do - with_strict_loading_by_default_enabled do - expect(having_many_children). - to have_many(:children).strict_loading + it 'accepts an association with a matching :strict_loading option without explicit value' do + with_strict_loading_by_default_enabled do + expect(having_many_children). + to have_many(:children).strict_loading + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to false)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to false)', + ].join - expect { - expect(having_many_children). - to have_many(:children).strict_loading(false) - }.to fail_with_message(message) + expect { + expect(having_many_children). + to have_many(:children).strict_loading(false) + }.to fail_with_message(message) + end end - end - context 'when the association is configured with a strict_loading constraint' do - context 'when qualified with strict_loading(true)' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_enabled do - expect(having_many_children(strict_loading: true)). - to have_many(:children).strict_loading(true) + context 'when the association is configured with a strict_loading constraint' do + context 'when qualified with strict_loading(true)' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_enabled do + expect(having_many_children(strict_loading: true)). + to have_many(:children).strict_loading(true) + end end - end - it 'accepts an association with a matching :strict_loading option without explicit value' do - with_strict_loading_by_default_enabled do - expect(having_many_children(strict_loading: true)). - to have_many(:children).strict_loading + it 'accepts an association with a matching :strict_loading option without explicit value' do + with_strict_loading_by_default_enabled do + expect(having_many_children(strict_loading: true)). + to have_many(:children).strict_loading + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to false)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to false)', + ].join - expect { - expect(having_many_children(strict_loading: true)). - to have_many(:children).strict_loading(false) - }.to fail_with_message(message) + expect { + expect(having_many_children(strict_loading: true)). + to have_many(:children).strict_loading(false) + }.to fail_with_message(message) + end end end - end - context 'when qualified with strict_loading(false)' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_enabled do - expect(having_many_children(strict_loading: false)). - to have_many(:children).strict_loading(false) + context 'when qualified with strict_loading(false)' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_enabled do + expect(having_many_children(strict_loading: false)). + to have_many(:children).strict_loading(false) + end end - end - it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - expect { - expect(having_many_children(strict_loading: false)). - to have_many(:children).strict_loading - }.to fail_with_message(message) + expect { + expect(having_many_children(strict_loading: false)). + to have_many(:children).strict_loading + }.to fail_with_message(message) + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - expect { - expect(having_many_children(strict_loading: false)). - to have_many(:children).strict_loading(true) - }.to fail_with_message(message) + expect { + expect(having_many_children(strict_loading: false)). + to have_many(:children).strict_loading(true) + }.to fail_with_message(message) + end end end end - end - context 'when strict_loading is defined on the model level' do - context 'when it is set to true' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_enabled do - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = true - model.has_many :children - end.new + context 'when strict_loading is defined on the model level' do + context 'when it is set to true' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_enabled do + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = true + model.has_many :children + end.new - expect(parent).to have_many(:children).strict_loading(true) + expect(parent).to have_many(:children).strict_loading(true) + end end - end - it 'accepts an association with a matching :strict_loading option without explicit value' do - with_strict_loading_by_default_enabled do - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = true - model.has_many :children - end.new + it 'accepts an association with a matching :strict_loading option without explicit value' do + with_strict_loading_by_default_enabled do + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = true + model.has_many :children + end.new - expect(parent).to have_many(:children).strict_loading + expect(parent).to have_many(:children).strict_loading + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to false)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to false)', + ].join - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = true - model.has_many :children - end.new + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = true + model.has_many :children + end.new - expect { - expect(parent).to have_many(:children).strict_loading(false) - }.to fail_with_message(message) + expect { + expect(parent).to have_many(:children).strict_loading(false) + }.to fail_with_message(message) + end end end - end - context 'when it is set to false' do - it 'accepts an association with a matching :strict_loading option' do - with_strict_loading_by_default_enabled do - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = false - model.has_many :children - end.new + context 'when it is set to false' do + it 'accepts an association with a matching :strict_loading option' do + with_strict_loading_by_default_enabled do + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = false + model.has_many :children + end.new - expect(parent).to have_many(:children).strict_loading(false) + expect(parent).to have_many(:children).strict_loading(false) + end end - end - it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option without explicit value with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = false - model.has_many :children - end.new + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = false + model.has_many :children + end.new - expect { - expect(parent).to have_many(:children).strict_loading - }.to fail_with_message(message) + expect { + expect(parent).to have_many(:children).strict_loading + }.to fail_with_message(message) + end end - end - it 'rejects an association with a non-matching :strict_loading option with the correct message' do - with_strict_loading_by_default_enabled do - message = [ - 'Expected Parent to have a has_many association called children ', - '(children should have strict_loading set to true)', - ].join + it 'rejects an association with a non-matching :strict_loading option with the correct message' do + with_strict_loading_by_default_enabled do + message = [ + 'Expected Parent to have a has_many association called children ', + '(children should have strict_loading set to true)', + ].join - define_model :child, parent_id: :integer - parent = define_model(:parent) do |model| - model.strict_loading_by_default = false - model.has_many :children - end.new + define_model :child, parent_id: :integer + parent = define_model(:parent) do |model| + model.strict_loading_by_default = false + model.has_many :children + end.new - expect { - expect(parent).to have_many(:children).strict_loading(true) - }.to fail_with_message(message) + expect { + expect(parent).to have_many(:children).strict_loading(true) + }.to fail_with_message(message) + end end end end