2014-04-16 06:24:02 +00:00
|
|
|
require 'forwardable'
|
|
|
|
|
2014-01-23 18:07:36 +00:00
|
|
|
module Shoulda
|
2012-10-16 17:45:06 +00:00
|
|
|
module Matchers
|
2014-01-23 18:07:36 +00:00
|
|
|
module ActiveModel
|
|
|
|
# @private
|
|
|
|
class DisallowValueMatcher
|
2014-04-16 06:24:02 +00:00
|
|
|
extend Forwardable
|
|
|
|
|
|
|
|
def_delegators :allow_matcher, :_after_setting_value
|
2012-10-16 17:45:06 +00:00
|
|
|
def initialize(value)
|
2012-10-23 16:30:18 +00:00
|
|
|
@allow_matcher = AllowValueMatcher.new(value)
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def matches?(subject)
|
|
|
|
!@allow_matcher.matches?(subject)
|
|
|
|
end
|
|
|
|
|
|
|
|
def for(attribute)
|
|
|
|
@allow_matcher.for(attribute)
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-07-02 02:16:32 +00:00
|
|
|
def on(context)
|
|
|
|
@allow_matcher.on(context)
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-07-24 21:46:01 +00:00
|
|
|
def with_message(message, options={})
|
|
|
|
@allow_matcher.with_message(message, options)
|
2012-10-16 17:45:06 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
Tighten CouldNotSetAttributeError restriction
Why:
* Previously, `allow_value` would raise a CouldNotSetAttributeError
if the value being set didn't match the value the attribute had after
being set, but only if the attribute was being changed from nil to
non-nil or non-nil to nil.
* It turns out it doesn't matter which value you're trying to set the
attribute to -- if the attribute rejects that change it's confusing
either way. (In fact, I was recently bit by a case in which I was
trying to validate numericality of an attribute, where the writer
method for that attribute was overridden to ensure that the attribute
always stored a number and never contained non-number characters.
This ended up making the numericality validation useless, of
course -- but it caused confusion because the test acted in a way
I didn't expect.)
To satisfy the above:
* `allow_value` now raises a CouldNotSetAttributeError if the attribute
rejects the value being set in *any* way.
* However, add a `ignoring_interference_by_writer` qualifier so that
it is possible to manually override this behavior.
* Fix tests that are failing now because of this new change:
* Fix tests for allow_value matcher
* Fix tests for numericality matcher
* Remove tests for numericality matcher + integer column
* An integer column will typecast any non-integer value to an
integer.
* Because of the typecasting, our tests for the numericality matcher
against an integer column don't quite work, because we can't
really test what happens when the attribute is set to a
non-integer value. Now that `allow_value` is more strict, we're
getting a CouldNotSetAttributeError when attempting to do so.
* The tests mentioned were originally added to ensure that we are
handling RangeErrors that ActiveRecord used to emit. This doesn't
happen anymore, so the tests aren't necessary anymore either.
* Fix tests for acceptance matcher
* Fix tests for absence matcher
2015-09-26 05:10:00 +00:00
|
|
|
def ignoring_interference_by_writer
|
|
|
|
@allow_matcher.ignoring_interference_by_writer
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-12-24 11:24:27 +00:00
|
|
|
def failure_message
|
|
|
|
@allow_matcher.failure_message_when_negated
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
|
2013-12-24 11:24:27 +00:00
|
|
|
def failure_message_when_negated
|
|
|
|
@allow_matcher.failure_message
|
2013-03-27 18:13:46 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def strict
|
|
|
|
@allow_matcher.strict
|
|
|
|
self
|
|
|
|
end
|
2014-04-16 06:24:02 +00:00
|
|
|
|
2014-06-24 15:57:52 +00:00
|
|
|
protected
|
2014-04-16 06:24:02 +00:00
|
|
|
|
|
|
|
attr_reader :allow_matcher
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|