+ Add inverse of matcher for active record association
This commit is contained in:
parent
723b5d3552
commit
31a0913d7f
2
NEWS.md
2
NEWS.md
|
@ -47,6 +47,8 @@
|
||||||
`has_secure_password` defines #password= such that `nil` will be ignored,
|
`has_secure_password` defines #password= such that `nil` will be ignored,
|
||||||
which interferes with how `validate_presence_of` works.
|
which interferes with how `validate_presence_of` works.
|
||||||
|
|
||||||
|
* Add ability to test `belongs_to` associations defined with `:inverse_of`.
|
||||||
|
|
||||||
# v 2.5.0
|
# v 2.5.0
|
||||||
|
|
||||||
* Fix Rails/Test::Unit integration to ensure that the test case classes we are
|
* Fix Rails/Test::Unit integration to ensure that the test case classes we are
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require 'shoulda/matchers/active_record/association_matcher'
|
require 'shoulda/matchers/active_record/association_matcher'
|
||||||
require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
||||||
|
require 'shoulda/matchers/active_record/association_matchers/inverse_of_matcher'
|
||||||
require 'shoulda/matchers/active_record/association_matchers/order_matcher'
|
require 'shoulda/matchers/active_record/association_matchers/order_matcher'
|
||||||
require 'shoulda/matchers/active_record/association_matchers/through_matcher'
|
require 'shoulda/matchers/active_record/association_matchers/through_matcher'
|
||||||
require 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
|
require 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
|
||||||
|
|
|
@ -125,6 +125,13 @@ module Shoulda # :nodoc:
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def inverse_of(inverse_of)
|
||||||
|
inverse_of_matcher =
|
||||||
|
AssociationMatchers::InverseOfMatcher.new(inverse_of, name)
|
||||||
|
add_submatcher(inverse_of_matcher)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
def source(source)
|
def source(source)
|
||||||
source_matcher = AssociationMatchers::SourceMatcher.new(source, name)
|
source_matcher = AssociationMatchers::SourceMatcher.new(source, name)
|
||||||
add_submatcher(source_matcher)
|
add_submatcher(source_matcher)
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
module Shoulda # :nodoc:
|
||||||
|
module Matchers
|
||||||
|
module ActiveRecord # :nodoc:
|
||||||
|
module AssociationMatchers
|
||||||
|
class InverseOfMatcher
|
||||||
|
attr_accessor :missing_option
|
||||||
|
|
||||||
|
def initialize(inverse_of, name)
|
||||||
|
@inverse_of = inverse_of
|
||||||
|
@name = name
|
||||||
|
@missing_option = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
def description
|
||||||
|
"inverse_of => #{inverse_of}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches?(subject)
|
||||||
|
self.subject = ModelReflector.new(subject, name)
|
||||||
|
|
||||||
|
if option_verifier.correct_for_string?(:inverse_of, inverse_of)
|
||||||
|
true
|
||||||
|
else
|
||||||
|
self.missing_option = "#{name} should have #{description}"
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_accessor :subject, :inverse_of, :name
|
||||||
|
|
||||||
|
def option_verifier
|
||||||
|
@option_verifier ||= OptionVerifier.new(subject)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -66,6 +66,21 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
||||||
expect(belonging_to_parent).not_to belong_to(:parent).counter_cache
|
expect(belonging_to_parent).not_to belong_to(:parent).counter_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'accepts an association with a valid :inverse_of option' do
|
||||||
|
expect(belonging_to_parent(inverse_of: :children))
|
||||||
|
.to belong_to(:parent).inverse_of(:children)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'rejects an association with a bad :inverse_of option' do
|
||||||
|
expect(belonging_to_parent(inverse_of: :other_children))
|
||||||
|
.not_to belong_to(:parent).inverse_of(:children)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'rejects an association that has no :inverse_of option' do
|
||||||
|
expect(belonging_to_parent)
|
||||||
|
.not_to belong_to(:parent).inverse_of(:children)
|
||||||
|
end
|
||||||
|
|
||||||
it 'accepts an association with a valid :conditions option' do
|
it 'accepts an association with a valid :conditions option' do
|
||||||
define_model :parent, adopter: :boolean
|
define_model :parent, adopter: :boolean
|
||||||
define_model(:child, parent_id: :integer).tap do |model|
|
define_model(:child, parent_id: :integer).tap do |model|
|
||||||
|
|
Loading…
Reference in New Issue