Skip to content

Commit

Permalink
Allow nil on size and inclusion validations. (#299)
Browse files Browse the repository at this point in the history
* Allow nil on size and inclusion validations.

* Update spec/validations_spec.cr

Co-Authored-By: Paul Smith <[email protected]>

* Update spec/validations_spec.cr

Co-Authored-By: Paul Smith <[email protected]>

* Add a nil-specific overload for validate_inclusion_of.

* Better method description for validate_inclusion_of with nil.

* Allow nil on validate_inclusion_of.

Co-authored-by: Paul Smith <[email protected]>
  • Loading branch information
wout and paulcsmith authored Feb 9, 2020
1 parent 4c08977 commit 7927e16
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 18 deletions.
38 changes: 33 additions & 5 deletions spec/validations_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,26 @@ describe Avram::Validations do
describe "validate_inclusion_of" do
it "validates" do
allowed_name = attribute("Jamie")
Avram::Validations.validate_inclusion_of allowed_name, in: ["Jamie"]
Avram::Validations.validate_inclusion_of(allowed_name, in: ["Jamie"])
allowed_name.valid?.should be_true

forbidden_name = attribute("123123123")
Avram::Validations.validate_inclusion_of forbidden_name, in: ["Jamie"]
Avram::Validations.validate_inclusion_of(forbidden_name, in: ["Jamie"])
forbidden_name.errors.should eq(["is invalid"])
end

it "can allow nil" do
nil_name = Avram::Attribute(String?).new(value: nil, param: nil, param_key: "fake", name: :fake)

Avram::Validations.validate_inclusion_of(nil_name, in: ["Jamie"], allow_nil: true)
nil_name.valid?.should be_true

Avram::Validations.validate_inclusion_of(nil_name, in: ["Jamie"], allow_nil: false)
nil_name.valid?.should be_false

Avram::Validations.validate_inclusion_of(nil_name, in: ["Jamie"])
nil_name.valid?.should be_false
end
end

describe "validate_size_of" do
Expand All @@ -218,9 +231,9 @@ describe Avram::Validations do
Avram::Validations.validate_size_of(too_short_attribute, min: 2)
too_short_attribute.errors.should eq(["is too short"])

too_long_attribute = attribute("P")
Avram::Validations.validate_size_of(too_long_attribute, min: 2)
too_long_attribute.errors.should eq(["is too short"])
too_long_attribute = attribute("Supercalifragilisticexpialidocious")
Avram::Validations.validate_size_of(too_long_attribute, max: 32)
too_long_attribute.errors.should eq(["is too long"])

just_right_attribute = attribute("Goldilocks")
Avram::Validations.validate_size_of(just_right_attribute, is: 10)
Expand All @@ -233,5 +246,20 @@ describe Avram::Validations do
Avram::Validations.validate_size_of does_not_matter, min: 4, max: 1
end
end

it "can allow nil" do
just_nil = attribute(nil)
Avram::Validations.validate_size_of(just_nil, is: 10, allow_nil: true)
just_nil.valid?.should be_true

Avram::Validations.validate_size_of(just_nil, min: 1, max: 2, allow_nil: true)
just_nil.valid?.should be_true

Avram::Validations.validate_size_of(just_nil, is: 10)
just_nil.valid?.should be_false

Avram::Validations.validate_size_of(just_nil, min: 1, max: 2)
just_nil.valid?.should be_false
end
end
end
42 changes: 29 additions & 13 deletions src/avram/validations.cr
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ module Avram::Validations
def validate_inclusion_of(
attribute : Avram::Attribute(T),
in allowed_values : Enumerable(T),
message : Avram::Attribute::ErrorMessage = "is invalid"
message : Avram::Attribute::ErrorMessage = "is invalid",
allow_nil : Bool = false
) forall T
if !allowed_values.includes? attribute.value
attribute.add_error message
unless allowed_values.includes? attribute.value
attribute.add_error message unless allow_nil && attribute.value.nil?
end
end

Expand All @@ -108,9 +109,15 @@ module Avram::Validations
# ```
# validate_size_of api_key, is: 32
# ```
def validate_size_of(attribute : Avram::Attribute, *, is exact_size, message : Avram::Attribute::ErrorMessage = "is invalid")
def validate_size_of(
attribute : Avram::Attribute,
*,
is exact_size,
message : Avram::Attribute::ErrorMessage = "is invalid",
allow_nil : Bool = false
)
if attribute.value.to_s.size != exact_size
attribute.add_error message
attribute.add_error message unless allow_nil && attribute.value.nil?
end
end

Expand All @@ -120,19 +127,28 @@ module Avram::Validations
# validate_size_of age, min: 18, max: 100
# validate_size_of account_balance, min: 500
# ```
def validate_size_of(attribute : Avram::Attribute, min = nil, max = nil)
def validate_size_of(
attribute : Avram::Attribute,
min = nil,
max = nil,
allow_nil : Bool = false
)
if !min.nil? && !max.nil? && min > max
raise ImpossibleValidation.new(attribute: attribute.name, message: "size greater than #{min} but less than #{max}")
raise ImpossibleValidation.new(
attribute: attribute.name,
message: "size greater than #{min} but less than #{max}")
end

size = attribute.value.to_s.size
unless allow_nil && attribute.value.nil?
size = attribute.value.to_s.size

if !min.nil? && size < min
attribute.add_error "is too short"
end
if !min.nil? && size < min
attribute.add_error "is too short"
end

if !max.nil? && size > max
attribute.add_error "is too long"
if !max.nil? && size > max
attribute.add_error "is too long"
end
end
end

Expand Down

0 comments on commit 7927e16

Please sign in to comment.