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 ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby
6
+ script: "rspec spec"
data/README.markdown CHANGED
@@ -1,7 +1,7 @@
1
- Active Model Validator
1
+ Active Model Validator [![Travis](https://secure.travis-ci.org/nahaylo/validator.png)](http://travis-ci.org/nahaylo/validator)
2
2
  ============================
3
3
 
4
- This is a ActiveModel validators for domains and ip addresses.
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 :ip_address
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 length and label length
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
@@ -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"
@@ -1,3 +1,3 @@
1
1
  module Validator
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
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 = "not_valid_because_of_length_#{'w'*230}.com"
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 = "not_valid_because_of_length_of_label#{'w'*230}.com"
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 = "Validator"
12
- s.description = "Validators for domains and ip addresses"
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', ['>= 3.0.0', '< 3.2.0']
23
- s.add_development_dependency 'activesupport', ['>= 3.0.0', '< 3.2.0']
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
- - 2
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-01-24 00:00:00 +02:00
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: Validators for domains and ip addresses
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: Validator
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