nano-fast-tool 0.0.1

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 (138) hide show
  1. checksums.yaml +7 -0
  2. data/mail-2.9.1/MIT-LICENSE +20 -0
  3. data/mail-2.9.1/README.md +771 -0
  4. data/mail-2.9.1/lib/mail/attachments_list.rb +109 -0
  5. data/mail-2.9.1/lib/mail/body.rb +305 -0
  6. data/mail-2.9.1/lib/mail/configuration.rb +78 -0
  7. data/mail-2.9.1/lib/mail/constants.rb +79 -0
  8. data/mail-2.9.1/lib/mail/elements/address.rb +258 -0
  9. data/mail-2.9.1/lib/mail/elements/address_list.rb +34 -0
  10. data/mail-2.9.1/lib/mail/elements/content_disposition_element.rb +20 -0
  11. data/mail-2.9.1/lib/mail/elements/content_location_element.rb +17 -0
  12. data/mail-2.9.1/lib/mail/elements/content_transfer_encoding_element.rb +13 -0
  13. data/mail-2.9.1/lib/mail/elements/content_type_element.rb +25 -0
  14. data/mail-2.9.1/lib/mail/elements/date_time_element.rb +15 -0
  15. data/mail-2.9.1/lib/mail/elements/envelope_from_element.rb +39 -0
  16. data/mail-2.9.1/lib/mail/elements/message_ids_element.rb +31 -0
  17. data/mail-2.9.1/lib/mail/elements/mime_version_element.rb +15 -0
  18. data/mail-2.9.1/lib/mail/elements/phrase_list.rb +19 -0
  19. data/mail-2.9.1/lib/mail/elements/received_element.rb +35 -0
  20. data/mail-2.9.1/lib/mail/elements.rb +15 -0
  21. data/mail-2.9.1/lib/mail/encodings/7bit.rb +27 -0
  22. data/mail-2.9.1/lib/mail/encodings/8bit.rb +18 -0
  23. data/mail-2.9.1/lib/mail/encodings/base64.rb +38 -0
  24. data/mail-2.9.1/lib/mail/encodings/binary.rb +13 -0
  25. data/mail-2.9.1/lib/mail/encodings/identity.rb +24 -0
  26. data/mail-2.9.1/lib/mail/encodings/quoted_printable.rb +45 -0
  27. data/mail-2.9.1/lib/mail/encodings/transfer_encoding.rb +77 -0
  28. data/mail-2.9.1/lib/mail/encodings/unix_to_unix.rb +20 -0
  29. data/mail-2.9.1/lib/mail/encodings.rb +314 -0
  30. data/mail-2.9.1/lib/mail/envelope.rb +28 -0
  31. data/mail-2.9.1/lib/mail/field.rb +313 -0
  32. data/mail-2.9.1/lib/mail/field_list.rb +87 -0
  33. data/mail-2.9.1/lib/mail/fields/bcc_field.rb +49 -0
  34. data/mail-2.9.1/lib/mail/fields/cc_field.rb +33 -0
  35. data/mail-2.9.1/lib/mail/fields/comments_field.rb +31 -0
  36. data/mail-2.9.1/lib/mail/fields/common_address_field.rb +162 -0
  37. data/mail-2.9.1/lib/mail/fields/common_date_field.rb +56 -0
  38. data/mail-2.9.1/lib/mail/fields/common_field.rb +77 -0
  39. data/mail-2.9.1/lib/mail/fields/common_message_id_field.rb +41 -0
  40. data/mail-2.9.1/lib/mail/fields/content_description_field.rb +12 -0
  41. data/mail-2.9.1/lib/mail/fields/content_disposition_field.rb +44 -0
  42. data/mail-2.9.1/lib/mail/fields/content_id_field.rb +35 -0
  43. data/mail-2.9.1/lib/mail/fields/content_location_field.rb +28 -0
  44. data/mail-2.9.1/lib/mail/fields/content_transfer_encoding_field.rb +44 -0
  45. data/mail-2.9.1/lib/mail/fields/content_type_field.rb +171 -0
  46. data/mail-2.9.1/lib/mail/fields/date_field.rb +28 -0
  47. data/mail-2.9.1/lib/mail/fields/from_field.rb +33 -0
  48. data/mail-2.9.1/lib/mail/fields/in_reply_to_field.rb +45 -0
  49. data/mail-2.9.1/lib/mail/fields/keywords_field.rb +30 -0
  50. data/mail-2.9.1/lib/mail/fields/message_id_field.rb +36 -0
  51. data/mail-2.9.1/lib/mail/fields/mime_version_field.rb +42 -0
  52. data/mail-2.9.1/lib/mail/fields/named_structured_field.rb +10 -0
  53. data/mail-2.9.1/lib/mail/fields/named_unstructured_field.rb +10 -0
  54. data/mail-2.9.1/lib/mail/fields/optional_field.rb +15 -0
  55. data/mail-2.9.1/lib/mail/fields/parameter_hash.rb +61 -0
  56. data/mail-2.9.1/lib/mail/fields/received_field.rb +61 -0
  57. data/mail-2.9.1/lib/mail/fields/references_field.rb +42 -0
  58. data/mail-2.9.1/lib/mail/fields/reply_to_field.rb +33 -0
  59. data/mail-2.9.1/lib/mail/fields/resent_bcc_field.rb +33 -0
  60. data/mail-2.9.1/lib/mail/fields/resent_cc_field.rb +33 -0
  61. data/mail-2.9.1/lib/mail/fields/resent_date_field.rb +10 -0
  62. data/mail-2.9.1/lib/mail/fields/resent_from_field.rb +33 -0
  63. data/mail-2.9.1/lib/mail/fields/resent_message_id_field.rb +10 -0
  64. data/mail-2.9.1/lib/mail/fields/resent_sender_field.rb +32 -0
  65. data/mail-2.9.1/lib/mail/fields/resent_to_field.rb +33 -0
  66. data/mail-2.9.1/lib/mail/fields/return_path_field.rb +60 -0
  67. data/mail-2.9.1/lib/mail/fields/sender_field.rb +45 -0
  68. data/mail-2.9.1/lib/mail/fields/structured_field.rb +24 -0
  69. data/mail-2.9.1/lib/mail/fields/subject_field.rb +14 -0
  70. data/mail-2.9.1/lib/mail/fields/to_field.rb +33 -0
  71. data/mail-2.9.1/lib/mail/fields/unstructured_field.rb +189 -0
  72. data/mail-2.9.1/lib/mail/fields.rb +45 -0
  73. data/mail-2.9.1/lib/mail/header.rb +237 -0
  74. data/mail-2.9.1/lib/mail/indifferent_hash.rb +147 -0
  75. data/mail-2.9.1/lib/mail/mail.rb +267 -0
  76. data/mail-2.9.1/lib/mail/matchers/attachment_matchers.rb +44 -0
  77. data/mail-2.9.1/lib/mail/matchers/has_sent_mail.rb +201 -0
  78. data/mail-2.9.1/lib/mail/message.rb +2159 -0
  79. data/mail-2.9.1/lib/mail/multibyte/chars.rb +318 -0
  80. data/mail-2.9.1/lib/mail/multibyte/unicode.rb +405 -0
  81. data/mail-2.9.1/lib/mail/multibyte/utils.rb +44 -0
  82. data/mail-2.9.1/lib/mail/multibyte.rb +82 -0
  83. data/mail-2.9.1/lib/mail/network/delivery_methods/exim.rb +50 -0
  84. data/mail-2.9.1/lib/mail/network/delivery_methods/file_delivery.rb +43 -0
  85. data/mail-2.9.1/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  86. data/mail-2.9.1/lib/mail/network/delivery_methods/sendmail.rb +87 -0
  87. data/mail-2.9.1/lib/mail/network/delivery_methods/smtp.rb +200 -0
  88. data/mail-2.9.1/lib/mail/network/delivery_methods/smtp_connection.rb +57 -0
  89. data/mail-2.9.1/lib/mail/network/delivery_methods/test_mailer.rb +44 -0
  90. data/mail-2.9.1/lib/mail/network/retriever_methods/base.rb +64 -0
  91. data/mail-2.9.1/lib/mail/network/retriever_methods/imap.rb +190 -0
  92. data/mail-2.9.1/lib/mail/network/retriever_methods/pop3.rb +143 -0
  93. data/mail-2.9.1/lib/mail/network/retriever_methods/test_retriever.rb +45 -0
  94. data/mail-2.9.1/lib/mail/network.rb +16 -0
  95. data/mail-2.9.1/lib/mail/parser_tools.rb +15 -0
  96. data/mail-2.9.1/lib/mail/parsers/address_lists_parser.rb +33245 -0
  97. data/mail-2.9.1/lib/mail/parsers/address_lists_parser.rl +183 -0
  98. data/mail-2.9.1/lib/mail/parsers/content_disposition_parser.rb +904 -0
  99. data/mail-2.9.1/lib/mail/parsers/content_disposition_parser.rl +93 -0
  100. data/mail-2.9.1/lib/mail/parsers/content_location_parser.rb +825 -0
  101. data/mail-2.9.1/lib/mail/parsers/content_location_parser.rl +82 -0
  102. data/mail-2.9.1/lib/mail/parsers/content_transfer_encoding_parser.rb +525 -0
  103. data/mail-2.9.1/lib/mail/parsers/content_transfer_encoding_parser.rl +75 -0
  104. data/mail-2.9.1/lib/mail/parsers/content_type_parser.rb +1051 -0
  105. data/mail-2.9.1/lib/mail/parsers/content_type_parser.rl +94 -0
  106. data/mail-2.9.1/lib/mail/parsers/date_time_parser.rb +894 -0
  107. data/mail-2.9.1/lib/mail/parsers/date_time_parser.rl +73 -0
  108. data/mail-2.9.1/lib/mail/parsers/envelope_from_parser.rb +3678 -0
  109. data/mail-2.9.1/lib/mail/parsers/envelope_from_parser.rl +93 -0
  110. data/mail-2.9.1/lib/mail/parsers/message_ids_parser.rb +5164 -0
  111. data/mail-2.9.1/lib/mail/parsers/message_ids_parser.rl +97 -0
  112. data/mail-2.9.1/lib/mail/parsers/mime_version_parser.rb +516 -0
  113. data/mail-2.9.1/lib/mail/parsers/mime_version_parser.rl +72 -0
  114. data/mail-2.9.1/lib/mail/parsers/phrase_lists_parser.rb +887 -0
  115. data/mail-2.9.1/lib/mail/parsers/phrase_lists_parser.rl +94 -0
  116. data/mail-2.9.1/lib/mail/parsers/received_parser.rb +8785 -0
  117. data/mail-2.9.1/lib/mail/parsers/received_parser.rl +95 -0
  118. data/mail-2.9.1/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  119. data/mail-2.9.1/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  120. data/mail-2.9.1/lib/mail/parsers/rfc2045_mime.rl +16 -0
  121. data/mail-2.9.1/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  122. data/mail-2.9.1/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  123. data/mail-2.9.1/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  124. data/mail-2.9.1/lib/mail/parsers/rfc5322.rl +74 -0
  125. data/mail-2.9.1/lib/mail/parsers/rfc5322_address.rl +72 -0
  126. data/mail-2.9.1/lib/mail/parsers/rfc5322_date_time.rl +37 -0
  127. data/mail-2.9.1/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  128. data/mail-2.9.1/lib/mail/parsers.rb +13 -0
  129. data/mail-2.9.1/lib/mail/part.rb +119 -0
  130. data/mail-2.9.1/lib/mail/parts_list.rb +131 -0
  131. data/mail-2.9.1/lib/mail/smtp_envelope.rb +57 -0
  132. data/mail-2.9.1/lib/mail/utilities.rb +576 -0
  133. data/mail-2.9.1/lib/mail/values/unicode_tables.dat +0 -0
  134. data/mail-2.9.1/lib/mail/version.rb +17 -0
  135. data/mail-2.9.1/lib/mail/yaml.rb +30 -0
  136. data/mail-2.9.1/lib/mail.rb +65 -0
  137. data/nano-fast-tool.gemspec +12 -0
  138. metadata +177 -0
