Add in_array to ensure_exclusion_of

This commit is contained in:
Grzesiek Kolodziejczyk 2012-08-19 11:07:05 +02:00 committed by Jason Draper
parent 41c763d276
commit 8a477a92bd
3 changed files with 52 additions and 8 deletions

View File

@ -5,6 +5,7 @@ module Shoulda # :nodoc:
# Ensure that the attribute's value is not in the range specified
#
# Options:
# * <tt>in_array</tt> - the array of not allowed values for this attribute
# * <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
@ -18,6 +19,10 @@ module Shoulda # :nodoc:
end
class EnsureExclusionOfMatcher < ValidationMatcher # :nodoc:
def in_array(array)
@array = array
self
end
def in_range(range)
@range = range
@ -32,20 +37,30 @@ module Shoulda # :nodoc:
end
def description
"ensure exclusion of #{@attribute} in #{@range.inspect}"
"ensure exclusion of #{@attribute} in #{inspect_message}"
end
def matches?(subject)
super(subject)
allows_lower_value &&
disallows_minimum_value &&
allows_higher_value &&
disallows_maximum_value
if @range
allows_lower_value &&
disallows_minimum_value &&
allows_higher_value &&
disallows_maximum_value
elsif @array
disallows_all_values_in_array?
end
end
private
def disallows_all_values_in_array?
@array.all? do |value|
disallows_value_of(value, expected_message)
end
end
def allows_lower_value
@minimum == 0 || allows_value_of(@minimum - 1, expected_message)
end
@ -65,8 +80,15 @@ module Shoulda # :nodoc:
def expected_message
@expected_message || :exclusion
end
end
def inspect_message
if @range
@range.inspect
else
@array.inspect
end
end
end
end
end
end

View File

@ -5,7 +5,7 @@ module Shoulda # :nodoc:
# Ensure that the attribute's value is in the range specified
#
# Options:
# * <tt>in_array</tt> - the range of allowed values for this attribute
# * <tt>in_array</tt> - the array of allowed values for this attribute
# * <tt>in_range</tt> - the range of allowed values for this attribute
# * <tt>with_low_message</tt> - value the test expects to find in
# <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the

View File

@ -51,7 +51,29 @@ describe Shoulda::Matchers::ActiveModel::EnsureExclusionOfMatcher do
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
context "an attribute which must be excluded in an array" do
before do
@model = define_model(:example, :attr => :string) do
validates_exclusion_of :attr, :in => %w(one two)
end.new
end
it "accepts with correct array" do
@model.should ensure_exclusion_of(:attr).in_array(%w(one two))
end
it "rejects when only part of array matches" do
@model.should_not ensure_exclusion_of(:attr).in_array(%w(one wrong_value))
end
it "rejects when array doesn't match at all" do
@model.should_not ensure_exclusion_of(:attr).in_array(%w(cat dog))
end
it "has correct description" do
ensure_exclusion_of(:attr).in_array([true, 'dog']).description.should == 'ensure exclusion of attr in [true, "dog"]'
end
end
end