sup 0.22.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 (99) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/checks.yml +70 -0
  3. data/.gitignore +1 -3
  4. data/.rubocop.yml +5 -0
  5. data/CONTRIBUTORS +14 -5
  6. data/Gemfile +6 -1
  7. data/History.txt +76 -0
  8. data/Manifest.txt +149 -0
  9. data/README.md +32 -5
  10. data/Rakefile +40 -1
  11. data/bin/sup +7 -5
  12. data/bin/sup-add +16 -20
  13. data/bin/sup-config +30 -44
  14. data/bin/sup-dump +2 -2
  15. data/bin/sup-import-dump +4 -4
  16. data/bin/sup-sync +3 -3
  17. data/bin/sup-sync-back-maildir +2 -2
  18. data/bin/sup-tweak-labels +5 -5
  19. data/ext/mkrf_conf_xapian.rb +10 -4
  20. data/lib/sup/colormap.rb +1 -1
  21. data/lib/sup/crypto.rb +17 -8
  22. data/lib/sup/hook.rb +9 -9
  23. data/lib/sup/index.rb +20 -7
  24. data/lib/sup/keymap.rb +1 -1
  25. data/lib/sup/logger.rb +1 -1
  26. data/lib/sup/maildir.rb +4 -4
  27. data/lib/sup/mbox.rb +4 -4
  28. data/lib/sup/message.rb +26 -15
  29. data/lib/sup/message_chunks.rb +29 -20
  30. data/lib/sup/mode.rb +1 -0
  31. data/lib/sup/modes/completion_mode.rb +0 -1
  32. data/lib/sup/modes/contact_list_mode.rb +1 -0
  33. data/lib/sup/modes/file_browser_mode.rb +2 -2
  34. data/lib/sup/modes/label_list_mode.rb +1 -1
  35. data/lib/sup/modes/reply_mode.rb +3 -1
  36. data/lib/sup/modes/search_list_mode.rb +2 -2
  37. data/lib/sup/modes/thread_index_mode.rb +1 -1
  38. data/lib/sup/modes/thread_view_mode.rb +15 -13
  39. data/lib/sup/rfc2047.rb +21 -6
  40. data/lib/sup/source.rb +9 -3
  41. data/lib/sup/textfield.rb +0 -1
  42. data/lib/sup/thread.rb +0 -1
  43. data/lib/sup/util/axe.rb +17 -0
  44. data/lib/sup/util/ncurses.rb +3 -3
  45. data/lib/sup/util.rb +42 -67
  46. data/lib/sup/version.rb +10 -1
  47. data/lib/sup.rb +13 -8
  48. data/man/sup-add.1 +34 -55
  49. data/man/sup-config.1 +23 -36
  50. data/man/sup-dump.1 +25 -35
  51. data/man/sup-import-dump.1 +33 -54
  52. data/man/sup-psych-ify-config-files.1 +25 -34
  53. data/man/sup-recover-sources.1 +34 -49
  54. data/man/sup-sync-back-maildir.1 +39 -60
  55. data/man/sup-sync.1 +49 -79
  56. data/man/sup-tweak-labels.1 +35 -58
  57. data/man/sup.1 +50 -62
  58. data/sup.gemspec +12 -9
  59. data/test/dummy_source.rb +21 -15
  60. data/test/fixtures/embedded-message.eml +34 -0
  61. data/test/fixtures/mailing-list-header.eml +80 -0
  62. data/test/fixtures/non-ascii-header-in-nested-message.eml +36 -0
  63. data/test/fixtures/non-ascii-header.eml +8 -0
  64. data/test/fixtures/rfc2047-header-encoding.eml +15 -0
  65. data/test/fixtures/text-attachments-with-charset.eml +60 -0
  66. data/test/fixtures/utf8-header.eml +17 -0
  67. data/test/fixtures/zimbra-quote-with-bottom-post.eml +27 -0
  68. data/test/gnupg_test_home/gpg.conf +2 -1
  69. data/test/gnupg_test_home/private-keys-v1.d/306D2EE90FF0014B5B9FD07E265C751791674140.key +0 -0
  70. data/test/gnupg_test_home/pubring.gpg +0 -0
  71. data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
  72. data/test/gnupg_test_home/receiver_secring.gpg +0 -0
  73. data/test/gnupg_test_home/regen_keys.sh +69 -18
  74. data/test/gnupg_test_home/secring.gpg +0 -0
  75. data/test/gnupg_test_home/sup-test-2@foo.bar.asc +20 -22
  76. data/test/integration/test_mbox.rb +1 -1
  77. data/test/integration/test_sup-add.rb +83 -0
  78. data/test/test_crypto.rb +46 -0
  79. data/test/test_header_parsing.rb +9 -1
  80. data/test/test_helper.rb +7 -4
  81. data/test/test_message.rb +188 -22
  82. data/test/test_messages_dir.rb +13 -15
  83. data/test/unit/test_horizontal_selector.rb +4 -4
  84. data/test/unit/test_locale_fiddler.rb +1 -1
  85. data/test/unit/util/test_query.rb +10 -4
  86. data/test/unit/util/test_string.rb +9 -3
  87. data/test/unit/util/test_uri.rb +2 -2
  88. metadata +93 -51
  89. data/.travis.yml +0 -13
  90. data/bin/sup-psych-ify-config-files +0 -21
  91. data/test/gnupg_test_home/key1.gen +0 -15
  92. data/test/gnupg_test_home/key2.gen +0 -15
  93. data/test/gnupg_test_home/key_ecc.gen +0 -13
  94. data/test/gnupg_test_home/private-keys-v1.d/719C7455A7169C6EE8819C6E91002E4F9DD00A65.key +0 -1
  95. data/test/gnupg_test_home/private-keys-v1.d/8A130806A754AA29D59487D76BD355040D9F26C0.key +0 -0
  96. data/test/gnupg_test_home/private-keys-v1.d/B7AA46B22BD8A6AD1B4F266C19A3B124A32DDD71.key +0 -0
  97. data/test/gnupg_test_home/private-keys-v1.d/FA64ACD7CC871371BDF57285A6CDF0E618827783.key +0 -0
  98. data/test/integration/test_label_service.rb +0 -18
  99. data/test/test_yaml_migration.rb +0 -85
