mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
allow multiple values for AllowValueMatcher
With the deprecation of "should_allow_values_for" there is currently no clean way to specify multiple allowed (or forbidden) values for an attribute in a single assertion. This can make test cases unnecessarily verbose. This patch gives AllowValueMatcher the ability to take multiple values. The new matcher is fully downward compatible (i.e. given a single argument it behaves identically to the old matcher). This matcher will stop checking for bad values when the first bad value is encountered.
This commit is contained in:
parent
c86d8e2e0c
commit
cab62a1697
2 changed files with 50 additions and 9 deletions
|
@ -2,7 +2,10 @@ module Shoulda # :nodoc:
|
|||
module Matchers
|
||||
module ActiveModel # :nodoc:
|
||||
|
||||
# Ensures that the attribute can be set to the given value.
|
||||
# Ensures that the attribute can be set to the given value or values. If
|
||||
# multiple values are given the match succeeds only if all given values
|
||||
# are allowed. Otherwise, the matcher fails at the first bad value in the
|
||||
# argument list (the remaining arguments are not processed then).
|
||||
#
|
||||
# Options:
|
||||
# * <tt>with_message</tt> - value the test expects to find in
|
||||
|
@ -13,15 +16,16 @@ module Shoulda # :nodoc:
|
|||
# it { should_not allow_value('bad').for(:isbn) }
|
||||
# it { should allow_value("isbn 1 2345 6789 0").for(:isbn) }
|
||||
#
|
||||
def allow_value(value)
|
||||
AllowValueMatcher.new(value)
|
||||
def allow_value(*values)
|
||||
raise ArgumentError.new("need at least one argument") if values.empty?
|
||||
AllowValueMatcher.new(*values)
|
||||
end
|
||||
|
||||
class AllowValueMatcher # :nodoc:
|
||||
include Helpers
|
||||
|
||||
def initialize(value)
|
||||
@value = value
|
||||
def initialize(*values)
|
||||
@values_to_match = values
|
||||
end
|
||||
|
||||
def for(attribute)
|
||||
|
@ -39,8 +43,12 @@ module Shoulda # :nodoc:
|
|||
if Symbol === @expected_message
|
||||
@expected_message = default_error_message(@expected_message, :model_name => @instance.class.to_s.underscore, :attribute => @attribute)
|
||||
end
|
||||
@instance.send("#{@attribute}=", @value)
|
||||
!errors_match?
|
||||
@values_to_match.each do |value|
|
||||
@value = value
|
||||
@instance.send("#{@attribute}=", @value)
|
||||
return false if errors_match?
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def failure_message
|
||||
|
@ -52,7 +60,12 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def description
|
||||
"allow #{@attribute} to be set to #{@value.inspect}"
|
||||
"allow #{@attribute} to be set to " <<
|
||||
if @values_to_match.length > 1
|
||||
"any of [#{@values_to_match.map {|v| v.inspect }.join(', ')}]"
|
||||
else
|
||||
@values_to_match.first.inspect
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -17,6 +17,14 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|||
it "should not allow a bad value" do
|
||||
@model.should_not allow_value("xyz").for(:attr)
|
||||
end
|
||||
|
||||
it "should allow several good values" do
|
||||
@model.should allow_value("abcde", "deabc").for(:attr)
|
||||
end
|
||||
|
||||
it "should not allow several bad values" do
|
||||
@model.should_not allow_value("xyz", "zyx", nil, []).for(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a format validation and a custom message" do
|
||||
|
@ -51,12 +59,32 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|||
@model.should allow_value("12345").for(:attr)
|
||||
end
|
||||
|
||||
bad_values = [nil, "", "abc", "0", "50001", "123456"]
|
||||
bad_values = [nil, "", "abc", "0", "50001", "123456", []]
|
||||
|
||||
bad_values.each do |value|
|
||||
it "should not allow a bad value (#{value.inspect})" do
|
||||
@model.should_not allow_value(value).for(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
it "should not allow bad values (#{bad_values.map {|v| v.inspect}.join(', ')})" do
|
||||
@model.should_not allow_value(*bad_values).for(:attr)
|
||||
end
|
||||
end
|
||||
|
||||
context "an AllowValueMatcher with multiple values" do
|
||||
before { @matcher = allow_value("foo", "bar").for(:baz) }
|
||||
|
||||
it "should describe itself" do
|
||||
@matcher.description.should eq('allow baz to be set to any of ["foo", "bar"]')
|
||||
end
|
||||
end
|
||||
|
||||
context "an AllowValueMatcher with a single value" do
|
||||
before { @matcher = allow_value("foo").for(:baz) }
|
||||
|
||||
it "should describe itself" do
|
||||
@matcher.description.should eq('allow baz to be set to "foo"')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue