validates 0.0.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +14 -1
- data/.yardopts +3 -1
- data/CHANGELOG.md +3 -0
- data/CONTRIBUTING.md +33 -0
- data/Gemfile +5 -3
- data/LICENSE +2 -2
- data/README.md +64 -36
- data/gemfiles/Gemfile.activemodel-3.0 +8 -0
- data/gemfiles/Gemfile.activemodel-4.0 +8 -0
- data/lib/absolute_path_validator.rb +13 -0
- data/lib/association_length_validator.rb +0 -2
- data/lib/color_validator.rb +10 -0
- data/lib/email_validator.rb +32 -58
- data/lib/ip_validator.rb +7 -0
- data/lib/money_validator.rb +1 -1
- data/lib/slug_validator.rb +2 -2
- data/lib/uri_component_validator.rb +19 -0
- data/lib/url_validator.rb +8 -2
- data/lib/validates.rb +2 -1
- data/lib/validates/version.rb +1 -1
- data/test/lib/absolute_path_validator_test.rb +16 -0
- data/test/lib/color_validator_test.rb +48 -0
- data/test/lib/email_validator_test.rb +14 -4
- data/test/lib/ip_validator_test.rb +40 -0
- data/test/lib/money_validator_test.rb +41 -0
- data/test/lib/slug_validator_test.rb +41 -0
- data/test/lib/uri_component_validator_test.rb +29 -0
- data/test/lib/url_validator_test.rb +43 -0
- data/test/support/model.rb +5 -0
- data/test/test_helper.rb +12 -0
- data/validates.gemspec +3 -5
- metadata +34 -8
- data/lib/inn_validator.rb +0 -28
data/.travis.yml
CHANGED
@@ -1,2 +1,15 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1.0
|
6
|
+
- rbx
|
7
|
+
- jruby
|
8
|
+
gemfile:
|
9
|
+
- Gemfile
|
10
|
+
- gemfiles/Gemfile.activemodel-3.0
|
11
|
+
- gemfiles/Gemfile.activemodel-4.0
|
12
|
+
matrix:
|
13
|
+
allow_failures:
|
14
|
+
- rvm: rbx
|
15
|
+
- rvm: jruby
|
data/.yardopts
CHANGED
data/CHANGELOG.md
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
We love pull requests. Here's a quick guide.
|
4
|
+
|
5
|
+
Fork, then clone the repo:
|
6
|
+
|
7
|
+
git clone git@github.com:your-username/validates.git
|
8
|
+
|
9
|
+
Make sure the tests pass:
|
10
|
+
|
11
|
+
rake
|
12
|
+
|
13
|
+
Make your change. Add tests for your change. Make the tests pass:
|
14
|
+
|
15
|
+
rake
|
16
|
+
|
17
|
+
Push to your fork and [submit a pull request][pr].
|
18
|
+
|
19
|
+
[pr]: https://github.com/kaize/validates/compare/
|
20
|
+
|
21
|
+
At this point you're waiting on us. We like to at least comment on pull requests
|
22
|
+
within three business days (and, typically, one business day). We may suggest
|
23
|
+
some changes or improvements or alternatives.
|
24
|
+
|
25
|
+
Some things that will increase the chance that your pull request is accepted:
|
26
|
+
|
27
|
+
* Write tests.
|
28
|
+
* Follow common [style guides][style].
|
29
|
+
* Write a [good commit message][commit].
|
30
|
+
* squash your commits before sending PR.
|
31
|
+
|
32
|
+
[style]: https://github.com/thoughtbot/guides/tree/master/style
|
33
|
+
[commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2012 Mikhail Stolbov
|
1
|
+
Copyright (c) 2012 - 2014 Mikhail Stolbov and kaize
|
2
2
|
|
3
3
|
MIT License
|
4
4
|
|
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,30 +1,39 @@
|
|
1
|
-
# Validates [![Build Status](https://travis-ci.org/kaize/validates.png)](https://travis-ci.org/kaize/validates)
|
1
|
+
# Validates [![Gem Version](https://badge.fury.io/rb/validates.png)](http://badge.fury.io/rb/validates) [![Build Status](https://travis-ci.org/kaize/validates.png)](https://travis-ci.org/kaize/validates) [![Code Climate](https://codeclimate.com/github/kaize/validates.png)](https://codeclimate.com/github/kaize/validates)
|
2
2
|
|
3
|
-
Collection of useful custom validators for Rails
|
3
|
+
Collection of useful custom validators for Rails applications, including:
|
4
4
|
|
5
5
|
- EmailValidator
|
6
6
|
- UrlValidator
|
7
7
|
- SlugValidator
|
8
8
|
- MoneyValidator
|
9
|
-
-
|
9
|
+
- IpValidator
|
10
10
|
- AssociationLengthValidator
|
11
|
+
- AbsolutePathValidator
|
12
|
+
- UriComponentValidator
|
13
|
+
- ColorValidator
|
14
|
+
|
15
|
+
**Note** InnValidator and other Russian specific validators could be found at [validates_russian](https://github.com/asiniy/validates_russian) gem
|
11
16
|
|
12
17
|
## Installation
|
13
18
|
|
14
19
|
Add this line to your application's Gemfile:
|
15
20
|
|
16
|
-
|
21
|
+
``` ruby
|
22
|
+
gem 'validates'
|
23
|
+
```
|
17
24
|
|
18
25
|
Or install it yourself as:
|
19
26
|
|
20
|
-
|
27
|
+
``` bash
|
28
|
+
$ gem install 'validates'
|
29
|
+
```
|
21
30
|
|
22
31
|
## Usage
|
23
32
|
|
24
33
|
For most of the validators you just want to add this line to your model:
|
25
|
-
|
26
|
-
|
27
|
-
|
34
|
+
``` ruby
|
35
|
+
validates :attribute, <validator_underscore>: true
|
36
|
+
```
|
28
37
|
where `<validator_underscore>` is an underscored, lowercase form from the validator's name (see the examples section below).
|
29
38
|
|
30
39
|
### AssociationLengthValidator
|
@@ -36,39 +45,58 @@ which allows you to filter the collection of the associated objects.
|
|
36
45
|
|
37
46
|
## Examples
|
38
47
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
48
|
+
``` ruby
|
49
|
+
class User < ActiveRecord::Base
|
50
|
+
validates :email, :email => true
|
51
|
+
validates :site, :url => true, :allow_blank => true
|
52
|
+
end
|
53
|
+
|
54
|
+
class Company < ActiveRecord::Base
|
55
|
+
# note AssociationLengthValidator is inherited from ActiveModel::Validations::LengthValidator
|
56
|
+
# http://api.rubyonrails.org/classes/ActiveModel/Validations/LengthValidator.html
|
57
|
+
# so you can easily use standard options like :is, :minimum, :maximum, etc.
|
58
|
+
|
59
|
+
validates :employees,
|
60
|
+
:association_length => {
|
61
|
+
:minimum => 1,
|
62
|
+
:select => ->(employee) { employee.name.in? ["Mike", "John"] }
|
63
|
+
}
|
64
|
+
|
65
|
+
validates :employees, :association_length => { :minimum => 1, :select => :employees_filter }
|
44
66
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
67
|
+
def employees_filter(employees)
|
68
|
+
employees.select { |employee| employee.name.in? ["Mike", "John"] }
|
69
|
+
end
|
70
|
+
end
|
49
71
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
:select => ->(employee) { employee.name.in? ["Mike", "John"] }
|
54
|
-
}
|
72
|
+
class Page < ActiveRecord::Base
|
73
|
+
validates :slug, :slug => true
|
74
|
+
end
|
55
75
|
|
56
|
-
|
76
|
+
class Content < ActiveRecord::Base
|
77
|
+
# Validates URI component.
|
78
|
+
# URI component must be of the following type:
|
79
|
+
# :ABS_URI, :REL_URI, :URI_REF, :ABS_URI_REF, :REL_URI_REF, :ESCAPED, :UNSAFE, :SCHEME,
|
80
|
+
# :USERINFO, :HOST, :PORT, :OPAQUE, :REGISTRY, :ABS_PATH, :REL_PATH, :QUERY or :FRAGMENT.
|
81
|
+
# These types are provided URI library. For more info see URI::DEFAULT_PARSER.regexp.
|
57
82
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
83
|
+
validates :path, :uri_component => { :component => :ABS_PATH }
|
84
|
+
end
|
62
85
|
|
63
|
-
|
64
|
-
validates :slug, :slug => true
|
65
|
-
end
|
86
|
+
```
|
66
87
|
|
67
88
|
## Contributing
|
68
89
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
90
|
+
Please see CONTRIBUTING.md for details.
|
91
|
+
|
92
|
+
## Credits
|
93
|
+
|
94
|
+
Originally written by Mikhail Stolbov. Maintained by kaize.
|
95
|
+
|
96
|
+
Thank you to all our amazing [contributors](http://github.com/kaize/validates/contributors)!
|
97
|
+
|
98
|
+
## License
|
99
|
+
|
100
|
+
validates is Copyright © 2012-2014 Mikhail Stolbov and kaize. It is free
|
101
|
+
software, and may be redistributed under the terms specified in the LICENSE
|
102
|
+
file.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AbsolutePathValidator < ActiveModel::EachValidator
|
2
|
+
class << self
|
3
|
+
def valid?(value)
|
4
|
+
Pathname.new(value).absolute?
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate_each(record, attribute, value)
|
9
|
+
unless self.class.valid?(value)
|
10
|
+
record.errors.add(attribute, :absolute_path, options.merge(value: value))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class AssociationLengthValidator < ActiveModel::Validations::LengthValidator
|
2
|
-
|
3
2
|
def validate_each(record, attribute, value)
|
4
3
|
value = value.reject(&:marked_for_destruction?)
|
5
4
|
value = select_items(record, value, options[:select]) if options[:select]
|
@@ -23,5 +22,4 @@ class AssociationLengthValidator < ActiveModel::Validations::LengthValidator
|
|
23
22
|
items
|
24
23
|
end
|
25
24
|
end
|
26
|
-
|
27
25
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class ColorValidator < ActiveModel::EachValidator
|
2
|
+
def validate_each(record, attribute, value)
|
3
|
+
unless value =~ /^[#]([a-f0-9]{3}|[a-f0-9]{6})$/ || COLORS.include?(value)
|
4
|
+
record.errors.add(attribute, :color, options.merge(value: value))
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
# from W3C: http://www.w3.org/TR/css3-color/#svg-color
|
9
|
+
COLORS = %w(aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen)
|
10
|
+
end
|
data/lib/email_validator.rb
CHANGED
@@ -1,76 +1,50 @@
|
|
1
1
|
class EmailValidator < ActiveModel::EachValidator
|
2
|
-
|
3
2
|
def validate_each(record, attribute, value)
|
4
|
-
unless
|
5
|
-
record.errors.add(attribute, :email, options.merge(:
|
3
|
+
unless valid?(value)
|
4
|
+
record.errors.add(attribute, :email, options.merge(value: value))
|
6
5
|
end
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
MAX_DOMAIN_PART_LENGTH = 64
|
15
|
-
|
16
|
-
# Maximum user length
|
17
|
-
MAX_USER_LENGTH = 64
|
18
|
-
|
19
|
-
# User allowed chars
|
20
|
-
LOCAL_ALLOWED_CHARS = '(?:[a-z0-9A-Z\!\#\$\%\&\'\*\-\/\=\?\+\-\^\_\`\{\|\}\~]|(?<!(?:^|\.))\.(?!$))'
|
21
|
-
|
22
|
-
def valid?(value)
|
23
|
-
email_format_valid?(value.to_s)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Validate email format
|
29
|
-
# @params [String] email
|
30
|
-
# @return [true,false,nil]
|
31
|
-
def email_format_valid?(email)
|
32
|
-
|
33
|
-
domain, local= email.reverse.split('@', 2)
|
34
|
-
|
35
|
-
return if email.length > MAX_EMAIL_LENGTH
|
8
|
+
MAX_EMAIL_LENGTH = 254
|
9
|
+
MAX_DOMAIN_LENGTH = 255
|
10
|
+
MAX_DOMAIN_PART_LENGTH = 64
|
11
|
+
MAX_USER_LENGTH = 64
|
12
|
+
LOCAL_ALLOWED_CHARS = '(?:[a-z0-9A-Z\!\#\$\%\&\'\*\-\/\=\?\+\-\^\_\`\{\|\}\~]|(?<!(?:^|\.))\.(?!$))'
|
36
13
|
|
37
|
-
|
14
|
+
private_constant :MAX_EMAIL_LENGTH, :MAX_DOMAIN_LENGTH, :MAX_DOMAIN_PART_LENGTH, :MAX_USER_LENGTH, :LOCAL_ALLOWED_CHARS
|
38
15
|
|
39
|
-
|
40
|
-
local.reverse!
|
16
|
+
private
|
41
17
|
|
42
|
-
|
43
|
-
|
44
|
-
|
18
|
+
def valid?(value)
|
19
|
+
email_format_valid?(value.to_s)
|
20
|
+
end
|
45
21
|
|
46
|
-
|
47
|
-
|
22
|
+
def email_format_valid?(email)
|
23
|
+
domain, local = email.reverse.split('@', 2)
|
48
24
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
parts = domain.downcase.gsub(/(?:^\[(.+)\]$)/,'\1').split('.', -1)
|
25
|
+
return false if domain.blank? || local.blank?
|
26
|
+
return false if email.length > MAX_EMAIL_LENGTH
|
27
|
+
return false if domain.length > MAX_DOMAIN_LENGTH || local.length > MAX_USER_LENGTH
|
28
|
+
return false if !email_domain_syntax_valid?(domain) || !email_local_syntax_valid?(local)
|
54
29
|
|
55
|
-
|
30
|
+
true
|
31
|
+
end
|
56
32
|
|
57
|
-
|
33
|
+
def email_domain_syntax_valid?(domain)
|
34
|
+
parts = domain.reverse.downcase.gsub(/(?:^\[(.+)\]$)/,'\1').split('.', -1)
|
58
35
|
|
59
|
-
|
36
|
+
return false unless parts.all? { |part| part =~ /^(?!\-)[[:alnum:]\-]+(?<!\-)$/ && part.length < MAX_DOMAIN_PART_LENGTH }
|
37
|
+
return true if parts.length == 4 && parts.all? { |part| part =~ /\A[0-9]+\Z/ && part.to_i.between?(0, 255) }
|
38
|
+
return false if parts[-1] =~ /^\d+$/
|
60
39
|
|
61
|
-
|
62
|
-
|
40
|
+
true
|
41
|
+
end
|
63
42
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
true
|
68
|
-
end
|
43
|
+
def email_local_syntax_valid?(local)
|
44
|
+
email_local_syntax_regexp =~ local.reverse
|
45
|
+
end
|
69
46
|
|
70
|
-
|
71
|
-
|
72
|
-
def email_local_syntax_regexp
|
73
|
-
Regexp.new("^(?:\"(?:[\\\\]?#{LOCAL_ALLOWED_CHARS}|\\\\[\"\\s\\\\]|[@])*\"|#{LOCAL_ALLOWED_CHARS}*)$")
|
74
|
-
end
|
47
|
+
def email_local_syntax_regexp
|
48
|
+
Regexp.new("^(?:\"(?:[\\\\]?#{LOCAL_ALLOWED_CHARS}|\\\\[\"\\s\\\\]|[@])*\"|#{LOCAL_ALLOWED_CHARS}*)$")
|
75
49
|
end
|
76
50
|
end
|
data/lib/ip_validator.rb
ADDED
data/lib/money_validator.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class MoneyValidator < ActiveModel::EachValidator
|
2
2
|
def validate_each(record, attribute, value)
|
3
3
|
unless value =~ /^\d+?(?:\.\d{0,2})?$/
|
4
|
-
record.errors.add(attribute, :is_not_money, options.merge(:
|
4
|
+
record.errors.add(attribute, :is_not_money, options.merge(value: value))
|
5
5
|
end
|
6
6
|
end
|
7
7
|
end
|
data/lib/slug_validator.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class SlugValidator < ActiveModel::EachValidator
|
2
2
|
def validate_each(record, attribute, value)
|
3
3
|
unless value =~ /^[\w-]+$/i
|
4
|
-
record.errors.add(attribute, :slug, options.merge(:
|
4
|
+
record.errors.add(attribute, :slug, options.merge(value: value))
|
5
5
|
end
|
6
|
-
end
|
6
|
+
end
|
7
7
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class UriComponentValidator < ActiveModel::EachValidator
|
2
|
+
def validate_each(record, attribute, value)
|
3
|
+
unless value =~ URI::DEFAULT_PARSER.regexp[component]
|
4
|
+
record.errors.add(attribute, :uri_component, options.merge(value: value))
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def check_validity!
|
9
|
+
valid_components = URI::DEFAULT_PARSER.regexp.keys
|
10
|
+
|
11
|
+
if valid_components.exclude? component
|
12
|
+
raise ArgumentError, "Component must be of the following type: #{valid_components}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def component
|
17
|
+
options[:component]
|
18
|
+
end
|
19
|
+
end
|
data/lib/url_validator.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
class UrlValidator < ActiveModel::EachValidator
|
2
2
|
def validate_each(record, attribute, value)
|
3
|
-
unless value
|
4
|
-
record.errors.add(attribute, :url, options.merge(:
|
3
|
+
unless valid?(value)
|
4
|
+
record.errors.add(attribute, :url, options.merge(value: value))
|
5
5
|
end
|
6
6
|
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def valid?(url)
|
11
|
+
(url =~ URI::regexp(%w(http https))) == 0
|
12
|
+
end
|
7
13
|
end
|
data/lib/validates.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'active_support/core_ext/enumerable'
|
2
3
|
require 'active_model'
|
3
4
|
|
4
|
-
[:
|
5
|
+
[:absolute_path, :association_length, :color, :email, :inn, :ip, :money, :slug, :uri_component, :url].each do |name|
|
5
6
|
autoload :"#{name.to_s.classify}Validator", "#{name}_validator"
|
6
7
|
end
|
7
8
|
|
data/lib/validates/version.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AbsolutePathValidatorTest < Minitest::Test
|
4
|
+
def test_valid
|
5
|
+
valid_path = '/some/path'
|
6
|
+
|
7
|
+
assert AbsolutePathValidator.valid?(valid_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_invalid
|
11
|
+
invalid_path = 'some/path'
|
12
|
+
|
13
|
+
refute AbsolutePathValidator.valid?(invalid_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ColorValidatorTest < ValidatorTest
|
4
|
+
|
5
|
+
def test_valid
|
6
|
+
valid_colors = %w(
|
7
|
+
#fff
|
8
|
+
red
|
9
|
+
blueviolet
|
10
|
+
#eeeeee
|
11
|
+
#abc09a
|
12
|
+
black
|
13
|
+
#0cf
|
14
|
+
#012345
|
15
|
+
#6789ab
|
16
|
+
#cdefff
|
17
|
+
green
|
18
|
+
)
|
19
|
+
|
20
|
+
Model.validates :field, color: true
|
21
|
+
|
22
|
+
valid_colors.each do |color|
|
23
|
+
model = Model.new
|
24
|
+
model.field = color
|
25
|
+
|
26
|
+
assert model.valid?, "#{color} not valid"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_invalid
|
31
|
+
invalid_colors = %w(
|
32
|
+
#ffff
|
33
|
+
orange-duck
|
34
|
+
eee
|
35
|
+
xxx
|
36
|
+
epics
|
37
|
+
)
|
38
|
+
|
39
|
+
Model.validates :field, color: true
|
40
|
+
|
41
|
+
invalid_colors.each do |color|
|
42
|
+
model = Model.new
|
43
|
+
model.field = color
|
44
|
+
|
45
|
+
refute model.valid?, "#{color} not valid"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class EmailValidatorTest <
|
3
|
+
class EmailValidatorTest < ValidatorTest
|
4
|
+
|
4
5
|
def test_valid
|
5
6
|
valid_emails = [
|
6
7
|
'user@example.com',
|
@@ -46,8 +47,13 @@ class EmailValidatorTest < Test::Unit::TestCase
|
|
46
47
|
'test@xn--example.com'
|
47
48
|
]
|
48
49
|
|
50
|
+
Model.validates :field, email: true
|
51
|
+
|
49
52
|
valid_emails.each do |email|
|
50
|
-
|
53
|
+
model = Model.new
|
54
|
+
model.field = email
|
55
|
+
|
56
|
+
assert model.valid?, "#{email} not valid"
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
@@ -97,9 +103,13 @@ class EmailValidatorTest < Test::Unit::TestCase
|
|
97
103
|
'first(middle)last@iana.org'
|
98
104
|
]
|
99
105
|
|
106
|
+
Model.validates :field, email: true
|
107
|
+
|
100
108
|
invalid_emails.each do |email|
|
101
|
-
|
109
|
+
model = Model.new
|
110
|
+
model.field = email
|
111
|
+
|
112
|
+
refute model.valid?, "#{email} not valid"
|
102
113
|
end
|
103
114
|
end
|
104
|
-
|
105
115
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class IpValidatorTest < ValidatorTest
|
4
|
+
def test_valid
|
5
|
+
valid_ips = %w(
|
6
|
+
21.189.63.11
|
7
|
+
192.168.0.1
|
8
|
+
127.0.0.1
|
9
|
+
FE80:0000:0000:0000:0202:B3FF:FE1E:8329
|
10
|
+
)
|
11
|
+
|
12
|
+
Model.validates :field, ip: true
|
13
|
+
|
14
|
+
valid_ips.each do |ip|
|
15
|
+
model = Model.new
|
16
|
+
model.field = ip
|
17
|
+
|
18
|
+
assert model.valid?, "#{ip} not valid"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_invalid
|
23
|
+
invalid_ips = %w(
|
24
|
+
epic
|
25
|
+
123.18.18
|
26
|
+
127.0.0.
|
27
|
+
127.0.0.1.0
|
28
|
+
)
|
29
|
+
|
30
|
+
Model.validates :field, ip: true
|
31
|
+
|
32
|
+
invalid_ips.each do |ip|
|
33
|
+
model = Model.new
|
34
|
+
model.field = ip
|
35
|
+
|
36
|
+
refute model.valid?, "#{ip} not valid"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MoneyValidatorTest < ValidatorTest
|
4
|
+
|
5
|
+
def test_valid
|
6
|
+
valid_money_count = %w(
|
7
|
+
100
|
8
|
+
1000.00
|
9
|
+
1456
|
10
|
+
5
|
11
|
+
9000.00
|
12
|
+
)
|
13
|
+
|
14
|
+
Model.validates :field, money: true
|
15
|
+
|
16
|
+
valid_money_count.each do |money_count|
|
17
|
+
model = Model.new
|
18
|
+
model.field = money_count
|
19
|
+
|
20
|
+
assert model.valid?, "#{money_count} not valid"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_invalid
|
25
|
+
invalid_money_cost = %w(
|
26
|
+
orange-duck
|
27
|
+
a11111
|
28
|
+
11111a
|
29
|
+
1234a5678
|
30
|
+
).push('', ' ', nil, {}, [])
|
31
|
+
|
32
|
+
Model.validates :field, money: true
|
33
|
+
|
34
|
+
invalid_money_cost.each do |money_cost|
|
35
|
+
model = Model.new
|
36
|
+
model.field = money_cost
|
37
|
+
|
38
|
+
refute model.valid?, "#{money_cost} not valid"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SlugValidatorTest < ValidatorTest
|
4
|
+
|
5
|
+
def test_valid
|
6
|
+
valid_slugs = %w(
|
7
|
+
home
|
8
|
+
global-news
|
9
|
+
global_news
|
10
|
+
new-2014-year
|
11
|
+
)
|
12
|
+
|
13
|
+
Model.validates :field, slug: true
|
14
|
+
|
15
|
+
valid_slugs.each do |slug|
|
16
|
+
model = Model.new
|
17
|
+
model.field = slug
|
18
|
+
|
19
|
+
assert model.valid?, "#{slug} not valid"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_invalid
|
24
|
+
invalid_slugs = %w(
|
25
|
+
home?
|
26
|
+
hello,world
|
27
|
+
new/page
|
28
|
+
!all'stars
|
29
|
+
hello?
|
30
|
+
)
|
31
|
+
|
32
|
+
Model.validates :field, slug: true
|
33
|
+
|
34
|
+
invalid_slugs.each do |slug|
|
35
|
+
model = Model.new
|
36
|
+
model.field = slug
|
37
|
+
|
38
|
+
refute model.valid?, "#{slug} not valid"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class UriComponentValidatorTest < ValidatorTest
|
4
|
+
|
5
|
+
def test_valid
|
6
|
+
Model.validates :field, uri_component: { component: :ABS_PATH }
|
7
|
+
model = Model.new
|
8
|
+
model.field = '/some/path'
|
9
|
+
|
10
|
+
assert model.valid?
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_invalid
|
14
|
+
Model.validates :field, uri_component: { component: :ABS_PATH }
|
15
|
+
invalid_paths = ['some/path', '/with/space path']
|
16
|
+
|
17
|
+
invalid_paths.each do |path|
|
18
|
+
model = Model.new
|
19
|
+
model.field = path
|
20
|
+
refute model.valid?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_check_arguments
|
25
|
+
assert_raises(ArgumentError) do
|
26
|
+
Model.validates :field, uri_component: { component: :WRONG }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class UrlValidatorTest < ValidatorTest
|
4
|
+
|
5
|
+
def test_valid
|
6
|
+
valid_urls = %w{
|
7
|
+
http://vk.com
|
8
|
+
http://www.mail.ru/secret
|
9
|
+
http://github.com/
|
10
|
+
http://odesk.com/query=ruby+rails
|
11
|
+
http://192.168.0.1
|
12
|
+
http://asiniy.ru
|
13
|
+
https://google.com
|
14
|
+
https://127.0.0.1
|
15
|
+
}
|
16
|
+
|
17
|
+
Model.validates :field, url: true
|
18
|
+
|
19
|
+
valid_urls.each do |url|
|
20
|
+
model = Model.new
|
21
|
+
model.field = url
|
22
|
+
assert model.valid?, "#{url} is not valid"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_invalid
|
27
|
+
invalid_urls = %w{
|
28
|
+
htt://yandex.ru
|
29
|
+
httpns
|
30
|
+
zzzz-mail
|
31
|
+
12345678
|
32
|
+
/1https://vk.com
|
33
|
+
}.push('', ' ', nil)
|
34
|
+
|
35
|
+
Model.validates :field, url: true
|
36
|
+
|
37
|
+
invalid_urls.each do |url|
|
38
|
+
model = Model.new
|
39
|
+
model.field = url
|
40
|
+
refute model.valid?, "#{url} is not valid"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,2 +1,14 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
Bundler.require
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
Dir[File.dirname(__FILE__) + '/support/*.rb'].each{ |file| require file }
|
7
|
+
|
8
|
+
class ValidatorTest < Minitest::Test
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
Model.reset_callbacks(:validate)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/validates.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Mikhail Stolbov","Anton Taraev","Konstantin Kosmatov","Andrey Subbota"]
|
9
9
|
s.email = ["mstolbov@gmail.com","anti191@gmail.com","key@kosmatov.su","subbota@gmail.com"]
|
10
10
|
s.homepage = "http://github.com/kaize/validates"
|
11
|
-
s.summary = %q{Collection of useful custom validators for Rails
|
12
|
-
s.description = %q{validates provides a set of commonly required validators (such as Email, Url, etc.) for Rails
|
11
|
+
s.summary = %q{Collection of useful custom validators for Rails applications}
|
12
|
+
s.description = %q{validates provides a set of commonly required validators (such as Email, Url, etc.) for Rails applications}
|
13
13
|
|
14
14
|
s.rubyforge_project = "validates"
|
15
15
|
|
@@ -20,10 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.rdoc_options = %w(--line-numbers --inline-source --title validates --main README.md)
|
23
|
-
s.extra_rdoc_files = %w(README.md LICENSE)
|
23
|
+
s.extra_rdoc_files = %w(README.md LICENSE CONTRIBUTING.md CHANGELOG.md)
|
24
24
|
|
25
|
-
# specify any dependencies here; for example:
|
26
|
-
# s.add_development_dependency "rspec"
|
27
25
|
s.add_dependency "activemodel", [">= 3.0.0"]
|
28
26
|
s.add_dependency "activesupport", [">= 3.0.0"]
|
29
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validates
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2014-06-18 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activemodel
|
@@ -47,7 +47,7 @@ dependencies:
|
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 3.0.0
|
49
49
|
description: validates provides a set of commonly required validators (such as Email,
|
50
|
-
Url, etc.) for Rails
|
50
|
+
Url, etc.) for Rails applications
|
51
51
|
email:
|
52
52
|
- mstolbov@gmail.com
|
53
53
|
- anti191@gmail.com
|
@@ -58,23 +58,40 @@ extensions: []
|
|
58
58
|
extra_rdoc_files:
|
59
59
|
- README.md
|
60
60
|
- LICENSE
|
61
|
+
- CONTRIBUTING.md
|
62
|
+
- CHANGELOG.md
|
61
63
|
files:
|
62
64
|
- .gitignore
|
63
65
|
- .travis.yml
|
64
66
|
- .yardopts
|
67
|
+
- CHANGELOG.md
|
68
|
+
- CONTRIBUTING.md
|
65
69
|
- Gemfile
|
66
70
|
- LICENSE
|
67
71
|
- README.md
|
68
72
|
- Rakefile
|
73
|
+
- gemfiles/Gemfile.activemodel-3.0
|
74
|
+
- gemfiles/Gemfile.activemodel-4.0
|
75
|
+
- lib/absolute_path_validator.rb
|
69
76
|
- lib/association_length_validator.rb
|
77
|
+
- lib/color_validator.rb
|
70
78
|
- lib/email_validator.rb
|
71
|
-
- lib/
|
79
|
+
- lib/ip_validator.rb
|
72
80
|
- lib/money_validator.rb
|
73
81
|
- lib/slug_validator.rb
|
82
|
+
- lib/uri_component_validator.rb
|
74
83
|
- lib/url_validator.rb
|
75
84
|
- lib/validates.rb
|
76
85
|
- lib/validates/version.rb
|
86
|
+
- test/lib/absolute_path_validator_test.rb
|
87
|
+
- test/lib/color_validator_test.rb
|
77
88
|
- test/lib/email_validator_test.rb
|
89
|
+
- test/lib/ip_validator_test.rb
|
90
|
+
- test/lib/money_validator_test.rb
|
91
|
+
- test/lib/slug_validator_test.rb
|
92
|
+
- test/lib/uri_component_validator_test.rb
|
93
|
+
- test/lib/url_validator_test.rb
|
94
|
+
- test/support/model.rb
|
78
95
|
- test/test_helper.rb
|
79
96
|
- validates.gemspec
|
80
97
|
homepage: http://github.com/kaize/validates
|
@@ -103,9 +120,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
120
|
version: '0'
|
104
121
|
requirements: []
|
105
122
|
rubyforge_project: validates
|
106
|
-
rubygems_version: 1.8.
|
123
|
+
rubygems_version: 1.8.25
|
107
124
|
signing_key:
|
108
125
|
specification_version: 3
|
109
|
-
summary: Collection of useful custom validators for Rails
|
110
|
-
test_files:
|
111
|
-
|
126
|
+
summary: Collection of useful custom validators for Rails applications
|
127
|
+
test_files:
|
128
|
+
- test/lib/absolute_path_validator_test.rb
|
129
|
+
- test/lib/color_validator_test.rb
|
130
|
+
- test/lib/email_validator_test.rb
|
131
|
+
- test/lib/ip_validator_test.rb
|
132
|
+
- test/lib/money_validator_test.rb
|
133
|
+
- test/lib/slug_validator_test.rb
|
134
|
+
- test/lib/uri_component_validator_test.rb
|
135
|
+
- test/lib/url_validator_test.rb
|
136
|
+
- test/support/model.rb
|
137
|
+
- test/test_helper.rb
|
data/lib/inn_validator.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
class InnValidator < ActiveModel::EachValidator
|
2
|
-
def validate_each(record, attribute, inn)
|
3
|
-
result = false
|
4
|
-
p10 = [2, 4, 10, 3, 5, 9, 4, 6, 8]
|
5
|
-
p11 = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8]
|
6
|
-
p12 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8]
|
7
|
-
inn = inn.gsub(/\D/, "") unless inn.nil?
|
8
|
-
inn ||= []
|
9
|
-
if inn.length == 10
|
10
|
-
n10 = calc(p10, inn)
|
11
|
-
result = (n10 == inn[9].to_i)
|
12
|
-
end
|
13
|
-
|
14
|
-
if inn.length == 12
|
15
|
-
n11 = calc(p11, inn)
|
16
|
-
n12 = calc(p12, inn)
|
17
|
-
result = (n11 == inn[10].to_i) && (n12 == inn[11].to_i)
|
18
|
-
end
|
19
|
-
|
20
|
-
unless result
|
21
|
-
record.errors.add(attribute, :inn, options.merge(:value => inn))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def calc(p, inn)
|
26
|
-
p.to_enum(:each_with_index).inject(0){|sum, elem| sum + elem[0].to_f * inn[elem[1]].to_f}%11%10
|
27
|
-
end
|
28
|
-
end
|