data/test/test_message.rb CHANGED
@@ -21,10 +21,8 @@ class TestMessage < Minitest::Test
21
21
  end
22
22
 
23
23
  def test_simple_message
24
- message = fixture('simple-message.eml')
25
-
26
24
  source = DummySource.new("sup-test://test_simple_message")
27
- source.messages = [ message ]
25
+ source.messages = [ fixture_path('simple-message.eml') ]
28
26
  source_info = 0
29
27
 
30
28
  sup_message = Message.build_from_source(source, source_info)
@@ -99,10 +97,8 @@ class TestMessage < Minitest::Test
99
97
  end
100
98
 
101
99
  def test_multipart_message
102
- message = fixture('multi-part.eml')
103
-
104
100
  source = DummySource.new("sup-test://test_multipart_message")
105
- source.messages = [ message ]
101
+ source.messages = [ fixture_path('multi-part.eml') ]
106
102
  source_info = 0
107
103
 
108
104
  sup_message = Message.build_from_source(source, source_info)
@@ -126,10 +122,8 @@ class TestMessage < Minitest::Test
126
122
  end
127
123
 
128
124
  def test_broken_message_1
129
- message = fixture('missing-from-to.eml')
130
-
131
125
  source = DummySource.new("sup-test://test_broken_message_1")
132
- source.messages = [ message ]
126
+ source.messages = [ fixture_path('missing-from-to.eml') ]
133
127
  source_info = 0
134
128
 
135
129
  sup_message = Message.build_from_source(source, source_info)
@@ -150,10 +144,8 @@ class TestMessage < Minitest::Test
150
144
  end
151
145
 
152
146
  def test_broken_message_2
153
- message = fixture('no-body.eml')
154
-
155
147
  source = DummySource.new("sup-test://test_broken_message_1")
156
- source.messages = [ message ]
148
+ source.messages = [ fixture_path('no-body.eml') ]
157
149
  source_info = 0
158
150
 
159
151
  sup_message = Message.build_from_source(source, source_info)
@@ -167,10 +159,8 @@ class TestMessage < Minitest::Test
167
159
  end
168
160
 
169
161
  def test_multipart_message_2
170
- message = fixture('multi-part-2.eml')
171
-
172
162
  source = DummySource.new("sup-test://test_multipart_message_2")
