From 1e403779bb6f610318af0295677a3f89b8e85f5e Mon Sep 17 00:00:00 2001 From: "Elias J. Perez" Date: Fri, 25 Dec 2020 20:20:47 -0500 Subject: [PATCH] Renames Validators to Predicates --- README.md | 57 ++++++++++--------- spec/validation_spec.cr | 1 - spec/validators_spec.cr | 4 +- src/schema/validation.cr | 12 ++-- src/schema/validation/constraint.cr | 3 +- .../{validators.cr => predicates.cr} | 4 +- .../{validators => predicates}/equal.cr | 0 .../{validators => predicates}/exclusion.cr | 0 .../greater_than.cr | 0 .../greater_than_or_equal.cr | 0 .../{validators => predicates}/inclusion.cr | 0 .../{validators => predicates}/less_than.cr | 0 .../less_than_or_equal.cr | 0 .../{validators => predicates}/presence.cr | 0 .../regular_expression.cr | 0 .../{validators => predicates}/size.cr | 0 src/schema/validation/validator.cr | 2 +- 17 files changed, 42 insertions(+), 41 deletions(-) rename src/schema/validation/{validators.cr => predicates.cr} (85%) rename src/schema/validation/{validators => predicates}/equal.cr (100%) rename src/schema/validation/{validators => predicates}/exclusion.cr (100%) rename src/schema/validation/{validators => predicates}/greater_than.cr (100%) rename src/schema/validation/{validators => predicates}/greater_than_or_equal.cr (100%) rename src/schema/validation/{validators => predicates}/inclusion.cr (100%) rename src/schema/validation/{validators => predicates}/less_than.cr (100%) rename src/schema/validation/{validators => predicates}/less_than_or_equal.cr (100%) rename src/schema/validation/{validators => predicates}/presence.cr (100%) rename src/schema/validation/{validators => predicates}/regular_expression.cr (100%) rename src/schema/validation/{validators => predicates}/size.cr (100%) diff --git a/README.md b/README.md index 73e2ddd..1fac89d 100644 --- a/README.md +++ b/README.md @@ -167,8 +167,7 @@ class User < Model property childrens : Array(String) property childrens_ages : Array(Int32) - # To use a custom validator, this will enable the predicate `unique_record` - # which is derived from the class name minus `validator` + # To use a custom validator. UniqueRecordValidator will be initialized with an `User` instance use UniqueRecordValidator # Use the `custom` class name predicate as follow @@ -182,13 +181,12 @@ class User < Model end ``` -## Custom Validations +### Custom Validations Simply create a class `{Name}Validator` with the following signature: ```crystal class EmailValidator < Schema::Validator - include Schema::Validators getter :record, :field, :message def initialize(@record : UserModel) @@ -215,11 +213,9 @@ class UniqueRecordValidator < Schema::Validator end ``` -Notice that `unique_record:` corresponds to `UniqueRecord`Validator. +### Defining Predicates -### Defining Your Own Predicates - -You can define your custom predicates by simply creating a custom validator or creating methods in the `Schema::Validators` module ending with `?` and it should return a `boolean`. For example: +You can define your custom predicates by simply creating a custom validator or creating methods in the `Schema::Predicates` module ending with `?` and it should return a `boolean`. For example: ```crystal class User < Model @@ -230,13 +226,16 @@ class User < Model property childrens : Array(String) property childrens_ages : Array(Int32) - ... - validate password : String, presence: true + ... + + # Uses a `presense` predicate + validate password : String, presence: true - predicates do - def presence?(password : String, _other : String) : Bool - !value.nil? - end + # Use the `predicates` macro to define predicate methods + predicates do + # Presence Predicate Definition + def presence?(password : String, _other : String) : Bool + !value.nil? end end @@ -245,15 +244,25 @@ class User < Model end ``` +### Differences: Custom Validator vs Predicates + The differences between a custom validator and a method predicate are: -- Custom validators receive an instance of the object as a `record` instance var. -- Custom validators allow for more control over validations. -- Predicates are assertions against the class properties (instance var). -- Predicates matches property value with predicate value. +**Custom Validators** +- Must be inherited from `Schema::Validator` abstract +- Receives an instance of the object as a `record` instance var. +- Must have a `:field` and `:message` defined. +- Must implement a `def valid? : Array(Schema::Error)` method. + +**Predicates** +- Assertions of the property value against an expected value. +- Predicates are light weight boolean methods. +- Predicates methods must be defined as `def {predicate}?(property_value, expected_value) : Bool` . ### Built in Predicates +These are the current available predicates. + ```crystal gte - Greater Than or Equal To lte - Less Than or Equal To @@ -265,6 +274,8 @@ regex - Regular Expression eq - Equal ``` +> **CONTRIBUTE** - Add more predicates to this shards by contributing a Pull Request. + Additional params ```crystal @@ -272,16 +283,6 @@ message - Error message to display nilable - Allow nil, true or false ``` -## Development (Help Wanted!) - -API subject to change until marked as released version - -Things left to do: - -- [x] Validate nested - When calling `valid?` validates schemas. -- [x] Build nested `json`- Currently `json` do not support the sub schemas. -- [x] Document Custom Converter for custom types. - ## Contributing 1. Fork it () diff --git a/spec/validation_spec.cr b/spec/validation_spec.cr index 6f4920a..81ac3fa 100644 --- a/spec/validation_spec.cr +++ b/spec/validation_spec.cr @@ -38,7 +38,6 @@ class UserModel end class EmailValidator < Schema::Validator - include Schema::Validators getter :record, :field, :message def initialize(@record : UserModel) diff --git a/spec/validators_spec.cr b/spec/validators_spec.cr index fec1d10..781d07f 100644 --- a/spec/validators_spec.cr +++ b/spec/validators_spec.cr @@ -1,7 +1,7 @@ require "./spec_helper" -include Schema::Validators +include Schema::Predicates -describe Schema::Validators do +describe Schema::Predicates do describe "#eq?" do it { eq?(1, 1).should be_true } it { eq?("one", "one").should be_true } diff --git a/src/schema/validation.cr b/src/schema/validation.cr index 89b6704..225f2af 100644 --- a/src/schema/validation.cr +++ b/src/schema/validation.cr @@ -1,4 +1,4 @@ -require "./validation/validators" +require "./validation/predicates" require "./validation/error" require "./validation/validator" require "./validation/constraint" @@ -25,14 +25,14 @@ module Schema end macro predicates - module Schema::Validators + module Schema::Predicates {{yield}} end end macro create_validator(type_validator) {% type_validator = type_validator.resolve %} - + class Validator def self.validate(instance : {{type_validator}}) errors = Array(Schema::Error).new @@ -42,18 +42,18 @@ module Schema errors + rule.valid? end end - + private def self.validations(rules, instance) {% for validtor in type_validator.constant(:SCHEMA_VALIDATORS) %} rules << {{validtor}}.new(instance) {% end %} - + rules << Schema::Constraint.new do |rule, errors| {% for name, options in type_validator.constant(:SCHEMA_VALIDATIONS) %} {% for predicate, expected_value in options %} {% if !["message"].includes?(predicate.stringify) %} unless rule.{{predicate.id}}?(instance.{{name.id}}, {{expected_value}}) - errors << Schema::Error.new(:{{name.id}}, {{options["message"] || "Invalid field: " + name.stringify}}) + errors << Schema::Error.new(:{{name.id}}, {{options["message"] || "Invalid field: " + name.stringify}}) end {% end %} {% end %} diff --git a/src/schema/validation/constraint.cr b/src/schema/validation/constraint.cr index 7e4ed5d..8fbbbd6 100644 --- a/src/schema/validation/constraint.cr +++ b/src/schema/validation/constraint.cr @@ -1,6 +1,7 @@ module Schema class Constraint - include Schema::Validators + include Schema::Predicates + @errors = Array(Schema::Error).new def initialize(&block : Constraint, Array(Schema::Error) -> Nil) diff --git a/src/schema/validation/validators.cr b/src/schema/validation/predicates.cr similarity index 85% rename from src/schema/validation/validators.cr rename to src/schema/validation/predicates.cr index 638b538..178db31 100644 --- a/src/schema/validation/validators.cr +++ b/src/schema/validation/predicates.cr @@ -1,7 +1,7 @@ -require "./validators/*" +require "./predicates/*" module Schema - module Validators + module Predicates include Equal include Exclusion include GreaterThan diff --git a/src/schema/validation/validators/equal.cr b/src/schema/validation/predicates/equal.cr similarity index 100% rename from src/schema/validation/validators/equal.cr rename to src/schema/validation/predicates/equal.cr diff --git a/src/schema/validation/validators/exclusion.cr b/src/schema/validation/predicates/exclusion.cr similarity index 100% rename from src/schema/validation/validators/exclusion.cr rename to src/schema/validation/predicates/exclusion.cr diff --git a/src/schema/validation/validators/greater_than.cr b/src/schema/validation/predicates/greater_than.cr similarity index 100% rename from src/schema/validation/validators/greater_than.cr rename to src/schema/validation/predicates/greater_than.cr diff --git a/src/schema/validation/validators/greater_than_or_equal.cr b/src/schema/validation/predicates/greater_than_or_equal.cr similarity index 100% rename from src/schema/validation/validators/greater_than_or_equal.cr rename to src/schema/validation/predicates/greater_than_or_equal.cr diff --git a/src/schema/validation/validators/inclusion.cr b/src/schema/validation/predicates/inclusion.cr similarity index 100% rename from src/schema/validation/validators/inclusion.cr rename to src/schema/validation/predicates/inclusion.cr diff --git a/src/schema/validation/validators/less_than.cr b/src/schema/validation/predicates/less_than.cr similarity index 100% rename from src/schema/validation/validators/less_than.cr rename to src/schema/validation/predicates/less_than.cr diff --git a/src/schema/validation/validators/less_than_or_equal.cr b/src/schema/validation/predicates/less_than_or_equal.cr similarity index 100% rename from src/schema/validation/validators/less_than_or_equal.cr rename to src/schema/validation/predicates/less_than_or_equal.cr diff --git a/src/schema/validation/validators/presence.cr b/src/schema/validation/predicates/presence.cr similarity index 100% rename from src/schema/validation/validators/presence.cr rename to src/schema/validation/predicates/presence.cr diff --git a/src/schema/validation/validators/regular_expression.cr b/src/schema/validation/predicates/regular_expression.cr similarity index 100% rename from src/schema/validation/validators/regular_expression.cr rename to src/schema/validation/predicates/regular_expression.cr diff --git a/src/schema/validation/validators/size.cr b/src/schema/validation/predicates/size.cr similarity index 100% rename from src/schema/validation/validators/size.cr rename to src/schema/validation/predicates/size.cr diff --git a/src/schema/validation/validator.cr b/src/schema/validation/validator.cr index 4a8727a..8f5ae67 100644 --- a/src/schema/validation/validator.cr +++ b/src/schema/validation/validator.cr @@ -1,6 +1,6 @@ module Schema abstract class Validator - include Schema::Validators + include Schema::Predicates def initialize(@record) end