Change behavior of should_not allow_value

Instead of asserting that any of the given value is an invalid value
(allowing good values to pass through), assert that *all* values are
invalid values (allowing good values not to pass through).

This means that this test which formerly passed now fails (assuming that
'good value' is a value that does not produce an invalid record):

    expect(record).not_to allow_value('good value', *bad_values)
This commit is contained in:
Elliot Winkler 2014-10-22 01:18:54 -06:00
parent a4045a1f9b
commit 19c38a642a
3 changed files with 41 additions and 15 deletions

12
NEWS.md
View File

@ -1,3 +1,15 @@
# 3.0.0
### Backward-incompatible changes
* The negative form of `allow_value` has been changed so that instead of
asserting that any of the given values is an invalid value (allowing good
values to pass through), assert that *all* values are invalid values (allowing
good values not to pass through). This means that this test which formerly
passed will now fail:
expect(record).not_to allow_value('good value', *bad_values)
# 2.8.0
### Deprecations

View File

@ -215,14 +215,12 @@ module Shoulda
def matches?(instance)
self.instance = instance
validator.record = instance
values_to_match.all? { |value| value_matches?(value) }
end
values_to_match.none? do |value|
validator.reset
self.value = value
set_attribute(value)
errors_match? || any_range_error_occurred?
end
def does_not_match?(instance)
self.instance = instance
values_to_match.all? { |value| !value_matches?(value) }
end
def failure_message
@ -241,15 +239,26 @@ module Shoulda
protected
attr_reader :attribute_to_check_message_against
attr_accessor :values_to_match, :instance, :attribute_to_set, :value,
attr_reader :instance, :attribute_to_check_message_against
attr_accessor :values_to_match, :attribute_to_set, :value,
:matched_error, :after_setting_value_callback, :validator
def instance=(instance)
@instance = instance
validator.record = instance
end
def attribute_to_check_message_against=(attribute)
@attribute_to_check_message_against = attribute
validator.attribute = attribute
end
def value_matches?(value)
self.value = value
set_attribute(value)
!(errors_match? || any_range_error_occurred?)
end
def set_attribute(value)
set_attribute_ignoring_range_errors(value)
after_setting_value_callback.call

View File

@ -165,24 +165,29 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher, type: :model do
less_than_or_equal_to: 50000
end.new
end
bad_values = [nil, '', 'abc', '0', '50001', '123456', []]
it 'allows a good value' do
it 'matches given a good value' do
expect(model).to allow_value('12345').for(:attr)
end
bad_values.each do |bad_value|
it "rejects a bad value (#{bad_value.inspect})" do
it 'does not match given a bad value' do
bad_values.each do |bad_value|
expect(model).not_to allow_value(bad_value).for(:attr)
end
end
it "rejects several bad values (#{bad_values.map(&:inspect).join(', ')})" do
it 'does not match given multiple bad values' do
expect(model).not_to allow_value(*bad_values).for(:attr)
end
it "rejects a mix of both good and bad values" do
expect(model).not_to allow_value('12345', *bad_values).for(:attr)
it "does not match given good values along with bad values" do
message = %{Expected errors when attr is set to "12345",\ngot no errors}
expect {
expect(model).not_to allow_value('12345', *bad_values).for(:attr)
}.to fail_with_message(message)
end
end