173
- source.messages = [ message ]
163
+ source.messages = [ fixture_path('multi-part-2.eml') ]
174
164
  source_info = 0
175
165
 
176
166
  sup_message = Message.build_from_source(source, source_info)
@@ -178,14 +168,61 @@ class TestMessage < Minitest::Test
178
168
 
179
169
  chunks = sup_message.load_from_source! # read the message body chunks
180
170
 
181
- # TODO: Add more asserts
171
+ assert_equal(1, chunks.length)
172
+ assert(chunks[0].is_a? Redwood::Chunk::Attachment)
182
173
  end
183
174
 
184
- def test_blank_header_lines
185
- message = fixture('blank-header-fields.eml')
175
+ def test_text_attachment_decoding
176
+ source = DummySource.new("sup-test://test_text_attachment_decoding")
177
+ source.messages = [ fixture_path('text-attachments-with-charset.eml') ]
178
+ source_info = 0
179
+
180
+ sup_message = Message.build_from_source(source, source_info)
181
+ sup_message.load_from_source!
182
+
183
+ chunks = sup_message.load_from_source!
184
+ assert_equal(7, chunks.length)
185
+ assert(chunks[0].is_a? Redwood::Chunk::Text)
186
+ ## The first attachment declares charset=us-ascii
187
+ assert(chunks[1].is_a? Redwood::Chunk::Attachment)
188
+ assert_equal(["This is ASCII"], chunks[1].lines)
189
+ ## The second attachment declares charset=koi8-r and has some Cyrillic
190
+ assert(chunks[2].is_a? Redwood::Chunk::Attachment)
191
+ assert_equal(["\u041f\u0440\u0438\u0432\u0435\u0442"], chunks[2].lines)
192
+ ## The third attachment declares charset=utf-8 and has an emoji
193
+ assert(chunks[3].is_a? Redwood::Chunk::Attachment)
194
+ assert_equal(["\u{1f602}"], chunks[3].lines)
195
+ ## The fourth attachment declares no charset and has a non-ASCII byte,
196
+ ## which will be replaced with U+FFFD REPLACEMENT CHARACTER
197
+ assert(chunks[4].is_a? Redwood::Chunk::Attachment)
198
+ assert_equal(["Embedded\ufffdgarbage"], chunks[4].lines)
199
+ ## The fifth attachment has an invalid charset, which should still
200
+ ## be handled gracefully
201
+ assert(chunks[5].is_a? Redwood::Chunk::Attachment)
202
+ assert_equal(["Example invalid charset"], chunks[5].lines)
203
+ ## The sixth attachment is UTF-7 encoded
204
+ assert(chunks[6].is_a? Redwood::Chunk::Attachment)
205
+ assert_equal(["This is ✨UTF-7✨"], chunks[6].lines)
206
+ end
207
+
208
+ def test_mailing_list_header
209
+ source = DummySource.new("sup-test://test_mailing_list_header")
210
+ source.messages = [ fixture_path('mailing-list-header.eml') ]
211
+ source_info = 0
186
212
 
213
+ sup_message = Message.build_from_source(source, source_info)
214
+ sup_message.load_from_source!
215
+
216
+ assert(sup_message.list_subscribe.nil?)
217
+ assert_equal("<https://lists.openembedded.org/g/openembedded-devel/unsub>",
218
+ sup_message.list_unsubscribe)
219
+ assert_equal("openembedded-devel@lists.openembedded.org", sup_message.list_address.email)
220
+ assert_equal("openembedded-devel", sup_message.list_address.name)
221
+ end
222
+
223
+ def test_blank_header_lines
187
224
  source = DummySource.new("sup-test://test_blank_header_lines")
188
- source.messages = [ message ]
225
+ source.messages = [ fixture_path('blank-header-fields.eml') ]
189
226
  source_info = 0
190
227
 
191
228
  sup_message = Message.build_from_source(source, source_info)
@@ -203,11 +240,113 @@ class TestMessage < Minitest::Test
203
240
 
204
241
  end
205
242
 
