tmail_es 1.2.7.2

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +83 -0
  3. data/LICENSE +21 -0
  4. data/NOTES +7 -0
  5. data/README +182 -0
  6. data/Rakefile +2 -0
  7. data/ext/Makefile +20 -0
  8. data/ext/tmailscanner/tmail/MANIFEST +4 -0
  9. data/ext/tmailscanner/tmail/depend +1 -0
  10. data/ext/tmailscanner/tmail/extconf.rb +33 -0
  11. data/ext/tmailscanner/tmail/tmailscanner.c +614 -0
  12. data/lib/tmail/Makefile +18 -0
  13. data/lib/tmail/address.rb +392 -0
  14. data/lib/tmail/attachments.rb +65 -0
  15. data/lib/tmail/base64.rb +46 -0
  16. data/lib/tmail/compat.rb +41 -0
  17. data/lib/tmail/config.rb +67 -0
  18. data/lib/tmail/core_extensions.rb +63 -0
  19. data/lib/tmail/encode.rb +590 -0
  20. data/lib/tmail/header.rb +962 -0
  21. data/lib/tmail/index.rb +9 -0
  22. data/lib/tmail/interface.rb +1162 -0
  23. data/lib/tmail/loader.rb +3 -0
  24. data/lib/tmail/mail.rb +578 -0
  25. data/lib/tmail/mailbox.rb +496 -0
  26. data/lib/tmail/main.rb +6 -0
  27. data/lib/tmail/mbox.rb +3 -0
  28. data/lib/tmail/net.rb +250 -0
  29. data/lib/tmail/obsolete.rb +132 -0
  30. data/lib/tmail/parser.rb +1060 -0
  31. data/lib/tmail/parser.y +416 -0
  32. data/lib/tmail/port.rb +379 -0
  33. data/lib/tmail/quoting.rb +164 -0
  34. data/lib/tmail/require_arch.rb +58 -0
  35. data/lib/tmail/scanner.rb +49 -0
  36. data/lib/tmail/scanner_r.rb +261 -0
  37. data/lib/tmail/stringio.rb +280 -0
  38. data/lib/tmail/utils.rb +361 -0
  39. data/lib/tmail/vendor/rchardet-1.3/COPYING +504 -0
  40. data/lib/tmail/vendor/rchardet-1.3/README +12 -0
  41. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/big5freq.rb +927 -0
  42. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/big5prober.rb +42 -0
  43. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/chardistribution.rb +238 -0
  44. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/charsetgroupprober.rb +112 -0
  45. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/charsetprober.rb +75 -0
  46. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/codingstatemachine.rb +64 -0
  47. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/constants.rb +42 -0
  48. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/escprober.rb +89 -0
  49. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/escsm.rb +244 -0
  50. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/eucjpprober.rb +88 -0
  51. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euckrfreq.rb +596 -0
  52. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euckrprober.rb +42 -0
  53. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euctwfreq.rb +430 -0
  54. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/euctwprober.rb +42 -0
  55. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/gb2312freq.rb +474 -0
  56. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/gb2312prober.rb +42 -0
  57. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/hebrewprober.rb +289 -0
  58. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/jisfreq.rb +570 -0
  59. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/jpcntx.rb +229 -0
  60. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langbulgarianmodel.rb +229 -0
  61. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langcyrillicmodel.rb +330 -0
  62. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langgreekmodel.rb +227 -0
  63. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langhebrewmodel.rb +202 -0
  64. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langhungarianmodel.rb +226 -0
  65. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/langthaimodel.rb +201 -0
  66. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/latin1prober.rb +147 -0
  67. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/mbcharsetprober.rb +89 -0
  68. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/mbcsgroupprober.rb +45 -0
  69. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/mbcssm.rb +542 -0
  70. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/sbcharsetprober.rb +124 -0
  71. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/sbcsgroupprober.rb +56 -0
  72. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/sjisprober.rb +88 -0
  73. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb +167 -0
  74. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet/utf8prober.rb +87 -0
  75. data/lib/tmail/vendor/rchardet-1.3/lib/rchardet.rb +67 -0
  76. data/lib/tmail/version.rb +40 -0
  77. data/lib/tmail.rb +6 -0
  78. data/setup.rb +1482 -0
  79. data/test/extctrl.rb +6 -0
  80. data/test/fixtures/apple_unquoted_content_type +44 -0
  81. data/test/fixtures/inline_attachment.txt +2095 -0
  82. data/test/fixtures/iso_8859_1_email_without_encoding_and_message_id.txt +16 -0
  83. data/test/fixtures/mailbox +414 -0
  84. data/test/fixtures/mailbox.zip +0 -0
  85. data/test/fixtures/mailbox_without_any_from_or_sender +10 -0
  86. data/test/fixtures/mailbox_without_from +11 -0
  87. data/test/fixtures/mailbox_without_return_path +12 -0
  88. data/test/fixtures/marked_as_iso_8859_1_but_it_is_utf_8.txt +33 -0
  89. data/test/fixtures/marked_as_utf_8_but_it_is_iso_8859_1.txt +56 -0
  90. data/test/fixtures/raw_attack_email_with_zero_length_whitespace +29 -0
  91. data/test/fixtures/raw_base64_decoded_string +0 -0
  92. data/test/fixtures/raw_base64_email +83 -0
  93. data/test/fixtures/raw_base64_encoded_string +1 -0
  94. data/test/fixtures/raw_email +14 -0
  95. data/test/fixtures/raw_email10 +20 -0
  96. data/test/fixtures/raw_email11 +34 -0
  97. data/test/fixtures/raw_email12 +32 -0
  98. data/test/fixtures/raw_email13 +29 -0
  99. data/test/fixtures/raw_email2 +114 -0
  100. data/test/fixtures/raw_email3 +70 -0
  101. data/test/fixtures/raw_email4 +59 -0
  102. data/test/fixtures/raw_email5 +19 -0
  103. data/test/fixtures/raw_email6 +20 -0
  104. data/test/fixtures/raw_email7 +66 -0
  105. data/test/fixtures/raw_email8 +47 -0
  106. data/test/fixtures/raw_email9 +28 -0
  107. data/test/fixtures/raw_email_bad_time +62 -0
  108. data/test/fixtures/raw_email_double_at_in_header +14 -0
  109. data/test/fixtures/raw_email_multiple_from +30 -0
  110. data/test/fixtures/raw_email_only_attachment +17 -0
  111. data/test/fixtures/raw_email_quoted_with_0d0a +14 -0
  112. data/test/fixtures/raw_email_reply +32 -0
  113. data/test/fixtures/raw_email_simple +11 -0
  114. data/test/fixtures/raw_email_string_in_date_field +17 -0
  115. data/test/fixtures/raw_email_trailing_dot +21 -0
  116. data/test/fixtures/raw_email_with_bad_date +48 -0
  117. data/test/fixtures/raw_email_with_illegal_boundary +58 -0
  118. data/test/fixtures/raw_email_with_mimepart_without_content_type +94 -0
  119. data/test/fixtures/raw_email_with_multipart_mixed_quoted_boundary +50 -0
  120. data/test/fixtures/raw_email_with_nested_attachment +100 -0
  121. data/test/fixtures/raw_email_with_partially_quoted_subject +14 -0
  122. data/test/fixtures/raw_email_with_quoted_attachment_filename +60 -0
  123. data/test/fixtures/raw_email_with_quoted_illegal_boundary +58 -0
  124. data/test/fixtures/raw_email_with_wrong_splitted_multibyte_encoded_word_subject +15 -0
  125. data/test/fixtures/the_only_part_is_a_word_document.txt +425 -0
  126. data/test/fixtures/unquoted_filename_in_attachment +177 -0
  127. data/test/kcode.rb +14 -0
  128. data/test/temp_test_one.rb +46 -0
  129. data/test/test_address.rb +1216 -0
  130. data/test/test_attachments.rb +133 -0
  131. data/test/test_base64.rb +64 -0
  132. data/test/test_encode.rb +139 -0
  133. data/test/test_header.rb +1021 -0
  134. data/test/test_helper.rb +9 -0
  135. data/test/test_mail.rb +756 -0
  136. data/test/test_mbox.rb +184 -0
  137. data/test/test_port.rb +440 -0
  138. data/test/test_quote.rb +107 -0
  139. data/test/test_scanner.rb +209 -0
  140. data/test/test_utils.rb +36 -0
  141. data/tmail_es.gemspec +35 -0
  142. metadata +257 -0