@@ -0,0 +1,267 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module Mail
4
+
5
+ # Allows you to create a new Mail::Message object.
6
+ #
7
+ # You can make an email via passing a string or passing a block.
8
+ #
9
+ # For example, the following two examples will create the same email
10
+ # message:
11
+ #
12
+ # Creating via a string:
13
+ #
14
+ # string = "To: mikel@test.lindsaar.net\r\n"
15
+ # string << "From: bob@test.lindsaar.net\r\n"
16
+ # string << "Subject: This is an email\r\n"
17
+ # string << "\r\n"
18
+ # string << "This is the body"
19
+ # Mail.new(string)
20
+ #
21
+ # Or creating via a block:
22
+ #
23
+ # message = Mail.new do
24
+ # to 'mikel@test.lindsaar.net'
25
+ # from 'bob@test.lindsaar.net'
26
+ # subject 'This is an email'
27
+ # body 'This is the body'
28
+ # end
29
+ #
30
+ # Or creating via a hash (or hash like object):
31
+ #
32
+ # message = Mail.new({:to => 'mikel@test.lindsaar.net',
33
+ # 'from' => 'bob@test.lindsaar.net',
34
+ # :subject => 'This is an email',
35
+ # :body => 'This is the body' })
36
+ #
37
+ # Note, the hash keys can be strings or symbols, the passed in object
38
+ # does not need to be a hash, it just needs to respond to :each_pair
39
+ # and yield each key value pair.
40
+ #
41
+ # As a side note, you can also create a new email through creating
42
+ # a Mail::Message object directly and then passing in values via string,
43
+ # symbol or direct method calls. See Mail::Message for more information.
44
+ #
45
+ # mail = Mail.new
46
+ # mail.to = 'mikel@test.lindsaar.net'
47
+ # mail[:from] = 'bob@test.lindsaar.net'
48
+ # mail['subject'] = 'This is an email'
49
+ # mail.body = 'This is the body'
50
+ def self.new(*args, &block)
51
+ Message.new(args, &block)
52
+ end
53
+
54
+ # Sets the default delivery method and retriever method for all new Mail objects.
55
+ # The delivery_method and retriever_method default to :smtp and :pop3, with defaults
56
+ # set.
57
+ #
58
+ # So sending a new email, if you have an SMTP server running on localhost is
59
+ # as easy as:
60
+ #
61
+ # Mail.deliver do
62
+ # to 'mikel@test.lindsaar.net'
63
+ # from 'bob@test.lindsaar.net'
64
+ # subject 'hi there!'
65
+ # body 'this is a body'
66
+ # end
67
+ #
68
+ # If you do not specify anything, you will get the following equivalent code set in
69
+ # every new mail object:
70
+ #
71
+ # Mail.defaults do
72
+ # delivery_method :smtp, { :address => "localhost",
73
+ # :port => 25,
74
+ # :domain => 'localhost.localdomain',
75
+ # :user_name => nil,
76
+ # :password => nil,
77
+ # :authentication => nil,
78
+ # :enable_starttls_auto => true }
79
+ #
80
+ # retriever_method :pop3, { :address => "localhost",
81
+ # :port => 995,
82
+ # :user_name => nil,
83
+ # :password => nil,
84
+ # :enable_ssl => true }
85
+ # end
86
+ #
87
+ # Mail.delivery_method.new #=> Mail::SMTP instance
88
+ # Mail.retriever_method.new #=> Mail::POP3 instance
89
+ #
90
+ # Each mail object inherits the default set in Mail.delivery_method, however, on
91
+ # a per email basis, you can override the method:
92
+ #
93
+ # mail.delivery_method :smtp
94
+ #
95
+ # Or you can override the method and pass in settings:
96
+ #
97
+ # mail.delivery_method :smtp, :address => 'some.host'
98
+ def self.defaults(&block)
99
+ Configuration.instance.instance_eval(&block)
100
+ end
101
+
102
+ # Returns the delivery method selected, defaults to an instance of Mail::SMTP
103
+ def self.delivery_method
104
+ Configuration.instance.delivery_method
105
+ end
106
+
107
+ # Returns the retriever method selected, defaults to an instance of Mail::POP3
108
+ def self.retriever_method
109
+ Configuration.instance.retriever_method
110
+ end
111
+
112
+ # Send an email using the default configuration. You do need to set a default
113
+ # configuration first before you use self.deliver, if you don't, an appropriate
114
+ # error will be raised telling you to.
115
+ #
116
+ # If you do not specify a delivery type, SMTP will be used.
117
+ #
118
+ # Mail.deliver do
119
+ # to 'mikel@test.lindsaar.net'
120
+ # from 'ada@test.lindsaar.net'
121
+ # subject 'This is a test email'
122
+ # body 'Not much to say here'
123
+ # end
124
+ #
125
+ # You can also do:
126
+ #
127
+ # mail = Mail.read('email.eml')
128
+ # mail.deliver!
129
+ #
130
+ # And your email object will be created and sent.
131
+ def self.deliver(*args, &block)
132
+ mail = self.new(args, &block)
133
+ mail.deliver
134
+ mail
135
+ end
136
+
137
+ # Find emails from the default retriever
138
+ # See Mail::Retriever for a complete documentation.
139
+ def self.find(*args, &block)
140
+ retriever_method.find(*args, &block)
141
+ end
142
+
143
+ # Finds and then deletes retrieved emails from the default retriever
144
+ # See Mail::Retriever for a complete documentation.
145
+ def self.find_and_delete(*args, &block)
146
+ retriever_method.find_and_delete(*args, &block)
147
+ end
148
+
149
+ # Receive the first email(s) from the default retriever
150
+ # See Mail::Retriever for a complete documentation.
151
+ def self.first(*args, &block)
152
+ retriever_method.first(*args, &block)
153
+ end
154
+
155
+ # Receive the last email(s) from the default retriever
156
+ # See Mail::Retriever for a complete documentation.
157
+ def self.last(*args, &block)
158
+ retriever_method.last(*args, &block)
159
+ end
160
+
161
+ # Receive all emails from the default retriever
162
+ # See Mail::Retriever for a complete documentation.
163
+ def self.all(*args, &block)
164
+ retriever_method.all(*args, &block)
165
+ end
166
+
167
+ # Reads in an email message from a path and instantiates it as a new Mail::Message
168
+ def self.read(filename)
169
+ self.new(File.open(filename, 'rb') { |f| f.read })
170
+ end
171
+
172
+ # Delete all emails from the default retriever
173
+ # See Mail::Retriever for a complete documentation.
174
+ def self.delete_all(*args, &block)
175
+ retriever_method.delete_all(*args, &block)
176
+ end
177
+
178
+ # Instantiates a new Mail::Message using a string
179
+ def Mail.read_from_string(mail_as_string)
180
+ Mail.new(mail_as_string)
181
+ end
182
+
183
+ def Mail.connection(&block)
184
+ retriever_method.connection(&block)
185
+ end
186
+
187
+ # Initialize the observers and interceptors arrays
188
+ @@delivery_notification_observers = []
189
+ @@delivery_interceptors = []
190
+
191
+ # You can register an object to be informed of every email that is sent through
192
+ # this method.
193
+ #
194
+ # Your object needs to respond to a single method #delivered_email(mail)
195
+ # which receives the email that is sent.
196
+ def self.register_observer(observer)
197
+ unless @@delivery_notification_observers.include?(observer)
198
+ @@delivery_notification_observers << observer
199
+ end
200
+ end
201
+
202
+ # Unregister the given observer, allowing mail to resume operations
203
+ # without it.
204
+ def self.unregister_observer(observer)
205
+ @@delivery_notification_observers.delete(observer)
206
+ end
207
+
208
+ # You can register an object to be given every mail object that will be sent,
209
+ # before it is sent. So if you want to add special headers or modify any
210
+ # email that gets sent through the Mail library, you can do so.
211
+ #
212
+ # Your object needs to respond to a single method #delivering_email(mail)
213
+ # which receives the email that is about to be sent. Make your modifications
214
+ # directly to this object.
215
+ def self.register_interceptor(interceptor)
216
+ unless @@delivery_interceptors.include?(interceptor)
217
+ @@delivery_interceptors << interceptor
218
+ end
219
+ end
220
+
221
+ # Unregister the given interceptor, allowing mail to resume operations
222
+ # without it.
223
+ def self.unregister_interceptor(interceptor)
224
+ @@delivery_interceptors.delete(interceptor)
225
+ end
226
+
227
+ def self.inform_observers(mail)
228
+ @@delivery_notification_observers.each do |observer|
229
+ observer.delivered_email(mail)
230
+ end
231
+ end
232
+
233
+ def self.inform_interceptors(mail)
234
+ @@delivery_interceptors.each do |interceptor|
235
+ interceptor.delivering_email(mail)
236
+ end
237
+ end
238
+
239
+ # Returns a list of registered delivery interceptors.
240
+ def self.delivery_interceptors
241
+ @@delivery_interceptors
242
+ end
243
+
244
+ protected
245
+
246
+ RANDOM_TAG='%x%x_%x%x%d%x'
247
+
248
+ def self.random_tag
249
+ t = Time.now
250
+ sprintf(RANDOM_TAG,
251
+ t.to_i, t.tv_usec,
252
+ $$, Thread.current.object_id.abs, self.uniq, rand(255))
253
+ end
254
+
255
+ private
256
+
257
+ def self.something_random
258
+ (Thread.current.object_id * rand(255) / Time.now.to_f).to_s.slice(-3..-1).to_i
259
+ end
260
+
261
+ def self.uniq
262
+ @@uniq += 1
263
+ end
264
+
265
+ @@uniq = self.something_random
266
+
267
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ module Mail
3
+ module Matchers
4
+ def any_attachment
5
+ AnyAttachmentMatcher.new
6
+ end
7
+
8
+ def an_attachment_with_filename(filename)
9
+ AttachmentFilenameMatcher.new(filename)
10
+ end
11
+
12
+ def an_attachment_with_mime_type(filename)
13
+ AttachmentMimeTypeMatcher.new(filename)
14
+ end
15
+
16
+ class AnyAttachmentMatcher
17
+ def ===(other)
18
+ other.attachment?
19
+ end
20
+ end
21
+
22
+ class AttachmentFilenameMatcher
23
+ attr_reader :filename
24
+ def initialize(filename)
25
+ @filename = filename
26
+ end
27
+
28
+ def ===(other)
29
+ other.attachment? && other.filename == filename
30
+ end
31
+ end
32
+
33
+ class AttachmentMimeTypeMatcher
34
+ attr_reader :mime_type
35
+ def initialize(mime_type)
36
+ @mime_type = mime_type
37
+ end
38
+
39
+ def ===(other)
40
+ other.attachment? && other.mime_type == mime_type
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+ module Mail
3
+ module Matchers
4
+ def have_sent_email
5
+ HasSentEmailMatcher.new(self)
6
+ end
7
+
8
+ class HasSentEmailMatcher
9
+ def initialize(_context)
10
+ end
11
+
12
+ def matches?(subject)
13
+ matching_deliveries = filter_matched_deliveries(Mail::TestMailer.deliveries)
14
+ !(matching_deliveries.empty?)
15
+ end
16
+
17
+ def from(sender)
18
+ @sender = sender
19
+ self
20
+ end
21
+
22
+ def to(recipient_or_list)
23
+ @recipients ||= []
24
+
25
+ if recipient_or_list.kind_of?(Array)
26
+ @recipients += recipient_or_list
27
+ else
28
+ @recipients << recipient_or_list
29
+ end
30
+ self
31
+ end
32
+
33
+ def cc(recipient_or_list)
34
+ @copy_recipients ||= []
35
+
36
+ if recipient_or_list.kind_of?(Array)
37
+ @copy_recipients += recipient_or_list
38
+ else
39
+ @copy_recipients << recipient_or_list
40
+ end
41
+ self
42
+ end
43
+
44
+ def bcc(recipient_or_list)
45
+ @blind_copy_recipients ||= []
46
+ @blind_copy_recipients.concat(Array(recipient_or_list))
47
+ self
48
+ end
49
+
50
+ def with_attachments(attachments)
51
+ @attachments ||= []
52
+ @attachments.concat(Array(attachments))
53
+ self
54
+ end
55
+
56
+ def with_no_attachments
57
+ @having_attachments = false
58
+ self
59
+ end
60
+
61
+ def with_any_attachments
62
+ @having_attachments = true
63
+ self
64
+ end
65
+
66
+ def with_subject(subject)
67
+ @subject = subject
68
+ self
69
+ end
70
+
71
+ def matching_subject(subject_matcher)
72
+ @subject_matcher = subject_matcher
73
+ self
74
+ end
75
+
76
+ def with_body(body)
77
+ @body = body
78
+ self
79
+ end
80
+
81
+ def matching_body(body_matcher)
82
+ @body_matcher = body_matcher
83
+ self
84
+ end
85
+
86
+ def with_html(body)
87
+ @html_part_body = body
88
+ self
89
+ end
90
+
91
+ def with_text(body)
92
+ @text_part_body = body
93
+ self
94
+ end
95
+
96
+ def description
97
+ result = "send a matching email"
98
+ result
99
+ end
100
+
101
+ def failure_message
102
+ result = "Expected email to be sent "
103
+ result += explain_expectations
104
+ result += dump_deliveries
105
+ result
106
+ end
107
+
108
+ def failure_message_when_negated
109
+ result = "Expected no email to be sent "
110
+ result += explain_expectations
111
+ result += dump_deliveries
112
+ result
113
+ end
114
+
115
+ protected
116
+
117
+ def filter_matched_deliveries(deliveries)
118
+ candidate_deliveries = deliveries
119
+ modifiers =
120
+ %w(sender recipients copy_recipients blind_copy_recipients subject
121
+ subject_matcher body body_matcher html_part_body text_part_body having_attachments attachments)
122
+ modifiers.each do |modifier_name|
123
+ next unless instance_variable_defined?("@#{modifier_name}")
124
+ candidate_deliveries = candidate_deliveries.select{|matching_delivery| self.send("matches_on_#{modifier_name}?", matching_delivery)}
125
+ end
126
+
127
+ candidate_deliveries
128
+ end
129
+
130
+ def matches_on_sender?(delivery)
131
+ delivery.from.include?(@sender)
132
+ end
133
+
134
+ def matches_on_recipients?(delivery)
135
+ @recipients.all? {|recipient| delivery.to.include?(recipient) }
136
+ end
137
+
138
+ def matches_on_copy_recipients?(delivery)
139
+ @copy_recipients.all? {|recipient| delivery.cc.include?(recipient) }
140
+ end
141
+
142
+ def matches_on_blind_copy_recipients?(delivery)
143
+ @blind_copy_recipients.all? {|recipient| delivery.bcc.include?(recipient) }
144
+ end
145
+
146
+ def matches_on_subject?(delivery)
147
+ delivery.subject == @subject
148
+ end
149
+
150
+ def matches_on_subject_matcher?(delivery)
151
+ @subject_matcher.match delivery.subject
152
+ end
153
+
154
+ def matches_on_having_attachments?(delivery)
155
+ @having_attachments && delivery.attachments.any? ||
156
+ (!@having_attachments && delivery.attachments.none?)
157
+ end
158
+
159
+ def matches_on_attachments?(delivery)
160
+ @attachments.each_with_index.inject( true ) do |sent_attachments, (attachment, index)|
161
+ sent_attachments &&= (attachment === delivery.attachments[index])
162
+ end
163
+ end
164
+
165
+ def matches_on_body?(delivery)
166
+ delivery.body == @body
167
+ end
168
+
169
+ def matches_on_body_matcher?(delivery)
170
+ @body_matcher.match delivery.body.raw_source
171
+ end
172
+
173
+ def matches_on_html_part_body?(delivery)
174
+ delivery.html_part.body == @html_part_body
175
+ end
176
+
177
+ def matches_on_text_part_body?(delivery)
178
+ delivery.text_part.body == @text_part_body
179
+ end
180
+
181
+ def explain_expectations
182
+ result = ''
183
+ result += "from #{@sender} " if instance_variable_defined?('@sender')
184
+ result += "to #{@recipients.inspect} " if instance_variable_defined?('@recipients')
185
+ result += "cc #{@copy_recipients.inspect} " if instance_variable_defined?('@copy_recipients')
186
+ result += "bcc #{@blind_copy_recipients.inspect} " if instance_variable_defined?('@blind_copy_recipients')
187
+ result += "with subject \"#{@subject}\" " if instance_variable_defined?('@subject')
188
+ result += "with subject matching \"#{@subject_matcher}\" " if instance_variable_defined?('@subject_matcher')
189
+ result += "with body \"#{@body}\" " if instance_variable_defined?('@body')
190
+ result += "with body matching \"#{@body_matcher}\" " if instance_variable_defined?('@body_matcher')
191
+ result += "with a text part matching \"#{@text_part_body}\" " if instance_variable_defined?('@text_part_body')
192
+ result += "with an HTML part matching \"#{@html_part_body}\" " if instance_variable_defined?('@html_part_body')
193
+ result
194
+ end
195
+
196
+ def dump_deliveries
197
+ "(actual deliveries: " + Mail::TestMailer.deliveries.inspect + ")"
198
+ end
199
+ end
200
+ end
201
+ end