thoughtbot--shoulda-matchers/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb

44 lines
979 B
Ruby
Raw Normal View History

Add `in: range` matcher to validate_numericality_of (#1512) Closes: #1493 In Rails 7 was added a new option to validate numericality. You can use `in: range` to specify a range to validate an attribute. ```ruby class User < ApplicationRecord validates :age, numericality: { greater_than_or_equal_to: 18, less_than_or_equal_to: 65 } end class User < ApplicationRecord validates :age, numericality: { in: 18..65 } end ``` In this commit we are adding the support matcher to this new functionality, while also making a refactor on the numericality matchers that use the concept of submatchers. We've created a new class (`NumericalityMatchers::Submatcher`) that's been used by `NumericalityMatchers::RangeMatcher` and `NumericalityMatchers::ComparisonMatcher`, this new class wil handle shared logic regarding having submatchers that will check if the parent matcher is valid or not. Our new class `Numericality::Matchers::RangeMatcher` is using as submatchers two `NumericalityMatchers::ComparisonMatcher` instances to avoid creating new logic to handle this new option and also to replicate what was being used before this option existed in Rails (see example above) In this commit we are adding: * NumericalityMatchers::RangeMatcher file to support the new `in: range` option. * Specs on ValidateNumericalityOfMatcherSpec file for the new supported option, only running on rails_versions > 7. * NumericalityMatchers::Submatchers file to handle having submatchers inside a matcher file. * Refactors to NumericalityMatchers::ComparisonMatcher.
2022-10-29 11:17:09 +00:00
module Shoulda
module Matchers
module ActiveModel
module NumericalityMatchers
# @private
class Submatchers
def initialize(submatchers)
@submatchers = submatchers
end
def matches?(subject)
@subject = subject
failing_submatchers.empty?
end
def failure_message
last_failing_submatcher.failure_message
end
def failure_message_when_negated
last_failing_submatcher.failure_message_when_negated
end
def add(submatcher)
@submatchers << submatcher
end
def last_failing_submatcher
failing_submatchers.last
end
private
def failing_submatchers
@_failing_submatchers ||= @submatchers.reject do |submatcher|
submatcher.matches?(@subject)
end
end
end
end
end
end
end