2010-12-13 22:28:59 +00:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2011-05-06 11:51:12 +00:00
|
|
|
describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
2010-12-13 22:28:59 +00:00
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'with a model with a numericality validation' do
|
|
|
|
it 'accepts' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality).to matcher
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'does not override the default message with a blank' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality).to matcher.with_message(nil)
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'with a model without a numericality validation' do
|
|
|
|
it 'rejects' do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(not_validating_numericality).not_to matcher
|
2011-10-27 02:21:06 +00:00
|
|
|
end
|
|
|
|
|
2013-04-12 17:11:07 +00:00
|
|
|
it 'rejects with the ActiveRecord :not_a_number message' do
|
|
|
|
the_matcher = matcher
|
|
|
|
|
2014-01-17 20:20:44 +00:00
|
|
|
the_matcher.matches?(define_model(:example, attr: :string).new)
|
2013-04-12 17:11:07 +00:00
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
expect(the_matcher.failure_message_when_negated)
|
|
|
|
.to include 'Did not expect errors to include "is not a number"'
|
2013-04-12 17:11:07 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'rejects with the ActiveRecord :not_an_integer message' do
|
|
|
|
the_matcher = matcher.only_integer
|
2014-02-27 03:26:37 +00:00
|
|
|
expect do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(not_validating_numericality).to the_matcher
|
2014-02-27 03:26:37 +00:00
|
|
|
end.to fail_with_message_including(
|
|
|
|
'Expected errors to include "must be an integer"'
|
|
|
|
)
|
2011-10-27 02:21:06 +00:00
|
|
|
end
|
2013-03-19 04:50:39 +00:00
|
|
|
|
|
|
|
it 'rejects with the ActiveRecord :odd message' do
|
|
|
|
the_matcher = matcher.odd
|
2014-02-27 03:26:37 +00:00
|
|
|
expect do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(not_validating_numericality).to the_matcher
|
2014-02-27 03:26:37 +00:00
|
|
|
end.to fail_with_message_including(
|
|
|
|
'Expected errors to include "must be odd"'
|
|
|
|
)
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects with the ActiveRecord :even message' do
|
|
|
|
the_matcher = matcher.even
|
2014-02-27 03:26:37 +00:00
|
|
|
expect do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(not_validating_numericality).to the_matcher
|
2014-02-27 03:26:37 +00:00
|
|
|
end.to fail_with_message_including(
|
|
|
|
'Expected errors to include "must be even"'
|
|
|
|
)
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
2011-10-27 02:21:06 +00:00
|
|
|
end
|
|
|
|
|
2014-02-21 22:31:48 +00:00
|
|
|
context 'with the allow_nil option' do
|
|
|
|
it 'allows nil values for that attribute' do
|
|
|
|
expect(validating_numericality(allow_nil: true)).to matcher.allow_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects when the model does not allow nil' do
|
|
|
|
the_matcher = matcher.allow_nil
|
|
|
|
expect {
|
|
|
|
expect(validating_numericality).to the_matcher
|
|
|
|
}.to fail_with_message_including('Did not expect errors to include "is not a number"')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'with the only_integer option' do
|
|
|
|
it 'allows integer values for that attribute' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality(only_integer: true)).to matcher.only_integer
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'rejects when the model does not enforce integer values' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality).not_to matcher.only_integer
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'rejects with the ActiveRecord :not_an_integer message' do
|
|
|
|
the_matcher = matcher.only_integer
|
2014-02-27 03:26:37 +00:00
|
|
|
expect do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(validating_numericality).to the_matcher
|
2014-02-27 03:26:37 +00:00
|
|
|
end.to fail_with_message_including(
|
|
|
|
'Expected errors to include "must be an integer"'
|
|
|
|
)
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-03-19 04:50:39 +00:00
|
|
|
context 'with the odd option' do
|
|
|
|
it 'allows odd number values for that attribute' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality(odd: true)).to matcher.odd
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects when the model does not enforce odd number values' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality).not_to matcher.odd
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects with the ActiveRecord :odd message' do
|
|
|
|
the_matcher = matcher.odd
|
2014-02-27 03:26:37 +00:00
|
|
|
expect do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(validating_numericality).to the_matcher
|
2014-02-27 03:26:37 +00:00
|
|
|
end.to fail_with_message_including(
|
|
|
|
'Expected errors to include "must be odd"'
|
|
|
|
)
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with the even option' do
|
|
|
|
it 'allows even number values for that attribute' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality(even: true)).to matcher.even
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects when the model does not enforce even number values' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality).not_to matcher.even
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects with the ActiveRecord :even message' do
|
|
|
|
the_matcher = matcher.even
|
2014-02-27 03:26:37 +00:00
|
|
|
expect do
|
2014-01-13 01:43:36 +00:00
|
|
|
expect(validating_numericality).to the_matcher
|
2014-02-27 03:26:37 +00:00
|
|
|
end.to fail_with_message_including(
|
|
|
|
'Expected errors to include "must be even"'
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with multiple options together' do
|
|
|
|
context 'the success cases' do
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(only_integer: true, greater_than: 18))
|
|
|
|
.to matcher.only_integer.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(even: true, greater_than: 18))
|
|
|
|
.to matcher.even.is_greater_than(18)
|
|
|
|
end
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(odd: true, less_than_or_equal_to: 99))
|
|
|
|
.to matcher.odd.is_less_than_or_equal_to(99)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(
|
|
|
|
only_integer: true,
|
|
|
|
greater_than: 18,
|
|
|
|
less_than: 99)
|
|
|
|
).to matcher.only_integer.is_greater_than(18).is_less_than(99)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'the failure cases with different validators' do
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(even: true, greater_than: 18))
|
|
|
|
.not_to matcher.only_integer.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(greater_than: 18))
|
|
|
|
.not_to matcher.only_integer.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(
|
|
|
|
validating_numericality(even: true, greater_than_or_equal_to: 18)
|
|
|
|
).not_to matcher.even.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(odd: true, greater_than: 18))
|
|
|
|
.not_to matcher.even.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(
|
|
|
|
odd: true,
|
|
|
|
greater_than_or_equal_to: 99
|
|
|
|
)
|
|
|
|
).not_to matcher.odd.is_less_than_or_equal_to(99)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(
|
|
|
|
only_integer: true,
|
|
|
|
greater_than_or_equal_to: 18,
|
|
|
|
less_than: 99
|
|
|
|
)
|
|
|
|
).not_to matcher.only_integer.is_greater_than(18).is_less_than(99)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'the failure cases with wrong values' do
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(only_integer: true, greater_than: 19))
|
|
|
|
.not_to matcher.only_integer.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(only_integer: true, greater_than: 17))
|
|
|
|
.not_to matcher.only_integer.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(even: true, greater_than: 20))
|
|
|
|
.not_to matcher.even.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(even: true, greater_than: 16))
|
|
|
|
.not_to matcher.even.is_greater_than(18)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(odd: true, less_than_or_equal_to: 101))
|
|
|
|
.not_to matcher.odd.is_less_than_or_equal_to(99)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(odd: true, less_than_or_equal_to: 97))
|
|
|
|
.not_to matcher.odd.is_less_than_or_equal_to(99)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(only_integer: true,
|
|
|
|
greater_than: 19,
|
|
|
|
less_than: 99))
|
|
|
|
.not_to matcher.only_integer.is_greater_than(18).is_less_than(99)
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(validating_numericality(only_integer: true,
|
|
|
|
greater_than: 18,
|
|
|
|
less_than: 100))
|
|
|
|
.not_to matcher.only_integer.is_greater_than(18).is_less_than(99)
|
|
|
|
end
|
2013-03-19 04:50:39 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
context 'with a custom validation message' do
|
|
|
|
it 'accepts when the messages match' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality(message: 'custom')).
|
2014-01-13 01:43:36 +00:00
|
|
|
to matcher.with_message(/custom/)
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
it 'rejects when the messages do not match' do
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(validating_numericality(message: 'custom')).
|
2014-01-13 01:43:36 +00:00
|
|
|
not_to matcher.with_message(/wrong/)
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
2012-12-20 05:04:27 +00:00
|
|
|
end
|
2012-10-16 17:45:06 +00:00
|
|
|
|
2013-07-10 17:05:41 +00:00
|
|
|
context 'when the subject is stubbed' do
|
|
|
|
it 'retains stubs on submatchers' do
|
2014-01-17 20:20:44 +00:00
|
|
|
subject = define_model :example, attr: :string do
|
|
|
|
validates_numericality_of :attr, odd: true
|
2013-07-10 17:05:41 +00:00
|
|
|
before_validation :set_attr!
|
|
|
|
def set_attr!; self.attr = 5 end
|
|
|
|
end.new
|
|
|
|
|
|
|
|
subject.stubs(:set_attr!)
|
2014-01-17 22:01:43 +00:00
|
|
|
expect(subject).to matcher.odd
|
2013-07-10 17:05:41 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-13 01:43:36 +00:00
|
|
|
describe '#description' do
|
|
|
|
context 'without submatchers' do
|
|
|
|
it { expect(matcher.description).to eq 'only allow numbers for attr' }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with only integer option' do
|
2014-02-27 03:26:37 +00:00
|
|
|
it do
|
|
|
|
expect(matcher.only_integer.description)
|
|
|
|
.to eq 'only allow integers for attr'
|
|
|
|
end
|
2014-01-13 01:43:36 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
[:odd, :even].each do |type|
|
|
|
|
context "with #{type} option" do
|
2014-02-27 03:26:37 +00:00
|
|
|
it do
|
|
|
|
expect(matcher.__send__(type).description)
|
|
|
|
.to eq "only allow #{type} numbers for attr"
|
|
|
|
end
|
2014-01-13 01:43:36 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
[:is_greater_than,
|
|
|
|
:is_greater_than_or_equal_to,
|
|
|
|
:is_less_than,
|
|
|
|
:is_less_than_or_equal_to,
|
2014-01-13 01:43:36 +00:00
|
|
|
:is_equal_to ].each do |comparison|
|
|
|
|
context "with #{comparison} option" do
|
2014-02-27 03:26:37 +00:00
|
|
|
it do
|
|
|
|
expect(matcher.__send__(comparison, 18).description)
|
|
|
|
.to eq(
|
|
|
|
'only allow numbers for attr which are ' +
|
|
|
|
"#{comparison.to_s.sub('is_', '').gsub('_', ' ')} 18"
|
|
|
|
)
|
|
|
|
end
|
2014-01-13 01:43:36 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with odd, is_greater_than_or_equal_to option' do
|
2014-02-27 03:26:37 +00:00
|
|
|
it do
|
|
|
|
expect(matcher.odd.is_greater_than_or_equal_to(18).description)
|
|
|
|
.to eq(
|
|
|
|
'only allow odd numbers for attr ' +
|
|
|
|
'which are greater than or equal to 18'
|
|
|
|
)
|
|
|
|
end
|
2014-01-13 01:43:36 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'with only integer, is_greater_than and less_than_or_equal_to option' do
|
|
|
|
it { expect(matcher.only_integer.is_greater_than(18).is_less_than_or_equal_to(100).description).
|
|
|
|
to eq "only allow integers for attr which are greater than 18 and less than or equal to 100" }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
def validating_numericality(options = {})
|
2014-01-17 20:20:44 +00:00
|
|
|
define_model :example, attr: :string do
|
2012-12-20 05:04:27 +00:00
|
|
|
validates_numericality_of :attr, options
|
|
|
|
end.new
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|
|
|
|
|
2014-01-13 01:43:36 +00:00
|
|
|
def not_validating_numericality
|
|
|
|
define_model(:example, attr: :string).new
|
|
|
|
end
|
|
|
|
|
2012-12-20 05:04:27 +00:00
|
|
|
def matcher
|
|
|
|
validate_numericality_of(:attr)
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
2010-12-13 22:28:59 +00:00
|
|
|
end
|