validator 0.0.2 → 0.1.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.
- data/.travis.yml +6 -0
- data/README.markdown +17 -5
- data/lib/active_model/validations/email_validator.rb +67 -0
- data/lib/validator/email.rb +38 -0
- data/lib/validator/locale/en.yml +7 -0
- data/lib/validator/version.rb +1 -1
- data/lib/validator.rb +2 -1
- data/spec/domain_validator_spec.rb +2 -2
- data/spec/email_validator_spec.rb +133 -0
- data/spec/test_classes/email.rb +17 -0
- data/validator.gemspec +5 -5
- metadata +13 -22
data/.travis.yml
ADDED
data/README.markdown
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
Active Model Validator
|
1
|
+
Active Model Validator [](http://travis-ci.org/nahaylo/validator)
|
2
2
|
============================
|
3
3
|
|
4
|
-
This is a ActiveModel validators for domains and
|
4
|
+
This is a ActiveModel validators for domains, ip addresses and email addresses.
|
5
5
|
|
6
6
|
Installation
|
7
7
|
------------
|
@@ -10,11 +10,12 @@ Installation
|
|
10
10
|
Usage
|
11
11
|
-------
|
12
12
|
|
13
|
-
In your models, the gem provides new validators like :domain or :
|
13
|
+
In your models, the gem provides new validators like :domain, :ip_address or :email
|
14
14
|
|
15
15
|
class Model < ActiveRecord::Base
|
16
16
|
validates :domain_name, :domain => true
|
17
17
|
validates :ip, :ip_address => true
|
18
|
+
validates :email_address, :email => true
|
18
19
|
end
|
19
20
|
|
20
21
|
|
@@ -23,9 +24,9 @@ Domain Validator
|
|
23
24
|
|
24
25
|
validates :domain_name, :domain => true
|
25
26
|
|
26
|
-
validates :domain_name, :domain => {:message => 'custom message'}
|
27
|
+
validates :domain_name, :domain => { :message => 'custom message' }
|
27
28
|
|
28
|
-
# custom full domain
|
29
|
+
# custom full domain and label length
|
29
30
|
validates :domain_name, :domain => { :length => 200, :label_length => 60 }
|
30
31
|
|
31
32
|
|
@@ -47,6 +48,17 @@ Ip Address Validator
|
|
47
48
|
validates :ip, :ip_address => { :message => "custom message" }
|
48
49
|
|
49
50
|
|
51
|
+
Email Address Validator
|
52
|
+
-----------------------
|
53
|
+
|
54
|
+
validates :email_address, :email => true
|
55
|
+
|
56
|
+
validates :email_address, :email => { :message => 'custom message' }
|
57
|
+
|
58
|
+
# custom local part, full domain and label length of email address
|
59
|
+
validates :email_address, :email => { :local_length => 60, :domain => { :length => 200, :label_length => 60 }}
|
60
|
+
|
61
|
+
|
50
62
|
Localization Tricks
|
51
63
|
-------------------
|
52
64
|
To customize error message, you can use { :message => "your custom message" } or simple use Rails localization en.yml file, for instance:
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ActiveModel
|
2
|
+
module Validations
|
3
|
+
class EmailValidator < ActiveModel::EachValidator
|
4
|
+
def initialize(options)
|
5
|
+
options[:local_length] ||= ::Validator::Email::LOCAL_LENGTH
|
6
|
+
|
7
|
+
options[:domain] ||= {}
|
8
|
+
options[:domain_length] = options[:domain][:length] ||= ::Validator::Domain::LENGTH
|
9
|
+
options[:domain_label_length] = options[:domain][:label_length] ||= ::Validator::Domain::LABEL_LENGTH
|
10
|
+
|
11
|
+
super(options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_each(record, attr_name, value)
|
15
|
+
# do not validate if value is empty
|
16
|
+
return if value.nil?
|
17
|
+
|
18
|
+
@validator = ::Validator::Email.new(value)
|
19
|
+
|
20
|
+
unless @validator.is_email?
|
21
|
+
record.errors.add(attr_name, :'email.invalid', options)
|
22
|
+
return false
|
23
|
+
end
|
24
|
+
|
25
|
+
unless @validator.valid_by_local_length?(options[:local_length])
|
26
|
+
record.errors.add(attr_name, :'email.local_length', options)
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
unless @validator.valid_by_regexp?
|
31
|
+
record.errors.add(attr_name, :'email.invalid', options)
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
|
35
|
+
# validate domain part of email address
|
36
|
+
@domain_validator = ::Validator::Domain.new(@validator.domain)
|
37
|
+
|
38
|
+
# max domain length
|
39
|
+
unless @domain_validator.valid_by_length?(options[:domain_length])
|
40
|
+
record.errors.add(attr_name, :'email.domain.length', options)
|
41
|
+
end
|
42
|
+
|
43
|
+
# label is limited to between 1 and 63 octets
|
44
|
+
unless @domain_validator.valid_by_label_length?(options[:domain_label_length])
|
45
|
+
record.errors.add(attr_name, :'email.domain.label_length', options)
|
46
|
+
end
|
47
|
+
|
48
|
+
# skip proceeding validation if errors
|
49
|
+
return unless record.errors.blank?
|
50
|
+
|
51
|
+
unless @domain_validator.valid_by_regexp?
|
52
|
+
record.errors.add(attr_name, :'email.domain.invalid', options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module HelperMethods
|
58
|
+
# class User < ActiveRecord::Base
|
59
|
+
# validates_email_of :email_address
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
def validates_email_of(*attr_names)
|
63
|
+
validates_with EmailValidator, _merge_attributes(attr_names)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Validator
|
2
|
+
class Email
|
3
|
+
attr_accessor :domain
|
4
|
+
|
5
|
+
# Returns the local part (the left hand side of the @ sign in the email address) of the address
|
6
|
+
# a = Email.new('vitaliy@gmail.com')
|
7
|
+
# a.local #=> 'vitaliy'
|
8
|
+
attr_accessor :local
|
9
|
+
|
10
|
+
LOCAL_LENGTH = 64
|
11
|
+
|
12
|
+
def initialize(value)
|
13
|
+
@value = value
|
14
|
+
self.parse
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse
|
18
|
+
@local, @domain = @value.split(/@/)
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_email?
|
22
|
+
@value.split(/@/).size == 2
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid_by_local_length?(local_length = nil)
|
26
|
+
@local.length <= (local_length || LOCAL_LENGTH)
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_by_regexp?
|
30
|
+
@value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
31
|
+
end
|
32
|
+
|
33
|
+
# valid if passes all conditions
|
34
|
+
def valid?
|
35
|
+
is_email? and valid_by_local_length? and valid_by_regexp?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/validator/locale/en.yml
CHANGED
@@ -14,3 +14,10 @@ en:
|
|
14
14
|
prefix_invalid:
|
15
15
|
ipv4: "prefix must be in range 1..32"
|
16
16
|
ipv6: "prefix must be in range 1..128"
|
17
|
+
email:
|
18
|
+
invalid: "invalid email address"
|
19
|
+
local_length: "local part of email address is limited to %{local_length} characters"
|
20
|
+
domain:
|
21
|
+
invalid: "invalid domain name"
|
22
|
+
length: "domain name length is limited to %{domain_length} characters"
|
23
|
+
label_length: "domain label length is limited to %{domain_label_length} characters"
|
data/lib/validator/version.rb
CHANGED
data/lib/validator.rb
CHANGED
@@ -4,9 +4,10 @@ require "active_support/inflector"
|
|
4
4
|
|
5
5
|
require "active_model/validations/domain_validator"
|
6
6
|
require "active_model/validations/ip_address_validator"
|
7
|
+
require "active_model/validations/email_validator"
|
7
8
|
|
8
9
|
module Validator
|
9
|
-
%w(domain version ip_address).each do |model|
|
10
|
+
%w(domain version ip_address email).each do |model|
|
10
11
|
autoload model.camelize.to_sym, "validator/#{model}"
|
11
12
|
end
|
12
13
|
end
|
@@ -62,12 +62,12 @@ module ActiveModel
|
|
62
62
|
|
63
63
|
describe 'invalid' do
|
64
64
|
it {
|
65
|
-
domain.domain_name = "
|
65
|
+
domain.domain_name = "not-valid-because-of-length-#{'w'*230}.com"
|
66
66
|
domain.should have_errors_on(:domain_name, 2).with_message(I18n.t(:'errors.messages.domain.length', :length => 255))
|
67
67
|
}
|
68
68
|
|
69
69
|
it {
|
70
|
-
domain.domain_name = "
|
70
|
+
domain.domain_name = "not-valid-because-of-length-of-label#{'w'*230}.com"
|
71
71
|
domain.should have_errors_on(:domain_name, 2).with_message(I18n.t(:'errors.messages.domain.label_length', :label_length => 63))
|
72
72
|
}
|
73
73
|
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_classes/email'
|
3
|
+
|
4
|
+
module ActiveModel
|
5
|
+
module Validations
|
6
|
+
describe EmailValidator do
|
7
|
+
let(:email) { TestEmail.new }
|
8
|
+
let(:email_with_domain_length) { TestEmailWithDomainLength.new }
|
9
|
+
let(:email_with_message) { TestEmailWithMessage.new }
|
10
|
+
|
11
|
+
describe "validations" do
|
12
|
+
# for blank email
|
13
|
+
it { email.should be_valid }
|
14
|
+
|
15
|
+
describe 'valid' do
|
16
|
+
|
17
|
+
it {
|
18
|
+
[
|
19
|
+
"a+b@plus-in-local.com",
|
20
|
+
"a_b@underscore-in-local.com",
|
21
|
+
"user@example.com",
|
22
|
+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@letters-in-local.org",
|
23
|
+
"01234567890@numbers-in-local.net",
|
24
|
+
"a@single-character-in-local.org",
|
25
|
+
"one-character-third-level@a.example.com",
|
26
|
+
"single-character-in-sld@x.org",
|
27
|
+
"local@dash-in-sld.com",
|
28
|
+
"letters-in-sld@123.com",
|
29
|
+
"one-letter-sld@x.org",
|
30
|
+
"uncommon-tld@sld.museum",
|
31
|
+
"uncommon-tld@sld.travel",
|
32
|
+
"uncommon-tld@sld.mobi",
|
33
|
+
"country-code-tld@sld.uk",
|
34
|
+
"country-code-tld@sld.rw",
|
35
|
+
"local@sld.newTLD",
|
36
|
+
"local@sub.domains.com",
|
37
|
+
"aaa@bbb.co.jp",
|
38
|
+
"nigel.worthington@big.co.uk",
|
39
|
+
"f@c.com",
|
40
|
+
"areallylongnameaasdfasdfasdfasdf@asdfasdfasdfasdfasdf.ab.cd.ef.gh.co.ca",
|
41
|
+
"valid@#{'a'*63}.#{'b'*63}.#{'c'*63}.#{'d'*59}.com",
|
42
|
+
"valid@#{'w'*63}.com"
|
43
|
+
].each do |e|
|
44
|
+
email.email = e
|
45
|
+
email.should_not have_errors_on(:email)
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
it "should be valid with local part length 64" do
|
50
|
+
email.email = "valid_because_of_length#{'w'*41}@valid.domain.com"
|
51
|
+
email.should_not have_errors_on(:email)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be valid for custom length and label length" do
|
55
|
+
email_with_domain_length.email = "valid@valid-domain.com"
|
56
|
+
email_with_domain_length.should be_valid
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'invalid' do
|
62
|
+
it "if consists of more then two @" do
|
63
|
+
email.email = 'invali@email@domain.com'
|
64
|
+
email.should have_errors_on(:email).with_message(I18n.t(:'errors.messages.email.invalid'))
|
65
|
+
end
|
66
|
+
|
67
|
+
it {
|
68
|
+
email.email = "invalid_because_of_length#{'w'*41}@valid.domain.com"
|
69
|
+
email.should have_errors_on(:email).with_message(I18n.t(:'errors.messages.email.local_length', :local_length => 64))
|
70
|
+
}
|
71
|
+
|
72
|
+
it {
|
73
|
+
[
|
74
|
+
"f@s",
|
75
|
+
"f@s.c",
|
76
|
+
"@bar.com",
|
77
|
+
"test@example.com@example.com",
|
78
|
+
"test@",
|
79
|
+
"@missing-local.org",
|
80
|
+
"a b@space-in-local.com",
|
81
|
+
"! \#$%\`|@invalid-characters-in-local.org",
|
82
|
+
"<>@[]\`|@even-more-invalid-characters-in-local.org",
|
83
|
+
"missing-sld@.com",
|
84
|
+
"invalid-characters-in-sld@! \"\#$%(),/;<>_[]\`|.org",
|
85
|
+
"missing-dot-before-tld@com",
|
86
|
+
"missing-tld@sld.",
|
87
|
+
"missing-at-sign.net",
|
88
|
+
"unbracketed-IP@127.0.0.1",
|
89
|
+
"invalid-ip@127.0.0.1.26",
|
90
|
+
"another-invalid-ip@127.0.0.256",
|
91
|
+
"IP-and-port@127.0.0.1:25",
|
92
|
+
"the-local-part-is-invalid-if-it-is-longer-than-sixty-four-characters@sld.net",
|
93
|
+
"valid@not-valid-because-of-length-#{'w'*230}.com"
|
94
|
+
].each do |e|
|
95
|
+
email.email = e
|
96
|
+
email.should have_errors_on(:email)#.with_message(I18n.t(:'errors.messages.email.invalid_format'))
|
97
|
+
#puts email.errors.full_messages
|
98
|
+
end
|
99
|
+
}
|
100
|
+
|
101
|
+
it {
|
102
|
+
email.email = "valid-local-part@not-valid-because-of-length-#{'w'*230}.com"
|
103
|
+
email.should have_errors_on(:email).with_message(I18n.t(:'errors.messages.email.domain.length', :domain_length => 255))
|
104
|
+
}
|
105
|
+
|
106
|
+
it {
|
107
|
+
email.email = "valid-local-part@not-valid-because-of-length-of-label#{'w'*230}.com"
|
108
|
+
email.should have_errors_on(:email, 2).with_message(I18n.t(:'errors.messages.email.domain.label_length', :domain_label_length => 63))
|
109
|
+
}
|
110
|
+
|
111
|
+
it {
|
112
|
+
email.email = "valid-local-part@#{'w'*64}.com"
|
113
|
+
email.should have_errors_on(:email).with_message(I18n.t(:'errors.messages.email.domain.label_length', :domain_label_length => 63))
|
114
|
+
}
|
115
|
+
|
116
|
+
context 'custom full domain length and label length' do
|
117
|
+
it {
|
118
|
+
email_with_domain_length.email = "valid-local-part@#{'w'*61}.com"
|
119
|
+
email_with_domain_length.should have_errors_on(:email).with_message(I18n.t(:'errors.messages.email.domain.label_length', :domain_label_length => 60))
|
120
|
+
}
|
121
|
+
|
122
|
+
it {
|
123
|
+
email_with_domain_length.email = "valid-local-part@not-valid-because-of-length-#{'w'*190}.com"
|
124
|
+
email_with_domain_length.should have_errors_on(:email).with_message(I18n.t(:'errors.messages.email.domain.length', :domain_length => 200))
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class BaseTestEmail
|
2
|
+
include ActiveModel::Validations
|
3
|
+
|
4
|
+
attr_accessor :email
|
5
|
+
end
|
6
|
+
|
7
|
+
class TestEmail < BaseTestEmail
|
8
|
+
validates :email, :email => true
|
9
|
+
end
|
10
|
+
|
11
|
+
class TestEmailWithDomainLength < BaseTestEmail
|
12
|
+
validates :email, :email => { :domain => { :length => 200, :label_length => 60 } }
|
13
|
+
end
|
14
|
+
|
15
|
+
class TestEmailWithMessage < BaseTestEmail
|
16
|
+
validates :email, :email => { :message => 'invalid' }
|
17
|
+
end
|
data/validator.gemspec
CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Validator::VERSION
|
8
8
|
s.authors = ["Vitaliy Nahaylo"]
|
9
9
|
s.email = ["nahaylo@gmail.com"]
|
10
|
-
s.homepage = ""
|
11
|
-
s.summary = "
|
12
|
-
s.description = "
|
10
|
+
s.homepage = "https://github.com/nahaylo/validator"
|
11
|
+
s.summary = "ActiveModel validations for domains, ip addresses and email addresses with fully localization support."
|
12
|
+
s.description = "ActiveModel validations for domains, ip addresses and email addresses with fully localization support."
|
13
13
|
|
14
14
|
s.rubyforge_project = "validator"
|
15
15
|
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_dependency "ipaddress"
|
22
|
-
s.add_runtime_dependency 'activemodel',
|
23
|
-
s.add_development_dependency 'activesupport',
|
22
|
+
s.add_runtime_dependency 'activemodel', '>= 3.0.0'
|
23
|
+
s.add_development_dependency 'activesupport', '>= 3.0.0'
|
24
24
|
s.add_development_dependency "rspec"
|
25
25
|
end
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Vitaliy Nahaylo
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-02-20 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -46,14 +46,6 @@ dependencies:
|
|
46
46
|
- 0
|
47
47
|
- 0
|
48
48
|
version: 3.0.0
|
49
|
-
- - <
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
hash: 15
|
52
|
-
segments:
|
53
|
-
- 3
|
54
|
-
- 2
|
55
|
-
- 0
|
56
|
-
version: 3.2.0
|
57
49
|
type: :runtime
|
58
50
|
version_requirements: *id002
|
59
51
|
- !ruby/object:Gem::Dependency
|
@@ -70,14 +62,6 @@ dependencies:
|
|
70
62
|
- 0
|
71
63
|
- 0
|
72
64
|
version: 3.0.0
|
73
|
-
- - <
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
hash: 15
|
76
|
-
segments:
|
77
|
-
- 3
|
78
|
-
- 2
|
79
|
-
- 0
|
80
|
-
version: 3.2.0
|
81
65
|
type: :development
|
82
66
|
version_requirements: *id003
|
83
67
|
- !ruby/object:Gem::Dependency
|
@@ -94,7 +78,7 @@ dependencies:
|
|
94
78
|
version: "0"
|
95
79
|
type: :development
|
96
80
|
version_requirements: *id004
|
97
|
-
description:
|
81
|
+
description: ActiveModel validations for domains, ip addresses and email addresses with fully localization support.
|
98
82
|
email:
|
99
83
|
- nahaylo@gmail.com
|
100
84
|
executables: []
|
@@ -105,25 +89,30 @@ extra_rdoc_files: []
|
|
105
89
|
|
106
90
|
files:
|
107
91
|
- .gitignore
|
92
|
+
- .travis.yml
|
108
93
|
- Gemfile
|
109
94
|
- LICENSE
|
110
95
|
- README.markdown
|
111
96
|
- Rakefile
|
112
97
|
- lib/active_model/validations/domain_validator.rb
|
98
|
+
- lib/active_model/validations/email_validator.rb
|
113
99
|
- lib/active_model/validations/ip_address_validator.rb
|
114
100
|
- lib/validator.rb
|
115
101
|
- lib/validator/domain.rb
|
102
|
+
- lib/validator/email.rb
|
116
103
|
- lib/validator/ip_address.rb
|
117
104
|
- lib/validator/locale/en.yml
|
118
105
|
- lib/validator/version.rb
|
119
106
|
- spec/domain_validator_spec.rb
|
107
|
+
- spec/email_validator_spec.rb
|
120
108
|
- spec/ip_address_validator_spec.rb
|
121
109
|
- spec/spec_helper.rb
|
122
110
|
- spec/test_classes/domain.rb
|
111
|
+
- spec/test_classes/email.rb
|
123
112
|
- spec/test_classes/ip_address.rb
|
124
113
|
- validator.gemspec
|
125
114
|
has_rdoc: true
|
126
|
-
homepage:
|
115
|
+
homepage: https://github.com/nahaylo/validator
|
127
116
|
licenses: []
|
128
117
|
|
129
118
|
post_install_message:
|
@@ -155,10 +144,12 @@ rubyforge_project: validator
|
|
155
144
|
rubygems_version: 1.5.0
|
156
145
|
signing_key:
|
157
146
|
specification_version: 3
|
158
|
-
summary:
|
147
|
+
summary: ActiveModel validations for domains, ip addresses and email addresses with fully localization support.
|
159
148
|
test_files:
|
160
149
|
- spec/domain_validator_spec.rb
|
150
|
+
- spec/email_validator_spec.rb
|
161
151
|
- spec/ip_address_validator_spec.rb
|
162
152
|
- spec/spec_helper.rb
|
163
153
|
- spec/test_classes/domain.rb
|
154
|
+
- spec/test_classes/email.rb
|
164
155
|
- spec/test_classes/ip_address.rb
|