sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 8ce82d84eef45ed3de89ea90f00abc349fca19cd
parent de922cf7c20922286b5efe964c39dd57ab7e5771
Author: Dan Callaghan <djc@djc.id.au>
Date:   Sun, 12 Jul 2020 17:19:09 +1000

tests: refactor DummySource to read directly from files

This patch changes DummySource to follow a similar pattern to the
Maildir source, which works by opening the files directly for parsing.
Previously DummySource was parsing strings fed through StringIO,
which was introducing extra (or at least, different) complications with
encoding. See for example the comments in issue #205.

Diffstat:
M test/dummy_source.rb | 36 +++++++++++++++++++++---------------
M test/test_helper.rb | 12 +++++++-----
M test/test_message.rb | 40 ++++++++++------------------------------
M test/test_messages_dir.rb | 15 +++------------
4 files changed, 41 insertions(+), 62 deletions(-)
diff --git a/test/dummy_source.rb b/test/dummy_source.rb
@@ -25,32 +25,38 @@ class DummySource < Source
     return @messages ? @messages.length - 1 : 0
   end
 
-  def load_header offset
-    Source.parse_raw_email_header StringIO.new(raw_header(offset))
+  def with_file_for id
+    fn = @messages[id]
+    File.open(fn, 'rb') { |f| yield f }
   end
 
-  def load_message offset
-    RMail::Parser.read raw_message(offset)
+  def load_header id
+    with_file_for(id) { |f| parse_raw_email_header f }
   end
 
-  def raw_header offset
+  def load_message id
+    with_file_for(id) { |f| RMail::Parser.read f }
+  end
+
+  def raw_header id
     ret = ""
-    f = StringIO.new(@messages[offset])
-    until f.eof? || (l = f.gets) =~ /^$/
-      ret += l
+    with_file_for(id) do |f|
+      until f.eof? || (l = f.gets) =~ /^$/
+        ret += l
+      end
     end
     ret
   end
 
-  def raw_message offset
-    @messages[offset]
+  def raw_message id
+    with_file_for(id) { |f| f.read }
   end
 
-  def each_raw_message_line offset
-    ret = ""
-    f = StringIO.new(@messages[offset])
-    until f.eof?
-      yield f.gets
+  def each_raw_message_line id
+    with_file_for(id) do |f|
+      until f.eof?
+        yield f.gets
+      end
     end
   end
 end
diff --git a/test/test_helper.rb b/test/test_helper.rb
@@ -2,9 +2,12 @@ require "rubygems" rescue nil
 require 'minitest/autorun'
 require "rr"
 
-def fixture(filename)
+def fixture_path(filename)
+  File.expand_path("../fixtures/#{filename}", __FILE__)
+end
+
+def fixture_contents(filename)
   file = ''
-  path = File.expand_path("../fixtures/#{filename}", __FILE__)
-  File.open(path) { |io| file = io.read }
+  File.open(fixture_path(filename)) { |io| file = io.read }
   file
-end
-\ No newline at end of file
+end
diff --git a/test/test_message.rb b/test/test_message.rb
@@ -21,10 +21,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_simple_message
-    message = fixture('simple-message.eml')
-
     source = DummySource.new("sup-test://test_simple_message")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('simple-message.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -99,10 +97,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_multipart_message
-    message = fixture('multi-part.eml')
-
     source = DummySource.new("sup-test://test_multipart_message")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('multi-part.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -126,10 +122,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_broken_message_1
-    message = fixture('missing-from-to.eml')
-
     source = DummySource.new("sup-test://test_broken_message_1")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('missing-from-to.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -150,10 +144,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_broken_message_2
-    message = fixture('no-body.eml')
-
     source = DummySource.new("sup-test://test_broken_message_1")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('no-body.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -167,10 +159,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_multipart_message_2
-    message = fixture('multi-part-2.eml')
-
     source = DummySource.new("sup-test://test_multipart_message_2")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('multi-part-2.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -182,10 +172,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_text_attachment_decoding
-    message = fixture('text-attachments-with-charset.eml')
-
     source = DummySource.new("sup-test://test_text_attachment_decoding")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('text-attachments-with-charset.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -210,10 +198,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_mailing_list_header
-    message = fixture('mailing-list-header.eml')
-
     source = DummySource.new("sup-test://test_mailing_list_header")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('mailing-list-header.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -227,10 +213,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_blank_header_lines
-    message = fixture('blank-header-fields.eml')
-
     source = DummySource.new("sup-test://test_blank_header_lines")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('blank-header-fields.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -249,10 +233,8 @@ class TestMessage < Minitest::Test
   end
 
   def test_malicious_attachment_names
-    message = fixture('malicious-attachment-names.eml')
-
     source = DummySource.new("sup-test://test_blank_header_lines")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('malicious-attachment-names.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -276,10 +258,8 @@ class TestMessage < Minitest::Test
     # tries to do the right thing and reply after the quote.
     # In this case we want to just look at the > markers when determining where
     # the quoted chunk ends.
-    message = fixture('zimbra-quote-with-bottom-post.eml')
-
     source = DummySource.new("sup-test://test_zimbra_quote_with_bottom_post")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('zimbra-quote-with-bottom-post.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
diff --git a/test/test_messages_dir.rb b/test/test_messages_dir.rb
@@ -21,11 +21,8 @@ class TestMessagesDir < ::Minitest::Test
   end
 
   def test_binary_content_transfer_encoding
-    message = ''
-    File.open('test/fixtures/binary-content-transfer-encoding-2.eml') { |f| message = f.read }
-
     source = DummySource.new("sup-test://test_messages")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('binary-content-transfer-encoding-2.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -53,11 +50,8 @@ class TestMessagesDir < ::Minitest::Test
   end
 
   def test_bad_content_transfer_encoding
-    message = ''
-    File.open('test/fixtures/bad-content-transfer-encoding-1.eml') { |f| message = f.read }
-
     source = DummySource.new("sup-test://test_messages")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('bad-content-transfer-encoding-1.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)
@@ -85,11 +79,8 @@ class TestMessagesDir < ::Minitest::Test
   end
 
   def test_missing_line
-    message = ''
-    File.open('test/fixtures/missing-line.eml') { |f| message = f.read }
-
     source = DummySource.new("sup-test://test_messages")
-    source.messages = [ message ]
+    source.messages = [ fixture_path('missing-line.eml') ]
     source_info = 0
 
     sup_message = Message.build_from_source(source, source_info)