206
- def test_malicious_attachment_names
207
- message = fixture('malicious-attachment-names.eml')
243
+ def test_rfc2047_header_encoding
244
+ source = DummySource.new("sup-test://test_rfc2047_header_encoding")
245
+ source.messages = [ fixture_path("rfc2047-header-encoding.eml") ]
246
+ source_info = 0
247
+
248
+ sup_message = Message.build_from_source(source, source_info)
249
+ sup_message.load_from_source!
250
+
251
+ assert_equal("Hans Martin Djupvik, Ingrid Bø, Ирина Сидорова, " +
252
+ "Jesper Berg, Frida Engø " +
253
+ "bad: =?UTF16?q?badcharsetname?==?US-ASCII?b?/w?=" +
254
+ "=?UTF-7?Q?=41=6D=65=72=69=63=61=E2=80=99=73?=",
255
+ sup_message.subj)
256
+ end
257
+
258
+ def test_nonascii_header
259
+ ## Spammers sometimes send invalid high bytes in the headers.
260
+ ## They will be replaced with U+FFFD REPLACEMENT CHARACTER.
261
+ source = DummySource.new("sup-test://test_nonascii_header")
262
+ source.messages = [ fixture_path("non-ascii-header.eml") ]
263
+ source_info = 0
264
+
265
+ sup_message = Message.build_from_source(source, source_info)
266
+ sup_message.load_from_source!
208
267
 
268
+ assert_equal("SPAM \ufffd", sup_message.from.name)
269
+ assert_equal("spammer@example.com", sup_message.from.email)
270
+ assert_equal("spam \ufffd spam", sup_message.subj)
271
+ end
272
+
273
+ def test_utf8_header
274
+ ## UTF-8 is allowed in header values according to RFC6532.
275
+ source = DummySource.new("sup-test://test_utf8_header")
276
+ source.messages = [ fixture_path("utf8-header.eml") ]
277
+ source_info = 0
278
+
279
+ sup_message = Message.build_from_source(source, source_info)
280
+ sup_message.load_from_source!
281
+
282
+ assert_equal(Encoding::UTF_8, sup_message.subj.encoding)
283
+ assert_equal("LibraryThing: State of the Thing — January", sup_message.subj)
284
+ end
285
+
286
+ def test_nonascii_header_in_nested_message
287
+ source = DummySource.new("sup-test://test_nonascii_header_in_nested_message")
288
+ source.messages = [ fixture_path("non-ascii-header-in-nested-message.eml") ]
289
+ source_info = 0
290
+
291
+ sup_message = Message.build_from_source(source, source_info)
292
+ chunks = sup_message.load_from_source!
293
+
294
+ assert_equal(3, chunks.length)
295
+
296
+ assert(chunks[0].is_a? Redwood::Chunk::Text)
297
+
298
+ assert(chunks[1].is_a? Redwood::Chunk::EnclosedMessage)
299
+ assert_equal(4, chunks[1].lines.length)
300
+ assert_equal("From: SPAM \ufffd <spammer@example.com>", chunks[1].lines[0])
301
+ assert_equal("To: enclosed <enclosed@example.invalid>", chunks[1].lines[1])
302
+ assert_equal("Subject: spam \ufffd spam", chunks[1].lines[3])
303
+
304
+ assert(chunks[2].is_a? Redwood::Chunk::Text)
305
+ assert_equal(1, chunks[2].lines.length)
306
+ assert_equal("This is a spam.", chunks[2].lines[0])
307
+ end
308
+
309
+ def test_embedded_message
310
+ source = DummySource.new("sup-test://test_embedded_message")
311
+ source.messages = [ fixture_path("embedded-message.eml") ]
312
+ source_info = 0
313
+
314
+ sup_message = Message.build_from_source(source, source_info)
315
+
316
+ chunks = sup_message.load_from_source!
317
+ assert_equal(3, chunks.length)
318
+
319
+ assert_equal("sender@example.com", sup_message.from.email)
320
+ assert_equal("Sender", sup_message.from.name)
321
+ assert_equal(1, sup_message.to.length)
322
+ assert_equal("recipient@example.invalid", sup_message.to[0].email)
323
+ assert_equal("recipient", sup_message.to[0].name)
324
+ assert_equal("Email with embedded message", sup_message.subj)
325
+
326
+ assert(chunks[0].is_a? Redwood::Chunk::Text)
327
+ assert_equal("Example outer message.", chunks[0].lines[0])
328
+ assert_equal("Example second line.", chunks[0].lines[1])
329
+
330
+ assert(chunks[1].is_a? Redwood::Chunk::EnclosedMessage)
331
+ assert_equal(4, chunks[1].lines.length)
332
+ assert_equal("From: Embed sender <embed@example.com>", chunks[1].lines[0])
333
+ assert_equal("To: rcpt2 <rcpt2@example.invalid>", chunks[1].lines[1])
334
+ assert_equal("Date: ", chunks[1].lines[2][0..5])
335
+ assert_equal(
336
+ Time.rfc2822("Wed, 15 Jul 2020 12:34:56 +0000"),
337
+ Time.rfc2822(chunks[1].lines[2][6..-1])
338
+ )
339
+ assert_equal("Subject: Embedded subject line", chunks[1].lines[3])
340
+
341
+ assert(chunks[2].is_a? Redwood::Chunk::Text)
342
+ assert_equal(2, chunks[2].lines.length)
343
+ assert_equal("Example embedded message.", chunks[2].lines[0])
344
+ assert_equal("Second line.", chunks[2].lines[1])
345
+ end
346
+
347
+ def test_malicious_attachment_names
209
348
  source = DummySource.new("sup-test://test_blank_header_lines")
210
- source.messages = [ message ]
349
+ source.messages = [ fixture_path('malicious-attachment-names.eml') ]
211
350
  source_info = 0
212
351
 
213
352
  sup_message = Message.build_from_source(source, source_info)
@@ -225,6 +364,33 @@ class TestMessage < Minitest::Test
225
364
  # TODO: test different quoting styles, see that they are all divided
226
365
  # to chunks properly
227
366
 
367
+ def test_zimbra_quote_with_bottom_post
368
+ # Zimbra does an Outlook-style "Original Message" delimiter and then *also*
369
+ # prefixes each quoted line with a > marker. That's okay until the sender
370
+ # tries to do the right thing and reply after the quote.
371
+ # In this case we want to just look at the > markers when determining where
372
+ # the quoted chunk ends.
373
+ source = DummySource.new("sup-test://test_zimbra_quote_with_bottom_post")
374
+ source.messages = [ fixture_path('zimbra-quote-with-bottom-post.eml') ]
375
+ source_info = 0
376
+
377
+ sup_message = Message.build_from_source(source, source_info)
378
+ chunks = sup_message.load_from_source!
379
+
380
+ assert_equal(3, chunks.length)
381
+
382
+ # TODO this chunk should ideally be part of the quote chunk after it.
383
+ assert(chunks[0].is_a? Redwood::Chunk::Text)
384
+ assert_equal(1, chunks[0].lines.length)
385
+ assert_equal("----- Original Message -----", chunks[0].lines.first)
386
+
387
+ assert(chunks[1].is_a? Redwood::Chunk::Quote)
388
+
389
+ assert(chunks[2].is_a? Redwood::Chunk::Text)
390
+ assert_equal(3, chunks[2].lines.length)
391
+ assert_equal("This is the reply from the Zimbra user.",
392
+ chunks[2].lines[2])
393
+ end
228
394
  end
229
395
 
230
396
  end
@@ -13,19 +13,22 @@ class TestMessagesDir < ::Minitest::Test
13
13
  def setup
14
14
  @path = Dir.mktmpdir
15
15
  Redwood::HookManager.init File.join(@path, 'hooks')
16
+ @log = StringIO.new
17
+ Redwood::Logger.add_sink @log
18
+ Redwood::Logger.remove_sink $stderr
16
19
  end
17
20
 
18
21
  def teardown
22
+ Redwood::Logger.clear!
23
+ Redwood::Logger.remove_sink @log
24
+ Redwood::Logger.add_sink $stderr
19
25
  Redwood::HookManager.deinstantiate!
20
26
  FileUtils.rm_r @path
21
27
  end
22
28
 
23
29
  def test_binary_content_transfer_encoding
24
- message = ''
25
- File.open('test/fixtures/binary-content-transfer-encoding-2.eml') { |f| message = f.read }
26
-
27
30
  source = DummySource.new("sup-test://test_messages")
28
- source.messages = [ message ]
31
+ source.messages = [ fixture_path('binary-content-transfer-encoding-2.eml') ]
29
32
  source_info = 0
30
33
 
31
34
  sup_message = Message.build_from_source(source, source_info)
@@ -41,7 +44,6 @@ class TestMessagesDir < ::Minitest::Test
41
44
  assert_equal("Important", subj)
42
45
 
43
46
  chunks = sup_message.load_from_source!
44
- indexable_chunks = sup_message.indexable_chunks
45
47
 
46
48
  # there should be only one chunk
47
49
  #assert_equal(1, chunks.length)
@@ -50,14 +52,13 @@ class TestMessagesDir < ::Minitest::Test
50
52
 
51
53
  # lines should contain an error message
52
54
  assert (lines.join.include? "An error occurred while loading this message."), "This message should not load successfully"
55
+
56
+ assert_match(/WARNING: problem reading message/, @log.string)
53
57
  end
54
58
 
55
59
  def test_bad_content_transfer_encoding
56
- message = ''
57
- File.open('test/fixtures/bad-content-transfer-encoding-1.eml') { |f| message = f.read }
58
-
59
60
  source = DummySource.new("sup-test://test_messages")
60
- source.messages = [ message ]
61
+ source.messages = [ fixture_path('bad-content-transfer-encoding-1.eml') ]
61
62
  source_info = 0
62
63
 
63
64
  sup_message = Message.build_from_source(source, source_info)
@@ -73,7 +74,6 @@ class TestMessagesDir < ::Minitest::Test
73
74
  assert_equal("Content-Transfer-Encoding:-bug in sup", subj)
74
75
 
75
76
  chunks = sup_message.load_from_source!
76
- indexable_chunks = sup_message.indexable_chunks
77
77
 
78
78
  # there should be only one chunk
79
79
  #assert_equal(1, chunks.length)
@@ -82,14 +82,13 @@ class TestMessagesDir < ::Minitest::Test
82
82
 
83
83
  # lines should contain an error message
84
84
  assert (lines.join.include? "An error occurred while loading this message."), "This message should not load successfully"
85
+
86
+ assert_match(/WARNING: problem reading message/, @log.string)
85
87
  end
86
88
 
87
89
  def test_missing_line
88
- message = ''
89
- File.open('test/fixtures/missing-line.eml') { |f| message = f.read }
90
-
91
90
  source = DummySource.new("sup-test://test_messages")
92
- source.messages = [ message ]
91
+ source.messages = [ fixture_path('missing-line.eml') ]
93
92
  source_info = 0
94
93
 
95
94
  sup_message = Message.build_from_source(source, source_info)
@@ -105,7 +104,6 @@ class TestMessagesDir < ::Minitest::Test
105
104
  assert_equal("Encoding bug", subj)
106
105
 
107
106
  chunks = sup_message.load_from_source!
108
- indexable_chunks = sup_message.indexable_chunks
109
107
 
110
108
  # there should be only one chunk
111
109
  #assert_equal(1, chunks.length)
@@ -13,18 +13,18 @@ describe Redwood::HorizontalSelector do
13
13
 
14
14
  it "init w/ the first value selected" do
15
15
  first_value = values.first
16
- @selector.val.must_equal first_value
16
+ assert_equal first_value, @selector.val
17
17
  end
18
18
 
19
19
  it "stores value for selection" do
20
20
  second_value = values[1]
21
21
  @selector.set_to second_value
22
- @selector.val.must_equal second_value
22
+ assert_equal second_value, @selector.val
23
23
  end
24
24
 
25
25
  describe "for unknown value" do
26
26
  it "cannot select unknown value" do
27
- @selector.wont_be :can_set_to?, strange_value
27
+ assert_equal false, @selector.can_set_to?(strange_value)
28
28
  end
29
29
 
30
30
  it "refuses selecting unknown value" do
@@ -34,7 +34,7 @@ describe Redwood::HorizontalSelector do
34
34
  @selector.set_to strange_value
35
35
  end
36
36
 
37
- @selector.val.must_equal old_value
37
+ assert_equal old_value, @selector.val
38
38
  end
39
39
  end
40
40
  end
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
  require 'sup/util/locale_fiddler'
3
3
 
4
- class TestFiddle < ::Minitest::Unit::TestCase
4
+ class TestFiddle < Minitest::Test
5
5
  # TODO this is a silly test
6
6
  def test_fiddle_set_locale
7
7
  before = LocaleDummy.setlocale(6, nil).to_s
