# Use: it { should accept_nested_attributes_for(:association_name).and_accept({valid_values => true}).but_reject({ :reject_if_nil => nil })} | |
RSpec::Matchers.define :accept_nested_attributes_for do |association| | |
match do |model| | |
@model = model | |
@nested_att_present = model.respond_to?("#{association}_attributes=".to_sym) | |
if @nested_att_present && @reject | |
model.send("#{association}_attributes=".to_sym,[@reject]) | |
@reject_success = model.send("#{association}").empty? | |
end | |
model.send("#{association}").clear | |
if @nested_att_present && @accept | |
model.send("#{association}_attributes=".to_sym,[@accept]) | |
@accept_success = ! (model.send("#{association}").empty?) | |
end | |
@nested_att_present && ( @reject.nil? || @reject_success ) && ( @accept.nil? || @accept_success ) | |
end | |
failure_message_for_should do | |
messages = [] | |
messages << "accept nested attributes for #{association}" unless @nested_att_present | |
messages << "reject values #{@reject.inspect} for association #{association}" unless @reject_success | |
messages << "accept values #{@accept.inspect} for association #{association}" unless @accept_success | |
"expected #{@model.class} to " + messages.join(", ") | |
end | |
description do | |
desc = "accept nested attributes for #{expected}" | |
if @reject | |
desc << ", but reject if attributes are #{@reject.inspect}" | |
end | |
end | |
chain :but_reject do |reject| | |
@reject = reject | |
end | |
chain :and_accept do |accept| | |
@accept = accept | |
end | |
end |
This comment has been minimized.
This comment has been minimized.
Hi @maheeptathgur. I think you should just be able to do: it { should accept_nested_attributes_for(:association_name).but_reject({ :val_1 => "", :val_2 => "" }) } Let me know if that doesn't work, and I'll try and help some more. |
This comment has been minimized.
This comment has been minimized.
HI @pauljamesrussell |
This comment has been minimized.
This comment has been minimized.
Hi @maheeptathgur, no I'm afraid not - it'll just ignore the rejection test and not test for rejection. Your test will still pass, but it won't be proving what you want it to prove. |
This comment has been minimized.
This comment has been minimized.
Thank you! |
This comment has been minimized.
This comment has been minimized.
@pauljamesrussell the description message doesnt work. description do
desc = "accept nested attributes for #{expected}"
if @reject
desc << ", but reject if attributes are #{@reject.inspect}"
end
desc
end |
This comment has been minimized.
This comment has been minimized.
+1 to @Takehiro-Adachi . Thanks Paul for sharing! |
This comment has been minimized.
This comment has been minimized.
Great, it worked. But I thought RSpec already included Shoulda macros. I'm missing something here |
This comment has been minimized.
This comment has been minimized.
Thank you! Just what I was looking for |
This comment has been minimized.
This comment has been minimized.
@JohnSmall - I believe the Shoulda macros do not support the reject_if: option. |
This comment has been minimized.
This comment has been minimized.
@pauljamesrussell maybe you should do a pull request to the shoulda macros to use your features for rejection? |
This comment has been minimized.
This comment has been minimized.
+1 for @andreorvalho. cc @pauljamesrussell. |
This comment has been minimized.
hi paul,
firstly thank you for the code...is solved my problem for the rspec, however i would like to ask how can i test for the reject_if => proc { |attrs| attrs.all? { |key, val| val.blank?}}