pure_validator 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +27 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +22 -17
- data/README.md +15 -1
- data/docs/_config.yml +1 -0
- data/docs/index.md +139 -0
- data/lib/pure_validator/validator.rb +7 -2
- data/lib/pure_validator/validators/length_validator.rb +28 -17
- data/lib/pure_validator/validators/numericality_validator.rb +41 -22
- data/lib/pure_validator/version.rb +1 -1
- data/spec/pure_validator/validator_hash_spec.rb +153 -0
- data/spec/pure_validator/validator_spec.rb +19 -17
- data/spec/pure_validator/validators/email_validator_spec.rb +4 -4
- data/spec/pure_validator/validators/exclusion_validator_spec.rb +4 -4
- data/spec/pure_validator/validators/inclusion_validator_spec.rb +4 -4
- data/spec/pure_validator/validators/length_validator_spec.rb +7 -7
- data/spec/pure_validator/validators/not_nil_validator_spec.rb +2 -2
- data/spec/pure_validator/validators/numericality_validator_spec.rb +21 -17
- data/spec/pure_validator/validators/presence_validator_spec.rb +2 -2
- data/spec/pure_validator/validators/regexp_validator_spec.rb +16 -6
- data/spec/pure_validator/validators/url_validator_spec.rb +18 -10
- data/spec/spec_helper.rb +0 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77569240246f2ea1f784cab102071acb50716095
|
4
|
+
data.tar.gz: b247e8889706590ed2aee0a4f3ad2ae0d2d34d8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ede8f6afabc19468a541b78bf6c372d387827ac65f30df2a7f5fc9e351d5039b7959e228cf6ef99935afb1aa891e9877a636ab8f66601c0b2a1db30509316f54
|
7
|
+
data.tar.gz: be8130b200ea9b5777d9057f21a4ab7afcb2b3281c7b46f1e95a4f8e11275c3bcb44ae839aec2972c1760deaca392e04d8c425e16e3c4707d29ac03366047b3c
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
engines:
|
2
|
+
rubocop:
|
3
|
+
enabled: true
|
4
|
+
exclude_fingerprints:
|
5
|
+
- 1deadbbb4a858ae5aeeff38fc78ad557
|
6
|
+
- 10973ead6ddf385b4d4d7ec0f75236ae
|
7
|
+
|
8
|
+
bundler-audit:
|
9
|
+
enabled: true
|
10
|
+
|
11
|
+
fixme:
|
12
|
+
enabled: true
|
13
|
+
|
14
|
+
duplication:
|
15
|
+
enabled: true
|
16
|
+
config:
|
17
|
+
languages:
|
18
|
+
- ruby
|
19
|
+
|
20
|
+
ratings:
|
21
|
+
paths:
|
22
|
+
- Gemfile.lock
|
23
|
+
- "**.rb"
|
24
|
+
|
25
|
+
exclude_paths:
|
26
|
+
- spec/**/*
|
27
|
+
- lib/pure_validator/core_extensions/**/*
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -1,35 +1,40 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pure_validator (0.
|
4
|
+
pure_validator (0.4.0)
|
5
5
|
i18n
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
byebug (9.0.6)
|
11
|
-
codecov (0.1.
|
11
|
+
codecov (0.1.10)
|
12
12
|
json
|
13
13
|
simplecov
|
14
14
|
url
|
15
|
-
diff-lcs (1.
|
15
|
+
diff-lcs (1.3)
|
16
16
|
docile (1.1.5)
|
17
|
-
i18n (0.
|
18
|
-
json (2.0
|
19
|
-
rake (
|
20
|
-
rspec (
|
21
|
-
rspec-core (~>
|
22
|
-
rspec-expectations (~>
|
23
|
-
rspec-mocks (~>
|
24
|
-
rspec-core (
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
17
|
+
i18n (0.8.4)
|
18
|
+
json (2.1.0)
|
19
|
+
rake (12.0.0)
|
20
|
+
rspec (3.6.0)
|
21
|
+
rspec-core (~> 3.6.0)
|
22
|
+
rspec-expectations (~> 3.6.0)
|
23
|
+
rspec-mocks (~> 3.6.0)
|
24
|
+
rspec-core (3.6.0)
|
25
|
+
rspec-support (~> 3.6.0)
|
26
|
+
rspec-expectations (3.6.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.6.0)
|
29
|
+
rspec-mocks (3.6.0)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.6.0)
|
32
|
+
rspec-support (3.6.0)
|
33
|
+
simplecov (0.14.1)
|
29
34
|
docile (~> 1.1.0)
|
30
35
|
json (>= 1.8, < 3)
|
31
36
|
simplecov-html (~> 0.10.0)
|
32
|
-
simplecov-html (0.10.
|
37
|
+
simplecov-html (0.10.1)
|
33
38
|
url (0.3.2)
|
34
39
|
|
35
40
|
PLATFORMS
|
@@ -44,4 +49,4 @@ DEPENDENCIES
|
|
44
49
|
rspec
|
45
50
|
|
46
51
|
BUNDLED WITH
|
47
|
-
1.
|
52
|
+
1.14.6
|
data/README.md
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
# PureValidator
|
1
|
+
# PureValidator
|
2
|
+
[](https://travis-ci.org/ddd-ruby/pure_validator)
|
3
|
+
[](http://badge.fury.io/rb/pure_validator)
|
4
|
+
[](https://codeclimate.com/github/ddd-ruby/pure_validator)
|
5
|
+
[](https://codecov.io/gh/ddd-ruby/pure_validator)
|
6
|
+
[](https://gemnasium.com/ddd-ruby/pure_validator)
|
2
7
|
|
3
8
|
PureValidator is a simple, mostly dependency-free (except `i18n`) library to validate your domain Ruby objects.
|
4
9
|
|
@@ -10,6 +15,14 @@ It is a simple step to separate those concerns, but it will give you unlimited f
|
|
10
15
|
|
11
16
|
Do yourself a favor and start using PureValidator today, you will never look back!
|
12
17
|
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'pure_validator'
|
24
|
+
```
|
25
|
+
|
13
26
|
## Usage
|
14
27
|
Let's say you have the following class and you want to validate its instances:
|
15
28
|
|
@@ -137,3 +150,4 @@ Or install it yourself as:
|
|
137
150
|
|
138
151
|
- Albert Gazizov, [@deeper4k](https://twitter.com/deeper4k)
|
139
152
|
- Roman Heinrich, [@mindreframer](https://twitter.com/mindreframer)
|
153
|
+
|
data/docs/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-minimal
|
data/docs/index.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# PureValidator [](https://travis-ci.org/ddd-ruby/pure_validator) [](https://codeclimate.com/github/ddd-ruby/pure_validator) [](https://codecov.io/gh/ddd-ruby/pure_validator)
|
2
|
+
|
3
|
+
PureValidator is a simple, mostly dependency-free (except `i18n`) library to validate your domain Ruby objects.
|
4
|
+
|
5
|
+
It keeps the concerns of validation separate from the Entity / Value object itself.
|
6
|
+
|
7
|
+
This gives you the option to have different validations rules for different ocasions for the same object in a very clean and unit-testable way.
|
8
|
+
|
9
|
+
It is a simple step to separate those concerns, but it will give you unlimited flexibility and save your *SS from debugging entangled and conflicting validations for non-trivial requirements.
|
10
|
+
|
11
|
+
Do yourself a favor and start using PureValidator today, you will never look back!
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
Let's say you have the following class and you want to validate its instances:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
class Contact
|
18
|
+
attr_accessor :first_name, :last_name, :position, :age, :type, :email, :color, :status, :stage, :description, :companies
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
To validate objects of the Contact class define following validator:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
class ContactValidator
|
26
|
+
include PureValidator::Validator
|
27
|
+
|
28
|
+
validates :first_name, presence: true, length: { min: 4, max: 7 }
|
29
|
+
validates :last_name, length: { equal_to: 5 }
|
30
|
+
validates :position, length: { not_equal_to: 5 }
|
31
|
+
validates :age, numericality: { greater_than: 0, less_than: 150 }
|
32
|
+
validates :type, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 5 }
|
33
|
+
validates :email, email: true
|
34
|
+
validates :color, regexp: /#\w{6}/
|
35
|
+
validates :status, inclusion: { in: [:new, :lead] }
|
36
|
+
validates :stage, exclusion: { in: [:wrong, :bad] }
|
37
|
+
|
38
|
+
validate_associated :companies, validator: CompanyValidator
|
39
|
+
|
40
|
+
validate :check_description
|
41
|
+
|
42
|
+
def check_description(entity, errors)
|
43
|
+
if entity.description.nil?
|
44
|
+
errors.add(:description, "can't be empty")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
Instantiate the validator and call `validate` with a contact object:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
errors = ContactValidator.new.validate(contact)
|
54
|
+
```
|
55
|
+
|
56
|
+
`errors` is a Hash that contains all validation errors.
|
57
|
+
If the object is valid then errors will be an empty Hash.
|
58
|
+
|
59
|
+
### Adding own validators
|
60
|
+
|
61
|
+
PureValidator can be extended by adding your own validators.
|
62
|
+
To add a validator define a class with 2 static methods: `validate` and `validate_options`:
|
63
|
+
|
64
|
+
The following example shows the built-in inclusion validator, it validates that specified value is one of the defined values.
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
class PureValidator::Validators::InclusionValidator
|
68
|
+
|
69
|
+
# Validates that given value inscluded in the specified list
|
70
|
+
# @param value [Object] object to validate
|
71
|
+
# @parm options [Hash] validation options, e.g. { in: [:small, :medium, :large], message: "not included in the list of allowed items" }
|
72
|
+
# where :in - list of allowed values,
|
73
|
+
# message - is a message to return if value is not included in the list
|
74
|
+
# @return [Array] empty array if object is valid, list of errors otherwise
|
75
|
+
def self.validate(value, options)
|
76
|
+
return [] if value.nil?
|
77
|
+
|
78
|
+
errors = []
|
79
|
+
if options[:in]
|
80
|
+
unless options[:in].include?(value)
|
81
|
+
errors << (options[:message] || PureValidator::I18n.t('errors.should_be_included_in_list', list: options[:in]))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
errors
|
85
|
+
end
|
86
|
+
|
87
|
+
# Validates that options specified in
|
88
|
+
# :inclusion are valid
|
89
|
+
def self.validate_options(options)
|
90
|
+
raise ArgumentError, "validation options should be a Hash" unless options.is_a?(Hash)
|
91
|
+
raise ArgumentError, "validation options should have :in option and it should be an array of allowed values" unless options[:in].is_a?(Array)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
And register it in PureValidator:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
PureValidator.add_validator(:inclusion, PureValidator::Validators::InclusionValidator)
|
101
|
+
```
|
102
|
+
|
103
|
+
Now you can use it:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
class SomeValidator
|
107
|
+
include PureValidator::Validator
|
108
|
+
|
109
|
+
validates :size, inclusion: { in: [:small, :medium, :large] }
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
## Installation
|
114
|
+
|
115
|
+
Add this line to your application's Gemfile:
|
116
|
+
|
117
|
+
gem 'pure_validator'
|
118
|
+
|
119
|
+
And then execute:
|
120
|
+
|
121
|
+
$ bundle
|
122
|
+
|
123
|
+
Or install it yourself as:
|
124
|
+
|
125
|
+
$ gem install pure_validator
|
126
|
+
|
127
|
+
## Contributing
|
128
|
+
|
129
|
+
1. Fork it
|
130
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
131
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
132
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
133
|
+
5. Create new Pull Request
|
134
|
+
|
135
|
+
|
136
|
+
## Authors
|
137
|
+
|
138
|
+
- Albert Gazizov, [@deeper4k](https://twitter.com/deeper4k)
|
139
|
+
- Roman Heinrich, [@mindreframer](https://twitter.com/mindreframer)
|
@@ -66,7 +66,7 @@ module PureValidator::Validator
|
|
66
66
|
self.associated_validations.each do |association_name, options|
|
67
67
|
next if skip_validation?(options)
|
68
68
|
validator = options[:validator].is_a?(Class) ? options[:validator].new : self.send(options[:validator])
|
69
|
-
children = entity
|
69
|
+
children = get_attribute_value(entity, association_name)
|
70
70
|
if children.is_a?(Array)
|
71
71
|
validate_children(association_name, validator, children, errors)
|
72
72
|
elsif children
|
@@ -93,7 +93,7 @@ module PureValidator::Validator
|
|
93
93
|
private
|
94
94
|
|
95
95
|
def validate_attr(attr_name, entity, validators)
|
96
|
-
attr_value = entity
|
96
|
+
attr_value = get_attribute_value(entity, attr_name)
|
97
97
|
error_messages = []
|
98
98
|
validators.each do |validator, validation_rule|
|
99
99
|
error_messages = validator.validate(attr_value, validation_rule)
|
@@ -102,6 +102,11 @@ module PureValidator::Validator
|
|
102
102
|
error_messages
|
103
103
|
end
|
104
104
|
|
105
|
+
def get_attribute_value(entity, attr_name)
|
106
|
+
return entity[attr_name] if entity.is_a?(Hash)
|
107
|
+
return entity.send(attr_name)
|
108
|
+
end
|
109
|
+
|
105
110
|
def skip_validation?(options)
|
106
111
|
return unless options[:if] || options[:unless]
|
107
112
|
return handle_if_skip_validation(options) if options[:if]
|
@@ -5,23 +5,7 @@ class PureValidator::Validators::LengthValidator
|
|
5
5
|
# @param options [Hash] validation options, e.g. { min: 2, max: 4, equal_to: 3, not_equal_to: 6 }
|
6
6
|
# @return [Array] empty array if object is valid, array of error messages otherwise
|
7
7
|
def self.validate(object, options)
|
8
|
-
|
9
|
-
|
10
|
-
errors = []
|
11
|
-
if options[:min]
|
12
|
-
errors << PureValidator::I18n.t('errors.can_not_be_less_than', length: options[:min]) if object.length < options[:min]
|
13
|
-
end
|
14
|
-
if options[:max]
|
15
|
-
errors << PureValidator::I18n.t('errors.can_not_be_more_than', length: options[:max]) if object.length > options[:max]
|
16
|
-
end
|
17
|
-
if options[:equal_to]
|
18
|
-
errors << PureValidator::I18n.t('errors.should_be_equal_to', length: options[:equal_to]) if object.length != options[:equal_to]
|
19
|
-
end
|
20
|
-
if options[:not_equal_to]
|
21
|
-
errors << PureValidator::I18n.t('errors.should_not_be_equal_to', length: options[:not_equal_to]) if object.length == options[:not_equal_to]
|
22
|
-
end
|
23
|
-
|
24
|
-
errors
|
8
|
+
self.new(object, options).validate
|
25
9
|
end
|
26
10
|
|
27
11
|
def self.validate_options(options)
|
@@ -29,4 +13,31 @@ class PureValidator::Validators::LengthValidator
|
|
29
13
|
PureValidator::ArgsValidator.has_only_allowed_keys!(options, [:min, :max, :equal_to, :not_equal_to], :validation_rule)
|
30
14
|
end
|
31
15
|
|
16
|
+
attr_accessor :object, :options, :errors
|
17
|
+
def initialize(object, options)
|
18
|
+
@object, @options = object, options
|
19
|
+
@errors = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate
|
23
|
+
return errors if object.nil?
|
24
|
+
|
25
|
+
handle(:min, :<, 'errors.can_not_be_less_than')
|
26
|
+
handle(:max, :>, 'errors.can_not_be_more_than')
|
27
|
+
handle(:equal_to, :!=, 'errors.should_be_equal_to')
|
28
|
+
handle(:not_equal_to, :==, 'errors.should_not_be_equal_to')
|
29
|
+
|
30
|
+
errors
|
31
|
+
end
|
32
|
+
|
33
|
+
def handle(key, condition, error_key)
|
34
|
+
return unless options[key]
|
35
|
+
if object.length.send(condition, options[key])
|
36
|
+
add_error!(error_key, options[key])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_error!(key, length)
|
41
|
+
errors << PureValidator::I18n.t(key, length: length)
|
42
|
+
end
|
32
43
|
end
|
@@ -5,28 +5,7 @@ class PureValidator::Validators::NumericalityValidator
|
|
5
5
|
# @param options [Hash] validation rules
|
6
6
|
# @return [Array] empty array if number is valid, array of error messages otherwise
|
7
7
|
def self.validate(number, options)
|
8
|
-
|
9
|
-
|
10
|
-
errors = []
|
11
|
-
if options[:greater_than]
|
12
|
-
errors << PureValidator::I18n.t('errors.should_be_greater_than', number: options[:greater_than]) if number <= options[:greater_than]
|
13
|
-
end
|
14
|
-
if options[:greater_than_or_equal_to]
|
15
|
-
errors << PureValidator::I18n.t('errors.should_be_greater_than_or_equal_to', number: options[:greater_than_or_equal_to]) if number < options[:greater_than_or_equal_to]
|
16
|
-
end
|
17
|
-
if options[:less_than]
|
18
|
-
errors << PureValidator::I18n.t('errors.should_be_less_than', number: options[:less_than]) if number >= options[:less_than]
|
19
|
-
end
|
20
|
-
if options[:less_than_or_equal_to]
|
21
|
-
errors << PureValidator::I18n.t('errors.should_be_less_than_or_equal_to', number: options[:less_than_or_equal_to]) if number > options[:less_than_or_equal_to]
|
22
|
-
end
|
23
|
-
if options[:even]
|
24
|
-
errors << PureValidator::I18n.t('errors.should_be_even') unless number.even?
|
25
|
-
end
|
26
|
-
if options[:odd]
|
27
|
-
errors << PureValidator::I18n.t('errors.should_be_odd') unless number.odd?
|
28
|
-
end
|
29
|
-
errors
|
8
|
+
self.new(number, options).validate
|
30
9
|
end
|
31
10
|
|
32
11
|
def self.validate_options(options)
|
@@ -36,4 +15,44 @@ class PureValidator::Validators::NumericalityValidator
|
|
36
15
|
], :validation_rule)
|
37
16
|
end
|
38
17
|
|
18
|
+
attr_accessor :object, :options, :errors
|
19
|
+
def initialize(object, options)
|
20
|
+
@object, @options = object, options
|
21
|
+
@errors = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate
|
25
|
+
return errors if object.nil?
|
26
|
+
|
27
|
+
handle_compare(:greater_than, :<=, 'errors.should_be_greater_than')
|
28
|
+
handle_compare(:greater_than_or_equal_to, :<, 'errors.should_be_greater_than_or_equal_to')
|
29
|
+
handle_compare(:less_than, :>=, 'errors.should_be_less_than')
|
30
|
+
handle_compare(:less_than_or_equal_to, :>, 'errors.should_be_less_than_or_equal_to')
|
31
|
+
handle_condition(:even, :even?, 'errors.should_be_even')
|
32
|
+
handle_condition(:odd, :odd?, 'errors.should_be_odd')
|
33
|
+
|
34
|
+
errors
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle_compare(key, condition, error_key)
|
38
|
+
return unless options[key]
|
39
|
+
if object.send(condition, options[key])
|
40
|
+
add_error!(error_key, options[key])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def handle_condition(key, condition, error_key)
|
45
|
+
return unless options[key]
|
46
|
+
unless object.send(condition)
|
47
|
+
add_error!(error_key)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_error!(key, number=nil)
|
52
|
+
if number
|
53
|
+
errors << PureValidator::I18n.t(key, number: number)
|
54
|
+
else
|
55
|
+
errors << PureValidator::I18n.t(key)
|
56
|
+
end
|
57
|
+
end
|
39
58
|
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PureValidator::Validator do
|
4
|
+
describe "#validate" do
|
5
|
+
class ContactH
|
6
|
+
attr_accessor :first_name, :last_name, :position, :age, :type,
|
7
|
+
:email, :color, :status, :stage, :description,
|
8
|
+
:companies, :address
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
{
|
12
|
+
first_name: first_name,
|
13
|
+
last_name: last_name,
|
14
|
+
position: position,
|
15
|
+
age: age,
|
16
|
+
type: type,
|
17
|
+
email: email,
|
18
|
+
color: color,
|
19
|
+
status: status,
|
20
|
+
stage: stage,
|
21
|
+
description: description,
|
22
|
+
companies: (companies||[]).map(&:to_h),
|
23
|
+
address: (address && address.to_h),
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class CompanyH
|
29
|
+
attr_accessor :name
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
{name: name}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AddressH
|
37
|
+
attr_accessor :city, :street
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
city: city,
|
41
|
+
street: street,
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class CompanyValidatorH
|
47
|
+
include PureValidator::Validator
|
48
|
+
|
49
|
+
validates :name, presence: true, length: { min: 3, max: 9 }
|
50
|
+
end
|
51
|
+
|
52
|
+
class AddressValidatorH
|
53
|
+
include PureValidator::Validator
|
54
|
+
|
55
|
+
validates :city, presence: true, length: { min: 3, max: 33 }
|
56
|
+
validates :street, presence: true, length: { min: 3, max: 33 }
|
57
|
+
end
|
58
|
+
|
59
|
+
class ContactValidatorH
|
60
|
+
include PureValidator::Validator
|
61
|
+
|
62
|
+
validates :first_name, presence: true, length: { min: 4, max: 7 }
|
63
|
+
validates :last_name, length: { equal_to: 5 }
|
64
|
+
validates :position, length: { not_equal_to: 5 }
|
65
|
+
validates :age, numericality: { greater_than: 0, less_than: 150 }
|
66
|
+
validates :type, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 5 }
|
67
|
+
validates :email, email: true
|
68
|
+
validates :color, regexp: /#\w{6}/
|
69
|
+
validates :status, inclusion: { in: [:new, :lead] }
|
70
|
+
validates :stage, exclusion: { in: [:wrong, :bad] }
|
71
|
+
|
72
|
+
validate_associated :companies, validator: CompanyValidatorH
|
73
|
+
|
74
|
+
validates :address, presence: true
|
75
|
+
validate_associated :address, validator: AddressValidatorH
|
76
|
+
|
77
|
+
|
78
|
+
validate :check_description
|
79
|
+
|
80
|
+
def check_description(entity, errors)
|
81
|
+
if entity[:description].nil?
|
82
|
+
errors.add(:description, "can't be empty")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return empty errors if object is valid" do
|
88
|
+
contact = ContactH.new
|
89
|
+
contact.first_name = "John"
|
90
|
+
contact.last_name = "Smith"
|
91
|
+
contact.position = "Team Lead"
|
92
|
+
contact.age = 35
|
93
|
+
contact.type = 2
|
94
|
+
contact.email = "johh.smith@example.com"
|
95
|
+
contact.color = "#DDD333"
|
96
|
+
contact.status = :lead
|
97
|
+
contact.stage = :good
|
98
|
+
contact.description = "good guy"
|
99
|
+
|
100
|
+
company1 = CompanyH.new
|
101
|
+
company1.name = 'DroidLabs'
|
102
|
+
company2 = CompanyH.new
|
103
|
+
company2.name = 'ICL'
|
104
|
+
|
105
|
+
contact.companies = [company1, company2]
|
106
|
+
|
107
|
+
address = AddressH.new.tap do |a| a.city = "New York" ; a.street = "Wall Street" end
|
108
|
+
contact.address = address
|
109
|
+
|
110
|
+
errors = ContactValidatorH.new.validate(contact.to_h)
|
111
|
+
expect(errors).to be_empty
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return validation errors if object is invalid" do
|
115
|
+
contact = ContactH.new
|
116
|
+
contact.first_name = nil
|
117
|
+
contact.last_name = "Sm"
|
118
|
+
contact.position = "develp"
|
119
|
+
contact.age = -1
|
120
|
+
contact.type = 7
|
121
|
+
contact.email = "johh.com"
|
122
|
+
contact.color = "DDD333"
|
123
|
+
contact.status = :left
|
124
|
+
contact.stage = :bad
|
125
|
+
|
126
|
+
company1 = CompanyH.new
|
127
|
+
company1.name = 'DroidLabs Wrong'
|
128
|
+
company2 = CompanyH.new
|
129
|
+
company2.name = 'IC'
|
130
|
+
|
131
|
+
contact.companies = [company1, company2]
|
132
|
+
errors = ContactValidatorH.new.validate(contact.to_h)
|
133
|
+
expect(errors).to eq(
|
134
|
+
{
|
135
|
+
first_name: ["can not be blank"],
|
136
|
+
last_name: ["should be equal to 5"],
|
137
|
+
age: ["should be greater than 0"],
|
138
|
+
type: ["should be less than or equal to 5"],
|
139
|
+
email: ["invalid email"],
|
140
|
+
color: ["does not match defined format"],
|
141
|
+
status: ["should be included in [:new, :lead]"],
|
142
|
+
stage: ["should not be included in [:wrong, :bad]"],
|
143
|
+
description: ["can't be empty"],
|
144
|
+
companies_errors: [
|
145
|
+
{ name: ["can not be more than 9"] },
|
146
|
+
{ name: ["can not be less than 3"] },
|
147
|
+
],
|
148
|
+
address: ["can not be blank"],
|
149
|
+
}
|
150
|
+
)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -79,7 +79,7 @@ describe PureValidator::Validator do
|
|
79
79
|
contact.address = address
|
80
80
|
|
81
81
|
errors = ContactValidator.new.validate(contact)
|
82
|
-
errors.
|
82
|
+
expect(errors).to be_empty
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should return validation errors if object is invalid" do
|
@@ -102,22 +102,24 @@ describe PureValidator::Validator do
|
|
102
102
|
contact.companies = [company1, company2]
|
103
103
|
|
104
104
|
errors = ContactValidator.new.validate(contact)
|
105
|
-
errors.
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
105
|
+
expect(errors).to eq(
|
106
|
+
{
|
107
|
+
first_name: ["can not be blank"],
|
108
|
+
last_name: ["should be equal to 5"],
|
109
|
+
age: ["should be greater than 0"],
|
110
|
+
type: ["should be less than or equal to 5"],
|
111
|
+
email: ["invalid email"],
|
112
|
+
color: ["does not match defined format"],
|
113
|
+
status: ["should be included in [:new, :lead]"],
|
114
|
+
stage: ["should not be included in [:wrong, :bad]"],
|
115
|
+
description: ["can't be empty"],
|
116
|
+
companies_errors: [
|
117
|
+
{ name: ["can not be more than 9"] },
|
118
|
+
{ name: ["can not be less than 3"] },
|
119
|
+
],
|
120
|
+
address: ["can not be blank"],
|
121
|
+
}
|
122
|
+
)
|
121
123
|
end
|
122
124
|
end
|
123
125
|
|
@@ -4,12 +4,12 @@ describe PureValidator::Validators::EmailValidator do
|
|
4
4
|
describe ".validate" do
|
5
5
|
it "should return empty errors if email is valid" do
|
6
6
|
errors = PureValidator::Validators::EmailValidator.validate('test@example.com', true)
|
7
|
-
errors.
|
7
|
+
expect(errors).to be_empty
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should return errors if value is invalid" do
|
11
11
|
errors = PureValidator::Validators::EmailValidator.validate('test@asdffd', true)
|
12
|
-
errors.
|
12
|
+
expect(errors).to eq(["invalid email"])
|
13
13
|
end
|
14
14
|
|
15
15
|
context "false as email_flag" do
|
@@ -27,9 +27,9 @@ describe PureValidator::Validators::EmailValidator do
|
|
27
27
|
|
28
28
|
describe ".validate_options" do
|
29
29
|
it "should raise error if validation attributes are invalid" do
|
30
|
-
|
30
|
+
expect{
|
31
31
|
PureValidator::Validators::EmailValidator.validate_options("asdf")
|
32
|
-
|
32
|
+
}.to raise_error("validation_rule should be a Boolean")
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -4,20 +4,20 @@ describe PureValidator::Validators::ExclusionValidator do
|
|
4
4
|
describe ".validate" do
|
5
5
|
it "should return empty errors if value is valid" do
|
6
6
|
errors = PureValidator::Validators::ExclusionValidator.validate(:wrong_type, in: [:new, :old, :medium])
|
7
|
-
errors.
|
7
|
+
expect(errors).to be_empty
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should return errors if value is invalid" do
|
11
11
|
errors = PureValidator::Validators::ExclusionValidator.validate(:new, in: [:new, :old, :medium])
|
12
|
-
errors.
|
12
|
+
expect(errors).to eq(["should not be included in [:new, :old, :medium]"])
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
describe ".validate_options" do
|
17
17
|
it "should raise error if validation attributes are invalid" do
|
18
|
-
|
18
|
+
expect{
|
19
19
|
PureValidator::Validators::ExclusionValidator.validate_options(wrong_option: false, in: [])
|
20
|
-
|
20
|
+
}.to raise_error("validation_rule has unacceptable options [:wrong_option]")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -4,20 +4,20 @@ describe PureValidator::Validators::InclusionValidator do
|
|
4
4
|
describe ".validate" do
|
5
5
|
it "should return empty errors if value is valid" do
|
6
6
|
errors = PureValidator::Validators::InclusionValidator.validate(:old, in: [:new, :old, :medium])
|
7
|
-
errors.
|
7
|
+
expect(errors).to be_empty
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should return errors if value is invalid" do
|
11
11
|
errors = PureValidator::Validators::InclusionValidator.validate(:wrong_type, in: [:new, :old, :medium])
|
12
|
-
errors.
|
12
|
+
expect(errors).to eq(["should be included in [:new, :old, :medium]"])
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
describe ".validate_options" do
|
17
17
|
it "should raise error if validation attributes are invalid" do
|
18
|
-
|
18
|
+
expect{
|
19
19
|
PureValidator::Validators::InclusionValidator.validate_options(wrong_option: false, in: [])
|
20
|
-
|
20
|
+
}.to raise_error("validation options has unacceptable options [:wrong_option]")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -4,35 +4,35 @@ describe PureValidator::Validators::LengthValidator do
|
|
4
4
|
describe ".validate" do
|
5
5
|
it "should return empty errors if text has valid length" do
|
6
6
|
errors = PureValidator::Validators::LengthValidator.validate('home', max: 5, min: 3)
|
7
|
-
errors.
|
7
|
+
expect(errors).to be_empty
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should return errors if value has invalid max length" do
|
11
11
|
errors = PureValidator::Validators::LengthValidator.validate('long title', max: 5)
|
12
|
-
errors.
|
12
|
+
expect(errors).to eq(["can not be more than 5"])
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should return errors if value has invalid min length" do
|
16
16
|
errors = PureValidator::Validators::LengthValidator.validate('ya', min: 3)
|
17
|
-
errors.
|
17
|
+
expect(errors).to eq(["can not be less than 3"])
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should return errors if value has invalid equal_to length" do
|
21
21
|
errors = PureValidator::Validators::LengthValidator.validate('ya', equal_to: 3)
|
22
|
-
errors.
|
22
|
+
expect(errors).to eq(["should be equal to 3"])
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should return errors if value has invalid not_equal_to length" do
|
26
26
|
errors = PureValidator::Validators::LengthValidator.validate('yad', not_equal_to: 3)
|
27
|
-
errors.
|
27
|
+
expect(errors).to eq(["should not be equal to 3"])
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
describe ".validate_options" do
|
32
32
|
it "should raise error if validation attributes are invalid" do
|
33
|
-
|
33
|
+
expect {
|
34
34
|
PureValidator::Validators::LengthValidator.validate_options(max: 5, wrong_attr: 3)
|
35
|
-
|
35
|
+
}.to raise_error("validation_rule has unacceptable options [:wrong_attr]")
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -35,9 +35,9 @@ describe PureValidator::Validators::NotNilValidator do
|
|
35
35
|
|
36
36
|
describe ".validate_options" do
|
37
37
|
it "should raise error if validation attributes are invalid" do
|
38
|
-
|
38
|
+
expect{
|
39
39
|
PureValidator::Validators::NotNilValidator.validate_options("asdf")
|
40
|
-
|
40
|
+
}.to raise_error("validation_rule should be a Boolean")
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -1,49 +1,53 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe PureValidator::Validators::NumericalityValidator do
|
4
|
+
def validate(*args)
|
5
|
+
PureValidator::Validators::NumericalityValidator.validate(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def passes(v)
|
9
|
+
expect(v).to be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
def fails(v, errors)
|
13
|
+
expect(v).to eq(errors)
|
14
|
+
end
|
15
|
+
|
4
16
|
describe ".validate" do
|
5
17
|
it "should return empty errors if number is valid" do
|
6
|
-
|
7
|
-
errors.should be_empty
|
18
|
+
passes(validate(4, less_than: 5, greater_than: 3))
|
8
19
|
end
|
9
20
|
|
10
21
|
it "should return errors if value is less than needed" do
|
11
|
-
|
12
|
-
errors.should == ["should be greater than 5"]
|
22
|
+
fails(validate(5, greater_than: 5), ["should be greater than 5"])
|
13
23
|
end
|
14
24
|
|
15
25
|
it "should return errors if value is less than or equal to what needed" do
|
16
|
-
|
17
|
-
errors.should == ["should be greater than or equal to 5"]
|
26
|
+
fails(validate(4, greater_than_or_equal_to: 5), ["should be greater than or equal to 5"])
|
18
27
|
end
|
19
28
|
|
20
29
|
it "should return errors if value is greater than needed" do
|
21
|
-
|
22
|
-
errors.should == ["should be less than 5"]
|
30
|
+
fails(validate(5, less_than: 5), ["should be less than 5"])
|
23
31
|
end
|
24
32
|
|
25
33
|
it "should return errors if value is greater than or equal to what needed" do
|
26
|
-
|
27
|
-
errors.should == ["should be less than or equal to 5"]
|
34
|
+
fails(validate(6, less_than_or_equal_to: 5), ["should be less than or equal to 5"])
|
28
35
|
end
|
29
36
|
|
30
37
|
it "should return errors if value is not even" do
|
31
|
-
|
32
|
-
errors.should == ["should be even number"]
|
38
|
+
fails(validate(7, even: true), ["should be even number"])
|
33
39
|
end
|
34
40
|
|
35
41
|
it "should return errors if value is not odd" do
|
36
|
-
|
37
|
-
errors.should == ["should be odd number"]
|
42
|
+
fails(validate(6, odd: true), ["should be odd number"])
|
38
43
|
end
|
39
|
-
|
40
44
|
end
|
41
45
|
|
42
46
|
describe ".validate_options" do
|
43
47
|
it "should raise error if validation attributes are invalid" do
|
44
|
-
|
48
|
+
expect{
|
45
49
|
PureValidator::Validators::NumericalityValidator.validate_options(less_than: 5, wrong_attr: 3)
|
46
|
-
|
50
|
+
}.to raise_error("validation_rule has unacceptable options [:wrong_attr]")
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -29,9 +29,9 @@ describe PureValidator::Validators::PresenceValidator do
|
|
29
29
|
|
30
30
|
describe ".validate_options" do
|
31
31
|
it "should raise error if validation attributes are invalid" do
|
32
|
-
|
32
|
+
expect {
|
33
33
|
PureValidator::Validators::PresenceValidator.validate_options("asdf")
|
34
|
-
|
34
|
+
}.to raise_error("validation_rule should be a Boolean")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -1,23 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe PureValidator::Validators::RegexpValidator do
|
4
|
+
def validate(*args)
|
5
|
+
PureValidator::Validators::RegexpValidator.validate(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def passes(v)
|
9
|
+
expect(v).to be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
def fails(v, errors)
|
13
|
+
expect(v).to eq(errors)
|
14
|
+
end
|
15
|
+
|
4
16
|
describe ".validate" do
|
5
17
|
it "should return empty errors if value is valid" do
|
6
|
-
|
7
|
-
errors.should be_empty
|
18
|
+
passes(validate('#aaa', /#\w{3,6}/))
|
8
19
|
end
|
9
20
|
|
10
21
|
it "should return errors if value is invalid" do
|
11
|
-
|
12
|
-
errors.should == ["does not match defined format"]
|
22
|
+
fails(validate('asdf', /#\w{3,6}/), ["does not match defined format"])
|
13
23
|
end
|
14
24
|
end
|
15
25
|
|
16
26
|
describe ".validate_options" do
|
17
27
|
it "should raise error if validation attributes are invalid" do
|
18
|
-
|
28
|
+
expect {
|
19
29
|
PureValidator::Validators::RegexpValidator.validate_options({})
|
20
|
-
|
30
|
+
}.to raise_error("validation_rule should be a String or Regexp")
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
@@ -1,35 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe PureValidator::Validators::UrlValidator do
|
4
|
+
def validate(*args)
|
5
|
+
PureValidator::Validators::UrlValidator.validate(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def passes(v)
|
9
|
+
expect(v).to be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
def fails(v, errors)
|
13
|
+
expect(v).to eq(errors)
|
14
|
+
end
|
15
|
+
|
4
16
|
describe ".validate" do
|
5
17
|
it "should return empty errors if email is valid" do
|
6
|
-
|
7
|
-
errors.should be_empty
|
18
|
+
passes(validate('example-asdf.com', true))
|
8
19
|
end
|
9
20
|
|
10
21
|
it "should return errors if value is invalid" do
|
11
|
-
|
12
|
-
errors.should == ["invalid url"]
|
22
|
+
fails(validate(':123asdffd.com', true), ["invalid url"])
|
13
23
|
end
|
14
24
|
|
15
25
|
context "false as url_flag" do
|
16
26
|
it "fails if url is valid" do
|
17
|
-
|
18
|
-
expect(errors).to eq(["can not be a url"])
|
27
|
+
fails(validate('example-asdf.com', false), ["can not be a url"])
|
19
28
|
end
|
20
29
|
|
21
30
|
it "passes if url is invalid" do
|
22
|
-
|
23
|
-
expect(errors).to eq([])
|
31
|
+
passes(validate(':123asdffd.com', false))
|
24
32
|
end
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
28
36
|
describe ".validate_options" do
|
29
37
|
it "should raise error if validation attributes are invalid" do
|
30
|
-
|
38
|
+
expect{
|
31
39
|
PureValidator::Validators::UrlValidator.validate_options("asdf")
|
32
|
-
|
40
|
+
}.to raise_error("validation_rule should be a Boolean")
|
33
41
|
end
|
34
42
|
end
|
35
43
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pure_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert Gazizov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: i18n
|
@@ -89,14 +89,18 @@ executables:
|
|
89
89
|
extensions: []
|
90
90
|
extra_rdoc_files: []
|
91
91
|
files:
|
92
|
+
- ".codeclimate.yml"
|
92
93
|
- ".gitignore"
|
93
94
|
- ".travis.yml"
|
95
|
+
- CHANGELOG.md
|
94
96
|
- Gemfile
|
95
97
|
- Gemfile.lock
|
96
98
|
- LICENSE.txt
|
97
99
|
- README.md
|
98
100
|
- Rakefile
|
99
101
|
- bin/console
|
102
|
+
- docs/_config.yml
|
103
|
+
- docs/index.md
|
100
104
|
- lib/pure_validator.rb
|
101
105
|
- lib/pure_validator/args_validator.rb
|
102
106
|
- lib/pure_validator/concern.rb
|
@@ -123,6 +127,7 @@ files:
|
|
123
127
|
- spec/pure_validator/args_validator_spec.rb
|
124
128
|
- spec/pure_validator/errors_spec.rb
|
125
129
|
- spec/pure_validator/validation_errors_spec.rb
|
130
|
+
- spec/pure_validator/validator_hash_spec.rb
|
126
131
|
- spec/pure_validator/validator_spec.rb
|
127
132
|
- spec/pure_validator/validators/email_validator_spec.rb
|
128
133
|
- spec/pure_validator/validators/exclusion_validator_spec.rb
|
@@ -154,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
159
|
version: '0'
|
155
160
|
requirements: []
|
156
161
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.
|
162
|
+
rubygems_version: 2.6.11
|
158
163
|
signing_key:
|
159
164
|
specification_version: 4
|
160
165
|
summary: Moves validation logic to validators
|
@@ -162,6 +167,7 @@ test_files:
|
|
162
167
|
- spec/pure_validator/args_validator_spec.rb
|
163
168
|
- spec/pure_validator/errors_spec.rb
|
164
169
|
- spec/pure_validator/validation_errors_spec.rb
|
170
|
+
- spec/pure_validator/validator_hash_spec.rb
|
165
171
|
- spec/pure_validator/validator_spec.rb
|
166
172
|
- spec/pure_validator/validators/email_validator_spec.rb
|
167
173
|
- spec/pure_validator/validators/exclusion_validator_spec.rb
|