Association matchers support :autosave option
has_one, has_many, belongs_to, and has_and_belongs_to_many relationships can have an `:autosave` option, which causes the relevant associated records to be automatically saved when their parent is saved. This is based on a PR by @calebthompson, which I've brought up to date with master.
This commit is contained in:
parent
7fa7e67d88
commit
21e984cd28
2
NEWS.md
2
NEWS.md
|
@ -3,6 +3,8 @@
|
|||
* Association matchers now test that the model being referred to (either
|
||||
implicitly or explicitly, using `:class_name`) actually exists.
|
||||
|
||||
* Add ability to test `:autosave` option on associations.
|
||||
|
||||
# v 2.5.0
|
||||
|
||||
* Fix Rails/Test::Unit integration to ensure that the test case classes we are
|
||||
|
|
|
@ -28,6 +28,8 @@ module Shoulda # :nodoc:
|
|||
# * <tt>dependent</tt> - tests that the association makes use of the
|
||||
# dependent option.
|
||||
# * <tt>:class_name</tt> - tests that the association resoves to class_name.
|
||||
# * <tt>:autosave</tt> - tests that the association makes use of the
|
||||
# autosave option.
|
||||
# * <tt>:validate</tt> - tests that the association makes use of the validate
|
||||
# option.
|
||||
#
|
||||
|
@ -48,6 +50,8 @@ module Shoulda # :nodoc:
|
|||
# * <tt>:dependent</tt> - tests that the association makes use of the
|
||||
# dependent option.
|
||||
# * <tt>:class_name</tt> - tests that the association resolves to class_name.
|
||||
# * <tt>:autosave</tt> - tests that the association makes use of the
|
||||
# autosave option.
|
||||
# * <tt>:validate</tt> - tests that the association makes use of the validate
|
||||
# option.
|
||||
#
|
||||
|
@ -120,6 +124,11 @@ module Shoulda # :nodoc:
|
|||
self
|
||||
end
|
||||
|
||||
def autosave(autosave)
|
||||
@options[:autosave] = autosave
|
||||
self
|
||||
end
|
||||
|
||||
def class_name(class_name)
|
||||
@options[:class_name] = class_name
|
||||
self
|
||||
|
@ -163,6 +172,7 @@ module Shoulda # :nodoc:
|
|||
class_exists? &&
|
||||
foreign_key_exists? &&
|
||||
class_name_correct? &&
|
||||
autosave_correct? &&
|
||||
conditions_correct? &&
|
||||
join_table_exists? &&
|
||||
validate_correct? &&
|
||||
|
@ -266,6 +276,19 @@ module Shoulda # :nodoc:
|
|||
false
|
||||
end
|
||||
|
||||
def autosave_correct?
|
||||
if options.key?(:autosave)
|
||||
if option_verifier.correct_for_boolean?(:autosave, options[:autosave])
|
||||
true
|
||||
else
|
||||
@missing = "#{name} should have autosave set to #{options[:autosave]}"
|
||||
false
|
||||
end
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def conditions_correct?
|
||||
if options.key?(:conditions)
|
||||
if option_verifier.correct_for_relation_clause?(:conditions, options[:conditions])
|
||||
|
|
|
@ -116,6 +116,26 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
it 'accepts an association with a matching :autosave option' do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :autosave => true
|
||||
end
|
||||
expect(Child.new).to belong_to(:parent).autosave(true)
|
||||
end
|
||||
|
||||
it 'rejects an association with a non-matching :autosave option with the correct message' do
|
||||
define_model :parent, :adopter => :boolean
|
||||
define_model :child, :parent_id => :integer do
|
||||
belongs_to :parent, :autosave => false
|
||||
end
|
||||
|
||||
message = 'Expected Child to have a belongs_to association called parent (parent should have autosave set to true)'
|
||||
expect {
|
||||
expect(Child.new).to belong_to(:parent).autosave(true)
|
||||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
context 'an association with a :validate option' do
|
||||
[false, true].each do |validate_value|
|
||||
context "when the model has validate: #{validate_value}" do
|
||||
|
@ -380,6 +400,26 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
it 'accepts an association with a matching :autosave option' do
|
||||
define_model :child, :parent_id => :integer
|
||||
define_model :parent do
|
||||
has_many :children, :autosave => true
|
||||
end
|
||||
expect(Parent.new).to have_many(:children).autosave(true)
|
||||
end
|
||||
|
||||
it 'rejects an association with a non-matching :autosave option with 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 autosave set to true)'
|
||||
expect {
|
||||
expect(Parent.new).to have_many(:children).autosave(true)
|
||||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
context 'validate' do
|
||||
it 'accepts when the :validate option matches' do
|
||||
expect(having_many_children(validate: false)).to have_many(:children).validate(false)
|
||||
|
@ -530,6 +570,26 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
expect(having_one_detail).to have_one(:detail).class_name('Detail')
|
||||
end
|
||||
|
||||
it 'accepts an association with a matching :autosave option' do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail, :autosave => true
|
||||
end
|
||||
expect(Person.new).to have_one(:detail).autosave(true)
|
||||
end
|
||||
|
||||
it 'rejects an association with a non-matching :autosave option with the correct message' do
|
||||
define_model :detail, :person_id => :integer, :disabled => :boolean
|
||||
define_model :person do
|
||||
has_one :detail, :autosave => false
|
||||
end
|
||||
|
||||
message = 'Expected Person to have a has_one association called detail (detail should have autosave set to true)'
|
||||
expect {
|
||||
expect(Person.new).to have_one(:detail).autosave(true)
|
||||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
it 'accepts an association with a valid :class_name option' do
|
||||
define_model :person_detail, person_id: :integer
|
||||
define_model :person do
|
||||
|
@ -712,6 +772,30 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
it 'accepts an association with a matching :autosave option' do
|
||||
define_model :relatives, :adopted => :boolean
|
||||
define_model :person do
|
||||
has_and_belongs_to_many :relatives, :autosave => true
|
||||
end
|
||||
define_model :people_relative, :person_id => :integer,
|
||||
:relative_id => :integer
|
||||
expect(Person.new).to have_and_belong_to_many(:relatives).autosave(true)
|
||||
end
|
||||
|
||||
it 'rejects an association with a non-matching :autosave option with the correct message' 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
|
||||
|
||||
message = 'Expected Person to have a has_and_belongs_to_many association called relatives (relatives should have autosave set to true)'
|
||||
expect {
|
||||
expect(Person.new).to have_and_belong_to_many(:relatives).autosave(true)
|
||||
}.to fail_with_message(message)
|
||||
end
|
||||
|
||||
context 'validate' do
|
||||
it 'accepts when the :validate option matches' do
|
||||
expect(having_and_belonging_to_many_relatives(validate: false)).
|
||||
|
|
Loading…
Reference in New Issue