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