Add odd & even number matchers for numericality matcher
This commit is contained in:
parent
5ad04a89e2
commit
8aa860dc2d
1
NEWS.md
1
NEWS.md
|
@ -1,5 +1,6 @@
|
|||
# HEAD
|
||||
|
||||
* Add `:odd` and `:even` options to the `validate_numericality_of` matcher.
|
||||
* Add `:touch` option to the association matcher.
|
||||
* Ruby 2.0.0 is now officially supported.
|
||||
* Fixes the issue where using %{attribute} or %{model} in I18n translations
|
||||
|
|
|
@ -5,6 +5,7 @@ require 'shoulda/matchers/active_model/exception_message_finder'
|
|||
require 'shoulda/matchers/active_model/allow_value_matcher'
|
||||
require 'shoulda/matchers/active_model/disallow_value_matcher'
|
||||
require 'shoulda/matchers/active_model/only_integer_matcher'
|
||||
require 'shoulda/matchers/active_model/odd_even_number_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'
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
module Shoulda # :nodoc:
|
||||
module Matchers
|
||||
module ActiveModel # :nodoc:
|
||||
class OddEvenNumberMatcher # :nodoc:
|
||||
NON_EVEN_NUMBER_VALUE = 1
|
||||
NON_ODD_NUMBER_VALUE = 2
|
||||
|
||||
def initialize(attribute, options = {})
|
||||
@attribute = attribute
|
||||
options[:odd] ||= true
|
||||
options[:even] ||= false
|
||||
|
||||
if options[:odd] && !options[:even]
|
||||
@disallow_value_matcher = DisallowValueMatcher.new(NON_ODD_NUMBER_VALUE).
|
||||
for(@attribute).
|
||||
with_message(:odd)
|
||||
else
|
||||
@disallow_value_matcher = DisallowValueMatcher.new(NON_EVEN_NUMBER_VALUE).
|
||||
for(@attribute).
|
||||
with_message(:even)
|
||||
end
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@disallow_value_matcher.matches?(subject)
|
||||
end
|
||||
|
||||
def with_message(message)
|
||||
@disallow_value_matcher.with_message(message)
|
||||
self
|
||||
end
|
||||
|
||||
def allowed_types
|
||||
'integer'
|
||||
end
|
||||
|
||||
def failure_message_for_should
|
||||
@disallow_value_matcher.failure_message_for_should
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,10 +8,14 @@ module Shoulda # :nodoc:
|
|||
# <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
|
||||
# translation for <tt>:not_a_number</tt>.
|
||||
# * <tt>only_integer</tt> - allows only integer values
|
||||
# * <tt>odd</tt> - Specifies the value must be an odd number.
|
||||
# * <tt>even</tt> - Specifies the value must be an even number.
|
||||
#
|
||||
# Examples:
|
||||
# it { should validate_numericality_of(:price) }
|
||||
# it { should validate_numericality_of(:age).only_integer }
|
||||
# it { should validate_numericality_of(:frequency).odd }
|
||||
# it { should validate_numericality_of(:frequency).even }
|
||||
#
|
||||
def validate_numericality_of(attr)
|
||||
ValidateNumericalityOfMatcher.new(attr)
|
||||
|
@ -22,7 +26,6 @@ module Shoulda # :nodoc:
|
|||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute
|
||||
@options = {}
|
||||
@submatchers = []
|
||||
|
||||
add_disallow_value_matcher
|
||||
|
@ -34,6 +37,18 @@ module Shoulda # :nodoc:
|
|||
self
|
||||
end
|
||||
|
||||
def odd
|
||||
odd_number_matcher = OddEvenNumberMatcher.new(@attribute, :odd => true)
|
||||
add_submatcher(odd_number_matcher)
|
||||
self
|
||||
end
|
||||
|
||||
def even
|
||||
even_number_matcher = OddEvenNumberMatcher.new(@attribute, :even => true)
|
||||
add_submatcher(even_number_matcher)
|
||||
self
|
||||
end
|
||||
|
||||
def with_message(message)
|
||||
@submatchers.each { |matcher| matcher.with_message(message) }
|
||||
self
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::OddEvenNumberMatcher do
|
||||
context 'given an attribute that only allows odd number values' do
|
||||
it 'matches' do
|
||||
validating_odd_number.should new_odd_matcher
|
||||
end
|
||||
|
||||
it 'returns itself when given a message' do
|
||||
matcher = new_odd_matcher
|
||||
matcher.with_message('some message').should == matcher
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an attribute that only allows even number values' do
|
||||
it 'matches' do
|
||||
validating_even_number.should new_even_matcher
|
||||
end
|
||||
|
||||
it 'returns itself when given a message' do
|
||||
matcher = new_even_matcher
|
||||
matcher.with_message('some message').should == matcher
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an attribute that only allows odd number values with a custom validation message' do
|
||||
it 'only accepts odd number values for that attribute with that message' do
|
||||
validating_odd_number(:message => 'custom').should new_odd_matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it 'rejects odd number values for that attribute with another message' do
|
||||
validating_odd_number(:message => 'custom').should_not new_odd_matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'given an attribute that only allows even number values with a custom validation message' do
|
||||
it 'only accepts even number values for that attribute with that message' do
|
||||
validating_even_number(:message => 'custom').should new_even_matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it 'rejects even number values for that attribute with another message' do
|
||||
validating_even_number(:message => 'custom').should_not new_even_matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the model does not have an odd validation' do
|
||||
it 'does not match' do
|
||||
define_model(:example, :attr => :string).new.should_not new_odd_matcher
|
||||
end
|
||||
|
||||
it 'fails with the ActiveRecord :odd message' do
|
||||
matcher = new_odd_matcher
|
||||
|
||||
matcher.matches?(define_model(:example, :attr => :string).new)
|
||||
|
||||
matcher.failure_message_for_should.should include 'Expected errors to include "must be odd"'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the model does not have an even validation' do
|
||||
it 'does not match' do
|
||||
define_model(:example, :attr => :string).new.should_not new_even_matcher
|
||||
end
|
||||
|
||||
it 'fails with the ActiveRecord :even message' do
|
||||
matcher = new_even_matcher
|
||||
|
||||
matcher.matches?(define_model(:example, :attr => :string).new)
|
||||
|
||||
matcher.failure_message_for_should.should include 'Expected errors to include "must be even"'
|
||||
end
|
||||
end
|
||||
|
||||
def new_odd_matcher
|
||||
described_class.new(:attr, :odd => true)
|
||||
end
|
||||
|
||||
def new_even_matcher
|
||||
described_class.new(:attr, :even => true)
|
||||
end
|
||||
|
||||
def validating_odd_number(options = {})
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :odd => true }.merge(options)
|
||||
end.new
|
||||
end
|
||||
|
||||
def validating_even_number(options = {})
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :even => true }.merge(options)
|
||||
end.new
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
||||
context 'given an attribute that only allows integer values' do
|
||||
it 'matches' do
|
||||
only_integer.should new_matcher
|
||||
validating_only_integer.should new_matcher
|
||||
end
|
||||
|
||||
it 'allows integer types' do
|
||||
|
@ -18,11 +18,11 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
|||
|
||||
context 'given an attribute that only allows integer values with a custom validation message' do
|
||||
it 'only accepts integer values for that attribute with that message' do
|
||||
only_integer(:message => 'custom').should new_matcher.with_message(/custom/)
|
||||
validating_only_integer(:message => 'custom').should new_matcher.with_message(/custom/)
|
||||
end
|
||||
|
||||
it 'rejects integer values for that attribute with another message' do
|
||||
only_integer(:message => 'custom').should_not new_matcher.with_message(/wrong/)
|
||||
validating_only_integer(:message => 'custom').should_not new_matcher.with_message(/wrong/)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -44,7 +44,7 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
|||
described_class.new(:attr)
|
||||
end
|
||||
|
||||
def only_integer(options = {})
|
||||
def validating_only_integer(options = {})
|
||||
define_model :example, :attr => :string do
|
||||
validates_numericality_of :attr, { :only_integer => true }.merge(options)
|
||||
end.new
|
||||
|
|
|
@ -29,6 +29,22 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|||
|
||||
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be an integer"'
|
||||
end
|
||||
|
||||
it 'rejects with the ActiveRecord :odd message' do
|
||||
the_matcher = matcher.odd
|
||||
|
||||
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
||||
|
||||
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be odd"'
|
||||
end
|
||||
|
||||
it 'rejects with the ActiveRecord :even message' do
|
||||
the_matcher = matcher.even
|
||||
|
||||
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
||||
|
||||
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be even"'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with the only_integer option' do
|
||||
|
@ -49,6 +65,42 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with the odd option' do
|
||||
it 'allows odd number values for that attribute' do
|
||||
validating_numericality(:odd => true).should matcher.odd
|
||||
end
|
||||
|
||||
it 'rejects when the model does not enforce odd number values' do
|
||||
validating_numericality.should_not matcher.odd
|
||||
end
|
||||
|
||||
it 'rejects with the ActiveRecord :odd message' do
|
||||
the_matcher = matcher.odd
|
||||
|
||||
the_matcher.matches?(validating_numericality)
|
||||
|
||||
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be odd"'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with the even option' do
|
||||
it 'allows even number values for that attribute' do
|
||||
validating_numericality(:even => true).should matcher.even
|
||||
end
|
||||
|
||||
it 'rejects when the model does not enforce even number values' do
|
||||
validating_numericality.should_not matcher.even
|
||||
end
|
||||
|
||||
it 'rejects with the ActiveRecord :even message' do
|
||||
the_matcher = matcher.even
|
||||
|
||||
the_matcher.matches?(validating_numericality)
|
||||
|
||||
the_matcher.failure_message_for_should.should include 'Expected errors to include "must be even"'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a custom validation message' do
|
||||
it 'accepts when the messages match' do
|
||||
validating_numericality(:message => 'custom').
|
||||
|
|
Loading…
Reference in New Issue