#!/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 'tests/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
syntax highlighted by Code2HTML, v. 0.9.1