rmail 0.17

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 (91) hide show
  1. data/NEWS +309 -0
  2. data/NOTES +14 -0
  3. data/README +83 -0
  4. data/THANKS +25 -0
  5. data/TODO +112 -0
  6. data/guide/Intro.txt +122 -0
  7. data/guide/MIME.txt +6 -0
  8. data/guide/TableOfContents.txt +13 -0
  9. data/install.rb +1023 -0
  10. data/lib/rmail.rb +50 -0
  11. data/lib/rmail/address.rb +829 -0
  12. data/lib/rmail/header.rb +987 -0
  13. data/lib/rmail/mailbox.rb +62 -0
  14. data/lib/rmail/mailbox/mboxreader.rb +182 -0
  15. data/lib/rmail/message.rb +201 -0
  16. data/lib/rmail/parser.rb +412 -0
  17. data/lib/rmail/parser/multipart.rb +217 -0
  18. data/lib/rmail/parser/pushbackreader.rb +173 -0
  19. data/lib/rmail/serialize.rb +190 -0
  20. data/lib/rmail/utils.rb +59 -0
  21. data/rmail.gemspec +17 -0
  22. data/tests/addrgrammar.txt +113 -0
  23. data/tests/data/mbox.odd +4 -0
  24. data/tests/data/mbox.simple +8 -0
  25. data/tests/data/multipart/data.1 +5 -0
  26. data/tests/data/multipart/data.10 +1 -0
  27. data/tests/data/multipart/data.11 +9 -0
  28. data/tests/data/multipart/data.12 +9 -0
  29. data/tests/data/multipart/data.13 +3 -0
  30. data/tests/data/multipart/data.14 +3 -0
  31. data/tests/data/multipart/data.15 +3 -0
  32. data/tests/data/multipart/data.16 +3 -0
  33. data/tests/data/multipart/data.17 +0 -0
  34. data/tests/data/multipart/data.2 +5 -0
  35. data/tests/data/multipart/data.3 +2 -0
  36. data/tests/data/multipart/data.4 +3 -0
  37. data/tests/data/multipart/data.5 +1 -0
  38. data/tests/data/multipart/data.6 +2 -0
  39. data/tests/data/multipart/data.7 +3 -0
  40. data/tests/data/multipart/data.8 +5 -0
  41. data/tests/data/multipart/data.9 +4 -0
  42. data/tests/data/parser.badmime1 +4 -0
  43. data/tests/data/parser.badmime2 +6 -0
  44. data/tests/data/parser.nested-multipart +75 -0
  45. data/tests/data/parser.nested-simple +12 -0
  46. data/tests/data/parser.nested-simple2 +16 -0
  47. data/tests/data/parser.nested-simple3 +21 -0
  48. data/tests/data/parser.rfc822 +65 -0
  49. data/tests/data/parser.simple-mime +24 -0
  50. data/tests/data/parser/multipart.1 +8 -0
  51. data/tests/data/parser/multipart.10 +4 -0
  52. data/tests/data/parser/multipart.11 +12 -0
  53. data/tests/data/parser/multipart.12 +12 -0
  54. data/tests/data/parser/multipart.13 +6 -0
  55. data/tests/data/parser/multipart.14 +6 -0
  56. data/tests/data/parser/multipart.15 +6 -0
  57. data/tests/data/parser/multipart.16 +6 -0
  58. data/tests/data/parser/multipart.2 +8 -0
  59. data/tests/data/parser/multipart.3 +5 -0
  60. data/tests/data/parser/multipart.4 +6 -0
  61. data/tests/data/parser/multipart.5 +4 -0
  62. data/tests/data/parser/multipart.6 +5 -0
  63. data/tests/data/parser/multipart.7 +6 -0
  64. data/tests/data/parser/multipart.8 +8 -0
  65. data/tests/data/parser/multipart.9 +7 -0
  66. data/tests/data/transparency/absolute.1 +5 -0
  67. data/tests/data/transparency/absolute.2 +1 -0
  68. data/tests/data/transparency/absolute.3 +2 -0
  69. data/tests/data/transparency/absolute.4 +3 -0
  70. data/tests/data/transparency/absolute.5 +4 -0
  71. data/tests/data/transparency/absolute.6 +49 -0
  72. data/tests/data/transparency/message.1 +73 -0
  73. data/tests/data/transparency/message.2 +34 -0
  74. data/tests/data/transparency/message.3 +63 -0
  75. data/tests/data/transparency/message.4 +5 -0
  76. data/tests/data/transparency/message.5 +15 -0
  77. data/tests/data/transparency/message.6 +1185 -0
  78. data/tests/runtests.rb +35 -0
  79. data/tests/testaddress.rb +1192 -0
  80. data/tests/testbase.rb +207 -0
  81. data/tests/testheader.rb +1207 -0
  82. data/tests/testmailbox.rb +47 -0
  83. data/tests/testmboxreader.rb +161 -0
  84. data/tests/testmessage.rb +257 -0
  85. data/tests/testparser.rb +634 -0
  86. data/tests/testparsermultipart.rb +205 -0
  87. data/tests/testpushbackreader.rb +40 -0
  88. data/tests/testserialize.rb +264 -0
  89. data/tests/testtestbase.rb +112 -0
  90. data/tests/testtranspparency.rb +105 -0
  91. metadata +143 -0
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright (c) 2002 Matt Armstrong. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # 2. Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ # 3. The name of the author may not be used to endorse or promote products
14
+ # derived from this software without specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19
+ # NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #
27
+
28
+ require 'tests/testbase'
29
+ require 'rmail/mailbox'
30
+
31
+ class TestRMailMailbox < TestBase
32
+ def test_parse_mbox_simple
33
+ expected = ["From foo@bar Wed Nov 27 12:27:32 2002\nmessage1\n",
34
+ "From foo@bar Wed Nov 27 12:27:36 2002\nmessage2\n",
35
+ "From foo@bar Wed Nov 27 12:27:40 2002\nmessage3\n"]
36
+ data_as_file("mbox.simple") { |f|
37
+ assert_equal(expected, RMail::Mailbox::parse_mbox(f))
38
+ }
39
+ data_as_file("mbox.simple") { |f|
40
+ messages = []
41
+ RMail::Mailbox::parse_mbox(f) { |m|
42
+ messages << m
43
+ }
44
+ assert_equal(expected, messages)
45
+ }
46
+ end
47
+ end
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright (c) 2002 Matt Armstrong. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # 2. Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ # 3. The name of the author may not be used to endorse or promote products
14
+ # derived from this software without specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19
+ # NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #
27
+
28
+ require 'tests/testbase'
29
+ require 'rmail/mailbox/mboxreader'
30
+
31
+ class TextRMailMBoxReader < TestBase
32
+
33
+ def test_mbox_s_new
34
+ r = RMail::Mailbox::MBoxReader.new("")
35
+ assert_instance_of(RMail::Mailbox::MBoxReader, r)
36
+ end
37
+
38
+ def test_mbox_simple
39
+ data_as_file("mbox.simple") { |f|
40
+ mbox = RMail::Mailbox::MBoxReader.new(f)
41
+
42
+ chunk = mbox.read(nil)
43
+ assert_equal("From foo@bar Wed Nov 27 12:27:32 2002\nmessage1\n",
44
+ chunk)
45
+ chunk = mbox.read(nil)
46
+ assert_nil(chunk)
47
+ mbox.next
48
+
49
+ chunk = mbox.read(nil)
50
+ assert_equal("From foo@bar Wed Nov 27 12:27:36 2002\nmessage2\n",
51
+ chunk)
52
+ chunk = mbox.read(nil)
53
+ assert_nil(chunk)
54
+ mbox.next
55
+
56
+ chunk = mbox.read(nil)
57
+ assert_equal("From foo@bar Wed Nov 27 12:27:40 2002\nmessage3\n",
58
+ chunk)
59
+ chunk = mbox.read(nil)
60
+ assert_nil(chunk)
61
+
62
+ mbox.next
63
+ chunk = mbox.read(nil)
64
+ assert_nil(chunk)
65
+ }
66
+ end
67
+
68
+ def test_mbox_odd
69
+ data_as_file("mbox.odd") { |f|
70
+ mbox = RMail::Mailbox::MBoxReader.new(f)
71
+
72
+ chunk = mbox.read(nil)
73
+ assert_equal("From foo@bar Wed Nov 27 12:27:36 2002\nmessage1\n",
74
+ chunk)
75
+ chunk = mbox.read(nil)
76
+ assert_nil(chunk)
77
+ mbox.next
78
+
79
+ chunk = mbox.read(nil)
80
+ assert_equal("From foo@bar Wed Nov 27 12:27:40 2002\nmessage2\n",
81
+ chunk)
82
+ chunk = mbox.read(nil)
83
+ assert_nil(chunk)
84
+
85
+ mbox.next
86
+ chunk = mbox.read(nil)
87
+ assert_nil(chunk)
88
+ }
89
+ end
90
+
91
+ def t_chunksize_helper(reader, expected)
92
+ chunk = reader.read(nil)
93
+ assert_equal(expected, chunk)
94
+ end
95
+
96
+ def test_mbox_chunksize
97
+ 1.upto(80) { |chunk_size|
98
+ data_as_file("mbox.simple") { |f|
99
+ mbox = RMail::Mailbox::MBoxReader.new(f)
100
+
101
+ mbox.chunk_size = chunk_size
102
+
103
+ t_chunksize_helper(mbox,
104
+ "From foo@bar Wed Nov 27 12:27:32 2002\nmessage1\n")
105
+ mbox.next
106
+ t_chunksize_helper(mbox,
107
+ "From foo@bar Wed Nov 27 12:27:36 2002\nmessage2\n")
108
+ mbox.next
109
+ t_chunksize_helper(mbox,
110
+ "From foo@bar Wed Nov 27 12:27:40 2002\nmessage3\n")
111
+ mbox.next
112
+
113
+ chunk = mbox.read
114
+ assert_nil(chunk)
115
+ }
116
+ }
117
+ end
118
+
119
+ def t_randomly_randomize(template)
120
+ count = rand(10)
121
+ messages = []
122
+ 0.upto(count) { |i|
123
+ messages << template[0, 5 + rand(template.length - 5)] + "\n"
124
+ }
125
+ mbox_string = messages.join("\n")
126
+ return [ messages, mbox_string ]
127
+ end
128
+
129
+ def t_randomly_parse_messages(reader)
130
+ messages = []
131
+ while message = reader.read(nil)
132
+ messages << message
133
+ reader.next
134
+ end
135
+ return messages
136
+ end
137
+
138
+ def t_randomly_parse_helper(chunk_size, messages, mbox_string)
139
+ reader = RMail::Mailbox::MBoxReader.new(mbox_string)
140
+ reader.chunk_size = chunk_size unless chunk_size.nil?
141
+
142
+ messages2 = t_randomly_parse_messages(reader)
143
+ assert_equal(messages, messages2)
144
+ end
145
+
146
+ def test_mbox_randomly
147
+ 5.times {
148
+ template = ("From foo@bar\n" +
149
+ "text1\ntext2\ntext3\ntexttexttexttexttext4\n" +
150
+ (("abcdefghijklmnopqrstuvwxyz" * rand(5)) + "\n") * rand(20))
151
+
152
+ messages, mbox_string = t_randomly_randomize(template)
153
+
154
+ 1.upto(200) { |chunk_size|
155
+ t_randomly_parse_helper(chunk_size, messages, mbox_string)
156
+ }
157
+ t_randomly_parse_helper(nil, messages, mbox_string)
158
+ }
159
+ end
160
+
161
+ end
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env ruby
2
+ #--
3
+ # Copyright (C) 2001, 2002 Matt Armstrong. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # 2. Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ # 3. The name of the author may not be used to endorse or promote products
14
+ # derived from this software without specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19
+ # NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #
27
+
28
+ require 'rmail/message'
29
+ require 'tests/testbase'
30
+
31
+ class TestRMailMessage < TestBase
32
+
33
+ def setup
34
+ super
35
+
36
+ @the_mail_file = File.join(scratch_dir, "mail_file")
37
+
38
+ @the_mail = %q{From: somedude@example.com
39
+ To: someotherdude@example.com
40
+ Subject: this is some mail
41
+
42
+ First body line.
43
+
44
+ Second body line.
45
+ }
46
+
47
+ File.open(@the_mail_file, "w") { |file|
48
+ file.print(@the_mail)
49
+ }
50
+
51
+ # Test reading in a mail file that has a bad header. This makes
52
+ # sure we consider the message header to be everything up to the
53
+ # first blank line.
54
+ @the_mail_file_2 = File.join(scratch_dir, "mail_file_2")
55
+ @the_mail_2 = %q{From: somedude@example.com
56
+ To: someotherdude@example.com
57
+ this is not a valid header
58
+ Subject: this is some mail
59
+
60
+ First body line
61
+
62
+ Second body line
63
+ }
64
+ File.open(@the_mail_file_2, "w") { |file|
65
+ file.print(@the_mail_2)
66
+ }
67
+ end
68
+
69
+ def verify_message_interface(message)
70
+ assert_not_nil(message)
71
+ assert_kind_of(RMail::Message, message)
72
+ assert_not_nil(message.header)
73
+ assert_kind_of(RMail::Header, message.header)
74
+ assert_kind_of(Enumerable, message.header,
75
+ "RMail::Message.body should be an Enumerable")
76
+ end
77
+
78
+ def test_initialize
79
+
80
+ # Make sure an empty message actually is empty
81
+ message = RMail::Message.new
82
+ verify_message_interface(message)
83
+ assert_equal(message.header.length, 0)
84
+ assert_nil(message.body)
85
+ end
86
+
87
+ def test_EQUAL
88
+ m1 = RMail::Message.new
89
+ m2 = RMail::Message.new
90
+ assert(m1 == m2)
91
+
92
+ m1.header['To'] = 'bob'
93
+ assert(m1 != m2)
94
+ m2.header['To'] = 'bob'
95
+ assert(m1 == m2)
96
+
97
+ m1.preamble = 'the preamble'
98
+ assert(m1 != m2)
99
+ m2.preamble = 'the preamble'
100
+ assert(m1 == m2)
101
+
102
+ m1.epilogue = 'the epilogue'
103
+ assert(m1 != m2)
104
+ m2.epilogue = 'the epilogue'
105
+ assert(m1 == m2)
106
+
107
+ m1.body = "the body"
108
+ assert(m1 != m2)
109
+ m2.body = "the body"
110
+ assert(m1 == m2)
111
+
112
+ m3 = RMail::Message.new
113
+ m3.add_part(m1)
114
+ m4 = RMail::Message.new
115
+ m4.add_part(m2)
116
+ assert(m3 == m4)
117
+
118
+ m1.body = 'the other body'
119
+ assert(m3 != m4)
120
+ end
121
+
122
+ def test_multipart?
123
+ message = RMail::Message.new
124
+ assert_equal(false, message.multipart?)
125
+ message.add_part("This is a part.")
126
+ assert_equal(true, message.multipart?)
127
+ message.add_part("This is another part.")
128
+ assert_equal(true, message.multipart?)
129
+ end
130
+
131
+ def test_add_part
132
+ message = RMail::Message.new
133
+ part_a = Object.new
134
+ part_b = Object.new
135
+ message.add_part(part_a)
136
+ message.add_part(part_b)
137
+ assert_same(part_a, message.part(0))
138
+ assert_same(part_b, message.part(1))
139
+ end
140
+
141
+ def test_decode
142
+ message = RMail::Message.new
143
+
144
+ all_bytes = ''
145
+ 0.upto(255) do |i|
146
+ all_bytes << i
147
+ end
148
+
149
+ # These are base64 encoded strings that hold the data we'd really
150
+ # like to test. This avoids any problems with editors,
151
+ # etc. stripping tabs or having screwed fontification, etc.
152
+ base64_data = "CkFBRUNBd1FGQmdjSUNRb0xEQTBPRHhBUkVoTVVGUllYR0JrYUd4d2RIaDhn\nSVNJakpDVW1KeWdwS2lzc0xTNHZNREV5TXpRMQpOamM0T1RvN1BEMCtQMEJC\nUWtORVJVWkhTRWxLUzB4TlRrOVFVVkpUVkZWV1YxaFpXbHRjWFY1ZllHRmlZ\nMlJsWm1kb2FXcHIKYkcxdWIzQnhjbk4wZFhaM2VIbDZlM3g5Zm4rQWdZS0Ro\nSVdHaDRpSmlvdU1qWTZQa0pHU2s1U1ZscGVZbVpxYm5KMmVuNkNoCm9xT2tw\nYWFucUttcXE2eXRycSt3c2JLenRMVzJ0N2k1dXJ1OHZiNi93TUhDdzhURnhz\nZkl5Y3JMek0zT3o5RFIwdFBVMWRiWAoyTm5hMjl6ZDN0L2c0ZUxqNU9YbTUr\nanA2dXZzN2U3djhQSHk4L1QxOXZmNCtmcjcvUDMrL3c9PQo9MDA9MDE9MDI9\nMDM9MDQ9MDU9MDY9MDc9MDgJPTBBPTBCPTBDPTBEPTBFPTBGPTEwPTExPTEy\nPTEzPTE0PTE1PTE2PTE3PTE4PQo9MTk9MUE9MUI9MUM9MUQ9MUU9MUYgISIj\nJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0zRD4/QEFCQ0RFRkdISUpLTE1O\nT1BRUlM9Cgo=\n".unpack("m*").first
153
+ qp_data = "PTAwPTAxPTAyPTAzPTA0PTA1PTA2PTA3PTA4CT0wQT0wQj0wQz0wRD0wRT0w\nRj0xMD0xMT0xMj0xMz0xND0xNT0xNj0xNz0xOD0KPTE5PTFBPTFCPTFDPTFE\nPTFFPTFGICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9M0Q+P0BBQkNE\nRUZHSElKS0xNTk9QUVJTPQpUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5v\ncHFyc3R1dnd4eXp7fH1+PTdGPTgwPTgxPTgyPTgzPTg0PTg1PTg2PTg3PTg4\nPQo9ODk9OEE9OEI9OEM9OEQ9OEU9OEY9OTA9OTE9OTI9OTM9OTQ9OTU9OTY9\nOTc9OTg9OTk9OUE9OUI9OUM9OUQ9OUU9OUY9QTA9QTE9Cj1BMj1BMz1BND1B\nNT1BNj1BNz1BOD1BOT1BQT1BQj1BQz1BRD1BRT1BRj1CMD1CMT1CMj1CMz1C\nND1CNT1CNj1CNz1COD1COT1CQT0KPUJCPUJDPUJEPUJFPUJGPUMwPUMxPUMy\nPUMzPUM0PUM1PUM2PUM3PUM4PUM5PUNBPUNCPUNDPUNEPUNFPUNGPUQwPUQx\nPUQyPUQzPQo9RDQ9RDU9RDY9RDc9RDg9RDk9REE9REI9REM9REQ9REU9REY9\nRTA9RTE9RTI9RTM9RTQ9RTU9RTY9RTc9RTg9RTk9RUE9RUI9RUM9Cj1FRD1F\nRT1FRj1GMD1GMT1GMj1GMz1GND1GNT1GNj1GNz1GOD1GOT1GQT1GQj1GQz1G\nRD1GRT1GRg==\n".unpack("m*").first
154
+
155
+ base64_message = RMail::Message.new
156
+ base64_message.header['Content-Transfer-Encoding'] = ' base64 '
157
+ base64_message.body = base64_data
158
+ message.add_part(base64_message)
159
+
160
+ qp_message = RMail::Message.new
161
+ qp_message.header['Content-Transfer-Encoding'] = ' quoted-printable '
162
+ qp_message.body = qp_data
163
+ message.add_part(qp_message)
164
+
165
+ e = assert_exception(TypeError) {
166
+ message.decode
167
+ }
168
+ assert_equal('Can not decode a multipart message.', e.message)
169
+
170
+ assert_equal(base64_message, message.part(0))
171
+ assert_equal(qp_message, message.part(1))
172
+
173
+ assert_equal(base64_data, message.part(0).body)
174
+ assert_equal(qp_data, message.part(1).body)
175
+
176
+ assert_equal(all_bytes, message.part(0).decode)
177
+ assert_equal(all_bytes, message.part(1).decode)
178
+ end
179
+
180
+ def test_part
181
+ message = RMail::Message.new
182
+
183
+ e = assert_exception(TypeError) {
184
+ message.part(0)
185
+ }
186
+ assert_equal('Can not get part on a single part message.', e.message)
187
+
188
+ first = RMail::Message.new
189
+ message.add_part(first)
190
+ second = RMail::Message.new
191
+ message.add_part(second)
192
+ assert_equal(first, message.part(0))
193
+ assert_equal(second, message.part(1))
194
+ end
195
+
196
+ def test_preamble
197
+ m = RMail::Message.new
198
+ assert_nil(m.preamble)
199
+ m.preamble = "hello bob"
200
+ assert_equal("hello bob", m.preamble)
201
+ m.preamble = "hello bob\n"
202
+ assert_equal("hello bob\n", m.preamble)
203
+ end
204
+
205
+ def test_epilogue
206
+ m = RMail::Message.new
207
+ assert_nil(m.epilogue)
208
+ m.epilogue = "hello bob"
209
+ assert_equal("hello bob", m.epilogue)
210
+ m.epilogue = "hello bob\n"
211
+ assert_equal("hello bob\n", m.epilogue)
212
+ end
213
+
214
+ def test_to_s
215
+ begin
216
+ m = RMail::Message.new
217
+ m.header['To'] = 'bob@example.net'
218
+ m.header['From'] = 'sam@example.com'
219
+ m.header['Subject'] = 'hi bob'
220
+ m.body = "Just wanted to say Hi!\n"
221
+
222
+ desired =
223
+ %q{To: bob@example.net
224
+ From: sam@example.com
225
+ Subject: hi bob
226
+
227
+ Just wanted to say Hi!
228
+ }
229
+ assert_equal(desired, m.to_s)
230
+ end
231
+
232
+ begin
233
+ m = RMail::Message.new
234
+ m.header.set_boundary('=-=-=')
235
+ part1 = RMail::Message.new
236
+ part1.body = "part1 body"
237
+ part2 = RMail::Message.new
238
+ part2.body = "part2 body"
239
+ m.add_part(part1)
240
+ m.add_part(part2)
241
+ assert_equal(%q{Content-Type: multipart/mixed; boundary="=-=-="
242
+ MIME-Version: 1.0
243
+
244
+
245
+ --=-=-=
246
+
247
+ part1 body
248
+ --=-=-=
249
+
250
+ part2 body
251
+ --=-=-=--
252
+ },
253
+ m.to_s)
254
+ end
255
+ end
256
+
257
+ end