add ensure_exclusion_of

This commit is contained in:
Vasiliy Ermolovich 2011-10-16 20:49:58 +03:00
parent ead1e1d42c
commit d8308ec74d
3 changed files with 128 additions and 0 deletions

View File

@ -3,6 +3,7 @@ require 'shoulda/matchers/active_model/validation_matcher'
require 'shoulda/matchers/active_model/allow_value_matcher'
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
require 'shoulda/matchers/active_model/ensure_exclusion_of_matcher'
require 'shoulda/matchers/active_model/validate_presence_of_matcher'
require 'shoulda/matchers/active_model/validate_format_of_matcher'
require 'shoulda/matchers/active_model/validate_uniqueness_of_matcher'

View File

@ -0,0 +1,70 @@
module Shoulda # :nodoc:
module Matchers
module ActiveModel # :nodoc:
# Ensure that the attribute's value is not in the range specified
#
# Options:
# * <tt>in_range</tt> - the range of not allowed values for this attribute
# * <tt>with_message</tt> - value the test expects to find in
# <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
# translation for :exclusion.
#
# Example:
# it { should ensure_exclusion_of(:age).in_range(30..60) }
#
def ensure_exclusion_of(attr)
EnsureExclusionOfMatcher.new(attr)
end
class EnsureExclusionOfMatcher < ValidationMatcher # :nodoc:
def in_range(range)
@range = range
@minimum = range.first
@maximum = range.last
self
end
def with_message(message)
@expected_message = message if message
self
end
def description
"ensure exclusion of #{@attribute} in #{@range.inspect}"
end
def matches?(subject)
super(subject)
@expected_message ||= :exclusion
allows_lower_value &&
disallows_minimum_value &&
allows_higher_value &&
disallows_maximum_value
end
private
def allows_lower_value
@minimum == 0 || allows_value_of(@minimum - 1, @expected_message)
end
def allows_higher_value
allows_value_of(@maximum + 1, @expected_message)
end
def disallows_minimum_value
disallows_value_of(@minimum, @expected_message)
end
def disallows_maximum_value
disallows_value_of(@maximum, @expected_message)
end
end
end
end
end

View File

@ -0,0 +1,57 @@
require 'spec_helper'
describe Shoulda::Matchers::ActiveModel::EnsureExclusionOfMatcher do
context "an attribute which must be excluded of a range" do
before do
@model = define_model(:example, :attr => :integer) do
validates_exclusion_of :attr, :in => 2..5
end.new
end
it "should accept ensuring the correct range" do
@model.should ensure_exclusion_of(:attr).in_range(2..5)
end
it "should reject ensuring excluded value" do
@model.should_not ensure_exclusion_of(:attr).in_range(2..6)
end
it "should not override the default message with a blank" do
@model.should ensure_exclusion_of(:attr).in_range(2..5).with_message(nil)
end
end
context "an attribute with a custom ranged value validation" do
before do
@model = define_model(:example, :attr => :string) do
validates_exclusion_of :attr, :in => 2..4, :message => 'not good'
end.new
end
it "should accept ensuring the correct range" do
@model.should ensure_exclusion_of(:attr).in_range(2..4).with_message(/not good/)
end
end
context "an attribute with custom range validations" do
before do
define_model :example, :attr => :integer do
validate :custom_validation
def custom_validation
if attr >= 2 && attr <= 5
errors.add(:attr, 'shoud be out of this range')
end
end
end
@model = Example.new
end
it "should accept ensuring the correct range and messages" do
@model.should ensure_exclusion_of(:attr).in_range(2..5).with_message(/shoud be out of this range/)
end
end
end