-
-
Notifications
You must be signed in to change notification settings - Fork 910
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
in: range
matcher to validate_numericality_of
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.
- Loading branch information
1 parent
f029d26
commit 14379aa
Showing
7 changed files
with
336 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
require 'active_support/core_ext/module/delegation' | ||
|
||
module Shoulda | ||
module Matchers | ||
module ActiveModel | ||
module NumericalityMatchers | ||
# @private | ||
class RangeMatcher < ValidationMatcher | ||
OPERATORS = [:>=, :<=].freeze | ||
|
||
delegate :failure_message, to: :submatchers | ||
|
||
def initialize(numericality_matcher, attribute, range) | ||
super(attribute) | ||
unless numericality_matcher.respond_to? :diff_to_compare | ||
raise ArgumentError, 'numericality_matcher is invalid' | ||
end | ||
|
||
@numericality_matcher = numericality_matcher | ||
@range = range | ||
@attribute = attribute | ||
end | ||
|
||
def matches?(subject) | ||
@subject = subject | ||
submatchers.matches?(subject) | ||
end | ||
|
||
def simple_description | ||
description = '' | ||
|
||
if expects_strict? | ||
description << ' strictly' | ||
end | ||
|
||
description + | ||
"disallow :#{attribute} from being a number that is not " + | ||
range_description | ||
end | ||
|
||
def range_description | ||
"from #{Shoulda::Matchers::Util.inspect_range(@range)}" | ||
end | ||
|
||
def submatchers | ||
@_submatchers ||= NumericalityMatchers::Submatchers.new(build_submatchers) | ||
end | ||
|
||
private | ||
|
||
def build_submatchers | ||
submatcher_combos.map do |value, operator| | ||
build_comparison_submatcher(value, operator) | ||
end | ||
end | ||
|
||
def submatcher_combos | ||
@range.minmax.zip(OPERATORS) | ||
end | ||
|
||
def build_comparison_submatcher(value, operator) | ||
NumericalityMatchers::ComparisonMatcher.new(@numericality_matcher, value, operator). | ||
for(@attribute). | ||
with_message(@message). | ||
on(@context) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
43 changes: 43 additions & 0 deletions
43
lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.