heycarsten-email-veracity 0.3.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/README.rdoc ADDED
@@ -0,0 +1,72 @@
1
+ = Email Veracity
2
+
3
+ A straight-forward Ruby library for checking the real-world validity of email
4
+ addresses.
5
+
6
+
7
+ === It Can
8
+
9
+ * Validate email addresses for proper form against a pattern.
10
+ * Accept and reject addresses based whitelists and blacklists of domains.
11
+ * Check an address' domain for MX and/or A records.
12
+ * Be configured for a variety of use-cases, to be as discerning or as
13
+ indiscriminate as you would like.
14
+
15
+
16
+ === It Can Not
17
+
18
+ * Validate all possible permutations of addresses to the RFC 2822
19
+ specification.
20
+
21
+
22
+ == Using The Gem
23
+
24
+ In your project, you must require +email_veracity+ after that you can try it
25
+ out, consider the following examples:
26
+
27
+
28
+ require 'email_veracity'
29
+
30
+ address = EmailVeracity::Address.new('heycarsten@gmail.com')
31
+
32
+ address.valid?
33
+ # => true
34
+
35
+ address.domain.to_s
36
+ # => 'gmail.com'
37
+
38
+ address.domain.address_servers.collect { |s| s.to_s }
39
+ # => ["64.233.171.83", "64.233.161.83", "209.85.171.83"]
40
+
41
+ address = EmailVeracity::Address.new('fakey@crazy-z3d9df-domain.com')
42
+
43
+ address.valid?
44
+ # => false
45
+
46
+ address.errors
47
+ # => [:no_address_servers]
48
+
49
+
50
+ As you can see, playing with the core library is pretty fun. The basic building
51
+ blocks are:
52
+
53
+ ==== Address
54
+
55
+ Responsible for parsing full email addresses and checking for pattern-based
56
+ validity.
57
+
58
+ ==== Domain
59
+
60
+ Contains methods to query the domain for information.
61
+
62
+ ==== Resolver
63
+
64
+ Abstracts Resolv::DNS into a super-simple single public method, this is where
65
+ the timeout error is raised.
66
+
67
+
68
+ == Running The Tests
69
+
70
+ A few of the tests will fail if you don't have a live connection to the
71
+ internet, this is obviously not cool and it's high on my list of TODOs. [See
72
+ TODO]
data/Rakefile ADDED
@@ -0,0 +1,93 @@
1
+ # I used Haml as a template for these tasks: Thank you Nex3!
2
+ require 'rubygems'
3
+ require 'rake'
4
+
5
+
6
+ task :default => :test
7
+
8
+ require 'rake/testtask'
9
+
10
+ Rake::TestTask.new do |t|
11
+ t.libs << 'lib'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+
17
+
18
+ ### Packaging
19
+ require 'rake/gempackagetask'
20
+ load 'email_veracity.gemspec'
21
+ Rake::GemPackageTask.new(EMAIL_VERACITY_GEMSPEC) do |pkg|
22
+ if Rake.application.top_level_tasks.include?('release')
23
+ pkg.need_tar_gz = true
24
+ pkg.need_tar_bz2 = true
25
+ pkg.need_zip = true
26
+ end
27
+ end
28
+
29
+
30
+ task :revision_file do
31
+ require 'lib/email_veracity'
32
+
33
+ if EmailVeracity.version[:rev] && !Rake.application.top_level_tasks.include?('release')
34
+ File.open('REVISION', 'w') { |f| f.puts EmailVeracity.version[:rev] }
35
+ elsif Rake.application.top_level_tasks.include?('release')
36
+ File.open('REVISION', 'w') { |f| f.puts '(release)' }
37
+ else
38
+ File.open('REVISION', 'w') { |f| f.puts '(unknown)' }
39
+ end
40
+ end
41
+ Rake::Task[:package].prerequisites.insert(0, :revision_file)
42
+
43
+ # We also need to get rid of this file after packaging.
44
+ at_exit { File.delete('REVISION') rescue nil }
45
+
46
+
47
+ task :install => [:package] do
48
+ sudo = RUBY_PLATFORM =~ /win32/ ? '' : 'sudo'
49
+ `#{sudo} gem install --no-ri pkg/email-veracity-#{File.read('VERSION').strip}`
50
+ end
51
+
52
+
53
+ task :release => [:package] do
54
+ name, version = ENV['NAME'], ENV['VERSION']
55
+ raise "Must supply NAME and VERSION for release task." unless name && version
56
+ `rubyforge login`
57
+ `rubyforge add_release email-veracity email-veracity "#{name} (v#{version})" pkg/email-veracity-#{version}.gem`
58
+ `rubyforge add_file email-veracity email-veracity "#{name} (v#{version})" pkg/email-veracity-#{version}.tar.gz`
59
+ `rubyforge add_file email-veracity email-veracity "#{name} (v#{version})" pkg/email-veracity-#{version}.tar.bz2`
60
+ `rubyforge add_file email-veracity email-veracity "#{name} (v#{version})" pkg/email-veracity-#{version}.zip`
61
+ end
62
+
63
+
64
+
65
+ ### Documentation
66
+ require 'rake/rdoctask'
67
+
68
+ Rake::RDocTask.new do |rdoc|
69
+ rdoc.title = 'Email Veracity'
70
+ rdoc.options << '--line-numbers' << '--inline-source'
71
+ rdoc.rdoc_files.include(*FileList.new('*') do |list|
72
+ list.exclude(/(^|[^.a-z])[a-z]+/)
73
+ list.exclude('TODO')
74
+ end.to_a)
75
+ rdoc.rdoc_files.include('lib/**/*.rb')
76
+ rdoc.rdoc_files.exclude('TODO')
77
+ rdoc.rdoc_dir = 'rdoc'
78
+ rdoc.main = 'README.rdoc'
79
+ end
80
+
81
+
82
+
83
+ ### Coverage
84
+ require 'rcov/rcovtask'
85
+
86
+ Rcov::RcovTask.new do |t|
87
+ t.test_files = FileList['test/**/*_test.rb']
88
+ t.rcov_opts << '-x' << '"^\/"'
89
+ if ENV['NON_NATIVE']
90
+ t.rcov_opts << "--no-rcovrt"
91
+ end
92
+ t.verbose = true
93
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'email_veracity'
@@ -0,0 +1,56 @@
1
+ dir = File.dirname(__FILE__)
2
+ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
3
+
4
+ require 'resolv'
5
+ require 'timeout'
6
+ require 'email_veracity/core_extensions'
7
+ require 'email_veracity/validatability'
8
+ require 'email_veracity/errors'
9
+ require 'email_veracity/config'
10
+ require 'email_veracity/server'
11
+ require 'email_veracity/resolver'
12
+ require 'email_veracity/domain'
13
+ require 'email_veracity/address'
14
+
15
+
16
+ module EmailVeracity
17
+
18
+ def self.version # :nodoc:
19
+ return @@version if defined?(@@version)
20
+
21
+ numbers = File.read(scope('VERSION')).strip.split('.').map { |n| n.to_i }
22
+
23
+ @@version = {
24
+ :major => numbers[0],
25
+ :minor => numbers[1],
26
+ :teeny => numbers[2] }
27
+
28
+ @@version[:string] = [:major, :minor, :teeny].map { |comp| @@version[comp] }.compact.join('.')
29
+
30
+ if File.exists?(scope('REVISION'))
31
+ rev = File.read(scope('REVISION')).strip
32
+ rev = nil if rev !~ /[a-f0-9]+/
33
+ end
34
+
35
+ if rev.nil? && File.exists?(scope('.git/HEAD'))
36
+ rev = File.read(scope('.git/HEAD')).strip
37
+ if rev =~ /^ref: (.*)$/
38
+ rev = File.read(scope(".git/#{$1}")).strip
39
+ end
40
+ end
41
+
42
+ if rev
43
+ @@version[:rev] = rev
44
+ @@version[:string] << "." << rev[0...7]
45
+ end
46
+
47
+ @@version
48
+ end
49
+
50
+ def self.scope(file) # :nodoc:
51
+ File.join(File.dirname(__FILE__), '..', file)
52
+ end
53
+
54
+ VERSION = version[:string] unless defined?(EmailVeracity::VERSION)
55
+
56
+ end
@@ -0,0 +1,41 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class Address
5
+
6
+ include Validatability
7
+
8
+ attr_reader :domain
9
+
10
+ def initialize(email = '')
11
+ self.email_address = email
12
+ end
13
+
14
+ def to_s
15
+ email_address
16
+ end
17
+
18
+ def email_address
19
+ @email_address.to_s.strip
20
+ end
21
+
22
+ def email_address=(new_email_address)
23
+ @email_address = new_email_address
24
+ @domain = Domain.new(@email_address.split('@')[1] || '')
25
+ end
26
+
27
+ protected
28
+ def validate!
29
+ add_error(:malformed) if !pattern_valid?
30
+ return unless Config[:lookup]
31
+ add_errors(domain.errors)
32
+ end
33
+
34
+ def pattern_valid?
35
+ @email_address =~ Config[:valid_pattern]
36
+ end
37
+
38
+ end
39
+
40
+
41
+ end
@@ -0,0 +1,56 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class Config
5
+
6
+ DEFAULT_OPTIONS = {
7
+ :whitelist => %w[ aol.com gmail.com hotmail.com mac.com msn.com
8
+ rogers.com sympatico.ca yahoo.com telus.com sprint.com sprint.ca ],
9
+ :blacklist => %w[ dodgeit.com mintemail.com mintemail.uni.cc
10
+ 1mintemail.mooo.com spammotel.com trashmail.net ],
11
+ :valid_pattern => /\A(([\d\w\+_\-\.]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})){1}\Z/i,
12
+ :timeout => 2,
13
+ :lookup => [:a],
14
+ :enforce_blacklist => false,
15
+ :enforce_whitelist => true }
16
+ @options = DEFAULT_OPTIONS.clone
17
+
18
+ def Config.[](key)
19
+ @options[key.to_sym]
20
+ end
21
+
22
+ def Config.[]=(key, value)
23
+ @options[key.to_sym] = value
24
+ end
25
+
26
+ def Config.options
27
+ @options
28
+ end
29
+
30
+ def Config.options=(options)
31
+ unless options.is_a?(Hash)
32
+ raise ArgumentError, "options must be a Hash not #{options.class}"
33
+ end
34
+ @options = options
35
+ end
36
+
37
+ def Config.update(options)
38
+ unless options.is_a?(Hash)
39
+ raise ArgumentError, "options must be a Hash not #{options.class}"
40
+ end
41
+ @options.update(options)
42
+ end
43
+
44
+ def Config.enforce_lookup?(record)
45
+ return unless @options[:lookup].is_a?(Array)
46
+ @options[:lookup].any? { |i| i.to_s == record.to_s }
47
+ end
48
+
49
+ def Config.revert!
50
+ @options = DEFAULT_OPTIONS.clone
51
+ end
52
+
53
+ end
54
+
55
+
56
+ end
@@ -0,0 +1,27 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class ::Array
5
+
6
+ def reject_blank_items
7
+ reject { |i| i.to_s.strip.blank? }
8
+ end
9
+
10
+ def contains_single_item?
11
+ size == 1
12
+ end
13
+
14
+ end
15
+
16
+
17
+ class ::Object
18
+
19
+ # Snaked from Rails.
20
+ def blank?
21
+ respond_to?(:empty?) ? empty? : !self
22
+ end
23
+
24
+ end
25
+
26
+
27
+ end
@@ -0,0 +1,69 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class Domain
5
+
6
+ include Validatability
7
+
8
+ def Domain.whitelisted?(name)
9
+ Config[:whitelist].include?(name.downcase.strip)
10
+ end
11
+
12
+ def Domain.blacklisted?(name)
13
+ Config[:blacklist].include?(name.downcase.strip)
14
+ end
15
+
16
+ def initialize(name = '')
17
+ @name = name
18
+ end
19
+
20
+ def to_s
21
+ name
22
+ end
23
+
24
+ def name
25
+ @name.to_s.downcase.strip
26
+ end
27
+
28
+ def whitelisted?
29
+ Domain.whitelisted?(name)
30
+ end
31
+
32
+ def blacklisted?
33
+ Domain.blacklisted?(name)
34
+ end
35
+
36
+ def address_servers
37
+ @address_servers ||= servers_in(:a)
38
+ end
39
+
40
+ def exchange_servers
41
+ @exchange_servers ||= servers_in(:mx)
42
+ end
43
+
44
+ def servers
45
+ address_servers + exchange_servers
46
+ end
47
+
48
+ protected
49
+ def validate!
50
+ return if whitelisted?
51
+ add_error(:blacklisted) if blacklisted? &&
52
+ Config[:enforce_blacklist]
53
+ add_error(:no_address_servers) if address_servers.empty? &&
54
+ Config.enforce_lookup?(:a)
55
+ add_error(:no_exchange_servers) if exchange_servers.empty? &&
56
+ Config.enforce_lookup?(:mx)
57
+ end
58
+
59
+ def servers_in(record)
60
+ return [] if name.blank?
61
+ Resolver.get_servers_for(name, record)
62
+ rescue DomainResourcesTimeoutError
63
+ add_error :timed_out
64
+ end
65
+
66
+ end
67
+
68
+
69
+ end
@@ -0,0 +1,9 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class Error < StandardError; end
5
+ class MalformedEmailAddressError < Error; end
6
+ class DomainResourcesTimeoutError < Error; end
7
+
8
+
9
+ end
@@ -0,0 +1,46 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class Resolver
5
+
6
+ RECORD_NAMES_TO_RESOLVE_MAP = {
7
+ :a => {
8
+ :method => 'address',
9
+ :type => AddressServer,
10
+ :constant => Resolv::DNS::Resource::IN::A },
11
+ :mx => {
12
+ :method => 'exchange',
13
+ :type => ExchangeServer,
14
+ :constant => Resolv::DNS::Resource::IN::MX } }
15
+
16
+ def Resolver.get_servers_for(domain_name, record = :a)
17
+ Timeout::timeout(Config[:timeout]) do
18
+ get_resources_for(domain_name, record).collect do |server_name|
19
+ type = RECORD_NAMES_TO_RESOLVE_MAP[record.to_sym][:type]
20
+ type.new(server_name)
21
+ end
22
+ end
23
+ rescue Timeout::Error
24
+ raise DomainResourcesTimeoutError,
25
+ "Timed out while try to resolve #{domain_name}"
26
+ end
27
+
28
+ protected
29
+ def Resolver.get_resources_for(domain_name, record = :a)
30
+ Resolv::DNS.open do |server|
31
+ record_map = RECORD_NAMES_TO_RESOLVE_MAP[record]
32
+ resources = server.getresources(domain_name, record_map[:constant])
33
+ resources_to_servers(resources, record_map[:method])
34
+ end
35
+ end
36
+
37
+ def Resolver.resources_to_servers(resources, resolve_method)
38
+ resources.inject([]) do |array, resource|
39
+ array << resource.method(resolve_method).call.to_s.strip
40
+ end.reject_blank_items
41
+ end
42
+
43
+ end
44
+
45
+
46
+ end
@@ -0,0 +1,20 @@
1
+ module EmailVeracity
2
+
3
+
4
+ class Server
5
+
6
+ attr_reader :name
7
+ alias_method :to_s, :name
8
+
9
+ def initialize(name = '')
10
+ @name = name
11
+ end
12
+
13
+ end
14
+
15
+
16
+ class AddressServer < Server; end
17
+ class ExchangeServer < Server; end
18
+
19
+
20
+ end
@@ -0,0 +1,34 @@
1
+ module EmailVeracity
2
+
3
+
4
+ module Validatability
5
+
6
+ def valid?
7
+ self.errors.empty?
8
+ end
9
+
10
+ def errors
11
+ self.clear_errors!
12
+ self.validate!
13
+ @errors
14
+ end
15
+
16
+ protected
17
+ def validate!
18
+ # Adds errors to the object.
19
+ end
20
+
21
+ def clear_errors!
22
+ @errors = []
23
+ end
24
+
25
+ def add_error(*new_errors)
26
+ @errors ||= []
27
+ @errors.concat(new_errors.flatten)
28
+ end
29
+ alias_method :add_errors, :add_error
30
+
31
+ end
32
+
33
+
34
+ end
@@ -0,0 +1,16 @@
1
+ class ClassWithValidationMock
2
+
3
+ include EmailVeracity::Validatability
4
+
5
+ attr_accessor :give_error
6
+ attr_accessor :give_errors
7
+ attr_accessor :give_array_of_errors
8
+
9
+ def validate!
10
+ add_error(:one) if give_error
11
+ add_errors(:two, :three) if give_errors
12
+ add_errors([:four, :five]) if give_array_of_errors
13
+ add_errors []
14
+ end
15
+
16
+ end
@@ -0,0 +1,33 @@
1
+ require 'test/unit'
2
+ require 'lib/email_veracity'
3
+ Dir.glob('test/mocks/*.rb') { |f| require(f) }
4
+
5
+
6
+ class Test::Unit::TestCase
7
+
8
+ def domain_names
9
+ %w[ viarails.net heycarsten.com yahoo.com gmail.com savvica.com
10
+ learnhub.com github.com google.com rogers.com amd.com adobe.com
11
+ unspace.ca xerox.com webkit.org cooltown.net aiderss.com
12
+ del.icio.us ]
13
+ end
14
+
15
+ def assert_empty(array, message = nil)
16
+ unless array.is_a?(Array)
17
+ raise ArgumentError, 'First argument must be an Array'
18
+ end
19
+ message = [message, "Expected #{array.inspect} to be empty."].
20
+ flatten.join("\n")
21
+ assert_block(message) { array.empty? }
22
+ end
23
+
24
+ def assert_not_empty(array, message = nil)
25
+ unless array.is_a?(Array)
26
+ raise ArgumentError, 'First argument must be an Array'
27
+ end
28
+ message = [message, "Expected #{array.inspect} to contain items."].
29
+ flatten.join("\n")
30
+ assert_block(message) { !array.empty? }
31
+ end
32
+
33
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class AddressTest < Test::Unit::TestCase
5
+
6
+ def test_initialize
7
+ assert_instance_of EmailVeracity::Address,
8
+ EmailVeracity::Address.new('heycarsten@gmail.com'),
9
+ 'Should create a new Address object.'
10
+ assert_instance_of Array,
11
+ EmailVeracity::Address.new('heycarsten@gmail.com').errors,
12
+ 'Should errors should be an array.'
13
+ end
14
+
15
+ end
16
+
17
+
18
+ class DefaultConfigurationAddressValidationsTest < Test::Unit::TestCase
19
+
20
+ def test_a_well_formed_address_with_a_whitelisted_domain
21
+ address = new_address('heycarsten@gmail.com')
22
+ assert address.valid?,
23
+ "Should be valid. @errors: #{address.errors.inspect}"
24
+ end
25
+
26
+ def test_a_well_formed_address_with_a_blacklisted_domain
27
+ address = new_address('heycarsten@dodgeit.com')
28
+ assert address.valid?,
29
+ "Should be valid. @errors: #{address.errors.inspect}"
30
+ end
31
+
32
+ def test_a_well_formed_address_that_does_not_exist
33
+ address = new_address('heycarsten@i-surely-do-not-exist.nil')
34
+ assert !address.valid?,
35
+ 'Should not be valid.'
36
+ end
37
+
38
+ def test_a_well_formed_address_that_exists
39
+ address = new_address('itsme@heycarsten.com')
40
+ assert address.valid?,
41
+ "Should be valid. @errors: #{address.errors.inspect}"
42
+ end
43
+
44
+ private
45
+ def new_address(address = '')
46
+ EmailVeracity::Address.new(address)
47
+ end
48
+
49
+ end
@@ -0,0 +1,105 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class ConfigTest < Test::Unit::TestCase
5
+
6
+ def test_default_whitelist_domains
7
+ assert_instance_of Array, EmailVeracity::Config[:whitelist]
8
+ assert_not_empty EmailVeracity::Config[:whitelist],
9
+ 'Should have more than one item.'
10
+ end
11
+
12
+ def test_default_blacklist_domains
13
+ assert_instance_of Array, EmailVeracity::Config[:blacklist]
14
+ assert_not_empty EmailVeracity::Config[:blacklist],
15
+ 'Should have more than one item.'
16
+ end
17
+
18
+ def test_lookup_default_setting
19
+ assert_instance_of Array, EmailVeracity::Config[:lookup]
20
+ end
21
+
22
+ def test_enforce_lookup_with_symbols
23
+ assert EmailVeracity::Config.enforce_lookup?(:a),
24
+ 'Should check for A records by default'
25
+ assert !EmailVeracity::Config.enforce_lookup?(:mx),
26
+ 'Should not check for MX records be default'
27
+ end
28
+
29
+ def test_enforce_lookup_with_strings
30
+ assert EmailVeracity::Config.enforce_lookup?('a'),
31
+ 'Should check for A records by default'
32
+ assert !EmailVeracity::Config.enforce_lookup?('mx'),
33
+ 'Should not check for MX records be default'
34
+ end
35
+
36
+ def test_changing_and_reverting_configuration
37
+ EmailVeracity::Config.update(:lookup => false, :timeout => 3)
38
+ assert_equal false, EmailVeracity::Config[:lookup],
39
+ 'Should change configuration.'
40
+ assert_equal 3, EmailVeracity::Config[:timeout]
41
+ 'Should change configuration.'
42
+ EmailVeracity::Config.revert!
43
+ assert_equal EmailVeracity::Config::DEFAULT_OPTIONS,
44
+ EmailVeracity::Config.options,
45
+ 'Should revert configuration'
46
+ end
47
+
48
+ end
49
+
50
+
51
+ class DefaultValidAddressPatternTest < Test::Unit::TestCase
52
+
53
+ def test_default_valid_address_pattern
54
+ assert_instance_of Regexp, EmailVeracity::Config[:valid_pattern],
55
+ 'Should exist as a regular expression.'
56
+ end
57
+
58
+ def test_valid_email_addresses
59
+ %w[
60
+ goto@rubyfringe.ca
61
+ stuff+heyd00d@gmail.com
62
+ carsten_nielsen@gmail.com
63
+ carsten-nielsen@gmail.com
64
+ iwenttowestern@ivyleague.ca
65
+ old-skool@mail.mysite.on.ca
66
+ heycarsten@del.icio.us
67
+ nex3@haml.town
68
+ 1234@aplace.com
69
+ carsten2@happyland.net
70
+ sweetCandy4@me-and-you.ca
71
+ jesus@god.com
72
+ neat@b.eat
73
+ ].each do |address|
74
+ assert_match EmailVeracity::Config[:valid_pattern],
75
+ address,
76
+ "#{address} should be valid."
77
+ end
78
+ end
79
+
80
+ def test_invalid_email_addresses
81
+ %w[
82
+ @failure.net
83
+ craptastic@
84
+ !!!!!@gmail.com
85
+ oh-noez@f4iL/\/\@il.net
86
+ someone@somewhere
87
+ this!fails@comtown.com
88
+ $oWrong@fail.net
89
+ charles\ babbage@gmail.com
90
+ ,@crap.com
91
+ dis%20blos@dot.com
92
+ &^%$#$%@yojimbo.nil
93
+ "greetings\ friend"@comtastic.dk
94
+ this,fails@ice-t.com
95
+ ungültige@adresse.de
96
+ failure@10.0.0.1
97
+ douche@@bag.net
98
+ ].each do |address|
99
+ assert_no_match EmailVeracity::Config[:valid_pattern],
100
+ address,
101
+ "#{address} should be invalid."
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class ArrayExtensionsTest < Test::Unit::TestCase
5
+
6
+ def test_reject_blank_items
7
+ array = [[], {}, '', nil, ' ', 'good times!']
8
+ assert_equal ['good times!'], array.reject_blank_items, 'Should reject all blank and empty objects.'
9
+ array = [{:neat => 'o'}, ['cool'], 1, 's']
10
+ assert_equal array, array.reject_blank_items, 'Should not reject any filled or not-blank objects.'
11
+ end
12
+
13
+ def test_contains_single_item
14
+ assert [''].contains_single_item?, 'Should contain one item.'
15
+ assert [nil].contains_single_item?, 'Should contain one item.'
16
+ assert [[]].contains_single_item?, 'Should contain one item.'
17
+ assert ![].contains_single_item?, 'Should not contain one item.'
18
+ assert ![nil, false].contains_single_item?, 'Should not contain one item.'
19
+ end
20
+
21
+ def test_blank
22
+ assert [].blank?, '[] should be blank.'
23
+ assert ''.blank?, '"" should be blank.'
24
+ assert Hash.new.blank?, '{} should be blank.'
25
+ assert nil.blank?, 'nil should be blank.'
26
+ end
27
+
28
+ end
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class DomainTest < Test::Unit::TestCase
5
+
6
+ def test_blacklisted_domain
7
+ assert EmailVeracity::Domain.blacklisted?('dodgeit.com'),
8
+ 'Should match a blacklisted domain.'
9
+ assert EmailVeracity::Domain.blacklisted?('DoDgEiT.cOm'),
10
+ 'Should match a blacklisted domain regardless of case.'
11
+ assert EmailVeracity::Domain.blacklisted?(" dodgeit.com \r\n "),
12
+ 'Should match a blacklisted domain regardless of whitespace.'
13
+ assert !EmailVeracity::Domain.blacklisted?('iamnotblacklisted.com'),
14
+ 'Should not match a non-blacklisted domain.'
15
+ end
16
+
17
+ def test_whitelisted_domain
18
+ assert EmailVeracity::Domain.whitelisted?('gmail.com'),
19
+ 'Should match a whitelisted domain.'
20
+ assert EmailVeracity::Domain.whitelisted?('GmAiL.cOm'),
21
+ 'Should match a whitelisted domain regardless of case.'
22
+ assert EmailVeracity::Domain.whitelisted?(" gmail.com \r\n "),
23
+ 'Should match a whitelisted domain regardless of whitespace.'
24
+ assert !EmailVeracity::Domain.whitelisted?('iamnotwhitelisted.com'),
25
+ 'Should not match a non-whitelisted domain.'
26
+ end
27
+
28
+ def test_initializing_a_new_domain_with_whitespace
29
+ domain = new_domain(' heycarsten.com ')
30
+ assert_equal 'heycarsten.com', domain.name, 'Should strip whitespace.'
31
+ assert_respond_to domain, :to_s, 'Should have a to_s method.'
32
+ end
33
+
34
+ def test_a_valid_domain_for_servers
35
+ domain = new_domain('gmail.com')
36
+ assert_not_empty domain.exchange_servers, 'Should contain mail servers.'
37
+ assert_not_empty domain.address_servers, 'Should contain address servers.'
38
+ end
39
+
40
+ def test_a_valid_domain_with_whitespace_for_servers
41
+ domain = new_domain(' learnhub.com ')
42
+ assert_not_empty domain.exchange_servers, 'Should contain mail servers.'
43
+ assert_not_empty domain.address_servers, 'Should contain address servers.'
44
+ end
45
+
46
+ def test_an_invalid_domain_for_servers
47
+ domain = new_domain('i-surely-do-not.exist')
48
+ assert_empty domain.exchange_servers, 'Should not contain exchange servers.'
49
+ assert_empty domain.address_servers, 'Should not contain address servers.'
50
+ end
51
+
52
+ def test_a_blank_domain_for_servers
53
+ domain = new_domain('')
54
+ assert_empty domain.exchange_servers, 'Should not contain exchange servers.'
55
+ assert_empty domain.address_servers, 'Should not contain address servers.'
56
+ end
57
+
58
+ def test_for_errors_on_a_valid_domain
59
+ domain = new_domain('yahoo.com')
60
+ assert_empty domain.errors, 'Should not have errors.'
61
+ end
62
+
63
+ def test_for_errors_on_an_invalid_domain
64
+ domain = new_domain('i-surely-do-not.exist')
65
+ assert_not_empty domain.errors, 'Should have errors.'
66
+ end
67
+
68
+ private
69
+ def new_domain(name = 'heycarsten.com')
70
+ EmailVeracity::Domain.new(name)
71
+ end
72
+
73
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class ResolverTest < Test::Unit::TestCase
5
+
6
+ def test_consecutive_queries
7
+ EmailVeracity::Config[:timeout] = 60
8
+ assert_nothing_raised do
9
+ domain_names.each do |domain|
10
+ assert_instance_of Array,
11
+ EmailVeracity::Resolver.get_servers_for(domain),
12
+ 'Should return an array of servers'
13
+ end
14
+ end
15
+ end
16
+
17
+ def test_timing_out_while_resolving_a_domain
18
+ EmailVeracity::Config[:timeout] = 0.001
19
+ assert_raise EmailVeracity::DomainResourcesTimeoutError, 'Should time out' do
20
+ EmailVeracity::Resolver.get_servers_for('learnhub.com')
21
+ end
22
+ EmailVeracity::Config[:timeout] = 2
23
+ end
24
+
25
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class ServerTest < Test::Unit::TestCase
5
+
6
+ def test_creating_a_new_blank_server_object
7
+ new_server = EmailVeracity::Server.new
8
+ assert_equal '', new_server.to_s,
9
+ 'Should yield a blank string on call to to_s.'
10
+ assert_equal '', new_server.name,
11
+ 'Should yield a blank string on call to name.'
12
+ end
13
+
14
+ def test_creating_a_new_server_object_with_a_name_and_type
15
+ name = 'cooltown.ca'
16
+ new_server = EmailVeracity::Server.new(name)
17
+ assert_equal name, new_server.name,
18
+ 'Should yield the provided name on call to name.'
19
+ assert_equal name, new_server.to_s,
20
+ 'Should yield the provided name on call to to_s.'
21
+ end
22
+
23
+ def test_creating_a_new_blank_server_object_and_setting_its_name_after_initialization
24
+ new_server = EmailVeracity::Server.new('igvita.com')
25
+ assert_raise NoMethodError, 'Should fail miserably.' do
26
+ new_server.name = name
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+
4
+ class ValidatabilityTest < Test::Unit::TestCase
5
+
6
+ def test_includes_proper_methods
7
+ %w[ valid? validate! clear_errors! add_error errors ].each do |method_name|
8
+ assert_respond_to ClassWithValidationMock.new, method_name
9
+ end
10
+ end
11
+
12
+ def test_add_error
13
+ mock = ClassWithValidationMock.new
14
+ mock.give_error = true
15
+ assert_equal 1, mock.errors.size, 'Should set one error.'
16
+ mock.give_errors = true
17
+ assert_equal [:one, :two, :three], mock.errors,
18
+ 'Should push tow new errors for a total of three.'
19
+ mock.give_array_of_errors = true
20
+ assert_equal [:one, :two, :three, :four, :five], mock.errors,
21
+ 'Should concat the array leaving two new errors for a total of five.'
22
+ end
23
+
24
+ def test_valid?
25
+ mock = ClassWithValidationMock.new
26
+ assert mock.valid?, 'Should be valid by default.'
27
+ mock.give_error = true
28
+ assert !mock.valid?, 'Should not be valid if errors are set.'
29
+ end
30
+
31
+ def test_errors
32
+ assert ClassWithValidationMock.new.errors.empty?,
33
+ 'Should be empty by default.'
34
+ end
35
+
36
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heycarsten-email-veracity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Carsten Nielsen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-06 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Email Veracity abstracts an email address into a series of objects which makes it easy to see if an address is invalid, and if so, why.
17
+ email: heycarsten@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - lib/email_veracity/address.rb
26
+ - lib/email_veracity/config.rb
27
+ - lib/email_veracity/core_extensions.rb
28
+ - lib/email_veracity/domain.rb
29
+ - lib/email_veracity/errors.rb
30
+ - lib/email_veracity/resolver.rb
31
+ - lib/email_veracity/server.rb
32
+ - lib/email_veracity/validatability.rb
33
+ - lib/email_veracity.rb
34
+ - README.rdoc
35
+ - VERSION
36
+ - Rakefile
37
+ - init.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/heycarsten/email-veracity
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --title
43
+ - Email Veracity
44
+ - --main
45
+ - README.rdoc
46
+ - --line-numbers
47
+ - --inline-source
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.2.0
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: A simple library for checking the real-world validity of email addresses.
69
+ test_files:
70
+ - test/mocks/class_with_validation_mock.rb
71
+ - test/test_helper.rb
72
+ - test/unit/address_test.rb
73
+ - test/unit/config_test.rb
74
+ - test/unit/core_extensions_test.rb
75
+ - test/unit/domain_test.rb
76
+ - test/unit/resolver_test.rb
77
+ - test/unit/server_test.rb
78
+ - test/unit/validatability_test.rb