pure_validator 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/ddd-ruby/pure_validator.svg)](https://travis-ci.org/ddd-ruby/pure_validator)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/pure_validator.svg)](http://badge.fury.io/rb/pure_validator)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/ddd-ruby/pure_validator/badges/gpa.svg)](https://codeclimate.com/github/ddd-ruby/pure_validator)
|
5
|
+
[![codecov](https://codecov.io/gh/ddd-ruby/pure_validator/branch/master/graph/badge.svg)](https://codecov.io/gh/ddd-ruby/pure_validator)
|
6
|
+
[![Dependency Status](https://gemnasium.com/ddd-ruby/pure_validator.svg)](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 [![Build Status](https://travis-ci.org/ddd-ruby/pure_validator.png)](https://travis-ci.org/ddd-ruby/pure_validator) [![Code Climate](https://codeclimate.com/github/ddd-ruby/pure_validator/badges/gpa.svg)](https://codeclimate.com/github/ddd-ruby/pure_validator) [![codecov](https://codecov.io/gh/ddd-ruby/pure_validator/branch/master/graph/badge.svg)](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
|