Add a #validate check for association matchers
This commit is contained in:
parent
cb02954e57
commit
e831348a05
|
@ -3,6 +3,12 @@ module Shoulda # :nodoc:
|
||||||
module ActiveRecord # :nodoc:
|
module ActiveRecord # :nodoc:
|
||||||
# Ensure that the belongs_to relationship exists.
|
# Ensure that the belongs_to relationship exists.
|
||||||
#
|
#
|
||||||
|
# Options:
|
||||||
|
# * <tt>:class_name</tt> - tests that the association makes use of the class_name option.
|
||||||
|
# * <tt>:validate</tt> - tests that the association makes use of the validate
|
||||||
|
# option.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
# it { should belong_to(:parent) }
|
# it { should belong_to(:parent) }
|
||||||
#
|
#
|
||||||
def belong_to(name)
|
def belong_to(name)
|
||||||
|
@ -18,6 +24,8 @@ module Shoulda # :nodoc:
|
||||||
# * <tt>dependent</tt> - tests that the association makes use of the
|
# * <tt>dependent</tt> - tests that the association makes use of the
|
||||||
# dependent option.
|
# dependent option.
|
||||||
# * <tt>:class_name</tt> - tests that the association makes use of the class_name option.
|
# * <tt>:class_name</tt> - tests that the association makes use of the class_name option.
|
||||||
|
# * <tt>:validate</tt> - tests that the association makes use of the validate
|
||||||
|
# option.
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# it { should have_many(:friends) }
|
# it { should have_many(:friends) }
|
||||||
|
@ -36,6 +44,8 @@ module Shoulda # :nodoc:
|
||||||
# * <tt>:dependent</tt> - tests that the association makes use of the
|
# * <tt>:dependent</tt> - tests that the association makes use of the
|
||||||
# dependent option.
|
# dependent option.
|
||||||
# * <tt>:class_name</tt> - tests that the association makes use of the class_name option.
|
# * <tt>:class_name</tt> - tests that the association makes use of the class_name option.
|
||||||
|
# * <tt>:validate</tt> - tests that the association makes use of the validate
|
||||||
|
# option.
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# it { should have_one(:god) } # unless hindu
|
# it { should have_one(:god) } # unless hindu
|
||||||
|
@ -47,6 +57,11 @@ module Shoulda # :nodoc:
|
||||||
# Ensures that the has_and_belongs_to_many relationship exists, and that
|
# Ensures that the has_and_belongs_to_many relationship exists, and that
|
||||||
# the join table is in place.
|
# the join table is in place.
|
||||||
#
|
#
|
||||||
|
# Options:
|
||||||
|
# * <tt>:validate</tt> - tests that the association makes use of the validate
|
||||||
|
# option.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
# it { should have_and_belong_to_many(:posts) }
|
# it { should have_and_belong_to_many(:posts) }
|
||||||
#
|
#
|
||||||
def have_and_belong_to_many(name)
|
def have_and_belong_to_many(name)
|
||||||
|
@ -85,6 +100,11 @@ module Shoulda # :nodoc:
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate(validate = true)
|
||||||
|
@validate = validate
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
def matches?(subject)
|
def matches?(subject)
|
||||||
@subject = subject
|
@subject = subject
|
||||||
association_exists? &&
|
association_exists? &&
|
||||||
|
@ -95,7 +115,8 @@ module Shoulda # :nodoc:
|
||||||
class_name_correct? &&
|
class_name_correct? &&
|
||||||
order_correct? &&
|
order_correct? &&
|
||||||
conditions_correct? &&
|
conditions_correct? &&
|
||||||
join_table_exists?
|
join_table_exists? &&
|
||||||
|
validate_correct?
|
||||||
end
|
end
|
||||||
|
|
||||||
def failure_message
|
def failure_message
|
||||||
|
@ -230,6 +251,15 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_correct?
|
||||||
|
if !@validate && !reflection.options[:validate] || @validate == reflection.options[:validate]
|
||||||
|
true
|
||||||
|
else
|
||||||
|
@missing = "#{@name} should have #{@validate} as validate"
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def class_has_foreign_key?(klass)
|
def class_has_foreign_key?(klass)
|
||||||
if klass.column_names.include?(foreign_key)
|
if klass.column_names.include?(foreign_key)
|
||||||
true
|
true
|
||||||
|
|
|
@ -98,6 +98,46 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
||||||
end
|
end
|
||||||
Child.new.should_not @matcher.class_name('TreeChild')
|
Child.new.should_not @matcher.class_name('TreeChild')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a false :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :parent, :adopter => :boolean
|
||||||
|
define_model :child, :parent_id => :integer do
|
||||||
|
belongs_to :parent, :validate => false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Child.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a true :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :parent, :adopter => :boolean
|
||||||
|
define_model :child, :parent_id => :integer do
|
||||||
|
belongs_to :parent, :validate => true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Child.new }
|
||||||
|
specify { subject.should_not @matcher.validate(false) }
|
||||||
|
specify { subject.should @matcher.validate(true) }
|
||||||
|
specify { subject.should @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association without a :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :parent, :adopter => :boolean
|
||||||
|
define_model :child, :parent_id => :integer do
|
||||||
|
belongs_to :parent
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Child.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "have_many" do
|
context "have_many" do
|
||||||
|
@ -240,6 +280,45 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
||||||
Parent.new.should_not @matcher.class_name('Node')
|
Parent.new.should_not @matcher.class_name('Node')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a false :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||||
|
define_model :parent do
|
||||||
|
has_many :children, :validate => false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Parent.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a true :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||||
|
define_model :parent do
|
||||||
|
has_many :children, :validate => true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Parent.new }
|
||||||
|
specify { subject.should_not @matcher.validate(false) }
|
||||||
|
specify { subject.should @matcher.validate(true) }
|
||||||
|
specify { subject.should @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association without a :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :child, :parent_id => :integer, :adopted => :boolean
|
||||||
|
define_model :parent do
|
||||||
|
has_many :children
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Parent.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
it "should accept an association with a nonstandard reverse foreign key, using :inverse_of" do
|
it "should accept an association with a nonstandard reverse foreign key, using :inverse_of" do
|
||||||
define_model :child, :ancestor_id => :integer do
|
define_model :child, :ancestor_id => :integer do
|
||||||
belongs_to :ancestor, :inverse_of => :children, :class_name => :Parent
|
belongs_to :ancestor, :inverse_of => :children, :class_name => :Parent
|
||||||
|
@ -364,6 +443,45 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
||||||
Person.new.should_not @matcher.class_name('PersonDetail')
|
Person.new.should_not @matcher.class_name('PersonDetail')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a false :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||||
|
define_model :person do
|
||||||
|
has_one :detail, :validate => false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Person.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a true :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||||
|
define_model :person do
|
||||||
|
has_one :detail, :validate => true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Person.new }
|
||||||
|
specify { subject.should_not @matcher.validate(false) }
|
||||||
|
specify { subject.should @matcher.validate(true) }
|
||||||
|
specify { subject.should @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association without a :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||||
|
define_model :person do
|
||||||
|
has_one :detail
|
||||||
|
end
|
||||||
|
end
|
||||||
|
subject { Person.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "have_and_belong_to_many" do
|
context "have_and_belong_to_many" do
|
||||||
|
@ -445,5 +563,47 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
||||||
Person.new.should_not @matcher.class_name('PersonRelatives')
|
Person.new.should_not @matcher.class_name('PersonRelatives')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a false :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :relatives, :adopted => :boolean
|
||||||
|
define_model :person do
|
||||||
|
has_and_belongs_to_many :relatives, :validate => false
|
||||||
|
end
|
||||||
|
define_model :people_relative, :person_id => :integer, :relative_id => :integer
|
||||||
|
end
|
||||||
|
subject { Person.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association with a true :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :relatives, :adopted => :boolean
|
||||||
|
define_model :person do
|
||||||
|
has_and_belongs_to_many :relatives, :validate => true
|
||||||
|
end
|
||||||
|
define_model :people_relative, :person_id => :integer, :relative_id => :integer
|
||||||
|
end
|
||||||
|
subject { Person.new }
|
||||||
|
specify { subject.should_not @matcher.validate(false) }
|
||||||
|
specify { subject.should @matcher.validate(true) }
|
||||||
|
specify { subject.should @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'should accept an association without a :validate option' do
|
||||||
|
before do
|
||||||
|
define_model :relatives, :adopted => :boolean
|
||||||
|
define_model :person do
|
||||||
|
has_and_belongs_to_many :relatives
|
||||||
|
end
|
||||||
|
define_model :people_relative, :person_id => :integer, :relative_id => :integer
|
||||||
|
end
|
||||||
|
subject { Person.new }
|
||||||
|
specify { subject.should @matcher.validate(false) }
|
||||||
|
specify { subject.should_not @matcher.validate(true) }
|
||||||
|
specify { subject.should_not @matcher.validate }
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue