mail 2.8.1 → 2.9.0.beta1

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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -31
  3. data/lib/mail/attachments_list.rb +3 -1
  4. data/lib/mail/body.rb +28 -28
  5. data/lib/mail/encodings/quoted_printable.rb +1 -1
  6. data/lib/mail/encodings/unix_to_unix.rb +1 -1
  7. data/lib/mail/encodings.rb +2 -2
  8. data/lib/mail/field.rb +65 -35
  9. data/lib/mail/field_list.rb +1 -1
  10. data/lib/mail/fields/bcc_field.rb +0 -1
  11. data/lib/mail/fields/cc_field.rb +0 -1
  12. data/lib/mail/fields/comments_field.rb +0 -1
  13. data/lib/mail/fields/common_address_field.rb +9 -17
  14. data/lib/mail/fields/common_date_field.rb +0 -2
  15. data/lib/mail/fields/common_message_id_field.rb +0 -1
  16. data/lib/mail/fields/content_description_field.rb +0 -1
  17. data/lib/mail/fields/content_disposition_field.rb +0 -2
  18. data/lib/mail/fields/content_id_field.rb +0 -1
  19. data/lib/mail/fields/content_location_field.rb +0 -1
  20. data/lib/mail/fields/content_transfer_encoding_field.rb +0 -1
  21. data/lib/mail/fields/content_type_field.rb +5 -6
  22. data/lib/mail/fields/date_field.rb +0 -1
  23. data/lib/mail/fields/from_field.rb +0 -1
  24. data/lib/mail/fields/in_reply_to_field.rb +0 -1
  25. data/lib/mail/fields/keywords_field.rb +0 -1
  26. data/lib/mail/fields/message_id_field.rb +0 -1
  27. data/lib/mail/fields/mime_version_field.rb +1 -2
  28. data/lib/mail/fields/named_structured_field.rb +0 -1
  29. data/lib/mail/fields/named_unstructured_field.rb +0 -1
  30. data/lib/mail/fields/optional_field.rb +0 -1
  31. data/lib/mail/fields/received_field.rb +0 -1
  32. data/lib/mail/fields/references_field.rb +0 -1
  33. data/lib/mail/fields/reply_to_field.rb +0 -1
  34. data/lib/mail/fields/resent_bcc_field.rb +0 -1
  35. data/lib/mail/fields/resent_cc_field.rb +0 -1
  36. data/lib/mail/fields/resent_date_field.rb +0 -1
  37. data/lib/mail/fields/resent_from_field.rb +0 -1
  38. data/lib/mail/fields/resent_message_id_field.rb +0 -1
  39. data/lib/mail/fields/resent_sender_field.rb +0 -1
  40. data/lib/mail/fields/resent_to_field.rb +0 -1
  41. data/lib/mail/fields/return_path_field.rb +0 -1
  42. data/lib/mail/fields/sender_field.rb +0 -1
  43. data/lib/mail/fields/structured_field.rb +0 -1
  44. data/lib/mail/fields/subject_field.rb +0 -1
  45. data/lib/mail/fields/to_field.rb +0 -1
  46. data/lib/mail/fields/unstructured_field.rb +0 -1
  47. data/lib/mail/fields.rb +9 -0
  48. data/lib/mail/header.rb +1 -1
  49. data/lib/mail/mail.rb +32 -27
  50. data/lib/mail/message.rb +22 -19
  51. data/lib/mail/multibyte/chars.rb +1 -1
  52. data/lib/mail/multibyte/unicode.rb +1 -1
  53. data/lib/mail/network/delivery_methods/file_delivery.rb +2 -2
  54. data/lib/mail/network/delivery_methods/sendmail.rb +2 -48
  55. data/lib/mail/network/delivery_methods/smtp.rb +77 -42
  56. data/lib/mail/network/delivery_methods/smtp_connection.rb +7 -7
  57. data/lib/mail/network/delivery_methods/test_mailer.rb +4 -4
  58. data/lib/mail/network/retriever_methods/base.rb +5 -5
  59. data/lib/mail/network/retriever_methods/imap.rb +6 -3
  60. data/lib/mail/network/retriever_methods/pop3.rb +20 -20
  61. data/lib/mail/parsers/address_lists_parser.rb +8 -5
  62. data/lib/mail/parsers/address_lists_parser.rl +4 -0
  63. data/lib/mail/parsers/content_disposition_parser.rb +15 -12
  64. data/lib/mail/parsers/content_disposition_parser.rl +4 -0
  65. data/lib/mail/parsers/content_location_parser.rb +9 -6
  66. data/lib/mail/parsers/content_location_parser.rl +5 -1
  67. data/lib/mail/parsers/content_transfer_encoding_parser.rb +8 -5
  68. data/lib/mail/parsers/content_transfer_encoding_parser.rl +4 -0
  69. data/lib/mail/parsers/content_type_parser.rb +15 -12
  70. data/lib/mail/parsers/content_type_parser.rl +4 -0
  71. data/lib/mail/parsers/date_time_parser.rb +8 -5
  72. data/lib/mail/parsers/date_time_parser.rl +4 -0
  73. data/lib/mail/parsers/envelope_from_parser.rb +8 -5
  74. data/lib/mail/parsers/envelope_from_parser.rl +4 -0
  75. data/lib/mail/parsers/message_ids_parser.rb +8 -5
  76. data/lib/mail/parsers/message_ids_parser.rl +4 -0
  77. data/lib/mail/parsers/mime_version_parser.rb +8 -5
  78. data/lib/mail/parsers/mime_version_parser.rl +4 -0
  79. data/lib/mail/parsers/phrase_lists_parser.rb +8 -5
  80. data/lib/mail/parsers/phrase_lists_parser.rl +4 -0
  81. data/lib/mail/parsers/received_parser.rb +8 -5
  82. data/lib/mail/parsers/received_parser.rl +4 -0
  83. data/lib/mail/part.rb +19 -19
  84. data/lib/mail/smtp_envelope.rb +1 -1
  85. data/lib/mail/utilities.rb +5 -5
  86. data/lib/mail/version.rb +3 -3
  87. data/lib/mail.rb +2 -5
  88. metadata +3 -4
  89. data/lib/mail/check_delivery_params.rb +0 -65
@@ -1,7 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/named_structured_field'
4
- require 'mail/fields/parameter_hash'
5
3
 
6
4
  module Mail
7
5
  class ContentTypeField < NamedStructuredField #:nodoc:
@@ -129,15 +127,16 @@ module Mail
129
127
  val.downcase!
130
128
  end
131
129
 
130
+ val_chomp = val.chomp
132
131
  case
133
- when val.chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
132
+ when val_chomp =~ /^\s*([\w\-]+)\/([\w\-]+)\s*;\s?(ISO[\w\-]+)$/i
134
133
  # Microsoft helper:
135
134
  # Handles 'type/subtype;ISO-8559-1'
136
135
  "#{$1}/#{$2}; charset=#{Utilities.quote_atom($3)}"
137
- when val.chomp =~ /^text;?$/i
136
+ when /^text;?$/i.match?(val_chomp)
138
137
  # Handles 'text;' and 'text'
139
138
  "text/plain;"
140
- when val.chomp =~ /^(\w+);\s(.*)$/i
139
+ when val_chomp =~ /^(\w+);\s(.*)$/i
141
140
  # Handles 'text; <parameters>'
142
141
  "text/plain; #{$2}"
143
142
  when val =~ /([\w\-]+\/[\w\-]+);\scharset="charset="(\w+)""/i
@@ -153,7 +152,7 @@ module Mail
153
152
  params = params.map { |i| i.split(/\s*\=\s*/, 2) }
