2014-01-23 18:07:36 +00:00
|
|
|
module Shoulda
|
2010-12-15 22:34:19 +00:00
|
|
|
module Matchers
|
2014-01-23 18:07:36 +00:00
|
|
|
module ActiveModel
|
|
|
|
# The `validate_numericality_of` matcher tests usage of the
|
|
|
|
# `validates_numericality_of` validation.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :gpa
|
|
|
|
#
|
|
|
|
# validates_numericality_of :gpa
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it { should validate_numericality_of(:gpa) }
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:gpa)
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# #### Qualifiers
|
|
|
|
#
|
2015-03-28 15:03:31 +00:00
|
|
|
# ##### on
|
|
|
|
#
|
|
|
|
# Use `on` if your validation applies only under a certain context.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :number_of_dependents
|
|
|
|
#
|
|
|
|
# validates_numericality_of :number_of_dependents, on: :create
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it do
|
|
|
|
# should validate_numericality_of(:number_of_dependents).
|
|
|
|
# on(:create)
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2015-03-28 15:03:31 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:number_of_dependents).on(:create)
|
|
|
|
# end
|
|
|
|
#
|
2014-01-23 18:07:36 +00:00
|
|
|
# ##### only_integer
|
|
|
|
#
|
|
|
|
# Use `only_integer` to test usage of the `:only_integer` option. This
|
|
|
|
# asserts that your attribute only allows integer numbers and disallows
|
|
|
|
# non-integer ones.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :age
|
|
|
|
#
|
|
|
|
# validates_numericality_of :age, only_integer: true
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it { should validate_numericality_of(:age).only_integer }
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:age).only_integer
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### is_less_than
|
|
|
|
#
|
|
|
|
# Use `is_less_than` to test usage of the the `:less_than` option. This
|
|
|
|
# asserts that the attribute can take a number which is less than the
|
|
|
|
# given value and cannot take a number which is greater than or equal to
|
|
|
|
# it.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :number_of_cars
|
|
|
|
#
|
|
|
|
# validates_numericality_of :number_of_cars, less_than: 2
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it do
|
|
|
|
# should validate_numericality_of(:number_of_cars).
|
|
|
|
# is_less_than(2)
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:number_of_cars).
|
|
|
|
# is_less_than(2)
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### is_less_than_or_equal_to
|
|
|
|
#
|
|
|
|
# Use `is_less_than_or_equal_to` to test usage of the
|
|
|
|
# `:less_than_or_equal_to` option. This asserts that the attribute can
|
|
|
|
# take a number which is less than or equal to the given value and cannot
|
|
|
|
# take a number which is greater than it.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :birth_year
|
|
|
|
#
|
|
|
|
# validates_numericality_of :birth_year, less_than_or_equal_to: 1987
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it do
|
|
|
|
# should validate_numericality_of(:birth_year).
|
|
|
|
# is_less_than_or_equal_to(1987)
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:birth_year).
|
|
|
|
# is_less_than_or_equal_to(1987)
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### is_equal_to
|
|
|
|
#
|
|
|
|
# Use `is_equal_to` to test usage of the `:equal_to` option. This asserts
|
|
|
|
# that the attribute can take a number which is equal to the given value
|
|
|
|
# and cannot take a number which is not equal.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :weight
|
|
|
|
#
|
|
|
|
# validates_numericality_of :weight, equal_to: 150
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it { should validate_numericality_of(:weight).is_equal_to(150) }
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:weight).is_equal_to(150)
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### is_greater_than_or_equal_to
|
|
|
|
#
|
|
|
|
# Use `is_greater_than_or_equal_to` to test usage of the
|
|
|
|
# `:greater_than_or_equal_to` option. This asserts that the attribute can
|
|
|
|
# take a number which is greater than or equal to the given value and
|
|
|
|
# cannot take a number which is less than it.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :height
|
|
|
|
#
|
|
|
|
# validates_numericality_of :height, greater_than_or_equal_to: 55
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it do
|
|
|
|
# should validate_numericality_of(:height).
|
|
|
|
# is_greater_than_or_equal_to(55)
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:height).
|
|
|
|
# is_greater_than_or_equal_to(55)
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### is_greater_than
|
|
|
|
#
|
2015-10-07 12:42:25 +00:00
|
|
|
# Use `is_greater_than` to test usage of the `:greater_than` option.
|
2014-01-23 18:07:36 +00:00
|
|
|
# This asserts that the attribute can take a number which is greater than
|
|
|
|
# the given value and cannot take a number less than or equal to it.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :legal_age
|
|
|
|
#
|
|
|
|
# validates_numericality_of :legal_age, greater_than: 21
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it do
|
|
|
|
# should validate_numericality_of(:legal_age).
|
|
|
|
# is_greater_than(21)
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:legal_age).
|
|
|
|
# is_greater_than(21)
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### even
|
|
|
|
#
|
|
|
|
# Use `even` to test usage of the `:even` option. This asserts that the
|
|
|
|
# attribute can take odd numbers and cannot take even ones.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :birth_month
|
|
|
|
#
|
|
|
|
# validates_numericality_of :birth_month, even: true
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it { should validate_numericality_of(:birth_month).even }
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:birth_month).even
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### odd
|
|
|
|
#
|
|
|
|
# Use `odd` to test usage of the `:odd` option. This asserts that the
|
|
|
|
# attribute can take a number which is odd and cannot take a number which
|
|
|
|
# is even.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :birth_day
|
|
|
|
#
|
|
|
|
# validates_numericality_of :birth_day, odd: true
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it { should validate_numericality_of(:birth_day).odd }
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:birth_day).odd
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### with_message
|
|
|
|
#
|
|
|
|
# Use `with_message` if you are using a custom validation message.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :number_of_dependents
|
|
|
|
#
|
|
|
|
# validates_numericality_of :number_of_dependents,
|
|
|
|
# message: 'Number of dependents must be a number'
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Person do
|
|
|
|
# it do
|
|
|
|
# should validate_numericality_of(:number_of_dependents).
|
|
|
|
# with_message('Number of dependents must be a number')
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PersonTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:number_of_dependents).
|
|
|
|
# with_message('Number of dependents must be a number')
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# ##### allow_nil
|
|
|
|
#
|
|
|
|
# Use `allow_nil` to assert that the attribute allows nil.
|
|
|
|
#
|
|
|
|
# class Age
|
|
|
|
# include ActiveModel::Model
|
|
|
|
# attr_accessor :age
|
|
|
|
#
|
|
|
|
# validates_numericality_of :age, allow_nil: true
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# # RSpec
|
|
|
|
# describe Post do
|
|
|
|
# it { should validate_numericality_of(:age).allow_nil }
|
|
|
|
# end
|
|
|
|
#
|
2015-09-30 19:15:23 +00:00
|
|
|
# # Minitest (Shoulda)
|
2014-01-23 18:07:36 +00:00
|
|
|
# class PostTest < ActiveSupport::TestCase
|
|
|
|
# should validate_numericality_of(:age).allow_nil
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# @return [ValidateNumericalityOfMatcher]
|
2010-12-15 22:34:19 +00:00
|
|
|
#
|
|
|
|
def validate_numericality_of(attr)
|
|
|
|
ValidateNumericalityOfMatcher.new(attr)
|
|
|
|
end
|
|
|
|
|
2014-01-23 18:07:36 +00:00
|
|
|
# @private
|
2012-10-16 17:45:06 +00:00
|
|
|
class ValidateNumericalityOfMatcher
|
2014-01-13 01:43:36 +00:00
|
|
|
NUMERIC_NAME = 'numbers'
|
2012-10-23 16:30:18 +00:00
|
|
|
NON_NUMERIC_VALUE = 'abcd'
|
2014-04-26 15:13:57 +00:00
|
|
|
DEFAULT_DIFF_TO_COMPARE = 1
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
attr_reader :diff_to_compare
|
2012-10-23 16:30:18 +00:00
|
|
|
|
2012-04-24 22:00:26 +00:00
|
|
|
def initialize(attribute)
|
2012-10-16 17:45:06 +00:00
|
|
|
@attribute = attribute
|
|
|
|
@submatchers = []
|
2014-02-27 03:26:37 +00:00
|
|
|
@diff_to_compare = DEFAULT_DIFF_TO_COMPARE
|
2014-12-03 22:06:23 +00:00
|
|
|
@strict = false
|
2015-10-07 05:12:30 +00:00
|
|
|
|
2012-10-16 17:45:06 +00:00
|
|
|
add_disallow_value_matcher
|
2012-04-24 22:00:26 +00:00
|
|
|
end
|
2011-10-27 02:21:06 +00:00
|
|
|
|
2014-12-03 22:06:23 +00:00
|
|
|
def strict
|
|
|
|
@strict = true
|
2015-10-07 05:12:30 +00:00
|
|
|
@submatchers.each(&:strict)
|
2014-12-03 22:06:23 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2011-10-27 02:21:06 +00:00
|
|
|
def only_integer
|
2014-02-27 03:26:37 +00:00
|
|
|
prepare_submatcher(
|
2015-10-07 05:12:30 +00:00
|
|
|
NumericalityMatchers::OnlyIntegerMatcher.new(self, @attribute)
|
2014-02-27 03:26:37 +00:00
|
|
|
)
|
2013-02-19 10:09:13 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-21 22:31:48 +00:00
|
|
|
def allow_nil
|
2014-02-27 03:26:37 +00:00
|
|
|
prepare_submatcher(
|
|
|
|
AllowValueMatcher.new(nil)
|
|
|
|
.for(@attribute)
|
|
|
|
.with_message(:not_a_number)
|
|
|
|
)
|
2014-02-21 22:31:48 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def odd
|
|
|
|
prepare_submatcher(
|
2015-10-07 05:12:30 +00:00
|
|
|
NumericalityMatchers::OddNumberMatcher.new(self, @attribute)
|
2014-02-27 03:26:37 +00:00
|
|
|
)
|
2013-02-19 10:09:13 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def even
|
|
|
|
prepare_submatcher(
|
2015-10-07 05:12:30 +00:00
|
|
|
NumericalityMatchers::EvenNumberMatcher.new(self, @attribute)
|
2014-02-27 03:26:37 +00:00
|
|
|
)
|
2013-02-19 10:09:13 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def is_greater_than(value)
|
|
|
|
prepare_submatcher(comparison_matcher_for(value, :>).for(@attribute))
|
2013-02-19 10:09:13 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def is_greater_than_or_equal_to(value)
|
|
|
|
prepare_submatcher(comparison_matcher_for(value, :>=).for(@attribute))
|
2013-02-19 10:09:13 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def is_equal_to(value)
|
|
|
|
prepare_submatcher(comparison_matcher_for(value, :==).for(@attribute))
|
2011-10-27 02:21:06 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def is_less_than(value)
|
|
|
|
prepare_submatcher(comparison_matcher_for(value, :<).for(@attribute))
|
2013-03-19 04:50:39 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def is_less_than_or_equal_to(value)
|
|
|
|
prepare_submatcher(comparison_matcher_for(value, :<=).for(@attribute))
|
2013-03-19 04:50:39 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2010-12-15 22:34:19 +00:00
|
|
|
def with_message(message)
|
2012-10-23 16:30:18 +00:00
|
|
|
@submatchers.each { |matcher| matcher.with_message(message) }
|
2010-12-15 22:34:19 +00:00
|
|
|
self
|
2015-04-01 06:00:14 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def on(context)
|
|
|
|
@submatchers.each { |matcher| matcher.on(context) }
|
|
|
|
self
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def matches?(subject)
|
2012-10-16 17:45:06 +00:00
|
|
|
@subject = subject
|
2015-10-07 05:12:30 +00:00
|
|
|
|
|
|
|
if given_numeric_column?
|
|
|
|
remove_disallow_value_matcher
|
|
|
|
end
|
|
|
|
|
|
|
|
if @submatchers.empty?
|
|
|
|
raise IneffectiveTestError.create(
|
|
|
|
model: @subject.class,
|
|
|
|
attribute: @attribute,
|
|
|
|
column_type: column_type
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2015-04-09 14:27:26 +00:00
|
|
|
first_failing_submatcher.nil?
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def description
|
2014-12-03 22:06:23 +00:00
|
|
|
description_parts = ["only allow #{allowed_types} for #{@attribute}"]
|
|
|
|
|
|
|
|
if comparison_descriptions.present?
|
|
|
|
description_parts << comparison_descriptions
|
|
|
|
end
|
|
|
|
|
|
|
|
if @strict
|
|
|
|
description_parts.insert(1, 'strictly')
|
|
|
|
description_parts.join(', ')
|
|
|
|
else
|
|
|
|
description_parts.join(' ')
|
|
|
|
end
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
|
2013-12-24 11:24:27 +00:00
|
|
|
def failure_message
|
2015-04-09 14:27:26 +00:00
|
|
|
first_failing_submatcher.failure_message
|
2013-04-12 17:11:07 +00:00
|
|
|
end
|
|
|
|
|
2013-12-24 11:24:27 +00:00
|
|
|
def failure_message_when_negated
|
2015-04-09 14:27:26 +00:00
|
|
|
first_failing_submatcher.failure_message_when_negated
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
2015-10-07 05:12:30 +00:00
|
|
|
def given_numeric_column?
|
|
|
|
[:integer, :float].include?(column_type)
|
|
|
|
end
|
|
|
|
|
2012-03-30 14:36:55 +00:00
|
|
|
private
|
|
|
|
|
2015-10-07 05:12:30 +00:00
|
|
|
def column_type
|
|
|
|
if @subject.class.respond_to?(:columns_hash)
|
|
|
|
@subject.class.columns_hash[@attribute.to_s].type
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-10-16 17:45:06 +00:00
|
|
|
def add_disallow_value_matcher
|
2012-10-23 16:30:18 +00:00
|
|
|
disallow_value_matcher = DisallowValueMatcher.new(NON_NUMERIC_VALUE).
|
|
|
|
for(@attribute).
|
|
|
|
with_message(:not_a_number)
|
|
|
|
|
|
|
|
add_submatcher(disallow_value_matcher)
|
2012-04-04 00:20:50 +00:00
|
|
|
end
|
|
|
|
|
2015-10-07 05:12:30 +00:00
|
|
|
def remove_disallow_value_matcher
|
|
|
|
@submatchers.shift
|
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def prepare_submatcher(submatcher)
|
|
|
|
add_submatcher(submatcher)
|
2015-10-07 05:12:30 +00:00
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
if submatcher.respond_to?(:diff_to_compare)
|
|
|
|
update_diff_to_compare(submatcher)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def comparison_matcher_for(value, operator)
|
|
|
|
NumericalityMatchers::ComparisonMatcher
|
|
|
|
.new(self, value, operator)
|
|
|
|
.for(@attribute)
|
|
|
|
end
|
|
|
|
|
2012-10-16 17:45:06 +00:00
|
|
|
def add_submatcher(submatcher)
|
|
|
|
@submatchers << submatcher
|
2011-10-27 02:21:06 +00:00
|
|
|
end
|
|
|
|
|
2014-02-27 03:26:37 +00:00
|
|
|
def update_diff_to_compare(matcher)
|
|
|
|
@diff_to_compare = [@diff_to_compare, matcher.diff_to_compare].max
|
|
|
|
end
|
|
|
|
|
2015-04-09 14:27:26 +00:00
|
|
|
def first_failing_submatcher
|
|
|
|
@_first_failing_submatcher ||= @submatchers.detect do |submatcher|
|
|
|
|
!submatcher.matches?(@subject)
|
|
|
|
end
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def allowed_types
|
2014-01-13 01:43:36 +00:00
|
|
|
allowed_array = submatcher_allowed_types
|
|
|
|
allowed_array.empty? ? NUMERIC_NAME : allowed_array.join(', ')
|
2012-10-16 17:45:06 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def submatcher_allowed_types
|
2014-01-13 01:43:36 +00:00
|
|
|
@submatchers.inject([]){|m, s| m << s.allowed_type if s.respond_to?(:allowed_type); m }
|
|
|
|
end
|
|
|
|
|
|
|
|
def comparison_descriptions
|
|
|
|
description_array = submatcher_comparison_descriptions
|
2014-12-03 22:06:23 +00:00
|
|
|
description_array.empty? ? '' : 'which are ' + submatcher_comparison_descriptions.join(' and ')
|
2014-01-13 01:43:36 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def submatcher_comparison_descriptions
|
2014-02-27 03:26:37 +00:00
|
|
|
@submatchers.inject([]) do |arr, submatcher|
|
|
|
|
if submatcher.respond_to? :comparison_description
|
|
|
|
arr << submatcher.comparison_description
|
|
|
|
end
|
|
|
|
arr
|
|
|
|
end
|
2012-03-30 14:36:55 +00:00
|
|
|
end
|
2015-10-07 05:12:30 +00:00
|
|
|
|
|
|
|
class IneffectiveTestError < Shoulda::Matchers::Error
|
|
|
|
attr_accessor :model, :attribute, :column_type
|
|
|
|
|
|
|
|
def message
|
2015-10-09 05:44:23 +00:00
|
|
|
Shoulda::Matchers.word_wrap <<-MESSAGE
|
2015-10-07 05:12:30 +00:00
|
|
|
You are attempting to use validate_numericality_of, but the attribute you're
|
2015-10-09 05:44:23 +00:00
|
|
|
testing, :#{attribute}, is #{a_or_an(column_type)} column. One of the things
|
|
|
|
that the numericality matcher does is to assert that setting :#{attribute} to a
|
|
|
|
string that doesn't look like #{a_or_an(column_type)} will cause your
|
2015-10-07 05:12:30 +00:00
|
|
|
#{humanized_model_name} to become invalid. In this case, it's impossible to make
|
2015-10-09 05:44:23 +00:00
|
|
|
this assertion since :#{attribute} will typecast any incoming value to
|
|
|
|
#{a_or_an(column_type)}. This means that it's already guaranteed to be numeric!
|
2015-10-07 05:12:30 +00:00
|
|
|
Since this matcher isn't doing anything, you can remove it from your model
|
|
|
|
tests, and in fact, you can remove the validation from your model as it isn't
|
|
|
|
doing anything either.
|
2015-10-09 05:44:23 +00:00
|
|
|
MESSAGE
|
2015-10-07 05:12:30 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def humanized_model_name
|
|
|
|
model.name.humanize.downcase
|
|
|
|
end
|
2015-10-09 05:44:23 +00:00
|
|
|
|
|
|
|
def a_or_an(next_word)
|
|
|
|
if next_word =~ /[aeiou]/
|
|
|
|
"an #{next_word}"
|
|
|
|
else
|
|
|
|
"a #{next_word}"
|
|
|
|
end
|
|
|
|
end
|
2015-10-07 05:12:30 +00:00
|
|
|
end
|
2012-03-30 14:36:55 +00:00
|
|
|
end
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|