@@ -24,9 +24,14 @@ describe Redwood::Util::Query do
24
24
  query = Xapian::Query.new msg
25
25
  life = 'hæi'
26
26
 
27
- # this is now possibly UTF-8 string with possibly invalid chars
28
- assert_raises Redwood::Util::Query::QueryDescriptionError do
29
- desc = Redwood::Util::Query.describe (query)
27
+ if query.description.force_encoding("UTF-8").valid_encoding?
28
+ # xapian 1.4 internally handles this bad input
29
+ assert true
30
+ else
31
+ # xapian 1.2 doesn't handle this bad input, so we do
32
+ assert_raises Redwood::Util::Query::QueryDescriptionError do
33
+ _desc = Redwood::Util::Query.describe (query)
34
+ end
30
35
  end
31
36
 
32
37
  assert_raises Encoding::CompatibilityError do
@@ -40,7 +45,8 @@ describe Redwood::Util::Query do
40
45
 
41
46
  desc = Redwood::Util::Query.describe(query, "invalid query")
42
47
 
43
- assert_equal("invalid query", desc)
48
+ assert desc.force_encoding("UTF-8").valid_encoding?
49
+
44
50
  end
45
51
  end
46
52
  end
@@ -11,12 +11,14 @@ describe "Sup's String extension" do
11
11
  ['some words', 10,],
12
12
  ['中文', 4,],
13
13
  ['ä', 1,],
14
+ ['😱', 2],
15
+ #['🏳️‍🌈', 2], # Emoji ZWJ sequence not yet supported (see PR #563)
14
16
  ]
15
17
  end
16
18
 
17
19
  it "calculates display length of a string" do
18
20
  data.each do |(str, length)|
19
- str.display_length.must_equal length
21
+ assert_equal length, str.display_length
20
22
  end
21
23
  end
22
24
  end
@@ -27,12 +29,14 @@ describe "Sup's String extension" do
27
29
  ['some words', 6, 'some w'],
28
30
  ['中文', 2, '中'],
29
31
  ['älpha', 3, 'älp'],
32
+ ['😱😱', 2, '😱'],
33
+ #['🏳️‍🌈', 2, '🏳️‍🌈'], # Emoji ZWJ sequence not yet supported (see PR #563)
30
34
  ]
31
35
  end
32
36
 
33
37
  it "slices string by display length" do
34
38
  data.each do |(str, length, sliced)|
35
- str.slice_by_display_length(length).must_equal sliced
39
+ assert_equal sliced, str.slice_by_display_length(length)
36
40
  end
37
41
  end
38
42
  end
@@ -45,12 +49,14 @@ describe "Sup's String extension" do
45
49
  ['中文', 2, ['中', '文']],
46
50
  ['中文', 5, ['中文']],
47
51
  ['älpha', 3, ['älp', 'ha']],
52
+ ['😱😱', 2, ['😱', '😱']],
53
+ #['🏳️‍🌈🏳️‍🌈', 2, ['🏳️‍🌈', '🏳️‍🌈']], # Emoji ZWJ sequence not yet supported (see PR #563)
48
54
  ]
49
55
  end
50
56
 
51
57
  it "wraps string by display length" do
52
58
  data.each do |(str, length, wrapped)|
53
- str.wrap(length).must_equal wrapped
59
+ assert_equal wrapped, str.wrap(length)
54
60
  end
55
61
  end
56
62
  end
@@ -7,13 +7,13 @@ describe Redwood::Util::Uri do
7
7
  it "builds uri from hash" do
8
8
  components = {:path => "/var/mail/foo", :scheme => "mbox"}
9
9
  uri = Redwood::Util::Uri.build(components)
10
- uri.to_s.must_equal "mbox:/var/mail/foo"
10
+ assert_equal "mbox:/var/mail/foo", uri.to_s
11
11
  end
12
12
 
13
13
  it "expands ~ in path" do
14
14
  components = {:path => "~/foo", :scheme => "maildir"}
15
15
  uri = Redwood::Util::Uri.build(components)
16
- uri.to_s.must_equal "maildir:#{ENV["HOME"]}/foo"
16
+ assert_equal "maildir:#{ENV["HOME"]}/foo", uri.to_s
17
17
  end
18
18
  end
19
19
  end