154
153
  params = params.map { |i| "#{i[0]}=#{Utilities.dquote(i[1].to_s.gsub(/;$/,""))}" }.join('; ')
155
154
  "#{type}; #{params}"
156
- when val =~ /^\s*$/
155
+ when /^\s*$/.match?(val)
157
156
  'text/plain'
158
157
  else
159
158
  val
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_date_field'
4
3
 
5
4
  module Mail
6
5
  # = Date Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = From Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_message_id_field'
4
3
 
5
4
  module Mail
6
5
  # = In-Reply-To Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/named_structured_field'
4
3
 
5
4
  module Mail
6
5
  # keywords = "Keywords:" phrase *("," phrase) CRLF
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_message_id_field'
4
3
  require 'mail/utilities'
5
4
 
6
5
  module Mail
@@ -1,11 +1,10 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/named_structured_field'
4
3
  require 'mail/utilities'
5
4
 
6
5
  module Mail
7
6
  class MimeVersionField < NamedStructuredField #:nodoc:
8
- NAME = 'Mime-Version'
7
+ NAME = 'MIME-Version'
9
8
 
10
9
  def self.singular?
11
10
  true
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/structured_field'
4
3
 
5
4
  module Mail
6
5
  class NamedStructuredField < StructuredField #:nodoc:
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/unstructured_field'
4
3
 
5
4
  module Mail
6
5
  class NamedUnstructuredField < UnstructuredField #:nodoc:
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/unstructured_field'
4
3
 
5
4
  module Mail
6
5
  # The field names of any optional-field MUST NOT be identical to any
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/named_structured_field'
4
3
 
5
4
  module Mail
6
5
  # trace = [return]
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_message_id_field'
4
3
 
5
4
  module Mail
6
5
  # = References Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Reply-To Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Resent-Bcc Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Resent-Cc Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_date_field'
4
3
 
5
4
  module Mail
6
5
  #
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Resent-From Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_message_id_field'
4
3
 
5
4
  module Mail
6
5
  #
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Resent-Sender Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Resent-To Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # 4.4.3. REPLY-TO / RESENT-REPLY-TO
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = Sender Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_field'
4
3
 
5
4
  module Mail
6
5
  # Provides access to a structured header field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/named_unstructured_field'
4
3
 
5
4
  module Mail
6
5
  #
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_address_field'
4
3
 
5
4
  module Mail
6
5
  # = To Field
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'mail/fields/common_field'
4
3
  require 'mail/utilities'
5
4
 
6
5
  module Mail
data/lib/mail/fields.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
  module Mail
3
+ register_autoload :CommonField, 'mail/fields/common_field'
4
+ register_autoload :CommonAddressField, 'mail/fields/common_address_field'
5
+ register_autoload :CommonMessageIdField, 'mail/fields/common_message_id_field'
6
+ register_autoload :CommonDateField, 'mail/fields/common_date_field'
7
+
3
8
  register_autoload :UnstructuredField, 'mail/fields/unstructured_field'
9
+ register_autoload :NamedUnstructuredField, 'mail/fields/named_unstructured_field'
4
10
  register_autoload :StructuredField, 'mail/fields/structured_field'
5
11
  register_autoload :OptionalField, 'mail/fields/optional_field'
6
12
 
@@ -19,6 +25,7 @@ module Mail
19
25
  register_autoload :KeywordsField, 'mail/fields/keywords_field'
20
26
  register_autoload :MessageIdField, 'mail/fields/message_id_field'
21
27
  register_autoload :MimeVersionField, 'mail/fields/mime_version_field'
28
+ register_autoload :NamedStructuredField, 'mail/fields/named_structured_field'
22
29
  register_autoload :ReceivedField, 'mail/fields/received_field'
23
30
  register_autoload :ReferencesField, 'mail/fields/references_field'
24
31
  register_autoload :ReplyToField, 'mail/fields/reply_to_field'
@@ -33,4 +40,6 @@ module Mail
33
40
  register_autoload :SenderField, 'mail/fields/sender_field'
