Skip to content

Commit

Permalink
Support infinite ranges for LengthValidators :in/:within options
Browse files Browse the repository at this point in the history
  • Loading branch information
fatkodima committed May 20, 2022
1 parent 9868a26 commit 91cd5cb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
8 changes: 8 additions & 0 deletions activemodel/CHANGELOG.md
@@ -1,3 +1,11 @@
* Support infinite ranges for `LengthValidator`s `:in`/`:within` options

```ruby
validates_length_of :first_name, in: ..30
```

*fatkodima*

* Add support for beginless ranges to inclusivity/exclusivity validators:

```ruby
Expand Down
7 changes: 5 additions & 2 deletions activemodel/lib/active_model/validations/length.rb
Expand Up @@ -15,7 +15,8 @@ class LengthValidator < EachValidator # :nodoc:
def initialize(options)
if range = (options.delete(:in) || options.delete(:within))
raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
options[:minimum], options[:maximum] = range.min, range.max
options[:minimum] = range.min if range.begin
options[:maximum] = (range.exclude_end? ? range.end - 1 : range.end) if range.end
end

if options[:allow_blank] == false && options[:minimum].nil? && options[:is].nil?
Expand All @@ -35,7 +36,9 @@ def check_validity!
keys.each do |key|
value = options[key]

unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc)
unless (value.is_a?(Integer) && value >= 0) ||
value == Float::INFINITY || value == -Float::INFINITY ||
value.is_a?(Symbol) || value.is_a?(Proc)
raise ArgumentError, ":#{key} must be a non-negative Integer, Infinity, Symbol, or Proc"
end
end
Expand Down
25 changes: 25 additions & 0 deletions activemodel/test/cases/validations/length_validation_test.rb
Expand Up @@ -124,6 +124,31 @@ def test_validates_length_of_using_within_with_exclusive_range
assert_predicate t, :valid?
end

def test_validates_length_of_using_within_with_infinite_ranges
[
[-Float::INFINITY..10, 11],
[-Float::INFINITY...11, 11],
[-Float::INFINITY.., nil],
[10..Float::INFINITY, 9],
[10...Float::INFINITY, 9],
[10.., 9],
[..10, 11],
[...11, 11],
[-Float::INFINITY..Float::INFINITY, nil],
].each do |range, invalid_length|
Topic.clear_validators!
Topic.validates_length_of(:title, within: range)

t = Topic.new("title" => "a" * 10)
assert_predicate t, :valid?

if invalid_length
t.title = "a" * invalid_length
assert_predicate t, :invalid?
end
end
end

def test_optionally_validates_length_of_using_within
Topic.validates_length_of :title, :content, within: 3..5, allow_nil: true

Expand Down

0 comments on commit 91cd5cb

Please sign in to comment.