@@ -0,0 +1,1216 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'test_helper'
3
+ require 'tmail/address'
4
+
5
+ class TestAddress < Test::Unit::TestCase
6
+
7
+ def test_s_new
8
+ a = TMail::Address.new(%w(aamine), %w(loveruby net))
9
+ assert_instance_of TMail::Address, a
10
+ assert_nil a.phrase
11
+ assert_equal [], a.routes
12
+ assert_equal 'aamine@loveruby.net', a.spec
13
+ end
14
+
15
+ def test_local
16
+ [ [ ['aamine'], 'aamine' ],
17
+ [ ['Minero Aoki'], '"Minero Aoki"' ],
18
+ [ ['!@#$%^&*()'], '"!@#$%^&*()"' ],
19
+ [ ['a','b','c'], 'a.b.c' ]
20
+
21
+ ].each_with_index do |(words, ok), idx|
22
+ a = TMail::Address.new(words, nil)
23
+ assert_equal ok, a.local, "case #{idx+1}: #{ok.inspect}"
24
+ end
25
+ end
26
+
27
+ def test_domain
28
+ [ [ ['loveruby','net'], 'loveruby.net' ],
29
+ [ ['love ruby','net'], '"love ruby".net' ],
30
+ [ ['!@#$%^&*()'], '"!@#$%^&*()"' ],
31
+ [ ['[192.168.1.1]'], '[192.168.1.1]' ]
32
+
33
+ ].each_with_index do |(words, ok), idx|
34
+ a = TMail::Address.new(%w(test), words)
35
+ assert_equal ok, a.domain, "case #{idx+1}: #{ok.inspect}"
36
+ end
37
+ end
38
+
39
+ def test_EQUAL # ==
40
+ a = TMail::Address.new(%w(aamine), %w(loveruby net))
41
+ assert_equal a, a
42
+
43
+ b = TMail::Address.new(%w(aamine), %w(loveruby net))
44
+ b.phrase = 'Minero Aoki'
45
+ assert_equal a, b
46
+
47
+ b.routes.push 'a'
48
+ assert_equal a, b
49
+ end
50
+
51
+ def test_hash
52
+ a = TMail::Address.new(%w(aamine), %w(loveruby net))
53
+ assert_equal a.hash, a.hash
54
+
55
+ b = TMail::Address.new(%w(aamine), %w(loveruby net))
56
+ b.phrase = 'Minero Aoki'
57
+ assert_equal a.hash, b.hash
58
+
59
+ b.routes.push 'a'
60
+ assert_equal a.hash, b.hash
61
+ end
62
+
63
+ def test_dup
64
+ a = TMail::Address.new(%w(aamine), %w(loveruby net))
65
+ a.phrase = 'Minero Aoki'
66
+ a.routes.push 'someroute'
67
+
68
+ b = a.dup
69
+ assert_equal a, b
70
+
71
+ b.routes.push 'anyroute'
72
+ assert_equal a, b
73
+
74
+ b.phrase = 'AOKI, Minero'
75
+ assert_equal a, b
76
+ end
77
+
78
+ def test_inspect
79
+ a = TMail::Address.new(%w(aamine), %w(loveruby net))
80
+ a.inspect
81
+ a.phrase = 'Minero Aoki'
82
+ a.inspect
83
+ a.routes.push 'a'
84
+ a.routes.push 'b'
85
+ a.inspect
86
+ end
87
+
88
+
89
+ def validate_case__address( str, ok )
90
+ a = TMail::Address.parse(str)
91
+ assert_equal ok[:display_name], a.phrase, str.inspect + " (phrase)\n"
92
+ assert_equal ok[:address], a.spec, str.inspect + " (spec)\n"
93
+ assert_equal ok[:local], a.local, str.inspect + " (local)\n"
94
+ assert_equal ok[:domain], a.domain, str.inspect + " (domain)\n"
95
+ #assert_equal ok[:format], a.to_s, str.inspect + " (to_s)\n"
96
+ end
97
+
98
+ def validate_case__group( str, groupname, addrlist )
99
+ g = TMail::Address.parse(str)
100
+ assert_instance_of TMail::AddressGroup, g
101
+ assert_equal groupname, g.name
102
+ assert_equal addrlist.size, g.size
103
+ addrlist.each_with_index do |ok, idx|
104
+ a = g[idx]
105
+ assert_equal ok[:display_name], a.phrase, str.inspect + " (phrase)\n"
106
+ assert_equal ok[:address], a.spec, str.inspect + " (spec)\n"
107
+ assert_equal ok[:local], a.local, str.inspect + " (local)\n"
108
+ assert_equal ok[:domain], a.domain, str.inspect + " (domain)\n"
109
+ # assert_equal ok[:format], a.to_s, str.inspect + " (to_s)\n"
110
+ end
111
+ end
112
+
113
+ def test_parse__address
114
+ #
115
+ # basic tests
116
+ #
117
+
118
+ validate_case__address 'aamine@loveruby.net',
119
+ :display_name => nil,
120
+ :address => 'aamine@loveruby.net',
121
+ :local => 'aamine',
122
+ :domain => 'loveruby.net',
123
+ :format => 'aamine@loveruby.net'
124
+
125
+ validate_case__address 'Minero Aoki <aamine@loveruby.net>',
126
+ :display_name => 'Minero Aoki',
127
+ :address => 'aamine@loveruby.net',
128
+ :local => 'aamine',
129
+ :domain => 'loveruby.net',
130
+ :format => 'Minero Aoki <aamine@loveruby.net>'
131
+
132
+ validate_case__address 'Minero Aoki<aamine@loveruby.net>',
133
+ :display_name => 'Minero Aoki',
134
+ :address => 'aamine@loveruby.net',
135
+ :local => 'aamine',
136
+ :domain => 'loveruby.net',
137
+ :format => 'Minero Aoki <aamine@loveruby.net>'
138
+
139
+ validate_case__address '"Minero Aoki" <aamine@loveruby.net>',
140
+ :display_name => 'Minero Aoki',
141
+ :address => 'aamine@loveruby.net',
142
+ :local => 'aamine',
143
+ :domain => 'loveruby.net',
144
+ :format => 'Minero Aoki <aamine@loveruby.net>'
145
+
146
+ # integer in domain
147
+ validate_case__address 'Minero Aoki<aamine@0246.loveruby.net>',
148
+ :display_name => 'Minero Aoki',
149
+ :address => 'aamine@0246.loveruby.net',
150
+ :local => 'aamine',
151
+ :domain => '0246.loveruby.net',
152
+ :format => 'Minero Aoki <aamine@0246.loveruby.net>'
153
+
154
+ end
155
+
156
+ def test_parse__dots
157
+ 1.upto(10) do |times|
158
+ dots = "." * times
159
+ validate_case__address "hoge#{dots}test@docomo.ne.jp",
160
+ :display_name => nil,
161
+ :address => "hoge#{dots}test@docomo.ne.jp",
162
+ :local => "hoge#{dots}test",
163
+ :domain => 'docomo.ne.jp',
164
+ :format => "hoge#{dots}test@docomo.ne.jp"
165
+ end
166
+ end
167
+
168
+ unless RUBY_VERSION.match(/1.9/)
169
+ def test_parse__mime
170
+ # "\306\374\313\334\270\354"
171
+ # "\223\372\226{\214\352"
172
+ # "\e$BF|K\\8l\e(B"
173
+ # GyRCRnxLXDhsGyhC
174
+
175
+ TMail.KCODE = 'NONE'
176
+ validate_case__address\
177
+ '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>',
178
+ :display_name => "\e$BF|K\\8l\e(B",
179
+ :address => 'aamine@loveruby.net',
180
+ :local => 'aamine',
181
+ :domain => 'loveruby.net',
182
+ :format => '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>'
183
+
184
+ validate_case__address\
185
+ '=?iso-2022-jp?Q?=1b=24=42=46=7c=4b=5c=38=6c=1b=28=42?= <aamine@loveruby.net>',
186
+ :display_name => "\e$BF|K\\8l\e(B",
187
+ :address => 'aamine@loveruby.net',
188
+ :local => 'aamine',
189
+ :domain => 'loveruby.net',
190
+ :format => '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>'
191
+
192
+ TMail.KCODE = 'EUC'
193
+ expected = "\306\374\313\334\270\354"
194
+ expected.force_encoding('EUC-JP') if expected.respond_to? :force_encoding
195
+ validate_case__address\
196
+ '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>',
197
+ :display_name => expected,
198
+ :address => 'aamine@loveruby.net',
199
+ :local => 'aamine',
200
+ :domain => 'loveruby.net',
201
+ :format => '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>'
202
+
203
+ validate_case__address\
204
+ '=?iso-2022-jp?Q?=1b=24=42=46=7c=4b=5c=38=6c=1b=28=42?= <aamine@loveruby.net>',
205
+ :display_name => expected,
206
+ :address => 'aamine@loveruby.net',
207
+ :local => 'aamine',
208
+ :domain => 'loveruby.net',
209
+ :format => '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>'
210
+
211
+ TMail.KCODE = 'SJIS'
212
+ expected = "\223\372\226{\214\352"
213
+ expected.force_encoding('Windows-31J') if expected.respond_to? :force_encoding
214
+ validate_case__address\
215
+ '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>',
216
+ :display_name => expected,
217
+ :address => 'aamine@loveruby.net',
218
+ :local => 'aamine',
219
+ :domain => 'loveruby.net',
220
+ :format => '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>'
221
+
222
+ validate_case__address\
223
+ '=?iso-2022-jp?Q?=1b=24=42=46=7c=4b=5c=38=6c=1b=28=42?= <aamine@loveruby.net>',
224
+ :display_name => expected,
225
+ :address => 'aamine@loveruby.net',
226
+ :local => 'aamine',
227
+ :domain => 'loveruby.net',
228
+ :format => '=?iso-2022-jp?B?GyRCRnxLXDhsGyhC?= <aamine@loveruby.net>'
229
+ end
230
+ end
231
+
232
+ def test_parse__rawjp
233
+ begin
234
+ TMail.KCODE = 'EUC'
235
+ _test_parse__euc
236
+ _test_parse__jis
237
+ ensure
238
+ TMail.KCODE = 'NONE'
239
+ end
240
+ end
241
+
242
+ def _test_parse__euc
243
+ # raw EUC-JP
244
+ validate_case__address\
245
+ "\244\242\244\252\244\255 \244\337\244\315\244\355\244\246 <aamine@loveruby.net>",
246
+ :display_name => "\244\242\244\252\244\255 \244\337\244\315\244\355\244\246",
247
+ :address => 'aamine@loveruby.net',
248
+ :local => 'aamine',
249
+ :domain => 'loveruby.net',
250
+ :format => "\244\242\244\252\244\255 \244\337\244\315\244\355\244\246 <aamine@loveruby.net>"
251
+ end
252
+
253
+ def _test_parse__jis
254
+ # raw iso-2022-jp string in comment
255
+ validate_case__address\
256
+ "Minero Aoki (\e$B@DLZJvO:\e(B) <aamine@loveruby.net>",
257
+ :display_name => "Minero Aoki (\e$B@DLZJvO:\e(B)",
258
+ :address => 'aamine@loveruby.net',
259
+ :local => 'aamine',
260
+ :domain => 'loveruby.net',
261
+ :format => 'Minero Aoki <aamine@loveruby.net>'
262
+
263
+ validate_case__address\
264
+ "Minero Aoki <aamine@loveruby.net> (\e$B@DLZJvO:\e(B )",
265
+ :display_name => 'Minero Aoki',
266
+ :address => 'aamine@loveruby.net',
267
+ :local => 'aamine',
268
+ :domain => 'loveruby.net',
269
+ :format => 'Minero Aoki <aamine@loveruby.net>'
270
+
271
+ # raw iso-2022-jp string in quoted-word (it includes backslash)
272
+ validate_case__address\
273
+ %Q["\e$BF|K\\8l\e(B" <aamine@loveruby.net>],
274
+ :display_name => "\e$BF|K\\8l\e(B",
275
+ :address => 'aamine@loveruby.net',
276
+ :local => 'aamine',
277
+ :domain => 'loveruby.net',
278
+ :format => 'Minero Aoki <aamine@loveruby.net>'
279
+ end
280
+
281
+ def OFF_test_parse__group
282
+ validate_case__group 'Softica: Minero Aoki <aamine@loveruby.net>;',
283
+ 'Softica',
284
+ { :display_name => 'Minero Aoki',
285
+ :address => 'aamine@loveruby.net',
286
+ :local => 'aamine',
287
+ :domain => 'loveruby.net',
288
+ :format => 'Minero Aoki <aamine@loveruby.net>' }
289
+ end
290
+
291
+
292
+ #
293
+ # The following test cases are quoted from RubyMail 0.2
294
+ # (written by Matt Armstrong), with some modifications.
295
+ # The copyright notice of the original file is:
296
+ #
297
+ # Copyright (c) 2001 Matt Armstrong. All rights reserved.
298
+ #
299
+ # Permission is granted for use, copying, modification,
300
+ # distribution, and distribution of modified versions of this work
301
+ # as long as the above copyright notice is included.
302
+ #
303
+
304
+ def test_parse__rfc2822
305
+
306
+ validate_case__address\
307
+ '"Joe Q. Public" <john.q.public@example.com>',
308
+ :name => 'Joe Q. Public',
309
+ :display_name => 'Joe Q. Public',
310
+ :address => 'john.q.public@example.com',
311
+ :comments => nil,
312
+ :domain => 'example.com',
313
+ :local => 'john.q.public',
314
+ :format => '"Joe Q. Public" <john.q.public@example.com>'
315
+
316
+ validate_case__address\
317
+ 'Who? <one@y.test>',
318
+ :name => 'Who?',
319
+ :display_name => 'Who?',
320
+ :address => 'one@y.test',
321
+ :comments => nil,
322
+ :domain => 'y.test',
323
+ :local => 'one',
324
+ :format => 'Who? <one@y.test>'
325
+
326
+ validate_case__address\
327
+ '"Giant; \"Big\" Box" <sysservices@example.net>',
328
+ :name => 'Giant; "Big" Box',
329
+ :display_name => 'Giant; "Big" Box',
330
+ :address => 'sysservices@example.net',
331
+ :comments => nil,
332
+ :domain => 'example.net',
333
+ :local => 'sysservices',
334
+ :format => '"Giant; \"Big\" Box" <sysservices@example.net>'
335
+
336
+ validate_case__address\
337
+ '"Mary Smith: Personal Account" <smith@home.example> ',
338
+ :name => 'Mary Smith: Personal Account',
339
+ :display_name => 'Mary Smith: Personal Account',
340
+ :address => 'smith@home.example',
341
+ :comments => nil,
342
+ :domain => 'home.example',
343
+ :local => 'smith',
344
+ :format => '"Mary Smith: Personal Account" <smith@home.example>'
345
+
346
+ validate_case__address\
347
+ 'Pete(A wonderful \) chap) <pete(his account)@silly.test(his host)>',
348
+ :name => 'Pete',
349
+ :display_name => 'Pete',
350
+ :address => 'pete@silly.test',
351
+ :comments => ['A wonderful ) chap', 'his account', 'his host'],
352
+ :domain => 'silly.test',
353
+ :local => 'pete',
354
+ #:format => 'Pete <pete@silly.test> (A wonderful \) chap) (his account) (his host)'
355
+ :format => 'Pete <pete@silly.test>'
356
+
357
+ validate_case__address\
358
+ "Chris Jones <c@(Chris's host.)public.example>",
359
+ :name => 'Chris Jones',
360
+ :display_name => 'Chris Jones',
361
+ :address => 'c@public.example',
362
+ :comments => ['Chris\'s host.'],
363
+ :domain => 'public.example',
364
+ :local => 'c',
365
+ #:format => 'Chris Jones <c@public.example> (Chris\'s host.)'
366
+ :format => 'Chris Jones <c@public.example>'
367
+
368
+ validate_case__address\
369
+ 'Joe Q. Public <john.q.public@example.com>',
370
+ :name => 'Joe Q.Public',
371
+ :display_name => 'Joe Q.Public',
372
+ :address => 'john.q.public@example.com',
373
+ :comments => nil,
374
+ :domain => 'example.com',
375
+ :local => 'john.q.public',
376
+ :format => '"Joe Q.Public" <john.q.public@example.com>'
377
+
378
+ validate_case__address\
379
+ 'Mary Smith <@machine.tld:mary@example.net>',
380
+ :name => 'Mary Smith',
381
+ :display_name => 'Mary Smith',
382
+ :address => 'mary@example.net',
383
+ :comments => nil,
384
+ :domain => 'example.net',
385
+ :local => 'mary',
386
+ #:format => 'Mary Smith <mary@example.net>'
387
+ :format => 'Mary Smith <@machine.tld:mary@example.net>'
388
+
389
+ validate_case__address\
390
+ ' jdoe@test . example',
391
+ :name => nil,
392
+ :display_name => nil,
393
+ :address => 'jdoe@test.example',
394
+ :comments => nil,
395
+ :domain => 'test.example',
396
+ :local => 'jdoe',
397
+ :format => 'jdoe@test.example'
398
+
399
+ validate_case__address\
400
+ 'John Doe <jdoe@machine(comment). example>',
401
+ :name => 'John Doe',
402
+ :display_name => 'John Doe',
403
+ :address => 'jdoe@machine.example',
404
+ :comments => ['comment'],
405
+ :domain => 'machine.example',
406
+ :local => 'jdoe',
407
+ #:format => 'John Doe <jdoe@machine.example> (comment)'
408
+ :format => 'John Doe <jdoe@machine.example>'
409
+
410
+ validate_case__address\
411
+ "Mary Smith\n\r \n <mary@example.net>",
412
+ :name => 'Mary Smith',
413
+ :display_name => 'Mary Smith',
414
+ :address => 'mary@example.net',
415
+ :comments => nil,
416
+ :domain => 'example.net',
417
+ :local => 'mary',
418
+ :format => 'Mary Smith <mary@example.net>'
419
+ end
420
+
421
+
422
+ def test_parse__rfc822
423
+
424
+ validate_case__address\
425
+ '":sysmail"@ Some-Group. Some-Org',
426
+ :name => nil,
427
+ :display_name => nil,
428
+ #:address => ':sysmail@Some-Group.Some-Org',
429
+ :address => '":sysmail"@Some-Group.Some-Org',
430
+ :comments => nil,
431
+ :domain => 'Some-Group.Some-Org',
432
+ #:local => ':sysmail',
433
+ :local => '":sysmail"',
434
+ :format => '":sysmail"@Some-Group.Some-Org'
435
+
436
+ validate_case__address\
437
+ 'Muhammed.(I am the greatest) Ali @(the)Vegas.WBA',
438
+ :name => 'the',
439
+ :display_name => nil,
440
+ :address => 'Muhammed.Ali@Vegas.WBA',
441
+ :comments => ['I am the greatest', 'the'],
442
+ :domain => 'Vegas.WBA',
443
+ :local => 'Muhammed.Ali',
444
+ #:format => 'Muhammed.Ali@Vegas.WBA (I am the greatest) (the)'
445
+ :format => 'Muhammed.Ali@Vegas.WBA'
446
+
447
+
448
+ validate_case__group\
449
+ 'A Group:Chris Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;',
450
+ 'A Group',
451
+ [ { :name => 'Chris Jones',
452
+ :display_name => 'Chris Jones',
453
+ :address => 'c@a.test',
454
+ :comments => nil,
455
+ :domain => 'a.test',
456
+ :local => 'c',
457
+ :format => 'Chris Jones <c@a.test>' },
458
+ { :name => nil,
459
+ :display_name => nil,
460
+ :address => 'joe@where.test',
461
+ :comments => nil,
462
+ :domain => 'where.test',
463
+ :local => 'joe',
464
+ :format => 'joe@where.test' },
465
+ { :name => 'John',
466
+ :display_name => 'John',
467
+ :address => 'jdoe@one.test',
468
+ :comments => nil,
469
+ :domain => 'one.test',
470
+ :local => 'jdoe',
471
+ :format => 'John <jdoe@one.test>' }
472
+ ]
473
+
474
+ validate_case__group\
475
+ 'Undisclosed recipients:;',
476
+ 'Undisclosed recipients',
477
+ [ ]
478
+
479
+ validate_case__group\
480
+ 'undisclosed recipients: ;',
481
+ 'undisclosed recipients',
482
+ []
483
+
484
+ validate_case__group\
485
+ "A Group(Some people)\r\n :Chris Jones <c@(Chris's host.)public.example>,\r\n joe@example.org",
486
+ 'A Group',
487
+ [
488
+ { :name => 'Chris Jones',
489
+ :display_name => 'Chris Jones',
490
+ :address => 'c@public.example',
491
+ :comments => ['Chris\'s host.'],
492
+ :domain => 'public.example',
493
+ :local => 'c',
494
+ :format => 'Chris Jones <c@public.example> (Chris\'s host.)' },
495
+ { :name => nil,
496
+ :display_name => nil,
497
+ :address => 'joe@example.org',
498
+ :comments => nil,
499
+ :domain => 'example.org',
500
+ :local => 'joe',
501
+ :format => 'joe@example.org' }
502
+ ]
503
+
504
+ validate_case__group\
505
+ '(Empty list)(start)Undisclosed recipients :(nobody(that I know)) ;',
506
+ 'Undisclosed recipients',
507
+ []
508
+ end
509
+
510
+
511
+ def test_parse__mailtools
512
+ #
513
+ # The following are from the Perl MailTools module version 1.40
514
+ #
515
+ validate_case__address\
516
+ '"Joe & J. Harvey" <ddd @Org>',
517
+ :name => 'Joe & J. Harvey',
518
+ :display_name => 'Joe & J. Harvey',
519
+ :address => 'ddd@Org',
520
+ :comments => nil,
521
+ :domain => 'Org',
522
+ :local => 'ddd',
523
+ :format => '"Joe & J. Harvey" <ddd@Org>'
524
+
525
+ validate_case__address\
526
+ '"spickett@tiac.net" <Sean.Pickett@zork.tiac.net>',
527
+ :name => 'spickett@tiac.net',
528
+ :display_name => 'spickett@tiac.net',
529
+ :address => 'Sean.Pickett@zork.tiac.net',
530
+ :comments => nil,
531
+ :domain => 'zork.tiac.net',
532
+ :local => 'Sean.Pickett',
533
+ :format => '"spickett@tiac.net" <Sean.Pickett@zork.tiac.net>'
534
+
535
+ validate_case__address\
536
+ 'rls@intgp8.ih.att.com (-Schieve,R.L.)',
537
+ :name => '-Schieve,R.L.',
538
+ :display_name => nil,
539
+ :address => 'rls@intgp8.ih.att.com',
540
+ :comments => ['-Schieve,R.L.'],
541
+ :domain => 'intgp8.ih.att.com',
542
+ :local => 'rls',
543
+ #:format => 'rls@intgp8.ih.att.com (-Schieve,R.L.)'
544
+ :format => 'rls@intgp8.ih.att.com'
545
+
546
+ validate_case__address\
547
+ 'jrh%cup.portal.com@portal.unix.portal.com',
548
+ :name => nil,
549
+ :display_name => nil,
550
+ :address => 'jrh%cup.portal.com@portal.unix.portal.com',
551
+ :comments => nil,
552
+ :domain => 'portal.unix.portal.com',
553
+ :local => 'jrh%cup.portal.com',
554
+ :format => 'jrh%cup.portal.com@portal.unix.portal.com'
555
+
556
+ validate_case__address\
557
+ 'astrachan@austlcm.sps.mot.com (\'paul astrachan/xvt3\')',
558
+ :name => '\'paul astrachan/xvt3\'',
559
+ :display_name => nil,
560
+ :address => 'astrachan@austlcm.sps.mot.com',
561
+ :comments => ["'paul astrachan/xvt3'"],
562
+ :domain => 'austlcm.sps.mot.com',
563
+ :local => 'astrachan',
564
+ #:format => "astrachan@austlcm.sps.mot.com ('paul astrachan/xvt3')"
565
+ :format => 'astrachan@austlcm.sps.mot.com'
566
+
567
+ validate_case__address\
568
+ 'TWINE57%SDELVB.decnet@SNYBUF.CS.SNYBUF.EDU (JAMES R. TWINE - THE NERD)',
569
+ :name => 'JAMES R. TWINE - THE NERD',
570
+ :display_name => nil,
571
+ :address => 'TWINE57%SDELVB.decnet@SNYBUF.CS.SNYBUF.EDU',
572
+ :comments => ['JAMES R. TWINE - THE NERD'],
573
+ :domain => 'SNYBUF.CS.SNYBUF.EDU',
574
+ :local => 'TWINE57%SDELVB.decnet',
575
+ :format => 'TWINE57%SDELVB.decnet@SNYBUF.CS.SNYBUF.EDU'
576
+ #'TWINE57%SDELVB.decnet@SNYBUF.CS.SNYBUF.EDU (JAMES R. TWINE - THE NERD)'
577
+
578
+ validate_case__address\
579
+ 'David Apfelbaum <da0g+@andrew.cmu.edu>',
580
+ :name => 'David Apfelbaum',
581
+ :display_name => 'David Apfelbaum',
582
+ :address => 'da0g+@andrew.cmu.edu',
583
+ :comments => nil,
584
+ :domain => 'andrew.cmu.edu',
585
+ :local => 'da0g+',
586
+ :format => 'David Apfelbaum <da0g+@andrew.cmu.edu>'
587
+
588
+ validate_case__address\
589
+ '"JAMES R. TWINE - THE NERD" <TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU>',
590
+ :name => 'JAMES R. TWINE - THE NERD',
591
+ :display_name => 'JAMES R. TWINE - THE NERD',
592
+ :address => 'TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU',
593
+ :comments => nil,
594
+ :domain => 'CUNYVM.CUNY.EDU',
595
+ :local => 'TWINE57%SDELVB%SNYDELVA.bitnet',
596
+ :format =>
597
+ '"JAMES R. TWINE - THE NERD" <TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU>'
598
+
599
+ validate_case__address\
600
+ '/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk',
601
+ :name => nil,
602
+ :display_name => nil,
603
+ :address => '/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk',
604
+ :comments => nil,
605
+ :domain => 'mhs-relay.ac.uk',
606
+ :local => '/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/',
607
+ :format => '/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk'
608
+
609
+ validate_case__address\
610
+ '"Stephen Burke, Liverpool" <BURKE@vxdsya.desy.de>',
611
+ :name => 'Stephen Burke, Liverpool',
612
+ :display_name => 'Stephen Burke, Liverpool',
613
+ :address => 'BURKE@vxdsya.desy.de',
614
+ :comments => nil,
615
+ :domain => 'vxdsya.desy.de',
616
+ :local => 'BURKE',
617
+ :format => '"Stephen Burke, Liverpool" <BURKE@vxdsya.desy.de>'
618
+
619
+ validate_case__address\
620
+ 'The Newcastle Info-Server <info-admin@newcastle.ac.uk>',
621
+ :name => 'The Newcastle Info-Server',
622
+ :display_name => 'The Newcastle Info-Server',
623
+ :address => 'info-admin@newcastle.ac.uk',
624
+ :comments => nil,
625
+ :domain => 'newcastle.ac.uk',
626
+ :local => 'info-admin',
627
+ :format => 'The Newcastle Info-Server <info-admin@newcastle.ac.uk>'
628
+
629
+ validate_case__address\
630
+ 'Suba.Peddada@eng.sun.com (Suba Peddada [CONTRACTOR])',
631
+ :name => 'Suba Peddada [CONTRACTOR]',
632
+ :display_name => nil,
633
+ :address => 'Suba.Peddada@eng.sun.com',
634
+ :comments => ['Suba Peddada [CONTRACTOR]'],
635
+ :domain => 'eng.sun.com',
636
+ :local => 'Suba.Peddada',
637
+ #:format => 'Suba.Peddada@eng.sun.com (Suba Peddada [CONTRACTOR])'
638
+ :format => 'Suba.Peddada@eng.sun.com'
639
+
640
+ validate_case__address\
641
+ 'Paul Manser (0032 memo) <a906187@tiuk.ti.com>',
642
+ :name => 'Paul Manser',
643
+ :display_name => 'Paul Manser',
644
+ :address => 'a906187@tiuk.ti.com',
645
+ :comments => ['0032 memo'],
646
+ :domain => 'tiuk.ti.com',
647
+ :local => 'a906187',
648
+ #:format => 'Paul Manser <a906187@tiuk.ti.com> (0032 memo)'
649
+ :format => 'Paul Manser <a906187@tiuk.ti.com>'
650
+
651
+ validate_case__address\
652
+ '"gregg (g.) woodcock" <woodcock@bnr.ca>',
653
+ :name => 'gregg (g.) woodcock',
654
+ :display_name => 'gregg (g.) woodcock',
655
+ :address => 'woodcock@bnr.ca',
656
+ :comments => nil,
657
+ :domain => 'bnr.ca',
658
+ :local => 'woodcock',
659
+ :format => '"gregg (g.) woodcock" <woodcock@bnr.ca>'
660
+
661
+ validate_case__address\
662
+ 'Graham.Barr@tiuk.ti.com',
663
+ :name => nil,
664
+ :display_name => nil,
665
+ :address => 'Graham.Barr@tiuk.ti.com',
666
+ :comments => nil,
667
+ :domain => 'tiuk.ti.com',
668
+ :local => 'Graham.Barr',
669
+ :format => 'Graham.Barr@tiuk.ti.com'
670
+
671
+ validate_case__address\
672
+ 'a909937 (Graham Barr (0004 bodg))',
673
+ :name => 'Graham Barr (0004 bodg)',
674
+ :display_name => nil,
675
+ :address => 'a909937',
676
+ :comments => ['Graham Barr (0004 bodg)'],
677
+ :domain => nil,
678
+ :local => 'a909937',
679
+ #:format => 'a909937 (Graham Barr \(0004 bodg\))'
680
+ :format => 'a909937'
681
+
682
+ validate_case__address\
683
+ "david d `zoo' zuhn <zoo@aggregate.com>",
684
+ :name => "david d `zoo' zuhn",
685
+ :display_name => "david d `zoo' zuhn",
686
+ :address => 'zoo@aggregate.com',
687
+ :comments => nil,
688
+ :domain => 'aggregate.com',
689
+ :local => 'zoo',
690
+ :format => "david d `zoo' zuhn <zoo@aggregate.com>"
691
+
692
+ validate_case__address\
693
+ '(foo@bar.com (foobar), ned@foo.com (nedfoo) ) <kevin@goess.org>',
694
+ :name => 'foo@bar.com (foobar), ned@foo.com (nedfoo) ',
695
+ :display_name => "(foo@bar.com (foobar), ned@foo.com (nedfoo) )",
696
+ :address => 'kevin@goess.org',
697
+ :comments => ['foo@bar.com (foobar), ned@foo.com (nedfoo) '],
698
+ :domain => 'goess.org',
699
+ :local => 'kevin',
700
+ :format => 'kevin@goess.org'
701
+ #'kevin@goess.org (foo@bar.com \(foobar\), ned@foo.com \(nedfoo\) )'
702
+ end
703
+
704
+
705
+ def test_parse__pythonbuglist
706
+ #
707
+ # From Python address parsing bug list.
708
+ # This is valid according to RFC2822.
709
+ #
710
+
711
+ validate_case__address\
712
+ 'Amazon.com <delivers-news2@amazon.com>',
713
+ :name => 'Amazon.com',
714
+ :display_name => 'Amazon.com',
715
+ :address => 'delivers-news2@amazon.com',
716
+ :comments => nil,
717
+ :domain => 'amazon.com',
718
+ :local => 'delivers-news2',
719
+ :format => '"Amazon.com" <delivers-news2@amazon.com>'
720
+
721
+ validate_case__address\
722
+ "\r\n Amazon \r . \n com \t < delivers-news2@amazon.com > \n ",
723
+ :name => 'Amazon.com',
724
+ :display_name => 'Amazon.com',
725
+ :address => 'delivers-news2@amazon.com',
726
+ :comments => nil,
727
+ :domain => 'amazon.com',
728
+ :local => 'delivers-news2',
729
+ :format => '"Amazon.com" <delivers-news2@amazon.com>'
730
+
731
+ # From postfix-users@postfix.org
732
+ # Date: Tue, 13 Nov 2001 10:58:23 -0800
733
+ # Subject: Apparent bug in strict_rfc821_envelopes (Snapshot-20010714)
734
+ validate_case__address\
735
+ '"mailto:rfc"@monkeys.test',
736
+ :name => nil,
737
+ :display_name => nil,
738
+ #:address => 'mailto:rfc@monkeys.test',
739
+ :address => '"mailto:rfc"@monkeys.test',
740
+ :comments => nil,
741
+ :domain => 'monkeys.test',
742
+ #:local => 'mailto:rfc',
743
+ :local => '"mailto:rfc"',
744
+ :format => '"mailto:rfc"@monkeys.test'
745
+
746
+ # An unquoted mailto:rfc will end up having the mailto: portion
747
+ # discarded as a group name.
748
+ validate_case__group\
749
+ 'mailto:rfc@monkeys.test',
750
+ 'mailto',
751
+ [
752
+ { :name => nil,
753
+ :display_name => nil,
754
+ :address => 'rfc@monkeys.test',
755
+ :comments => nil,
756
+ :domain => 'monkeys.test',
757
+ :local => 'rfc',
758
+ :format => 'rfc@monkeys.test' }
759
+ ]
760
+
761
+ # From gnu.emacs.help
762
+ # Date: 24 Nov 2001 15:37:23 -0500
763
+ validate_case__address\
764
+ '"Stefan Monnier <foo@acm.com>" <monnier+gnu.emacs.help/news/@flint.cs.yale.edu>',
765
+ :name => 'Stefan Monnier <foo@acm.com>',
766
+ :display_name => 'Stefan Monnier <foo@acm.com>',
767
+ :address => 'monnier+gnu.emacs.help/news/@flint.cs.yale.edu',
768
+ :comments => nil,
769
+ :domain => 'flint.cs.yale.edu',
770
+ :local => 'monnier+gnu.emacs.help/news/',
771
+ :format => '"Stefan Monnier <foo@acm.com>" <monnier+gnu.emacs.help/news/@flint.cs.yale.edu>'
772
+
773
+ validate_case__address\
774
+ '"foo:" . bar@somewhere.test',
775
+ :name => nil,
776
+ :display_name => nil,
777
+ #:address => 'foo:.bar@somewhere.test',
778
+ :address => '"foo:".bar@somewhere.test',
779
+ :comments => nil,
780
+ :domain => 'somewhere.test',
781
+ #:local => 'foo:.bar',
782
+ :local => '"foo:".bar',
783
+ #:format => '"foo:.bar"@somewhere.test'
784
+ :format => '"foo:".bar@somewhere.test'
785
+
786
+ validate_case__address\
787
+ 'Some Dude <"foo:" . bar@somewhere.test>',
788
+ :name => 'Some Dude',
789
+ :display_name => 'Some Dude',
790
+ #:address => 'foo:.bar@somewhere.test',
791
+ :address => '"foo:".bar@somewhere.test',
792
+ :comments => nil,
793
+ :domain => 'somewhere.test',
794
+ #:local => 'foo:.bar',
795
+ :local => '"foo:".bar',
796
+ #:format => 'Some Dude <"foo:.bar"@somewhere.test>'
797
+ :format => 'Some Dude <"foo:".bar@somewhere.test>'
798
+
799
+ validate_case__address\
800
+ '"q\uo\ted"@example.com',
801
+ :name => nil,
802
+ :display_name => nil,
803
+ :address => 'quoted@example.com',
804
+ :comments => nil,
805
+ :domain => 'example.com',
806
+ :local => 'quoted',
807
+ :format => 'quoted@example.com'
808
+
809
+ validate_case__address\
810
+ 'Luke Skywalker <"use"."the.force"@space.test>',
811
+ :name => 'Luke Skywalker',
812
+ :display_name => 'Luke Skywalker',
813
+ #:address => 'use.the.force@space.test',
814
+ :address => 'use."the.force"@space.test',
815
+ :comments => nil,
816
+ :domain => 'space.test',
817
+ #:local => 'use.the.force',
818
+ :local => 'use."the.force"',
819
+ #:format => 'Luke Skywalker <use.the.force@space.test>'
820
+ :format => 'Luke Skywalker <use."the.force"@space.test>'
821
+
822
+ validate_case__address\
823
+ 'Erik =?ISO-8859-1?Q?B=E5gfors?= <erik@example.net>',
824
+ :name => 'Erik =?ISO-8859-1?Q?B=E5gfors?=',
825
+ :display_name => 'Erik =?ISO-8859-1?Q?B=E5gfors?=',
826
+ :address => 'erik@example.net',
827
+ :comments => nil,
828
+ :domain => 'example.net',
829
+ :local => 'erik',
830
+ :format => 'Erik =?ISO-8859-1?Q?B=E5gfors?= <erik@example.net>'
831
+ end
832
+
833
+ def test_parse__outofspec
834
+
835
+ =begin
836
+ validate_case__address\
837
+ 'bodg fred@tiuk.ti.com',
838
+ :name => nil,
839
+ :display_name => nil,
840
+ :address => 'bodg fred@tiuk.ti.com',
841
+ :comments => nil,
842
+ :domain => 'tiuk.ti.com',
843
+ :local => 'bodg fred',
844
+ :format => '"bodg fred"@tiuk.ti.com'
845
+
846
+ validate_case__address\
847
+ '<Investor Alert@example.com>',
848
+ :name => nil,
849
+ :display_name => nil,
850
+ :address => 'Investor Alert@example.com',
851
+ :comments => nil,
852
+ :domain => 'example.com',
853
+ :local => 'Investor Alert',
854
+ :format => '"Investor Alert"@example.com'
855
+ =end
856
+
857
+ validate_case__address\
858
+ '"" <bob@example.com>',
859
+ :name => nil,
860
+ :display_name => nil,
861
+ :address => 'bob@example.com',
862
+ :comments => nil,
863
+ :domain => 'example.com',
864
+ :local => 'bob',
865
+ :format => 'bob@example.com'
866
+
867
+ validate_case__address '"" <""@example.com>',
868
+ :name => nil,
869
+ :display_name => nil,
870
+ :address => '""@example.com',
871
+ :comments => nil,
872
+ :domain => 'example.com',
873
+ :local => '""',
874
+ :format => '""@example.com'
875
+
876
+ assert_raise(TMail::SyntaxError) {
877
+ TMail::Address.parse '@example.com'
878
+ }
879
+
880
+ validate_case__address\
881
+ 'bob',
882
+ :name => nil,
883
+ :display_name => nil,
884
+ :address => 'bob',
885
+ :comments => nil,
886
+ :domain => nil,
887
+ :local => 'bob',
888
+ :format => 'bob'
889
+
890
+ assert_raises(TMail::SyntaxError) {
891
+ TMail::Address.parse 'Undisclosed <>'
892
+ }
893
+ assert_raises(TMail::SyntaxError) {
894
+ TMail::Address.parse '"Mensagem Automatica do Terra" <>'
895
+ }
896
+
897
+ # These test cases are meanful in Japanese charset context.
898
+ # validate_case(["\177", []])
899
+ # validate_case(["\177\177\177", []])
900
+
901
+ end
902
+
903
+ def test_parse__domainliteral
904
+
905
+ validate_case__address\
906
+ 'test@[domain]',
907
+ :name => nil,
908
+ :display_name => nil,
909
+ :address => 'test@[domain]',
910
+ :comments => nil,
911
+ :domain => '[domain]',
912
+ :local => 'test',
913
+ :format => '<test@[domain]>'
914
+
915
+ validate_case__address\
916
+ '<@[obsdomain]:test@[domain]>',
917
+ :name => nil,
918
+ :display_name => nil,
919
+ :address => 'test@[domain]',
920
+ :comments => nil,
921
+ :domain => '[domain]',
922
+ :local => 'test',
923
+ :format => '<test@[domain]>'
924
+
925
+ validate_case__address\
926
+ '<@[ob\]sd\\\\omain]:test@[dom\]ai\\\\n]>',
927
+ :name => nil,
928
+ :display_name => nil,
929
+ :address => 'test@[dom]ai\\n]',
930
+ :comments => nil,
931
+ :domain => '[dom]ai\\n]',
932
+ :local => 'test',
933
+ :format => '<test@[dom\]ai\\\\n]>'
934
+
935
+ # ALL 'route's have '@' prefix so this example is wrong.
936
+ #"Bob \r<@machine.tld \r,\n [obsdomain]\t:\ntest @ [domain]>",
937
+ validate_case__address\
938
+ "Bob \r<@machine.tld \r,\n @[obsdomain]\t:\ntest @ [domain]>",
939
+ :name => 'Bob',
940
+ :display_name => 'Bob',
941
+ :address => 'test@[domain]',
942
+ :comments => nil,
943
+ :domain => '[domain]',
944
+ :local => 'test',
945
+ :format => 'Bob <test@[domain]>'
946
+ end
947
+
948
+
949
+ def test_exhaustive()
950
+
951
+ # We don't test every alphanumeric in atext -- assume that if a, m
952
+ # and z work, they all will.
953
+ atext = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a +
954
+ '!#$%&\'*+-/=?^_`{|}~'.split(//) #/
955
+ boring = ('b'..'l').to_a + ('n'..'o').to_a +
956
+ ('p'..'y').to_a + ('B'..'L').to_a + ('N'..'O').to_a +
957
+ ('P'..'Y').to_a + ('1'..'4').to_a + ('6'..'8').to_a
958
+
959
+ (atext - boring).each do |ch|
960
+ validate_case__address\
961
+ "#{ch} <#{ch}@test>",
962
+ :name => ch,
963
+ :display_name => ch,
964
+ :address => "#{ch}@test",
965
+ :comments => nil,
966
+ :domain => 'test',
967
+ :local => ch,
968
+ :format => ch + ' <' + ch + '@test>'
969
+ end
970
+
971
+ validate_case__address\
972
+ atext.join('') + ' <' + atext.join('') + '@test>',
973
+ :name => atext.join(''),
974
+ :display_name => atext.join(''),
975
+ :address => atext.join('') + '@test',
976
+ :comments => nil,
977
+ :domain => 'test',
978
+ :local => atext.join(''),
979
+ :format => atext.join('') + ' <' + atext.join('') + '@test>'
980
+
981
+ ascii = (0..127).collect {|i| i.chr }
982
+ whitespace = ["\r", "\n", ' ', "\t"]
983
+ # I remove ESC from this list because TMail is ESC sensitive.
984
+ # @ is explicitly tested below
985
+ qtext = ascii - (whitespace + ['"', '\\'] + ["\e"] + ["@"])
986
+ ctext = ascii - (whitespace + ['(', ')', '\\'] + ["\e"] + ["@"])
987
+ dtext = ascii - (whitespace + ['[', ']', '\\'] + ["\e"] + ["@"])
988
+
989
+ (qtext - atext).each do |ch|
990
+ validate_case__address\
991
+ %Q("#{ch}" <"#{ch}"@test>),
992
+ :name => ch,
993
+ :display_name => ch,
994
+ :address => %Q("#{ch}"@test),
995
+ :comments => nil,
996
+ :domain => 'test',
997
+ :local => %Q("#{ch}"),
998
+ :format => %Q("#{ch}" <"#{ch}"@test>)
999
+ end
1000
+
1001
+ ['"', "\\"].each do |ch|
1002
+ validate_case__address\
1003
+ %Q("\\#{ch}" <"\\#{ch}"@test>),
1004
+ :name => ch,
1005
+ :display_name => ch,
1006
+ :address => %Q("\\#{ch}"@test),
1007
+ :comments => nil,
1008
+ :domain => 'test',
1009
+ :local => %Q("\\#{ch}"),
1010
+ :format => %Q("\\#{ch}" <"\\#{ch}"@test>)
1011
+
1012
+ end
1013
+
1014
+ (ctext - boring).each do |ch|
1015
+ validate_case__address\
1016
+ "bob@test (#{ch})",
1017
+ :name => ch,
1018
+ :display_name => nil,
1019
+ :address => 'bob@test',
1020
+ :comments => ["#{ch}"],
1021
+ :domain => 'test',
1022
+ :local => 'bob',
1023
+ :format => "bob@test (#{ch})"
1024
+
1025
+ validate_case__address\
1026
+ "bob@test (\\#{ch})",
1027
+ :name => ch,
1028
+ :display_name => nil,
1029
+ :address => 'bob@test',
1030
+ :comments => ["#{ch}"],
1031
+ :domain => 'test',
1032
+ :local => 'bob',
1033
+ :format => "bob@test (#{ch})"
1034
+ end
1035
+ [')', '(', '\\'].each do |ch|
1036
+ validate_case__address\
1037
+ "bob@test (\\#{ch})",
1038
+ :name => ch,
1039
+ :display_name => nil,
1040
+ :address => 'bob@test',
1041
+ :comments => ["#{ch}"],
1042
+ :domain => 'test',
1043
+ :local => 'bob',
1044
+ :format => "bob@test (\\#{ch})"
1045
+ end
1046
+
1047
+
1048
+ (dtext - boring).each do |ch|
1049
+ validate_case__address\
1050
+ "test@[\\#{ch}] (Sam)",
1051
+ :name => "Sam",
1052
+ :display_name => nil,
1053
+ :address => 'test@[' + ch + ']',
1054
+ :comments => ["Sam"],
1055
+ :domain => '[' + ch + ']',
1056
+ :local => 'test',
1057
+ :format => "<test@[#{ch}]> (Sam)"
1058
+
1059
+ validate_case__address\
1060
+ "Sally <test@[\\#{ch}]>",
1061
+ :name => 'Sally',
1062
+ :display_name => 'Sally',
1063
+ :address => "test@[#{ch}]",
1064
+ :comments => nil,
1065
+ :domain => "[#{ch}]",
1066
+ :local => 'test',
1067
+ :format => "Sally <test@[#{ch}]>"
1068
+ end
1069
+
1070
+ validate_case__address\
1071
+ "test@[" + (dtext - boring).join('') + "]",
1072
+ :name => nil,
1073
+ :display_name => nil,
1074
+ :address => 'test@[' + (dtext - boring).join('') + "]",
1075
+ :comments => nil,
1076
+ :domain => '[' + (dtext - boring).join('') + ']',
1077
+ :local => 'test',
1078
+ :format => '<test@[' + (dtext - boring).join('') + ']>'
1079
+
1080
+ validate_case__address\
1081
+ 'Bob <test@[' + (dtext - boring).join('') + ']>',
1082
+ :name => "Bob",
1083
+ :display_name => "Bob",
1084
+ :address => 'test@[' + (dtext - boring).join('') + "]",
1085
+ :comments => nil,
1086
+ :domain => '[' + (dtext - boring).join('') + ']',
1087
+ :local => 'test',
1088
+ :format => 'Bob <test@[' + (dtext - boring).join('') + ']>'
1089
+
1090
+ end
1091
+
1092
+ def test_dot_in_address()
1093
+
1094
+ validate_case__address\
1095
+ %Q(Minero A. <aamine@loveruby.net>),
1096
+ :name => "Minero A.",
1097
+ :display_name => "Minero A.",
1098
+ :address => %Q(aamine@loveruby.net),
1099
+ :comments => nil,
1100
+ :domain => 'loveruby.net',
1101
+ :local => %Q(aamine),
1102
+ :format => %Q("me@my_place" <aamine@loveruby.net>)
1103
+
1104
+ validate_case__address\
1105
+ %Q(mikel . <mikel@lindsaar.net>),
1106
+ :name => "mikel .",
1107
+ :display_name => "mikel .",
1108
+ :address => %Q(mikel@lindsaar.net),
1109
+ :comments => nil,
1110
+ :domain => 'lindsaar.net',
1111
+ :local => %Q(mikel),
1112
+ :format => %Q("mikel ." <mikel@lindsaar.net>)
1113
+
1114
+ validate_case__address\
1115
+ %Q("mikel ." <mikel@lindsaar.net>),
1116
+ :name => "mikel .",
1117
+ :display_name => "mikel .",
1118
+ :address => %Q(mikel@lindsaar.net),
1119
+ :comments => nil,
1120
+ :domain => 'lindsaar.net',
1121
+ :local => %Q(mikel),
1122
+ :format => %Q("mikel ." <mikel@lindsaar.net>)
1123
+
1124
+ validate_case__address\
1125
+ %Q(mikel "." <mikel@lindsaar.net>),
1126
+ :name => %Q(mikel .),
1127
+ :display_name => %Q(mikel .),
1128
+ :address => %Q(mikel@lindsaar.net),
1129
+ :comments => nil,
1130
+ :domain => 'lindsaar.net',
1131
+ :local => %Q(mikel),
1132
+ :format => %Q(mikel "." <mikel@lindsaar.net>)
1133
+
1134
+ end
1135
+
1136
+ def test_at_char_in_address()
1137
+
1138
+ validate_case__address\
1139
+ %Q(mikel@lindsaar.net <lindsaar@you.net>),
1140
+ :name => "mikel@lindsaar.net",
1141
+ :display_name => "mikel@lindsaar.net",
1142
+ :address => %Q(lindsaar@you.net),
1143
+ :comments => nil,
1144
+ :domain => 'you.net',
1145
+ :local => %Q(lindsaar),
1146
+ :format => %Q("mikel@lindsaar.net" <lindsaar@you.net>)
1147
+
1148
+ validate_case__address\
1149
+ %Q(mikel@lindsaar.net <mikel@lindsaar.net>),
1150
+ :name => %Q(mikel@lindsaar.net),
1151
+ :display_name => %Q(mikel@lindsaar.net),
1152
+ :address => %Q(mikel@lindsaar.net),
1153
+ :comments => nil,
1154
+ :domain => 'lindsaar.net',
1155
+ :local => %Q(mikel),
1156
+ :format => %Q(mikel@lindsaar.net)
1157
+
1158
+ validate_case__address\
1159
+ %Q("mikel@lindsaar.net" <mikel@lindsaar.net>),
1160
+ :name => %Q(mikel@lindsaar.net),
1161
+ :display_name => %Q(mikel@lindsaar.net),
1162
+ :address => %Q(mikel@lindsaar.net),
1163
+ :comments => nil,
1164
+ :domain => 'lindsaar.net',
1165
+ :local => %Q(mikel),
1166
+ :format => %Q(mikel@lindsaar.net)
1167
+
1168
+ validate_case__address\
1169
+ %Q("@" <"@"@lindsaar.net>),
1170
+ :name => "@",
1171
+ :display_name => "@",
1172
+ :address => %Q("@"@lindsaar.net),
1173
+ :comments => nil,
1174
+ :domain => 'lindsaar.net',
1175
+ :local => %Q("@"),
1176
+ :format => %Q("@" <"@"@lindsaar.net>)
1177
+
1178
+ validate_case__address\
1179
+ %Q("@" <"me@me"@lindsaar.net>),
1180
+ :name => "@",
1181
+ :display_name => "@",
1182
+ :address => %Q("me@me"@lindsaar.net),
1183
+ :comments => nil,
1184
+ :domain => 'lindsaar.net',
1185
+ :local => %Q("me@me"),
1186
+ :format => %Q("@" <"me@me"@lindsaar.net>)
1187
+
1188
+ validate_case__address\
1189
+ %Q("mikel" <mikel@lindsaar.net>),
1190
+ :name => "mikel",
1191
+ :display_name => "mikel",
1192
+ :address => %Q(mikel@lindsaar.net),
1193
+ :comments => nil,
1194
+ :domain => 'lindsaar.net',
1195
+ :local => %Q(mikel),
1196
+ :format => %Q("mikel" <mikel@lindsaar.net>)
1197
+
1198
+ validate_case__address\
1199
+ %Q(mikel <mikel@lindsaar.net>),
1200
+ :name => "mikel",
1201
+ :display_name => "mikel",
1202
+ :address => %Q(mikel@lindsaar.net),
1203
+ :comments => nil,
1204
+ :domain => 'lindsaar.net',
1205
+ :local => %Q(mikel),
1206
+ :format => %Q(mikel <mikel@lindsaar.net>)
1207
+ end
1208
+
1209
+ def test_trailing_dot_in_name
1210
+ fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email_trailing_dot")
1211
+ str = 'Sandy M. <noreply@rubyforge.org>'
1212
+ mail = TMail::Mail.parse(fixture)
1213
+ assert_equal '"Sandy M." <noreply@rubyforge.org>', mail['from'].to_s
1214
+ end
1215
+
1216
+ end