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,126 @@
1
+ require 'tmail/mailbox'
2
+ require 'fileutils'
3
+ require 'test/unit'
4
+
5
+ class MailboxTester < Test::Unit::TestCase
6
+ include FileUtils
7
+
8
+ MAILBOX = '_mh'
9
+ N = 5
10
+
11
+ def setup
12
+ rm_rf MAILBOX
13
+ mkdir MAILBOX
14
+ N.downto(1) do |i|
15
+ File.open( "#{MAILBOX}/#{i}", 'w' ) {|f|
16
+ f.puts 'From: aamine'
17
+ f.puts 'To: aamine@loveruby.net'
18
+ f.puts "Subject: #{i}"
19
+ f.puts ''
20
+ f.puts 'body'
21
+ }
22
+ end
23
+ @n = N
24
+
25
+ @ld = TMail::MhMailbox.new( MAILBOX )
26
+ end
27
+
28
+ def make_mails_older( diff )
29
+ Dir.entries( MAILBOX ).collect {|n| "#{MAILBOX}/#{n}" }.each do |path|
30
+ if File.file? path then
31
+ t = File.mtime(path) - diff
32
+ File.utime t, t, path
33
+ end
34
+ end
35
+ end
36
+
37
+ def teardown
38
+ rm_rf MAILBOX
39
+ end
40
+
41
+ def test_s_new
42
+ ld = TMail::MhMailbox.new( MAILBOX )
43
+ assert_instance_of TMail::MhMailbox, ld
44
+ end
45
+
46
+ def test_each_port
47
+ dir = File.expand_path(MAILBOX)
48
+ c = 0
49
+ n = 0
50
+ TMail::MhMailbox.new( MAILBOX ).each_port do |port|
51
+ assert_kind_of TMail::FilePort, port
52
+ assert_equal dir, File.dirname(port.filename)
53
+ assert_match(/\A\d+\z/, File.basename(port.filename))
54
+ nn = File.basename(port.filename).to_i
55
+ assert nn > n
56
+ n = nn
57
+ c += 1
58
+ end
59
+ assert_equal N, c
60
+ end
61
+
62
+ def test_reverse_each_port
63
+ dir = File.expand_path(MAILBOX)
64
+ c = 0
65
+ n = 100000
66
+ TMail::MhMailbox.new( MAILBOX ).reverse_each_port do |port|
67
+ assert_kind_of TMail::FilePort, port
68
+ assert_equal dir, File.dirname(port.filename)
69
+ assert_match(/\A\d+\z/, File.basename(port.filename))
70
+ nn = File.basename(port.filename).to_i
71
+ assert nn < n
72
+ n = nn
73
+ c += 1
74
+ end
75
+ assert_equal N, c
76
+ end
77
+
78
+ def test_new_port
79
+ port = @ld.new_port
80
+ assert_kind_of TMail::FilePort, port
81
+ assert_equal File.expand_path('.') + '/' + MAILBOX,
82
+ File.dirname(port.filename)
83
+ assert_equal( (N+1).to_s, File.basename(port.filename) )
84
+
85
+ create port
86
+ end
87
+
88
+ def create( port )
89
+ port.wopen {|f|
90
+ f.puts 'From: aamine'
91
+ f.puts 'To: aamine@loveruby.net'
92
+ f.puts "Subject: #{@n + 1}"
93
+ f.puts ''
94
+ f.puts 'body'
95
+ }
96
+ @n += 1
97
+ end
98
+
99
+ def test_each_new_port
100
+ make_mails_older 5
101
+
102
+ c = 0
103
+ @ld.each_new_port do |port|
104
+ assert_kind_of TMail::FilePort, port
105
+ c += 1
106
+ end
107
+ assert_equal @n, c
108
+
109
+ t = Time.now - 2
110
+ create @ld.new_port
111
+ c = 0
112
+ @ld.each_new_port( t ) do |port|
113
+ assert_kind_of TMail::FilePort, port
114
+ c += 1
115
+ end
116
+ assert_equal 1, c
117
+
118
+ make_mails_older 5
119
+ c = 0
120
+ @ld.each_new_port do |port|
121
+ assert_kind_of TMail::FilePort, port
122
+ c += 1
123
+ end
124
+ assert_equal 0, c
125
+ end
126
+ end
@@ -0,0 +1,430 @@
1
+ require 'tmail/loader'
2
+ require 'tmail/port'
3
+ require 'fileutils'
4
+ require 'test/unit'
5
+
6
+ class FilePortTester < Test::Unit::TestCase
7
+ include FileUtils
8
+
9
+ def setup
10
+ rm_rf 'tmp'
11
+ mkdir 'tmp'
12
+ 5.times do |n|
13
+ File.open('tmp/' + n.to_s, 'w') {|f|
14
+ f.puts "file #{n}"
15
+ }
16
+ end
17
+ end
18
+
19
+ def teardown
20
+ rm_rf 'tmp'
21
+ end
22
+
23
+ def test_s_new
24
+ port = TMail::FilePort.new('tmp/1')
25
+ assert_instance_of TMail::FilePort, port
26
+ end
27
+
28
+ def test_inspect
29
+ port = TMail::FilePort.new('tmp/1')
30
+ port.inspect
31
+ end
32
+
33
+ def test_EQUAL # ==
34
+ port = TMail::FilePort.new('tmp/1')
35
+ assert_equal port, port
36
+ p2 = TMail::FilePort.new('tmp/1')
37
+ assert_equal port, p2
38
+ end
39
+
40
+ def test_eql?
41
+ port = TMail::FilePort.new('tmp/1')
42
+ assert_equal true, port.eql?(port)
43
+ p2 = TMail::FilePort.new('tmp/1')
44
+ assert_equal true, port.eql?(p2)
45
+ end
46
+
47
+ def test_hash
48
+ port = TMail::FilePort.new('tmp/1')
49
+ assert_equal port.hash, port.hash
50
+ p2 = TMail::FilePort.new('tmp/1')
51
+ assert_equal port.hash, p2.hash
52
+ end
53
+
54
+ def test_filename
55
+ port = TMail::FilePort.new('tmp/1')
56
+ assert_not_nil port.filename
57
+ assert_equal File.expand_path('tmp/1'), port.filename
58
+ assert_equal File.expand_path('tmp/1'), port.filename
59
+
60
+ port = TMail::FilePort.new('tmp/2')
61
+ assert_not_nil port.filename
62
+ assert_equal File.expand_path('tmp/2'), port.filename
63
+ assert_equal File.expand_path('tmp/2'), port.filename
64
+ end
65
+
66
+ def test_ident
67
+ ports = []
68
+ 5.times do |n|
69
+ ports.push TMail::FilePort.new("tmp/#{n}")
70
+ end
71
+
72
+ until ports.empty? do
73
+ base = ports.shift
74
+ ports.each do |other|
75
+ assert_not_equal base.ident, other.ident
76
+ end
77
+ end
78
+ end
79
+
80
+ def test_size
81
+ 5.times do |n|
82
+ port = TMail::FilePort.new("tmp/#{n}")
83
+ assert_equal File.size("tmp/#{n}"), port.size
84
+ end
85
+ end
86
+
87
+ def test_ropen
88
+ port = TMail::FilePort.new("tmp/1")
89
+ f = port.ropen
90
+ assert_instance_of File, f
91
+ assert_equal false, f.closed?
92
+ assert_equal 'f', f.read(1)
93
+ f.close
94
+
95
+ f = nil
96
+ port.ropen {|f|
97
+ assert_instance_of File, f
98
+ assert_equal false, f.closed?
99
+ assert_equal 'f', f.read(1)
100
+ }
101
+ assert_equal true, f.closed?
102
+
103
+ assert_raises( Errno::ENOENT ) {
104
+ TMail::FilePort.new('tmp/100').ropen
105
+ }
106
+ end
107
+
108
+ def test_wopen
109
+ port = TMail::FilePort.new('tmp/1')
110
+ f = port.wopen
111
+ assert_instance_of File, f
112
+ assert_equal false, f.closed?
113
+ f.puts 'ok'
114
+ f.close
115
+
116
+ f = nil
117
+ port.wopen {|f|
118
+ assert_instance_of File, f
119
+ assert_equal false, f.closed?
120
+ f.puts 'ok'
121
+ }
122
+ assert_equal true, f.closed?
123
+
124
+ TMail::FilePort.new('tmp/100').wopen {|f| }
125
+ end
126
+
127
+ def test_aopen
128
+ port = TMail::FilePort.new('tmp/1')
129
+ size = port.size
130
+ f = port.aopen
131
+ assert_instance_of File, f
132
+ assert_equal false, f.closed?
133
+ f.print 'N'
134
+ f.close
135
+ assert_equal size + 1, port.size
136
+ port.ropen {|f|
137
+ assert_equal 'f', f.read(1)
138
+ }
139
+
140
+ f = nil
141
+ port.aopen {|f|
142
+ assert_instance_of File, f
143
+ assert_equal false, f.closed?
144
+ f.print 'N'
145
+ }
146
+ assert_equal true, f.closed?
147
+ assert_equal size + 1 + 1, port.size
148
+ port.ropen {|f|
149
+ assert_equal 'f', f.read(1)
150
+ }
151
+
152
+ TMail::FilePort.new('tmp/100').aopen {|f| }
153
+ end
154
+
155
+ def test_read_all
156
+ 5.times do |n|
157
+ port = TMail::FilePort.new("tmp/#{n}")
158
+ assert_equal readall("tmp/#{n}"), port.read_all
159
+ end
160
+ end
161
+
162
+ def test_copy_to
163
+ src = TMail::FilePort.new('tmp/1')
164
+ dest = TMail::FilePort.new('tmp/10')
165
+ src.copy_to dest
166
+ assert_equal readall('tmp/1'), readall('tmp/10')
167
+ end
168
+
169
+ def test_move_to
170
+ src = TMail::FilePort.new('tmp/1')
171
+ str = src.read_all
172
+ dest = TMail::FilePort.new('tmp/10')
173
+ src.move_to dest
174
+ assert_equal str, readall('tmp/10')
175
+ assert_raises( Errno::ENOENT ) { src.ropen }
176
+ end
177
+
178
+ def test_remove
179
+ port = TMail::FilePort.new('tmp/1')
180
+ port.remove
181
+ assert_raises(Errno::ENOENT) {
182
+ port.ropen
183
+ }
184
+
185
+ port = TMail::FilePort.new('tmp/100')
186
+ assert_raises(Errno::ENOENT) {
187
+ port.remove
188
+ }
189
+ end
190
+
191
+ def readall(fname)
192
+ File.open(fname) {|f|
193
+ return f.read
194
+ }
195
+ end
196
+ end
197
+
198
+ class StringPortTester < Test::Unit::TestCase
199
+ def test_s_new
200
+ port = TMail::StringPort.new
201
+ assert_instance_of TMail::StringPort, port
202
+ end
203
+
204
+ def test_EQUAL # ==
205
+ port = TMail::StringPort.new(str = '')
206
+ port2 = TMail::StringPort.new(str)
207
+ other = TMail::StringPort.new
208
+ assert_equal port, port
209
+ assert_equal port, port2
210
+ assert_not_equal port, other
211
+ end
212
+
213
+ def test_eql?
214
+ port = TMail::StringPort.new(str = '')
215
+ port2 = TMail::StringPort.new(str)
216
+ other = TMail::StringPort.new
217
+ assert_equal true, port.eql?(port)
218
+ assert_equal true, port.eql?(port2)
219
+ assert_equal false, port.eql?(other)
220
+ end
221
+
222
+ def test_hash
223
+ port = TMail::StringPort.new(str = '')
224
+ port2 = TMail::StringPort.new(str)
225
+ other = TMail::StringPort.new
226
+ assert_equal port.hash, port.hash
227
+ assert_equal port.hash, port2.hash
228
+ # assert_not_equal port.hash, other.hash
229
+ end
230
+
231
+ def test_string
232
+ port = TMail::StringPort.new(str = '')
233
+ assert_same str, port.string
234
+ assert_same port.string, port.string
235
+ end
236
+
237
+ def test_to_s
238
+ port = TMail::StringPort.new(str = 'abc')
239
+ assert_equal str, port.to_s
240
+ port.to_s.concat 'XXX'
241
+ assert_equal str, port.to_s
242
+ end
243
+
244
+ def test_inspect
245
+ TMail::StringPort.new.inspect
246
+ TMail::StringPort.new('abc').inspect
247
+ end
248
+
249
+ def test_size
250
+ port = TMail::StringPort.new(str = 'abc')
251
+ assert_equal str.size, port.size
252
+ end
253
+
254
+ def test_ropen
255
+ port = TMail::StringPort.new(str = 'abc')
256
+ f = port.ropen
257
+ assert_equal false, f.closed?
258
+ assert_equal 'a', f.read(1)
259
+ f.close
260
+
261
+ port.ropen {|f|
262
+ assert_equal false, f.closed?
263
+ assert_equal 'a', f.read(1)
264
+ }
265
+ assert_equal true, f.closed?
266
+ end
267
+
268
+ def test_wopen
269
+ port = TMail::StringPort.new(str = 'abc')
270
+ f = port.wopen
271
+ assert_equal false, f.closed?
272
+ f.print 'N'
273
+ f.close
274
+ assert_equal 'N', port.read_all
275
+
276
+ port.wopen {|f|
277
+ assert_equal false, f.closed?
278
+ f.print 'NN'
279
+ }
280
+ assert_equal true, f.closed?
281
+ assert_equal 'NN', port.read_all
282
+ end
283
+
284
+ def test_aopen
285
+ port = TMail::StringPort.new(str = 'abc')
286
+ f = port.aopen
287
+ assert_equal false, f.closed?
288
+ f.print 'N'
289
+ f.close
290
+ assert_equal 'abcN', port.read_all
291
+
292
+ port.aopen {|f|
293
+ assert_equal false, f.closed?
294
+ f.print 'F'
295
+ }
296
+ assert_equal true, f.closed?
297
+ assert_equal 'abcNF', port.read_all
298
+ end
299
+
300
+ include FileUtils
301
+
302
+ def test_copy_to
303
+ src = TMail::StringPort.new('abc')
304
+ dest = TMail::StringPort.new
305
+ src.copy_to dest
306
+ assert_equal src.read_all, dest.read_all
307
+ assert_not_equal src.string.object_id, dest.string.object_id
308
+ end
309
+
310
+ def test_move_to
311
+ src = TMail::StringPort.new(str = 'abc')
312
+ dest = TMail::StringPort.new
313
+ src.move_to dest
314
+ assert_same str, dest.string
315
+ assert_raises(Errno::ENOENT) {
316
+ src.ropen
317
+ }
318
+ end
319
+
320
+ def test_remove
321
+ port = TMail::StringPort.new(str = 'abc')
322
+ port.remove
323
+ assert_raises(Errno::ENOENT) {
324
+ port.ropen
325
+ }
326
+ end
327
+ end
328
+
329
+ class MhPortTester < Test::Unit::TestCase
330
+ include FileUtils
331
+
332
+ def setup
333
+ rm_rf 'tmp'
334
+ mkdir 'tmp'
335
+ 3.times do |n|
336
+ File.open( "tmp/#{n}", 'w' ) {|f|
337
+ f.puts 'From: Minero Aoki <aamine@loveruby.net>'
338
+ f.puts "Subject: test file #{n}"
339
+ f.puts
340
+ f.puts 'This is body.'
341
+ }
342
+ end
343
+ end
344
+
345
+ def teardown
346
+ rm_rf 'tmp'
347
+ end
348
+
349
+ def test_flags
350
+ port = TMail::MhPort.new('tmp/1')
351
+ assert_equal false, port.flagged?
352
+ port.flagged = true
353
+ assert_equal true, port.flagged?
354
+
355
+ assert_equal false, port.replied?
356
+ port.replied = true
357
+ assert_equal true, port.replied?
358
+
359
+ assert_equal false, port.seen?
360
+ port.seen = true
361
+ assert_equal true, port.seen?
362
+
363
+ port = TMail::MhPort.new('tmp/1')
364
+ assert_equal true, port.flagged?
365
+ assert_equal true, port.replied?
366
+ assert_equal true, port.seen?
367
+
368
+ port = TMail::MhPort.new('tmp/1')
369
+ port.flagged = false
370
+ port.replied = false
371
+ port.seen = false
372
+
373
+ port = TMail::MhPort.new('tmp/1')
374
+ assert_equal false, port.flagged?
375
+ assert_equal false, port.replied?
376
+ assert_equal false, port.seen?
377
+ end
378
+ end
379
+
380
+ class MaildirPortTester < Test::Unit::TestCase
381
+ include FileUtils
382
+
383
+ def setup
384
+ rm_rf 'tmp'
385
+ mkdir 'tmp'
386
+ 3.times do |n|
387
+ File.open( "tmp/000.00#{n}.a", 'w' ) {|f|
388
+ f.puts 'From: Minero Aoki <aamine@loveruby.net>'
389
+ f.puts "Subject: test file #{n}"
390
+ f.puts
391
+ f.puts 'This is body.'
392
+ }
393
+ end
394
+ end
395
+
396
+ def teardown
397
+ rm_rf 'tmp'
398
+ end
399
+
400
+ def test_flags
401
+ port = TMail::MaildirPort.new('tmp/000.001.a')
402
+
403
+ assert_equal false, port.flagged?
404
+ port.flagged = true
405
+ assert_equal true, port.flagged?
406
+
407
+ assert_equal false, port.replied?
408
+ port.replied = true
409
+ assert_equal true, port.replied?
410
+
411
+ assert_equal false, port.seen?
412
+ port.seen = true
413
+ assert_equal true, port.seen?
414
+
415
+ port = TMail::MaildirPort.new(port.filename)
416
+ assert_equal true, port.flagged?
417
+ assert_equal true, port.replied?
418
+ assert_equal true, port.seen?
419
+
420
+ port = TMail::MaildirPort.new(port.filename)
421
+ port.flagged = false
422
+ port.replied = false
423
+ port.seen = false
424
+
425
+ port = TMail::MaildirPort.new(port.filename)
426
+ assert_equal false, port.flagged?
427
+ assert_equal false, port.replied?
428
+ assert_equal false, port.seen?
429
+ end
430
+ end