pluginaweek-validates_as_email_address 0.2.3
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/CHANGELOG.rdoc +40 -0
- data/LICENSE +2 -0
- data/README.rdoc +59 -0
- data/Rakefile +96 -0
- data/init.rb +1 -0
- data/lib/validates_as_email_address.rb +87 -0
- data/lib/validates_as_email_address/locale.rb +9 -0
- data/lib/validates_as_email_address/rfc_1035.rb +28 -0
- data/lib/validates_as_email_address/rfc_822.rb +38 -0
- data/test/app_root/app/models/user.rb +2 -0
- data/test/app_root/db/migrate/001_create_users.rb +11 -0
- data/test/factory.rb +41 -0
- data/test/test_helper.rb +13 -0
- data/test/unit/validates_as_email_address_test.rb +329 -0
- metadata +73 -0
data/CHANGELOG.rdoc
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
== master
|
|
2
|
+
|
|
3
|
+
== 0.2.3 / 2009-04-13
|
|
4
|
+
|
|
5
|
+
* Update docs
|
|
6
|
+
|
|
7
|
+
== 0.2.2 / 2009-03-15
|
|
8
|
+
|
|
9
|
+
* Add support for Rails 2.2 i18n error messages [Saimon Moore]
|
|
10
|
+
|
|
11
|
+
== 0.2.1 / 2009-01-11
|
|
12
|
+
|
|
13
|
+
* Ensure correct encoding for regular expressions to be compatible with Ruby 1.9+
|
|
14
|
+
|
|
15
|
+
== 0.2.0 / 2008-12-14
|
|
16
|
+
|
|
17
|
+
* Remove the PluginAWeek namespace
|
|
18
|
+
|
|
19
|
+
== 0.1.1 / 2008-10-25
|
|
20
|
+
|
|
21
|
+
* Fix major performance hit on long domains when in strict mode
|
|
22
|
+
* Fix single-character/digit domains not being allowed in strict mode
|
|
23
|
+
|
|
24
|
+
== 0.1.0 / 2008-09-07
|
|
25
|
+
|
|
26
|
+
* Allow all options to be passed to format/length validations so that future options can be defined without changing this plugin
|
|
27
|
+
* Add support for overriding length limits
|
|
28
|
+
* Add support for requiring that domains follow the RFC 1035 format (on by default) [Kacper Bielecki]
|
|
29
|
+
|
|
30
|
+
== 0.0.3 / 2008-06-22
|
|
31
|
+
|
|
32
|
+
* Remove log files from gems
|
|
33
|
+
|
|
34
|
+
== 0.0.2 / 2008-05-05
|
|
35
|
+
|
|
36
|
+
* Update documentation
|
|
37
|
+
|
|
38
|
+
== 0.0.1 / 2007-09-26
|
|
39
|
+
|
|
40
|
+
* Add documentation
|
data/LICENSE
ADDED
data/README.rdoc
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
= validates_as_email_address
|
|
2
|
+
|
|
3
|
+
+validates_as_email_address+ adds support for validating the format/length of
|
|
4
|
+
email addresses.
|
|
5
|
+
|
|
6
|
+
== Resources
|
|
7
|
+
|
|
8
|
+
API
|
|
9
|
+
|
|
10
|
+
* http://api.pluginaweek.org/validates_as_email_address
|
|
11
|
+
|
|
12
|
+
Bugs
|
|
13
|
+
|
|
14
|
+
* http://pluginaweek.lighthouseapp.com/projects/13293-validates_as_email_address
|
|
15
|
+
|
|
16
|
+
Development
|
|
17
|
+
|
|
18
|
+
* http://github.com/pluginaweek/validates_as_email_address
|
|
19
|
+
|
|
20
|
+
Source
|
|
21
|
+
|
|
22
|
+
* git://github.com/pluginaweek/validates_as_email_address.git
|
|
23
|
+
|
|
24
|
+
== Description
|
|
25
|
+
|
|
26
|
+
Consistently reliable email address validations are difficult to find and hard
|
|
27
|
+
to choose as there are far too many implementations in various programming
|
|
28
|
+
languages. This plugins builds on Thijs van der Vossen's validates_as_email
|
|
29
|
+
by adding advanced validation option support and also validating the length of
|
|
30
|
+
the email address.
|
|
31
|
+
|
|
32
|
+
== Usage
|
|
33
|
+
|
|
34
|
+
=== Example
|
|
35
|
+
|
|
36
|
+
class Person < ActiveRecord::Base
|
|
37
|
+
validates_as_email_address :email, :on => :create
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
== Testing
|
|
41
|
+
|
|
42
|
+
Before you can run any tests, the following gem must be installed:
|
|
43
|
+
* plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
|
|
44
|
+
|
|
45
|
+
To run against a specific version of Rails:
|
|
46
|
+
|
|
47
|
+
rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
|
|
48
|
+
|
|
49
|
+
== Dependencies
|
|
50
|
+
|
|
51
|
+
* Rails 2.0 or later
|
|
52
|
+
|
|
53
|
+
== References
|
|
54
|
+
|
|
55
|
+
* Cal Henderson - {Parsing Email Adresses in PHP}[http://iamcal.com/publish/articles/php/parsing_email]
|
|
56
|
+
* Tim Fletcher - {Ruby Translation}[http://tfletcher.com/lib/rfc822.rb]
|
|
57
|
+
* Dan Kubb[dan.kubb@autopilotmarketing.com]
|
|
58
|
+
* Ximon Eighteen[ximon.eightee@int.greenpeace.org]
|
|
59
|
+
* Thijs van der Vossen - validates_as_email[https://svn.greenpeace.org/repositories/rails_plugins/validates_as_email]
|
data/Rakefile
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'rake/testtask'
|
|
2
|
+
require 'rake/rdoctask'
|
|
3
|
+
require 'rake/gempackagetask'
|
|
4
|
+
require 'rake/contrib/sshpublisher'
|
|
5
|
+
|
|
6
|
+
spec = Gem::Specification.new do |s|
|
|
7
|
+
s.name = 'validates_as_email_address'
|
|
8
|
+
s.version = '0.2.3'
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.summary = 'Adds support for validating the format/length of email addresses in ActiveRecord'
|
|
11
|
+
s.description = s.summary
|
|
12
|
+
|
|
13
|
+
s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
|
|
14
|
+
s.require_path = 'lib'
|
|
15
|
+
s.has_rdoc = true
|
|
16
|
+
s.test_files = Dir['test/**/*_test.rb']
|
|
17
|
+
|
|
18
|
+
s.author = 'Aaron Pfeifer'
|
|
19
|
+
s.email = 'aaron@pluginaweek.org'
|
|
20
|
+
s.homepage = 'http://www.pluginaweek.org'
|
|
21
|
+
s.rubyforge_project = 'pluginaweek'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc 'Default: run all tests.'
|
|
25
|
+
task :default => :test
|
|
26
|
+
|
|
27
|
+
desc "Test the #{spec.name} plugin."
|
|
28
|
+
Rake::TestTask.new(:test) do |t|
|
|
29
|
+
t.libs << 'lib'
|
|
30
|
+
t.test_files = spec.test_files
|
|
31
|
+
t.verbose = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
require 'rcov/rcovtask'
|
|
36
|
+
namespace :test do
|
|
37
|
+
desc "Test the #{spec.name} plugin with Rcov."
|
|
38
|
+
Rcov::RcovTask.new(:rcov) do |t|
|
|
39
|
+
t.libs << 'lib'
|
|
40
|
+
t.test_files = spec.test_files
|
|
41
|
+
t.rcov_opts << '--exclude="^(?!lib/)"'
|
|
42
|
+
t.verbose = true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
rescue LoadError
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
desc "Generate documentation for the #{spec.name} plugin."
|
|
49
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
51
|
+
rdoc.title = spec.name
|
|
52
|
+
rdoc.template = '../rdoc_template.rb'
|
|
53
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
54
|
+
rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc 'Generate a gemspec file.'
|
|
58
|
+
task :gemspec do
|
|
59
|
+
File.open("#{spec.name}.gemspec", 'w') do |f|
|
|
60
|
+
f.write spec.to_ruby
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Rake::GemPackageTask.new(spec) do |p|
|
|
65
|
+
p.gem_spec = spec
|
|
66
|
+
p.need_tar = true
|
|
67
|
+
p.need_zip = true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
desc 'Publish the beta gem.'
|
|
71
|
+
task :pgem => [:package] do
|
|
72
|
+
Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
desc 'Publish the API documentation.'
|
|
76
|
+
task :pdoc => [:rdoc] do
|
|
77
|
+
Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
desc 'Publish the API docs and gem'
|
|
81
|
+
task :publish => [:pgem, :pdoc, :release]
|
|
82
|
+
|
|
83
|
+
desc 'Publish the release files to RubyForge.'
|
|
84
|
+
task :release => [:gem, :package] do
|
|
85
|
+
require 'rubyforge'
|
|
86
|
+
|
|
87
|
+
ruby_forge = RubyForge.new.configure
|
|
88
|
+
ruby_forge.login
|
|
89
|
+
|
|
90
|
+
%w(gem tgz zip).each do |ext|
|
|
91
|
+
file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
|
|
92
|
+
puts "Releasing #{File.basename(file)}..."
|
|
93
|
+
|
|
94
|
+
ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
|
|
95
|
+
end
|
|
96
|
+
end
|
data/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'validates_as_email_address'
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require 'validates_as_email_address/rfc_822'
|
|
2
|
+
require 'validates_as_email_address/rfc_1035'
|
|
3
|
+
|
|
4
|
+
# Adds validations for email addresses
|
|
5
|
+
module ValidatesAsEmailAddress
|
|
6
|
+
# The default error message to use for improperly formatted e-mail addresses
|
|
7
|
+
mattr_accessor :invalid_email_message
|
|
8
|
+
self.invalid_email_message = 'is an invalid email address'
|
|
9
|
+
|
|
10
|
+
# Validates whether the value of the specific attribute matches against the
|
|
11
|
+
# RFC822/RFC1035 specification.
|
|
12
|
+
#
|
|
13
|
+
# class Person < ActiveRecord::Base
|
|
14
|
+
# validates_as_email_address :email, :on => :create
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# This will also validate that the email address is within the specification
|
|
18
|
+
# limits, i.e. between 3 and 320 characters in length.
|
|
19
|
+
#
|
|
20
|
+
# Configuration options for length:
|
|
21
|
+
# * <tt>:minimum</tt> - The minimum size of the attribute
|
|
22
|
+
# * <tt>:maximum</tt> - The maximum size of the attribute
|
|
23
|
+
# * <tt>:is</tt> - The exact size of the attribute
|
|
24
|
+
# * <tt>:within</tt> - A range specifying the minimum and maximum size of the
|
|
25
|
+
# attribute
|
|
26
|
+
# * <tt>:in</tt> - A synonym (or alias) for <tt>:within</tt>
|
|
27
|
+
# * <tt>:too_long</tt> - The error message if the attribute goes over the
|
|
28
|
+
# maximum (default is: "is too long (maximum is %d characters)")
|
|
29
|
+
# * <tt>:too_short</tt> - The error message if the attribute goes under the
|
|
30
|
+
# minimum (default is: "is too short (minimum is %d characters)")
|
|
31
|
+
# * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt>
|
|
32
|
+
# method and the attribute is the wrong size (default is:
|
|
33
|
+
# "is the wrong length (should be %d characters)")
|
|
34
|
+
# * <tt>:tokenizer</tt> - Specifies how to split up the attribute string.
|
|
35
|
+
# (e.g. <tt>:tokenizer => lambda {|str| str.scan(/\w+/)}</tt> to count
|
|
36
|
+
# words.) Defaults to <tt>lambda {|value| value.split(//)}</tt> which
|
|
37
|
+
# counts individual characters.
|
|
38
|
+
#
|
|
39
|
+
# Configuration options for format:
|
|
40
|
+
# * <tt>:wrong_format</tt> - A custom error message (default is:
|
|
41
|
+
# "is an invalid email address")
|
|
42
|
+
#
|
|
43
|
+
# Miscellaneous configuration options:
|
|
44
|
+
# * <tt>:allow_nil</tt> - Attribute may be nil; skip validation.
|
|
45
|
+
# * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
|
|
46
|
+
# * <tt>:on</tt> - Specifies when this validation is active (default is
|
|
47
|
+
# :save, other options :create, :update)
|
|
48
|
+
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if
|
|
49
|
+
# the validation should occur (e.g. :if => :allow_validation, or
|
|
50
|
+
# :if => lambda { |user| user.signup_step > 2 }). The method, proc or
|
|
51
|
+
# string should return or evaluate to a true or false value.
|
|
52
|
+
# * <tt>:strict</tt> - Specifies if the domain part of the email should be
|
|
53
|
+
# compliant to RFC 1035 (default is true). If set to false domains such as
|
|
54
|
+
# '-online.com', '[127.0.0.1]' become valid.
|
|
55
|
+
def validates_as_email_address(*attr_names)
|
|
56
|
+
configuration = attr_names.last.is_a?(Hash) ? attr_names.pop : {}
|
|
57
|
+
configuration.reverse_merge!(
|
|
58
|
+
:wrong_format => Object.const_defined?(:I18n) ? :invalid_email : ActiveRecord::Errors.default_error_messages[:invalid_email],
|
|
59
|
+
:strict => true
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Add format validation
|
|
63
|
+
format_configuration = configuration.dup
|
|
64
|
+
format_configuration[:message] = configuration.delete(:wrong_format)
|
|
65
|
+
format_configuration[:with] = configuration[:strict] ? RFC1035::EmailAddress : RFC822::EmailAddress
|
|
66
|
+
validates_format_of attr_names, format_configuration
|
|
67
|
+
|
|
68
|
+
# Add length validation
|
|
69
|
+
length_configuration = configuration.dup
|
|
70
|
+
length_configuration.reverse_merge!(:within => 3..320) unless ([:minimum, :maximum, :is, :within, :in] & configuration.keys).any?
|
|
71
|
+
validates_length_of attr_names, length_configuration
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
ActiveRecord::Base.class_eval do
|
|
76
|
+
extend ValidatesAsEmailAddress
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Load default error messages
|
|
81
|
+
if Object.const_defined?(:I18n) # Rails >= 2.2
|
|
82
|
+
I18n.load_path << "#{File.dirname(__FILE__)}/validates_as_email_address/locale.rb"
|
|
83
|
+
else
|
|
84
|
+
ActiveRecord::Errors.default_error_messages.update(
|
|
85
|
+
:invalid_email => ValidatesAsEmailAddress.invalid_email_message
|
|
86
|
+
)
|
|
87
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module ValidatesAsEmailAddress
|
|
2
|
+
# The standard describing the format of domains
|
|
3
|
+
module RFC1035
|
|
4
|
+
# Matches domain according to the RFC 1035 standard, with the exception
|
|
5
|
+
# that domains can start with a letter *or* digit
|
|
6
|
+
Domain = begin
|
|
7
|
+
digit = '[\\d]'
|
|
8
|
+
letter = '[\\x61-\\x7a\\x41-\\x5a]'
|
|
9
|
+
let_dig = "(?:#{letter}|#{digit})"
|
|
10
|
+
let_dig_hyp = "(?:#{let_dig}|[\\x2d])"
|
|
11
|
+
label = "#{let_dig}(?:#{let_dig_hyp}*#{let_dig})?"
|
|
12
|
+
subdomain = "(?:#{label}\\.)*#{label}"
|
|
13
|
+
domain = "(?:#{subdomain}|\\x20)"
|
|
14
|
+
|
|
15
|
+
/#{domain}/
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Matches email addresses with domains that follow the RFC 1035 standard
|
|
19
|
+
EmailAddress = begin
|
|
20
|
+
local_part = RFC822::LocalPart.source
|
|
21
|
+
domain = Domain.source
|
|
22
|
+
addr_spec = "(#{local_part})\\x40(#{domain})"
|
|
23
|
+
addr_spec.force_encoding('binary') if addr_spec.respond_to?(:force_encoding)
|
|
24
|
+
|
|
25
|
+
/\A#{addr_spec}\z/
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ValidatesAsEmailAddress
|
|
2
|
+
# The standard describing the format of email addresses
|
|
3
|
+
module RFC822
|
|
4
|
+
# Matches the two parts of an email address (before/after @)
|
|
5
|
+
LocalPart, Domain = begin
|
|
6
|
+
# Shared
|
|
7
|
+
qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
|
|
8
|
+
dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
|
|
9
|
+
atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
|
|
10
|
+
quoted_pair = '\\x5c[\\x00-\\x7f]'
|
|
11
|
+
domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
|
|
12
|
+
quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
|
|
13
|
+
|
|
14
|
+
# Local part
|
|
15
|
+
word = "(?:#{atom}|#{quoted_string})"
|
|
16
|
+
local_part = "#{word}(?:\\x2e#{word})*"
|
|
17
|
+
local_part.force_encoding('binary') if local_part.respond_to?(:force_encoding)
|
|
18
|
+
|
|
19
|
+
# Domain
|
|
20
|
+
domain_ref = atom
|
|
21
|
+
sub_domain = "(?:#{domain_ref}|#{domain_literal})"
|
|
22
|
+
domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
|
|
23
|
+
domain.force_encoding('binary') if domain.respond_to?(:force_encoding)
|
|
24
|
+
|
|
25
|
+
[/#{local_part}/, /#{domain}/]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Matches email addresses according to the RFC822 standard
|
|
29
|
+
EmailAddress = begin
|
|
30
|
+
local_part = LocalPart.source
|
|
31
|
+
domain = Domain.source
|
|
32
|
+
addr_spec = "(#{local_part})\\x40(#{domain})"
|
|
33
|
+
addr_spec.force_encoding('binary') if addr_spec.respond_to?(:force_encoding)
|
|
34
|
+
|
|
35
|
+
/\A#{addr_spec}\z/
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/test/factory.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Factory
|
|
2
|
+
# Build actions for the model
|
|
3
|
+
def self.build(model, &block)
|
|
4
|
+
name = model.to_s.underscore
|
|
5
|
+
|
|
6
|
+
define_method("#{name}_attributes", block)
|
|
7
|
+
define_method("valid_#{name}_attributes") {|*args| valid_attributes_for(model, *args)}
|
|
8
|
+
define_method("new_#{name}") {|*args| new_record(model, *args)}
|
|
9
|
+
define_method("create_#{name}") {|*args| create_record(model, *args)}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Get valid attributes for the model
|
|
13
|
+
def valid_attributes_for(model, attributes = {})
|
|
14
|
+
name = model.to_s.underscore
|
|
15
|
+
send("#{name}_attributes", attributes)
|
|
16
|
+
attributes.stringify_keys!
|
|
17
|
+
attributes
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Build an unsaved record
|
|
21
|
+
def new_record(model, *args)
|
|
22
|
+
attributes = valid_attributes_for(model, *args)
|
|
23
|
+
record = model.new(attributes)
|
|
24
|
+
attributes.each {|attr, value| record.send("#{attr}=", value) if model.accessible_attributes && !model.accessible_attributes.include?(attr) || model.protected_attributes && model.protected_attributes.include?(attr)}
|
|
25
|
+
record
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Build and save/reload a record
|
|
29
|
+
def create_record(model, *args)
|
|
30
|
+
record = new_record(model, *args)
|
|
31
|
+
record.save!
|
|
32
|
+
record.reload
|
|
33
|
+
record
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
build User do |attributes|
|
|
37
|
+
attributes.reverse_merge!(
|
|
38
|
+
:email => 'john.smith@gmail.com'
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Load the plugin testing framework
|
|
2
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib")
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'plugin_test_helper'
|
|
5
|
+
|
|
6
|
+
# Run the migrations
|
|
7
|
+
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
|
|
8
|
+
|
|
9
|
+
# Mixin the factory helper
|
|
10
|
+
require File.expand_path("#{File.dirname(__FILE__)}/factory")
|
|
11
|
+
Test::Unit::TestCase.class_eval do
|
|
12
|
+
include Factory
|
|
13
|
+
end
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
|
2
|
+
|
|
3
|
+
class ValidatesAsEmailAddressByDefaultTest < ActiveSupport::TestCase
|
|
4
|
+
def setup
|
|
5
|
+
User.validates_as_email_address :email
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_should_not_allow_email_addresses_shorter_than_3_characters
|
|
9
|
+
user = new_user(:email => 'a@')
|
|
10
|
+
assert !user.valid?
|
|
11
|
+
assert user.errors.invalid?(:email)
|
|
12
|
+
assert_equal 'is an invalid email address', user.errors.on(:email).first
|
|
13
|
+
|
|
14
|
+
user.email = 'a@a'
|
|
15
|
+
assert user.valid?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_should_not_allow_email_addresses_longer_than_320_characters
|
|
19
|
+
user = new_user(:email => 'a@' + 'a' * 318)
|
|
20
|
+
assert user.valid?
|
|
21
|
+
|
|
22
|
+
user.email += 'a'
|
|
23
|
+
assert !user.valid?
|
|
24
|
+
assert user.errors.invalid?(:email)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_should_allow_legal_rfc822_formats
|
|
28
|
+
[
|
|
29
|
+
'test@example',
|
|
30
|
+
'test@example.com',
|
|
31
|
+
'test@example.co.uk',
|
|
32
|
+
'"J. Smith\'s House, a.k.a. Home!"@example.com',
|
|
33
|
+
'test@123.com',
|
|
34
|
+
].each do |address|
|
|
35
|
+
user = new_user(:email => address)
|
|
36
|
+
assert user.valid?, "#{address} should be legal."
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_should_not_allow_illegal_rfc822_formats
|
|
41
|
+
[
|
|
42
|
+
'test@Monday 1:00',
|
|
43
|
+
'test@Monday the first',
|
|
44
|
+
'J. Smith\'s House, a.k.a. Home!@example.com',
|
|
45
|
+
].each do |address|
|
|
46
|
+
user = new_user(:email => address)
|
|
47
|
+
assert !user.valid?, "#{address} should be illegal."
|
|
48
|
+
assert user.errors.invalid?(:email)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_should_not_allow_illegal_rfc1035_formats
|
|
53
|
+
[
|
|
54
|
+
'test@[127.0.0.1]',
|
|
55
|
+
'test@-domain-not-starting-with-letter.com',
|
|
56
|
+
'test@domain-not-ending-with-alphanum-.com'
|
|
57
|
+
].each do |address|
|
|
58
|
+
user = new_user(:email => address)
|
|
59
|
+
assert !user.valid?, "#{address} should be illegal."
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def teardown
|
|
64
|
+
User.class_eval do
|
|
65
|
+
@validate_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
66
|
+
@validate_on_create_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
67
|
+
@validate_on_update_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class ValidatesAsEmailAddressTest < ActiveSupport::TestCase
|
|
73
|
+
def test_should_allow_minimum_length
|
|
74
|
+
User.validates_as_email_address :email, :minimum => 8
|
|
75
|
+
|
|
76
|
+
user = new_user(:email => 'a@' + 'a' * 6)
|
|
77
|
+
assert user.valid?
|
|
78
|
+
|
|
79
|
+
user.email.chop!
|
|
80
|
+
assert !user.valid?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_should_not_check_maximum_length_if_minimum_length_defined
|
|
84
|
+
User.validates_as_email_address :email, :minimum => 10
|
|
85
|
+
|
|
86
|
+
user = new_user(:email => 'a@' + 'a' * 319)
|
|
87
|
+
assert user.valid?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_should_allow_maximum_length
|
|
91
|
+
User.validates_as_email_address :email, :maximum => 8
|
|
92
|
+
|
|
93
|
+
user = new_user(:email => 'a@' + 'a' * 6)
|
|
94
|
+
assert user.valid?
|
|
95
|
+
|
|
96
|
+
user.email += 'a'
|
|
97
|
+
assert !user.valid?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_should_not_check_minimum_length_if_maximum_length_defined
|
|
101
|
+
User.validates_as_email_address :email, :maximum => 8
|
|
102
|
+
|
|
103
|
+
user = new_user(:email => 'a@')
|
|
104
|
+
assert !user.valid?
|
|
105
|
+
assert user.errors.invalid?(:email)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_should_allow_exact_length
|
|
109
|
+
User.validates_as_email_address :email, :is => 8
|
|
110
|
+
|
|
111
|
+
user = new_user(:email => 'a@' + 'a' * 6)
|
|
112
|
+
assert user.valid?
|
|
113
|
+
|
|
114
|
+
user.email.chop!
|
|
115
|
+
assert !user.valid?
|
|
116
|
+
|
|
117
|
+
user.email += 'aa'
|
|
118
|
+
assert !user.valid?
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_should_allow_within_range
|
|
122
|
+
User.validates_as_email_address :email, :within => 8..9
|
|
123
|
+
|
|
124
|
+
user = new_user(:email => 'a@' + 'a' * 5)
|
|
125
|
+
assert !user.valid?
|
|
126
|
+
|
|
127
|
+
user.email += 'a'
|
|
128
|
+
assert user.valid?
|
|
129
|
+
|
|
130
|
+
user.email += 'a'
|
|
131
|
+
assert user.valid?
|
|
132
|
+
|
|
133
|
+
user.email += 'a'
|
|
134
|
+
assert !user.valid?
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_should_allow_in_range
|
|
138
|
+
User.validates_as_email_address :email, :in => 8..9
|
|
139
|
+
|
|
140
|
+
user = new_user(:email => 'a@' + 'a' * 5)
|
|
141
|
+
assert !user.valid?
|
|
142
|
+
|
|
143
|
+
user.email += 'a'
|
|
144
|
+
assert user.valid?
|
|
145
|
+
|
|
146
|
+
user.email += 'a'
|
|
147
|
+
assert user.valid?
|
|
148
|
+
|
|
149
|
+
user.email += 'a'
|
|
150
|
+
assert !user.valid?
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_should_allow_too_long_message
|
|
154
|
+
User.validates_as_email_address :email, :too_long => 'custom'
|
|
155
|
+
|
|
156
|
+
user = new_user(:email => 'a@' + 'a' * 319)
|
|
157
|
+
user.valid?
|
|
158
|
+
|
|
159
|
+
assert_equal 'custom', Array(user.errors.on(:email)).last
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_should_allow_too_short_message
|
|
163
|
+
User.validates_as_email_address :email, :too_short => 'custom'
|
|
164
|
+
|
|
165
|
+
user = new_user(:email => 'a@')
|
|
166
|
+
user.valid?
|
|
167
|
+
|
|
168
|
+
assert_equal 'custom', Array(user.errors.on(:email)).last
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def test_should_allow_wrong_length_message
|
|
172
|
+
User.validates_as_email_address :email, :is => 8, :wrong_length => 'custom'
|
|
173
|
+
|
|
174
|
+
user = new_user(:email => 'a@a.com')
|
|
175
|
+
user.valid?
|
|
176
|
+
|
|
177
|
+
assert_equal 'custom', Array(user.errors.on(:email)).last
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_should_allow_wrong_format_message
|
|
181
|
+
User.validates_as_email_address :email, :wrong_format => 'custom'
|
|
182
|
+
|
|
183
|
+
user = new_user(:email => 'a@!')
|
|
184
|
+
user.valid?
|
|
185
|
+
|
|
186
|
+
assert_equal 'custom', Array(user.errors.on(:email)).first
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def test_should_validate_if_if_is_true
|
|
190
|
+
User.validates_as_email_address :email, :if => lambda {|user| true}
|
|
191
|
+
|
|
192
|
+
user = new_user(:email => 'a')
|
|
193
|
+
assert !user.valid?
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def test_should_not_validate_if_if_is_false
|
|
197
|
+
User.validates_as_email_address :email, :if => lambda {|user| false}
|
|
198
|
+
|
|
199
|
+
user = new_user(:email => 'a')
|
|
200
|
+
assert user.valid?
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def test_should_validate_if_unless_is_false
|
|
204
|
+
User.validates_as_email_address :email, :unless => lambda {|user| false}
|
|
205
|
+
|
|
206
|
+
user = new_user(:email => 'a')
|
|
207
|
+
assert !user.valid?
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_should_not_validate_if_unless_is_true
|
|
211
|
+
User.validates_as_email_address :email, :unless => lambda {|user| true}
|
|
212
|
+
|
|
213
|
+
user = new_user(:email => 'a')
|
|
214
|
+
assert user.valid?
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_should_validate_if_on_event
|
|
218
|
+
User.validates_as_email_address :email, :on => :update
|
|
219
|
+
|
|
220
|
+
user = create_user
|
|
221
|
+
user.email = 'a'
|
|
222
|
+
assert !user.valid?
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_should_not_validate_if_not_on_event
|
|
226
|
+
User.validates_as_email_address :email, :on => :create
|
|
227
|
+
|
|
228
|
+
user = create_user
|
|
229
|
+
user.email = 'a'
|
|
230
|
+
assert user.valid?
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def test_should_not_validate_if_allow_nil_and_nil
|
|
234
|
+
User.validates_as_email_address :email, :allow_nil => true
|
|
235
|
+
|
|
236
|
+
user = create_user
|
|
237
|
+
user.email = nil
|
|
238
|
+
assert user.valid?
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def test_should_validate_if_allow_nil_and_not_nil
|
|
242
|
+
User.validates_as_email_address :email, :allow_nil => true
|
|
243
|
+
|
|
244
|
+
user = create_user
|
|
245
|
+
user.email = 'a'
|
|
246
|
+
assert !user.valid?
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def test_should_validate_if_not_allow_nil_and_nil
|
|
250
|
+
User.validates_as_email_address :email, :allow_nil => false
|
|
251
|
+
|
|
252
|
+
user = create_user
|
|
253
|
+
user.email = nil
|
|
254
|
+
assert !user.valid?
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def test_should_validate_if_not_allow_nil_and_not_nil
|
|
258
|
+
User.validates_as_email_address :email, :allow_nil => false
|
|
259
|
+
|
|
260
|
+
user = create_user
|
|
261
|
+
user.email = 'a'
|
|
262
|
+
assert !user.valid?
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def test_should_not_validate_if_allow_blank_and_blank
|
|
266
|
+
User.validates_as_email_address :email, :allow_blank => true
|
|
267
|
+
|
|
268
|
+
user = create_user
|
|
269
|
+
user.email = ''
|
|
270
|
+
assert user.valid?
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def test_should_validate_if_allow_blank_and_not_blank
|
|
274
|
+
User.validates_as_email_address :email, :allow_blank => true
|
|
275
|
+
|
|
276
|
+
user = create_user
|
|
277
|
+
user.email = 'a'
|
|
278
|
+
assert !user.valid?
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def test_should_validate_if_not_allow_blank_and_blank
|
|
282
|
+
User.validates_as_email_address :email, :allow_blank => false
|
|
283
|
+
|
|
284
|
+
user = create_user
|
|
285
|
+
user.email = ''
|
|
286
|
+
assert !user.valid?
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def test_should_validate_if_not_allow_nil_and_not_nil
|
|
290
|
+
User.validates_as_email_address :email, :allow_blank => false
|
|
291
|
+
|
|
292
|
+
user = create_user
|
|
293
|
+
user.email = 'a'
|
|
294
|
+
assert !user.valid?
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def teardown
|
|
298
|
+
User.class_eval do
|
|
299
|
+
@validate_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
300
|
+
@validate_on_create_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
301
|
+
@validate_on_update_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
class ValidatesAsEmailAddressUnrestrictedTest < ActiveSupport::TestCase
|
|
307
|
+
def setup
|
|
308
|
+
User.validates_as_email_address :email, :strict => false
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def test_should_allow_illegal_rfc1035_formats
|
|
312
|
+
[
|
|
313
|
+
'test@[127.0.0.1]',
|
|
314
|
+
'test@-domain-not-starting-with-letter.com',
|
|
315
|
+
'test@domain-not-ending-with-alphanum-.com'
|
|
316
|
+
].each do |address|
|
|
317
|
+
user = new_user(:email => address)
|
|
318
|
+
assert user.valid?, "#{address} should be legal."
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def teardown
|
|
323
|
+
User.class_eval do
|
|
324
|
+
@validate_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
325
|
+
@validate_on_create_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
326
|
+
@validate_on_update_callbacks = ActiveSupport::Callbacks::CallbackChain.new
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: pluginaweek-validates_as_email_address
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Aaron Pfeifer
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-06-08 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: Adds support for validating the format/length of email addresses in ActiveRecord
|
|
17
|
+
email: aaron@pluginaweek.org
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- lib/validates_as_email_address.rb
|
|
26
|
+
- lib/validates_as_email_address
|
|
27
|
+
- lib/validates_as_email_address/locale.rb
|
|
28
|
+
- lib/validates_as_email_address/rfc_1035.rb
|
|
29
|
+
- lib/validates_as_email_address/rfc_822.rb
|
|
30
|
+
- test/unit
|
|
31
|
+
- test/unit/validates_as_email_address_test.rb
|
|
32
|
+
- test/factory.rb
|
|
33
|
+
- test/app_root
|
|
34
|
+
- test/app_root/app
|
|
35
|
+
- test/app_root/app/models
|
|
36
|
+
- test/app_root/app/models/user.rb
|
|
37
|
+
- test/app_root/db
|
|
38
|
+
- test/app_root/db/migrate
|
|
39
|
+
- test/app_root/db/migrate/001_create_users.rb
|
|
40
|
+
- test/test_helper.rb
|
|
41
|
+
- CHANGELOG.rdoc
|
|
42
|
+
- init.rb
|
|
43
|
+
- LICENSE
|
|
44
|
+
- Rakefile
|
|
45
|
+
- README.rdoc
|
|
46
|
+
has_rdoc: true
|
|
47
|
+
homepage: http://www.pluginaweek.org
|
|
48
|
+
post_install_message:
|
|
49
|
+
rdoc_options: []
|
|
50
|
+
|
|
51
|
+
require_paths:
|
|
52
|
+
- lib
|
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: "0"
|
|
58
|
+
version:
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: "0"
|
|
64
|
+
version:
|
|
65
|
+
requirements: []
|
|
66
|
+
|
|
67
|
+
rubyforge_project: pluginaweek
|
|
68
|
+
rubygems_version: 1.2.0
|
|
69
|
+
signing_key:
|
|
70
|
+
specification_version: 2
|
|
71
|
+
summary: Adds support for validating the format/length of email addresses in ActiveRecord
|
|
72
|
+
test_files:
|
|
73
|
+
- test/unit/validates_as_email_address_test.rb
|