34
41
  register_autoload :SubjectField, 'mail/fields/subject_field'
35
42
  register_autoload :ToField, 'mail/fields/to_field'
43
+
44
+ register_autoload :ParameterHash, 'mail/fields/parameter_hash'
36
45
  end
data/lib/mail/header.rb CHANGED
@@ -217,7 +217,7 @@ module Mail
217
217
 
218
218
  # Returns true if the header has a MIME version defined (empty or not)
219
219
  def has_mime_version?
220
- fields.has_field? 'Mime-Version'
220
+ fields.has_field? 'MIME-Version'
221
221
  end
222
222
 
223
223
  private
data/lib/mail/mail.rb CHANGED
@@ -3,45 +3,45 @@
3
3
  module Mail
4
4
 
5
5
  # Allows you to create a new Mail::Message object.
6
- #
6
+ #
7
7
  # You can make an email via passing a string or passing a block.
8
- #
8
+ #
9
9
  # For example, the following two examples will create the same email
10
10
  # message:
11
- #
11
+ #
12
12
  # Creating via a string:
13
- #
13
+ #
14
14
  # string = "To: mikel@test.lindsaar.net\r\n"
15
15
  # string << "From: bob@test.lindsaar.net\r\n"
16
16
  # string << "Subject: This is an email\r\n"
17
17
  # string << "\r\n"
18
18
  # string << "This is the body"
19
19
  # Mail.new(string)
20
- #
20
+ #
21
21
  # Or creating via a block:
22
- #
22
+ #
23
23
  # message = Mail.new do
24
24
  # to 'mikel@test.lindsaar.net'
25
25
  # from 'bob@test.lindsaar.net'
26
26
  # subject 'This is an email'
27
27
  # body 'This is the body'
28
28
  # end
29
- #
29
+ #
30
30
  # Or creating via a hash (or hash like object):
31
- #
31
+ #
32
32
  # message = Mail.new({:to => 'mikel@test.lindsaar.net',
33
33
  # 'from' => 'bob@test.lindsaar.net',
34
34
  # :subject => 'This is an email',
35
35
  # :body => 'This is the body' })
36
- #
36
+ #
37
37
  # Note, the hash keys can be strings or symbols, the passed in object
38
38
  # does not need to be a hash, it just needs to respond to :each_pair
39
39
  # and yield each key value pair.
40
- #
40
+ #
41
41
  # As a side note, you can also create a new email through creating
42
42
  # a Mail::Message object directly and then passing in values via string,
43
43
  # symbol or direct method calls. See Mail::Message for more information.
44
- #
44
+ #
45
45
  # mail = Mail.new
46
46
  # mail.to = 'mikel@test.lindsaar.net'
47
47
  # mail[:from] = 'bob@test.lindsaar.net'
@@ -54,20 +54,20 @@ module Mail
54
54
  # Sets the default delivery method and retriever method for all new Mail objects.
55
55
  # The delivery_method and retriever_method default to :smtp and :pop3, with defaults
56
56
  # set.
57
- #
57
+ #
58
58
  # So sending a new email, if you have an SMTP server running on localhost is
59
59
  # as easy as:
60
- #
60
+ #
61
61
  # Mail.deliver do
62
62
  # to 'mikel@test.lindsaar.net'
63
63
  # from 'bob@test.lindsaar.net'
64
64
  # subject 'hi there!'
65
65
  # body 'this is a body'
66
66
  # end
67
- #
67
+ #
68
68
  # If you do not specify anything, you will get the following equivalent code set in
69
69
  # every new mail object:
70
- #
70
+ #
71
71
  # Mail.defaults do
72
72
  # delivery_method :smtp, { :address => "localhost",
73
73
  # :port => 25,
@@ -76,14 +76,14 @@ module Mail
76
76
  # :password => nil,
77
77
  # :authentication => nil,
78
78
  # :enable_starttls_auto => true }
