mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Add #on qualifier to numericality matcher
This is present in all other matchers through ValidationMatcher. However, ValidateNumericalityOfMatcher does not inherit from ValidationMatcher. (This happens to be okay, since ValidateNumericalityOfMatcher contains submatchers and we have to make sure to pass the context all the way through.) Hat tip @sj26 for most of the content of this commit, as well as @anujbiyani for another approach to this.
This commit is contained in:
parent
aab1aa5bc1
commit
9748869091
8 changed files with 128 additions and 1 deletions
4
NEWS.md
4
NEWS.md
|
@ -70,6 +70,8 @@
|
||||||
|
|
||||||
* Add `strict` qualifier to `validate_numericality_of`. ([#620])
|
* Add `strict` qualifier to `validate_numericality_of`. ([#620])
|
||||||
|
|
||||||
|
* Add `on` qualifier to `validate_numericality_of`. (h/t [#356], [#358])
|
||||||
|
|
||||||
[#402]: https://github.com/thoughtbot/shoulda-matchers/pull/402
|
[#402]: https://github.com/thoughtbot/shoulda-matchers/pull/402
|
||||||
[#587]: https://github.com/thoughtbot/shoulda-matchers/pull/587
|
[#587]: https://github.com/thoughtbot/shoulda-matchers/pull/587
|
||||||
[#662]: https://github.com/thoughtbot/shoulda-matchers/pull/662
|
[#662]: https://github.com/thoughtbot/shoulda-matchers/pull/662
|
||||||
|
@ -82,6 +84,8 @@
|
||||||
[#677]: https://github.com/thoughtbot/shoulda-matchers/pull/677
|
[#677]: https://github.com/thoughtbot/shoulda-matchers/pull/677
|
||||||
[#620]: https://github.com/thoughtbot/shoulda-matchers/pull/620
|
[#620]: https://github.com/thoughtbot/shoulda-matchers/pull/620
|
||||||
[#693]: https://github.com/thoughtbot/shoulda-matchers/pull/693
|
[#693]: https://github.com/thoughtbot/shoulda-matchers/pull/693
|
||||||
|
[#356]: https://github.com/thoughtbot/shoulda-matchers/pull/356
|
||||||
|
[#358]: https://github.com/thoughtbot/shoulda-matchers/pull/358
|
||||||
|
|
||||||
# 2.8.0
|
# 2.8.0
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@ module Shoulda
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on(context)
|
||||||
|
@disallow_value_matcher.on(context)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
def allowed_type
|
def allowed_type
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
|
@ -384,6 +384,11 @@ module Shoulda
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def on(context)
|
||||||
|
@submatchers.each { |matcher| matcher.on(context) }
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
def matches?(subject)
|
def matches?(subject)
|
||||||
@subject = subject
|
@subject = subject
|
||||||
failing_submatchers.empty?
|
failing_submatchers.empty?
|
||||||
|
|
|
@ -197,6 +197,26 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'qualified with on and validating with on' do
|
||||||
|
it 'accepts' do
|
||||||
|
expect(instance_with_validations(on: :customizable)).
|
||||||
|
to matcher.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'qualified with on but not validating with on' do
|
||||||
|
it 'accepts since the validation never considers a context' do
|
||||||
|
expect(instance_with_validations).to matcher.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not qualified with on but validating with on' do
|
||||||
|
it 'rejects since the validation never runs' do
|
||||||
|
expect(instance_with_validations(on: :customizable)).
|
||||||
|
not_to matcher
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#comparison_description' do
|
describe '#comparison_description' do
|
||||||
[{ operator: :>, value: 0, expectation: 'greater than 0' },
|
[{ operator: :>, value: 0, expectation: 'greater than 0' },
|
||||||
{ operator: :>=, value: -1.0, expectation: 'greater than or equal to -1.0' },
|
{ operator: :>=, value: -1.0, expectation: 'greater than or equal to -1.0' },
|
||||||
|
|
|
@ -64,6 +64,26 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::EvenNumberMatcher
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'qualified with on and validating with on' do
|
||||||
|
it 'accepts' do
|
||||||
|
expect(validating_even_number(on: :customizable)).
|
||||||
|
to subject.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'qualified with on but not validating with on' do
|
||||||
|
it 'accepts since the validation never considers a context' do
|
||||||
|
expect(validating_even_number).to subject.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not qualified with on but validating with on' do
|
||||||
|
it 'rejects since the validation never runs' do
|
||||||
|
expect(validating_even_number(on: :customizable)).
|
||||||
|
not_to subject
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def validating_even_number(options = {})
|
def validating_even_number(options = {})
|
||||||
define_model :example, attr: :string do
|
define_model :example, attr: :string do
|
||||||
validates_numericality_of :attr, { even: true }.merge(options)
|
validates_numericality_of :attr, { even: true }.merge(options)
|
||||||
|
|
|
@ -64,6 +64,26 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::OddNumberMatcher
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'qualified with on and validating with on' do
|
||||||
|
it 'accepts' do
|
||||||
|
expect(validating_odd_number(on: :customizable)).
|
||||||
|
to subject.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'qualified with on but not validating with on' do
|
||||||
|
it 'accepts since the validation never considers a context' do
|
||||||
|
expect(validating_odd_number).to subject.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not qualified with on but validating with on' do
|
||||||
|
it 'rejects since the validation never runs' do
|
||||||
|
expect(validating_odd_number(on: :customizable)).
|
||||||
|
not_to subject
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def validating_odd_number(options = {})
|
def validating_odd_number(options = {})
|
||||||
define_model :example, attr: :string do
|
define_model :example, attr: :string do
|
||||||
validates_numericality_of :attr, { odd: true }.merge(options)
|
validates_numericality_of :attr, { odd: true }.merge(options)
|
||||||
|
|
|
@ -64,6 +64,26 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::OnlyIntegerMatche
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'qualified with on and validating with on' do
|
||||||
|
it 'accepts' do
|
||||||
|
expect(validating_only_integer(on: :customizable)).
|
||||||
|
to subject.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'qualified with on but not validating with on' do
|
||||||
|
it 'accepts since the validation never considers a context' do
|
||||||
|
expect(validating_only_integer).to subject.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not qualified with on but validating with on' do
|
||||||
|
it 'rejects since the validation never runs' do
|
||||||
|
expect(validating_only_integer(on: :customizable)).
|
||||||
|
not_to subject
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def validating_only_integer(options = {})
|
def validating_only_integer(options = {})
|
||||||
define_model :example, attr: :string do
|
define_model :example, attr: :string do
|
||||||
validates_numericality_of :attr, { only_integer: true }.merge(options)
|
validates_numericality_of :attr, { only_integer: true }.merge(options)
|
||||||
|
|
|
@ -55,6 +55,12 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher, type: :m
|
||||||
name: :only_integer,
|
name: :only_integer,
|
||||||
validation_name: :only_integer,
|
validation_name: :only_integer,
|
||||||
validation_value: true,
|
validation_value: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: :on,
|
||||||
|
argument: :customizable,
|
||||||
|
validation_name: :on,
|
||||||
|
validation_value: :customizable
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
@ -454,6 +460,32 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher, type: :m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'qualified with on and validating with on' do
|
||||||
|
it 'accepts' do
|
||||||
|
record = build_record_validating_numericality(on: :customizable)
|
||||||
|
expect(record).to validate_numericality.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'qualified with on but not validating with on' do
|
||||||
|
it 'accepts since the validation never considers a context' do
|
||||||
|
record = build_record_validating_numericality
|
||||||
|
expect(record).to validate_numericality.on(:customizable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not qualified with on but validating with on' do
|
||||||
|
it 'rejects since the validation never runs' do
|
||||||
|
record = build_record_validating_numericality(on: :customizable)
|
||||||
|
assertion = lambda do
|
||||||
|
expect(record).to validate_numericality
|
||||||
|
end
|
||||||
|
expect(&assertion).to fail_with_message_including(
|
||||||
|
'Expected errors to include "is not a number"'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with combinations of qualifiers together' do
|
context 'with combinations of qualifiers together' do
|
||||||
all_qualifier_combinations.each do |combination|
|
all_qualifier_combinations.each do |combination|
|
||||||
if combination.size > 1
|
if combination.size > 1
|
||||||
|
@ -778,7 +810,8 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher, type: :m
|
||||||
end
|
end
|
||||||
|
|
||||||
def define_model_validating_numericality(options = {})
|
def define_model_validating_numericality(options = {})
|
||||||
attribute_name = options.fetch(:attribute_name) { self.attribute_name }
|
attribute_name = options.delete(:attribute_name) { self.attribute_name }
|
||||||
|
|
||||||
define_model 'Example', attribute_name => :string do |model|
|
define_model 'Example', attribute_name => :string do |model|
|
||||||
model.validates_numericality_of(attribute_name, options)
|
model.validates_numericality_of(attribute_name, options)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue