File: testparsermultipart.rb

package info (click to toggle)
ruby-rubymail 1.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,056 kB
  • sloc: ruby: 6,061; makefile: 7
file content (205 lines) | stat: -rw-r--r-- 8,058 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/env ruby
#--
#   Copyright (C) 2002, 2004 Matt Armstrong.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

require 'test/testbase'
require 'rmail/parser/multipart'

class TestRMailParserMultipart < TestBase

  # FIXME: TODO
  # - test \n -vs- \r\n -vs \r end of line characters

  def parse_multipart(filename, boundary, chunk_size, expected_results)
    assembled = nil

    data_as_file(filename) { |f|
      parser = RMail::Parser::MultipartReader.new(f, boundary)
      parser.chunk_size = chunk_size

      results = []
      loop {
        chunk = parser.read(nil)
        puts "test: got part #{chunk.inspect}" if $DEBUG
        delimiter = parser.delimiter
        puts "test: got delimiter #{delimiter.inspect}" if $DEBUG
        if chunk
          assembled ||= ''
          assembled << chunk
        end
        if delimiter
          assembled ||= ''
          assembled << delimiter
        end
        results << [
          chunk,
          parser.preamble?,
          parser.epilogue?,
          delimiter
        ]
        unless parser.next_part
          break
        end
      }
      if expected_results != results
        puts "\nfailure for chunks size #{chunk_size.to_s}"
        pp expected_results
        pp results
      end
      assert_equal(expected_results, results,
                   "\nfile #{filename}\nchunk_size #{chunk_size}\n")
    }

    filedata = data_as_file(filename) { |f|
      f.read(nil)
    }
    filedata = nil if filedata.empty?

    assert_equal(filedata, assembled,
                 "data loss while reassembling file data")
  end

  def for_all_chunk_sizes(filename, boundary, expected_results)
    size = File.stat(data_filename(filename)).size
    (size + 10).downto(1) { |chunk_size|
      parse_multipart(filename, boundary, chunk_size, expected_results)
    }
  end

  def test_multipart_data_01
    for_all_chunk_sizes('multipart/data.1', 'aa',
                        [ [ "preamble", true, false, "\n--aa\n" ],
                          [ "part1", false, false, "\n--aa--\n" ],
                          [ "epilogue\n", false, true, nil ] ])
  end
  def test_multipart_data_02
    for_all_chunk_sizes('multipart/data.2', 'aa',
                        [ [ nil, true, false, "\n--aa\n" ],
                          [ nil, false, false, "\n--aa--\n" ],
                          [ "\n", false, true, nil ] ])
  end
  def test_multipart_data_03
    for_all_chunk_sizes('multipart/data.3', 'aa',
                        [ [ nil, true, false, "--aa\n" ],
                          [ nil, false, false, "--aa--\n" ],
                          [ "", false, true, nil ] ])
  end
  def test_multipart_data_04
    for_all_chunk_sizes('multipart/data.4', 'aa',
                        [ [ "preamble", true, false, "\n--aa--\n" ],
                          [ "epilogue\n", false, true, nil ] ])
  end
  def test_multipart_data_05
    for_all_chunk_sizes('multipart/data.5', 'aa',
                        [ [ nil, true, false, "--aa--\n" ],
                          [ "", false, true, nil ] ])
  end
  def test_multipart_data_06
    for_all_chunk_sizes('multipart/data.6', 'aa',
                        [ [ nil, true, false, "\n--aa--\n" ],
                          [ "", false, true, nil ] ])
  end
  def test_multipart_data_07
    for_all_chunk_sizes('multipart/data.7', 'aa',
                        [ [ "preamble\n", true, false, "\n--aa--\n" ],
                          [ "", false, true, nil ] ])
  end
  def test_multipart_data_08
    for_all_chunk_sizes('multipart/data.8', 'aa',
                        [ [ "preamble", true, false, "\n--aa\n" ],
                          [ "part1", false, false, "\n--aa--\n" ],
                          [ "epilogue", false, true, nil ] ])
  end
  def test_multipart_data_09
    for_all_chunk_sizes('multipart/data.9', 'aa',
                        [ [ nil, true, false, "\n--aa\n" ],
                          [ nil, false, false, "\n--aa--" ],
                          [ "", false, true, nil ] ])
  end
  def test_multipart_data_10
    for_all_chunk_sizes('multipart/data.10', 'aa',
                        [ [ nil, true, false, "--aa--" ],
                          [ "", false, true, nil ] ])
  end
  def test_multipart_data_11
    for_all_chunk_sizes('multipart/data.11', 'aa',
                        [ [ "preamble", true, false, "\n--aa\t\n" ],
                          [ "part1", false, false, "\n--aa \n" ],
                          [ "part2", false, false, "\n--aa \t \t\n" ],
                          [ "part3", false, false, "\n--aa-- \n" ],
                          [ "epilogue\n", false, true, nil ] ])
  end
  def test_multipart_data_12
    # The following from RFC2046 indicates that a delimiter existing
    # as the prefix of a line is sufficient for the line to be
    # considered a delimiter -- even if there is stuff after the
    # boundary:
    #
    #    NOTE TO IMPLEMENTORS: Boundary string comparisons must
    #    compare the boundary value with the beginning of each
    #    candidate line.  An exact match of the entire candidate line
    #    is not required; it is sufficient that the boundary appear in
    #    its entirety following the CRLF.
    #
    # However, messages in the field do not seem to comply with this
    # (namely, Eudora), so we parse more strictly.
    for_all_chunk_sizes('multipart/data.12', 'aa',
                        [[ "preamble\n--aaZ\npart1\n--aa notignored\npart2\n--aa \t \tnotignored\npart3\n--aa--notignored\nepilogue\n",
                            true,
                            false,
                            nil ]])
  end
  def test_multipart_data_13
    for_all_chunk_sizes('multipart/data.13', 'aa',
                        [ [ "preamble", true, false, "\n--aa\n" ],
                          [ "part1\n", false, false, nil ] ])
  end
  def test_multipart_data_14
    for_all_chunk_sizes('multipart/data.14', 'aa',
                        [ [ "preamble", true, false, "\n--aa\n" ],
                          [ "part1", false, false, nil ] ])
  end
  def test_multipart_data_15
    for_all_chunk_sizes('multipart/data.15', 'aa',
                        [ [ "preamble\nline1\nline2\n", true, false, nil ] ])
  end
  def test_multipart_data_16
    for_all_chunk_sizes('multipart/data.16', 'aa',
                        [ [ "preamble\nline1\nline2", true, false, nil ] ])
  end
  def test_multipart_data_17
    for_all_chunk_sizes('multipart/data.17', 'aa',
                        [ [ nil, true, false, nil ] ])
  end

  def test_s_new
    data_as_file('multipart/data.1') { |f|
      p = RMail::Parser::MultipartReader.new(f, "foo")
      assert_kind_of(RMail::Parser::MultipartReader, p)
    }
  end

end