79
- #
79
+ #
80
80
  # retriever_method :pop3, { :address => "localhost",
81
81
  # :port => 995,
82
82
  # :user_name => nil,
83
83
  # :password => nil,
84
84
  # :enable_ssl => true }
85
85
  # end
86
- #
86
+ #
87
87
  # Mail.delivery_method.new #=> Mail::SMTP instance
88
88
  # Mail.retriever_method.new #=> Mail::POP3 instance
89
89
  #
@@ -91,9 +91,9 @@ module Mail
91
91
  # a per email basis, you can override the method:
92
92
  #
93
93
  # mail.delivery_method :smtp
94
- #
94
+ #
95
95
  # Or you can override the method and pass in settings:
96
- #
96
+ #
97
97
  # mail.delivery_method :smtp, :address => 'some.host'
98
98
  def self.defaults(&block)
99
99
  Configuration.instance.instance_eval(&block)
@@ -112,21 +112,21 @@ module Mail
112
112
  # Send an email using the default configuration. You do need to set a default
113
113
  # configuration first before you use self.deliver, if you don't, an appropriate
114
114
  # error will be raised telling you to.
115
- #
115
+ #
116
116
  # If you do not specify a delivery type, SMTP will be used.
117
- #
117
+ #
118
118
  # Mail.deliver do
119
119
  # to 'mikel@test.lindsaar.net'
120
120
  # from 'ada@test.lindsaar.net'
121
121
  # subject 'This is a test email'
122
122
  # body 'Not much to say here'
123
123
  # end
124
- #
124
+ #
125
125
  # You can also do:
126
- #
126
+ #
127
127
  # mail = Mail.read('email.eml')
128
128
  # mail.deliver!
129
- #
129
+ #
130
130
  # And your email object will be created and sent.
131
131
  def self.deliver(*args, &block)
132
132
  mail = self.new(args, &block)
@@ -152,7 +152,7 @@ module Mail
152
152
  retriever_method.first(*args, &block)
153
153
  end
154
154
 
155
- # Receive the first email(s) from the default retriever
155
+ # Receive the last email(s) from the default retriever
156
156
  # See Mail::Retriever for a complete documentation.
157
157
  def self.last(*args, &block)
158
158
  retriever_method.last(*args, &block)
@@ -190,7 +190,7 @@ module Mail
190
190
 
191
191
  # You can register an object to be informed of every email that is sent through
192
192
  # this method.
193
- #
193
+ #
194
194
  # Your object needs to respond to a single method #delivered_email(mail)
195
195
  # which receives the email that is sent.
196
196
  def self.register_observer(observer)
@@ -208,7 +208,7 @@ module Mail
208
208
  # You can register an object to be given every mail object that will be sent,
209
209
  # before it is sent. So if you want to add special headers or modify any
210
210
  # email that gets sent through the Mail library, you can do so.
211
- #
211
+ #
212
212
  # Your object needs to respond to a single method #delivering_email(mail)
213
213
  # which receives the email that is about to be sent. Make your modifications
214
214
  # directly to this object.
@@ -236,6 +236,11 @@ module Mail
236
236
  end
237
237
  end
238
238
 
239
+ # Returns a list of registered delivery interceptors.
240
+ def self.delivery_interceptors
241
+ @@delivery_interceptors
242
+ end
243
+
239
244
  protected
240
245
 
241
246
  RANDOM_TAG='%x%x_%x%x%d%x'
data/lib/mail/message.rb CHANGED
@@ -294,7 +294,7 @@ module Mail
294
294
  reply.references ||= bracketed_message_id
295
295
  end
296
296
  if subject
297
- reply.subject = subject =~ /^Re:/i ? subject : "Re: #{subject}"
297
+ reply.subject = /^Re:/i.match?(subject) ? subject : "Re: #{subject}"
298
298
  end
299
299
  if reply_to || from
