Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow nil on size and inclusion validations. #299

Merged
merged 7 commits into from
Feb 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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