thoughtbot--shoulda-matchers/lib/shoulda/matchers/active_model/disallow_value_matcher.rb

59 lines
1.2 KiB
Ruby
Raw Normal View History

require 'forwardable'
module Shoulda
module Matchers
module ActiveModel
# @private
class DisallowValueMatcher
extend Forwardable
def_delegators :allow_matcher, :_after_setting_value
def initialize(value)
@allow_matcher = AllowValueMatcher.new(value)
end
def matches?(subject)
!@allow_matcher.matches?(subject)
end
def for(attribute)
@allow_matcher.for(attribute)
self
end
def on(context)
@allow_matcher.on(context)
self
end
def with_message(message, options={})
@allow_matcher.with_message(message, options)
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
def failure_message
@allow_matcher.failure_message_when_negated
end
def failure_message_when_negated
@allow_matcher.failure_message
end
def strict
@allow_matcher.strict
self
end
protected
attr_reader :allow_matcher
end
end
end
end