300
300
  reply.to = self[reply_to ? :reply_to : :from].to_s
@@ -349,6 +349,10 @@ module Mail
349
349
  # the same content, ignoring the Message-ID field, unless BOTH emails have a defined and
350
350
  # different Message-ID value, then they are false.
351
351
  #
352
+ # Note that Mail creates Date and Mime-Type fields if they don't exist.
353
+ # The Date field is derived from the current time, so this needs to be allowed for in comparisons.
354
+ # (Mime-type does not depend on dynamic data, so cannot affect equality)
355
+ #
352
356
  # So, in practice the == operator works like this:
353
357
  #
354
358
  # m1 = Mail.new("Subject: Hello\r\n\r\nHello")
@@ -370,14 +374,17 @@ module Mail
370
374
  # m1 = Mail.new("Message-ID: <1234@test>\r\nSubject: Hello\r\n\r\nHello")
371
375
  # m2 = Mail.new("Message-ID: <DIFFERENT@test>\r\nSubject: Hello\r\n\r\nHello")
372
376
  # m1 == m2 #=> false
373
- def ==(other)
377
+ def ==(other) # TODO could be more efficient
374
378
  return false unless other.respond_to?(:encoded)
375
379
 
380
+ stamp = Mail::CommonDateField.normalize_datetime('')
381
+ # Note: must always dup the inputs so they are not altered by encoded
376
382
  if self.message_id && other.message_id
377
- self.encoded == other.encoded
383
+ dup.tap { |m| m.date ||= stamp }.encoded ==
384
+ other.dup.tap { |m| m.date ||= stamp }.encoded
378
385
  else
379
- dup.tap { |m| m.message_id = '<temp@test>' }.encoded ==
380
- other.dup.tap { |m| m.message_id = '<temp@test>' }.encoded
386
+ dup.tap { |m| m.message_id = '<temp@test>'; m.date ||= stamp }.encoded ==
387
+ other.dup.tap { |m| m.message_id = '<temp@test>'; m.date ||= stamp }.encoded
381
388
  end
382
389
  end
383
390
 
@@ -464,7 +471,7 @@ module Mail
464
471
  # message.errors.size #=> 1
465
472
  # message.errors.first[0] #=> "Content-Transfer-Encoding"
466
473
  # message.errors.first[1] #=> "weirdo"
467
- # message.errors.first[3] #=> <The original error message exception>
474
+ # message.errors.first[2] #=> <The original error message exception>
468
475
  #
469
476
  # This is a good first defence on detecting spam by the way. Some spammers send
470
477
  # invalid emails to try and get email parsers to give up parsing them.
@@ -1316,7 +1323,7 @@ module Mail
1316
1323
  def []=(name, value)
1317
1324
  if name.to_s == 'body'
1318
1325
  self.body = value
1319
- elsif name.to_s =~ /content[-_]type/i
1326
+ elsif /content[-_]type/i.match?(name.to_s)
1320
1327
  header[name] = value
1321
1328
  elsif name.to_s == 'charset'
1322
1329
  self.charset = value
@@ -1409,7 +1416,7 @@ module Mail
1409
1416
  header.has_date?
1410
1417
  end
1411
1418
 
1412
- # Returns true if the message has a Mime-Version field, the field may or may
1419
+ # Returns true if the message has a MIME-Version field, the field may or may
1413
1420
  # not have a value, but the field exists or not.
1414
1421
  def has_mime_version?
1415
1422
  header.has_mime_version?
@@ -1526,17 +1533,17 @@ module Mail
1526
1533
 
1527
1534
  # Returns true if the message is multipart
1528
1535
  def multipart?
1529
- has_content_type? ? !!(main_type =~ /^multipart$/i) : false
1536
+ has_content_type? ? /^multipart$/i.match?(main_type) : false
1530
1537
  end
1531
1538
 
1532
1539
  # Returns true if the message is a multipart/report
1533
1540
  def multipart_report?
1534
- multipart? && sub_type =~ /^report$/i
1541
+ multipart? && /^report$/i.match?(sub_type)
1535
1542
  end
1536
1543
 
1537
1544
  # Returns true if the message is a multipart/report; report-type=delivery-status;
1538
1545
  def delivery_status_report?
1539
- multipart_report? && content_type_parameters['report-type'] =~ /^delivery-status$/i
1546
+ multipart_report? && /^delivery-status$/i.match?(content_type_parameters['report-type'])
1540
1547
  end
1541
1548
 
1542
1549
  # returns the part in a multipart/report email that has the content-type delivery-status
@@ -1855,7 +1862,7 @@ module Mail
1855
1862
  m.transport_encoding(v)
1856
1863
  when k == 'multipart_body'
1857
1864
  v.map {|part| m.add_part Mail::Part.from_yaml(part) }
1858
- when k =~ /^@/
1865
+ when k.start_with?('@')
1859
1866
  m.instance_variable_set(k.to_sym, v)
1860
1867
  end
1861
1868
  end
@@ -1892,7 +1899,7 @@ module Mail
1892
1899
  when !self.multipart?
1893
1900
  body.decoded
1894
1901
  else
1895
- raise NoMethodError, 'Can not decode an entire message, try calling #decoded on the various fields and body or parts if it is a multipart message.'
1902
+ raise NoMethodError, 'This message cannot be decoded as _entire_ message, try calling #decoded on the various fields and body or parts if it is a multipart message.'
1896
1903
  end
1897
1904
  end
1898
1905
 
@@ -1962,7 +1969,7 @@ module Mail
1962
1969
  end
1963
1970
 
1964
1971
  def text?
1965
- has_content_type? ? !!(main_type =~ /^text$/i) : false
1972
+ has_content_type? ? /^text$/i.match?(main_type) : false
1966
1973
  end
1967
1974
 
1968
1975
  private
@@ -2066,11 +2073,7 @@ module Mail
2066
2073
 
2067
2074
  def add_boundary
2068
2075
  unless body.boundary && boundary
2069
- unless header['content-type']
2070
- _charset = charset
2071
- header['content-type'] = 'multipart/mixed'
2072
- header['content-type'].parameters[:charset] = _charset
2073
- end
2076
+ header['content-type'] = 'multipart/mixed' unless header['content-type']
2074
2077
  header['content-type'].parameters[:boundary] = ContentTypeField.generate_boundary
2075
2078
  body.boundary = boundary
2076
2079
  end
@@ -46,7 +46,7 @@ module Mail #:nodoc:
46
46
 
47
47
  # Forward all undefined methods to the wrapped string.
48
48
  def method_missing(method, *args, &block)
49
- if method.to_s =~ /!$/
49
+ if method.to_s.end_with?('!')
50
50
  @wrapped_string.__send__(method, *args, &block)
51
51
  self
52
52
  else
@@ -375,7 +375,7 @@ module Mail
375
375
 
376
376
  # Returns the directory in which the data files are stored
377
377
  def self.dirname
378
- File.dirname(__FILE__) + '/../values/'
378
+ __dir__ + '/../values/'
379
379
  end
380
380
 
381
381
  # Returns the filename for the data file for this version
@@ -4,12 +4,12 @@ require 'mail/smtp_envelope'
4
4
  module Mail
5
5
  # FileDelivery class delivers emails into multiple files based on the destination
6
6
  # address. Each file is appended to if it already exists.
7
- #
7
+ #
8
8
  # So if you have an email going to fred@test, bob@test, joe@anothertest, and you
9
9
  # set your location path to /path/to/mails then FileDelivery will create the directory
10
10
  # if it does not exist, and put one copy of the email in three files, called
11
11
  # by their message id
12
- #
12
+ #
13
13
  # Make sure the path you specify with :location is writable by the Ruby process
14
14
  # running Mail.
15
15
  class FileDelivery