bzip2-ffi 1.0.0 → 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.
data/test/reader_test.rb CHANGED
@@ -1,12 +1,44 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  require 'fileutils'
2
- require 'pathname'
3
5
  require 'stringio'
4
- require 'test_helper'
5
6
  require 'tmpdir'
7
+ require_relative 'test_helper'
6
8
 
7
9
  class ReaderTest < Minitest::Test
8
- class StringIOWithoutSeek < StringIO
9
- undef_method :seek
10
+ class StringIOWithSeekCount < StringIO
11
+ def seek_count
12
+ instance_variable_defined?(:@seek_count) ? @seek_count : 0
13
+ end
14
+
15
+ def seek(amount, whence = IO::SEEK_SET)
16
+ if instance_variable_defined?(:@seek_count)
17
+ @seek_count += 1
18
+ else
19
+ @seek_count = 1
20
+ end
21
+
22
+ super
23
+ end
24
+ end
25
+
26
+ class << self
27
+ def read_size_and_use_outbuf_combinations(fixture)
28
+ [16, 1024, 16384, File.size(fixture_path(fixture)), nil].each do |read_size|
29
+ [false, true].each do |use_outbuf|
30
+ yield read_size, use_outbuf, "#{read_size ? "_with_read_size_#{read_size}" : ''}#{use_outbuf ? '_using_outbuf' : ''}"
31
+ end
32
+ end
33
+ end
34
+
35
+ def bzip_fixture_tests(name, fixture)
36
+ read_size_and_use_outbuf_combinations(fixture) do |read_size, use_outbuf, description|
37
+ define_method("test_fixture_#{name}#{description}") do
38
+ bzip_test(fixture, read_size: read_size, use_outbuf: use_outbuf)
39
+ end
40
+ end
41
+ end
10
42
  end
11
43
 
12
44
  def setup
@@ -18,14 +50,24 @@ class ReaderTest < Minitest::Test
18
50
  Bzip2::FFI::Reader.test_after_open_file_last_io = nil
19
51
  end
20
52
 
21
- def compare_fixture(reader, fixture, read_size = nil, use_outbuf = nil)
53
+ def compare_fixture(reader, fixture, read_size = nil, use_outbuf = nil, limit = nil)
22
54
  File.open(fixture_path(fixture), 'rb') do |input|
23
55
  if read_size
56
+ count = 0
24
57
  loop do
25
- buffer = input.read(read_size)
26
-
27
- if use_outbuf
28
- outbuf = 'outbuf'
58
+ next_read_size = limit ? [limit - count, read_size].min : read_size
59
+ buffer = input.read(next_read_size)
60
+
61
+ # Note that reader.eof? may not be true if buffer is nil -
62
+ # BZ2_bzDecompress may not yet have had a chance to indicate
63
+ # BZ_STREAM_END.
64
+ if (buffer)
65
+ assert_equal(false, reader.eof?)
66
+ assert_equal(false, reader.eof)
67
+ end
68
+
69
+ if use_outbuf
70
+ outbuf = 'outbuf'.dup
29
71
  decompressed = reader.read(read_size, outbuf)
30
72
 
31
73
  if decompressed
@@ -37,30 +79,42 @@ class ReaderTest < Minitest::Test
37
79
  decompressed = reader.read(read_size)
38
80
  end
39
81
 
82
+ assert_equal(input.tell, reader.tell)
83
+ assert_equal(input.pos, reader.pos)
84
+
40
85
  if buffer
86
+ refute_nil(decompressed)
41
87
  assert_same(Encoding::ASCII_8BIT, decompressed.encoding)
42
88
  assert_equal(buffer, decompressed)
89
+ count += buffer.bytesize
90
+ break if limit && count >= limit
43
91
  else
44
92
  assert_nil(decompressed)
45
93
  break
46
94
  end
47
- end
95
+ end
48
96
  else
49
97
  buffer = input.read
98
+ buffer = buffer[0, limit] if limit
50
99
 
51
100
  if use_outbuf
52
- outbuf = 'outbuf'
101
+ outbuf = 'outbuf'.dup
53
102
  decompressed = reader.read(nil, outbuf)
54
103
  assert_same(outbuf, decompressed)
55
104
  else
56
105
  decompressed = reader.read
57
106
  end
58
-
107
+
108
+ assert_equal(buffer.bytesize, reader.tell)
109
+ assert_equal(buffer.bytesize, reader.pos)
110
+
59
111
  refute_nil(decompressed)
60
112
  assert_same(Encoding::ASCII_8BIT, decompressed.encoding)
61
- assert_equal(buffer, decompressed)
113
+ assert_equal(buffer, decompressed)
62
114
  end
63
115
 
116
+ assert_equal(true, reader.eof?)
117
+ assert_equal(true, reader.eof)
64
118
  assert_nil(reader.read(1))
65
119
  assert_equal(0, reader.read.bytesize)
66
120
  end
@@ -68,26 +122,60 @@ class ReaderTest < Minitest::Test
68
122
 
69
123
  def bzip_test(fixture, options = {})
70
124
  Dir.mktmpdir('bzip2-ffi-test') do |dir|
125
+ split_length = options[:split_length]
126
+ split_files = nil
71
127
  uncompressed = File.join(dir, 'test')
72
128
  if fixture
73
- FileUtils.cp(fixture_path(fixture), uncompressed)
129
+ if split_length && split_length > 0
130
+ File.open(fixture_path(fixture), 'rb') do |source|
131
+ split_files = 0
132
+
133
+ loop do
134
+ buffer = source.read(split_length)
135
+ buffer = '' if !buffer && split_files == 0
136
+ break unless buffer
137
+
138
+ split_files += 1
139
+ File.open("#{uncompressed}.#{split_files}", 'wb') do |target|
140
+ target.write(buffer)
141
+ end
142
+ end
143
+ end
144
+ else
145
+ FileUtils.cp(fixture_path(fixture), uncompressed)
146
+ end
74
147
  else
75
148
  FileUtils.touch(uncompressed)
76
149
  end
77
-
78
- assert_bzip2_successful(uncompressed)
79
-
80
- compressed = File.join(dir, "test.bz2")
150
+
151
+ compressed = "#{uncompressed}.bz2"
152
+
153
+ if split_files
154
+ File.open(compressed, 'wb') do |target|
155
+ 1.upto(split_files) do |i|
156
+ split_file = "#{uncompressed}.#{i}"
157
+ assert_bzip2_successful(split_file)
158
+ File.open("#{split_file}.bz2", 'rb') do |source|
159
+ target.write(source.read)
160
+ end
161
+ end
162
+ end
163
+ else
164
+ assert_bzip2_successful(uncompressed)
165
+ end
166
+
81
167
  assert(File.exist?(compressed))
82
168
 
83
- Bzip2::FFI::Reader.open(compressed, options[:reader_options] || {}) do |reader|
169
+ reader_options = options[:reader_options] || {}
170
+
171
+ Bzip2::FFI::Reader.open(compressed, reader_options) do |reader|
84
172
  if fixture
85
- compare_fixture(reader, fixture, options[:read_size], options[:use_outbuf])
173
+ compare_fixture(reader, fixture, options[:read_size], options[:use_outbuf], reader_options[:first_only] ? split_length : nil)
86
174
  else
87
175
  assert_equal(0, reader.read.bytesize)
88
176
  end
89
177
  end
90
- end
178
+ end
91
179
  end
92
180
 
93
181
  def test_initialize_nil_io
@@ -102,48 +190,58 @@ class ReaderTest < Minitest::Test
102
190
  bzip_test(nil)
103
191
  end
104
192
 
105
- def test_fixture_text
106
- [16, 1024, 16384, File.size(fixture_path('lorem.txt')), nil].each do |read_size|
107
- [false, true].each do |use_outbuf|
108
- bzip_test('lorem.txt', read_size: read_size, use_outbuf: use_outbuf)
109
- end
110
- end
111
- end
193
+ bzip_fixture_tests(:text, 'lorem.txt')
194
+ bzip_fixture_tests(:very_compressible, 'zero.txt')
195
+ bzip_fixture_tests(:uncompressible, 'compressed.bz2')
196
+ bzip_fixture_tests(:image, 'moon.tiff')
112
197
 
113
- def test_fixture_very_compressible
114
- [16, 1024, 16384, File.size(fixture_path('zero.txt')), nil].each do |read_size|
115
- [false, true].each do |use_outbuf|
116
- bzip_test('zero.txt', read_size: read_size, use_outbuf: use_outbuf)
117
- end
198
+ [false, true].each do |small|
199
+ define_method("test_#{small ? '' : 'not_'}small") do
200
+ # Not trivial to check if the value passed has any effect. Just check that
201
+ # there are no failures.
202
+ bzip_test('lorem.txt', reader_options: {small: small})
118
203
  end
119
204
  end
120
205
 
121
- def test_fixture_uncompressible
122
- [16, 1024, 16384, File.size(fixture_path('bzipped')), nil].each do |read_size|
123
- [false, true].each do |use_outbuf|
124
- bzip_test('bzipped', read_size: read_size, use_outbuf: use_outbuf)
206
+ read_size_and_use_outbuf_combinations('lorem.txt') do |read_size, use_outbuf, description|
207
+ [16361, 16384, 32647, 32768].each do |split_length|
208
+ [false, true].each do |first_only|
209
+ define_method("test_multiple_bzip2_structures#{description}_with_split_length_#{split_length}#{first_only ? '_first_only' : ''}") do
210
+ bzip_test('lorem.txt', read_size: read_size, use_outbuf: use_outbuf, split_length: split_length, reader_options: {first_only: first_only})
211
+ end
125
212
  end
126
213
  end
127
214
  end
128
215
 
129
- def test_fixture_image
130
- [16, 1024, 16384, File.size(fixture_path('moon.tiff')), nil].each do |read_size|
131
- [false, true].each do |use_outbuf|
132
- bzip_test('moon.tiff', read_size: read_size, use_outbuf: use_outbuf)
133
- end
134
- end
216
+ def test_reads_all_when_bzip2_structure_ends_at_end_of_a_compressed_data_read
217
+ # Tests s[:avail_in] reaching zero when @in_eof is false at the end of the
218
+ # only bzip2 structure.
219
+ #
220
+ # Requires a single structure bzip2 fixture that has a compressed size of
221
+ # Bzip2::FFI::Reader::READ_BUFFER_SIZE bytes.
222
+
223
+ assert_equal(0, 4096 % Bzip2::FFI::Reader.const_get(:READ_BUFFER_SIZE))
224
+ result = Bzip2::FFI::Reader.read(fixture_path('lorem-4096-bytes-compressed.txt.bz2'))
225
+ expected = File.open(fixture_path('lorem.txt'), 'rb') {|f| f.read(8930) }
226
+ assert_equal(expected, result)
135
227
  end
136
228
 
137
- def test_small
138
- # Not trivial to check if the value passed has any effect. Just check that
139
- # there are no failures.
140
- [false, true].each do |small|
141
- bzip_test('lorem.txt', reader_options: {small: small})
142
- end
229
+ def test_reads_all_when_first_bzip2_structure_ends_at_end_of_a_compressed_data_read
230
+ # Tests s[:avail_in] reaching zero when @in_eof is false at the end of the
231
+ # first bzip2 structure with additional bzip2 structures following.
232
+ #
233
+ # Requires a bzip2 fixture with a first structure that ends at the end of a
234
+ # read from the compressed stream (read Bzip2::FFI::Reader::READ_BUFFER_SIZE
235
+ # bytes at a time).
236
+
237
+ assert_equal(0, 4096 % Bzip2::FFI::Reader.const_get(:READ_BUFFER_SIZE))
238
+ result = Bzip2::FFI::Reader.read(fixture_path('lorem-first-structure-4096-bytes.txt.bz2'))
239
+ expected = File.open(fixture_path('lorem.txt'), 'rb') {|f| f.read }
240
+ assert_equal(expected, result)
143
241
  end
144
242
 
145
243
  def test_close_mid_read
146
- Bzip2::FFI::Reader.open(fixture_path('bzipped')) do |reader|
244
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
147
245
  decompressed = reader.read(1)
148
246
  refute_nil(decompressed)
149
247
  assert_equal(1, decompressed.bytesize)
@@ -151,16 +249,17 @@ class ReaderTest < Minitest::Test
151
249
  end
152
250
 
153
251
  def test_read_zero_before_eof
154
- Bzip2::FFI::Reader.open(fixture_path('bzipped')) do |reader|
252
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
155
253
  decompressed = reader.read(0)
156
254
  refute_nil(decompressed)
157
255
  assert_equal(0, decompressed.bytesize)
256
+ refute(decompressed.frozen?)
158
257
  end
159
258
  end
160
259
 
161
260
  def test_read_zero_before_eof_buffer
162
- Bzip2::FFI::Reader.open(fixture_path('bzipped')) do |reader|
163
- buffer = 'outbuf'
261
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
262
+ buffer = 'outbuf'.dup
164
263
  decompressed = reader.read(0, buffer)
165
264
  assert_same(buffer, decompressed)
166
265
  assert_equal(0, decompressed.bytesize)
@@ -168,18 +267,19 @@ class ReaderTest < Minitest::Test
168
267
  end
169
268
 
170
269
  def test_read_zero_after_eof
171
- Bzip2::FFI::Reader.open(fixture_path('bzipped')) do |reader|
270
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
172
271
  reader.read
173
272
  decompressed = reader.read(0) # would return nil if greater than 0
174
273
  refute_nil(decompressed)
175
274
  assert_equal(0, decompressed.bytesize)
275
+ refute(decompressed.frozen?)
176
276
  end
177
277
  end
178
278
 
179
279
  def test_read_zero_after_eof_buffer
180
- Bzip2::FFI::Reader.open(fixture_path('bzipped')) do |reader|
280
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
181
281
  reader.read
182
- buffer = 'outbuf'
282
+ buffer = 'outbuf'.dup
183
283
  decompressed = reader.read(0, buffer) # would return nil if greater than 0
184
284
  assert_same(buffer, decompressed)
185
285
  assert_equal(0, decompressed.bytesize)
@@ -187,7 +287,7 @@ class ReaderTest < Minitest::Test
187
287
  end
188
288
 
189
289
  def test_read_after_close_read_all
190
- File.open(fixture_path('bzipped'), 'rb') do |file|
290
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
191
291
  reader = Bzip2::FFI::Reader.new(file)
192
292
  reader.close
193
293
  assert_raises(IOError) { reader.read }
@@ -195,15 +295,15 @@ class ReaderTest < Minitest::Test
195
295
  end
196
296
 
197
297
  def test_read_after_close_read_all_buffer
198
- File.open(fixture_path('bzipped'), 'rb') do |file|
298
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
199
299
  reader = Bzip2::FFI::Reader.new(file)
200
300
  reader.close
201
- assert_raises(IOError) { reader.read(nil, '') }
301
+ assert_raises(IOError) { reader.read(nil, String.new) }
202
302
  end
203
303
  end
204
304
 
205
305
  def test_read_after_close_read_n
206
- File.open(fixture_path('bzipped'), 'rb') do |file|
306
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
207
307
  reader = Bzip2::FFI::Reader.new(file)
208
308
  reader.close
209
309
  assert_raises(IOError) { reader.read(1) }
@@ -211,15 +311,15 @@ class ReaderTest < Minitest::Test
211
311
  end
212
312
 
213
313
  def test_read_after_close_read_n_buffer
214
- File.open(fixture_path('bzipped'), 'rb') do |file|
314
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
215
315
  reader = Bzip2::FFI::Reader.new(file)
216
316
  reader.close
217
- assert_raises(IOError) { reader.read(1, '') }
317
+ assert_raises(IOError) { reader.read(1, String.new) }
218
318
  end
219
319
  end
220
320
 
221
321
  def test_read_after_close_read_zero
222
- File.open(fixture_path('bzipped'), 'rb') do |file|
322
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
223
323
  reader = Bzip2::FFI::Reader.new(file)
224
324
  reader.close
225
325
  assert_raises(IOError) { reader.read(0) }
@@ -227,10 +327,10 @@ class ReaderTest < Minitest::Test
227
327
  end
228
328
 
229
329
  def test_read_after_close_read_zero_buffer
230
- File.open(fixture_path('bzipped'), 'rb') do |file|
330
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
231
331
  reader = Bzip2::FFI::Reader.new(file)
232
332
  reader.close
233
- assert_raises(IOError) { reader.read(0, '') }
333
+ assert_raises(IOError) { reader.read(0, String.new) }
234
334
  end
235
335
  end
236
336
 
@@ -245,11 +345,11 @@ class ReaderTest < Minitest::Test
245
345
  end
246
346
  end
247
347
 
248
- def test_truncated_bzip
249
- [1024, Bzip2::FFI::Reader::READ_BUFFER_SIZE, 8192].each do |size|
348
+ [1024, Bzip2::FFI::Reader.const_get(:READ_BUFFER_SIZE), Bzip2::FFI::Reader.const_get(:READ_BUFFER_SIZE) + 1, 8192].each do |size|
349
+ define_method("test_bzip_truncated_to_#{size}_bytes") do
250
350
  partial = StringIO.new
251
351
 
252
- File.open(fixture_path('bzipped'), 'rb') do |input|
352
+ File.open(fixture_path('compressed.bz2'), 'rb') do |input|
253
353
  buffer = input.read(size)
254
354
  refute_nil(buffer)
255
355
  assert_equal(size, buffer.bytesize)
@@ -257,7 +357,7 @@ class ReaderTest < Minitest::Test
257
357
  end
258
358
 
259
359
  partial.seek(0)
260
-
360
+
261
361
  Bzip2::FFI::Reader.open(partial) do |reader|
262
362
  assert_raises(Bzip2::FFI::Error::UnexpectedEofError) { reader.read }
263
363
  end
@@ -267,9 +367,9 @@ class ReaderTest < Minitest::Test
267
367
  def test_corrupted_bzip
268
368
  corrupted = StringIO.new
269
369
 
270
- File.open(fixture_path('bzipped'), 'rb') do |file|
370
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
271
371
  corrupted.write(file.read)
272
- end
372
+ end
273
373
 
274
374
  corrupted.seek(4000)
275
375
  corrupted.write("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
@@ -284,7 +384,7 @@ class ReaderTest < Minitest::Test
284
384
  def test_data_after_compressed
285
385
  suffixed = StringIO.new
286
386
 
287
- File.open(fixture_path('bzipped'), 'rb') do |file|
387
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
288
388
  suffixed.write(file.read)
289
389
  end
290
390
 
@@ -294,17 +394,19 @@ class ReaderTest < Minitest::Test
294
394
 
295
395
  Bzip2::FFI::Reader.open(suffixed) do |reader|
296
396
  assert_equal(65670, reader.read.bytesize)
397
+ assert_equal(true, reader.eof?)
398
+ assert_equal(true, reader.eof)
297
399
  assert_nil(reader.read(1))
298
400
  assert_equal(0, reader.read.bytesize)
299
401
  end
300
-
402
+
301
403
  assert_equal('Test', suffixed.read)
302
404
  end
303
405
 
304
406
  def test_data_after_compressed_no_seek
305
407
  suffixed = StringIO.new
306
408
 
307
- File.open(fixture_path('bzipped'), 'rb') do |file|
409
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
308
410
  suffixed.write(file.read)
309
411
  end
310
412
 
@@ -318,9 +420,11 @@ class ReaderTest < Minitest::Test
318
420
 
319
421
  Bzip2::FFI::Reader.open(suffixed) do |reader|
320
422
  assert_equal(65670, reader.read.bytesize)
423
+ assert_equal(true, reader.eof?)
424
+ assert_equal(true, reader.eof)
321
425
  assert_nil(reader.read(1))
322
426
  assert_equal(0, reader.read.bytesize)
323
- end
427
+ end
324
428
 
325
429
  # For this input, the suffix will already have been consumed before the
326
430
  # end of the bzip2 stream is reached. There is no seek method, so it is not
@@ -331,7 +435,7 @@ class ReaderTest < Minitest::Test
331
435
  def test_data_after_compressed_seek_raises_io_error
332
436
  suffixed = StringIO.new
333
437
 
334
- File.open(fixture_path('bzipped'), 'rb') do |file|
438
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
335
439
  suffixed.write(file.read)
336
440
  end
337
441
 
@@ -345,9 +449,11 @@ class ReaderTest < Minitest::Test
345
449
 
346
450
  Bzip2::FFI::Reader.open(suffixed) do |reader|
347
451
  assert_equal(65670, reader.read.bytesize)
452
+ assert_equal(true, reader.eof?)
453
+ assert_equal(true, reader.eof)
348
454
  assert_nil(reader.read(1))
349
455
  assert_equal(0, reader.read.bytesize)
350
- end
456
+ end
351
457
 
352
458
  # For this input, the suffix will already have been consumed before the
353
459
  # end of the bzip2 stream is reached. There is no seek method, so it is not
@@ -355,6 +461,138 @@ class ReaderTest < Minitest::Test
355
461
  assert_equal(0, suffixed.read.bytesize)
356
462
  end
357
463
 
464
+ def test_data_after_compressed_multiple_structures
465
+ suffixed = StringIO.new
466
+
467
+ File.open(fixture_path('two_structures.bz2'), 'rb') do |file|
468
+ suffixed.write(file.read)
469
+ end
470
+
471
+ suffixed.write('Test')
472
+
473
+ suffixed.seek(0)
474
+
475
+ Bzip2::FFI::Reader.open(suffixed) do |reader|
476
+ assert_equal(111, reader.read.bytesize)
477
+ assert_equal(true, reader.eof?)
478
+ assert_equal(true, reader.eof)
479
+ assert_nil(reader.read(1))
480
+ assert_equal(0, reader.read.bytesize)
481
+ end
482
+
483
+ assert_equal('Test', suffixed.read)
484
+ end
485
+
486
+ def test_data_after_compressed_first_only
487
+ File.open(fixture_path('two_structures.bz2'), 'rb') do |file|
488
+ Bzip2::FFI::Reader.open(file, first_only: true) do |reader|
489
+ assert_equal(55, reader.read.bytesize)
490
+ assert_equal(true, reader.eof?)
491
+ assert_equal(true, reader.eof)
492
+ assert_nil(reader.read(1))
493
+ assert_equal(0, reader.read.bytesize)
494
+ end
495
+
496
+ assert_equal('BZh', file.read(3)) # Bzip2 magic for second strcture
497
+ end
498
+ end
499
+
500
+ def test_data_before_and_after_compressed
501
+ # Tests that a relative seek (IO::SEEK_CUR) is performed to reset the
502
+ # position.
503
+
504
+ suffixed_and_prefixed = StringIOWithSeekCount.new
505
+ suffixed_and_prefixed.write('Before')
506
+
507
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
508
+ suffixed_and_prefixed.write(file.read)
509
+ end
510
+
511
+ suffixed_and_prefixed.write('After')
512
+
513
+ suffixed_and_prefixed.seek(0)
514
+ assert_equal('Before', suffixed_and_prefixed.read(6))
515
+
516
+ Bzip2::FFI::Reader.open(suffixed_and_prefixed) do |reader|
517
+ assert_equal(65670, reader.read.bytesize)
518
+ assert_equal(true, reader.eof?)
519
+ assert_equal(true, reader.eof)
520
+ assert_nil(reader.read(1))
521
+ assert_equal(0, reader.read.bytesize)
522
+ end
523
+
524
+ assert_equal(2, suffixed_and_prefixed.seek_count)
525
+ assert_equal('After', suffixed_and_prefixed.read)
526
+ end
527
+
528
+ def test_data_before_and_after_compressed_first_only
529
+ # Tests that a relative seek (IO::SEEK_CUR) is performed to reset the
530
+ # position.
531
+
532
+ prefixed = StringIOWithSeekCount.new
533
+ prefixed.write('Before')
534
+
535
+ File.open(fixture_path('two_structures.bz2'), 'rb') do |file|
536
+ prefixed.write(file.read)
537
+ end
538
+
539
+ prefixed.seek(0)
540
+ assert_equal('Before', prefixed.read(6))
541
+
542
+ Bzip2::FFI::Reader.open(prefixed, first_only: true) do |reader|
543
+ assert_equal(55, reader.read.bytesize)
544
+ assert_equal(true, reader.eof?)
545
+ assert_equal(true, reader.eof)
546
+ assert_nil(reader.read(1))
547
+ assert_equal(0, reader.read.bytesize)
548
+ end
549
+
550
+ assert_equal(2, prefixed.seek_count)
551
+ assert_equal('BZh', prefixed.read(3)) # Bzip2 magic for second strcture
552
+ end
553
+
554
+ [[:eof, 'eof'], [:eof?, 'eof_q']].each do |(method, name)|
555
+ define_method("test_sets_#{name}_when_complete") do
556
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
557
+ assert_equal(false, reader.public_send(method))
558
+ reader.read(17)
559
+ assert_equal(false, reader.public_send(method))
560
+ reader.read
561
+ assert_equal(true, reader.public_send(method))
562
+ end
563
+ end
564
+
565
+ define_method("test_#{name}_raises_io_error_when_closed") do
566
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
567
+ reader = Bzip2::FFI::Reader.new(file)
568
+ reader.close
569
+ assert_raises(IOError) { reader.public_send(method) }
570
+ end
571
+ end
572
+ end
573
+
574
+ [:tell, :pos].each do |method|
575
+ define_method("test_#{method}_returns_decompressed_position") do
576
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) do |reader|
577
+ assert_equal(0, reader.public_send(method))
578
+ reader.read(17)
579
+ assert_equal(17, reader.public_send(method))
580
+ reader.read(8837)
581
+ assert_equal(8854, reader.public_send(method))
582
+ reader.read
583
+ assert_equal(65670, reader.public_send(method))
584
+ end
585
+ end
586
+
587
+ define_method("test_#{method}_raises_io_error_when_closed") do
588
+ File.open(fixture_path('compressed.bz2'), 'rb') do |file|
589
+ reader = Bzip2::FFI::Reader.new(file)
590
+ reader.close
591
+ assert_raises(IOError) { reader.public_send(method) }
592
+ end
593
+ end
594
+ end
595
+
358
596
  def test_finalizer
359
597
  # Code coverage will verify that the finalizer was called.
360
598
  10.times { Bzip2::FFI::Reader.new(StringIO.new) }
@@ -388,43 +626,39 @@ class ReaderTest < Minitest::Test
388
626
  end
389
627
  end
390
628
 
391
- def test_open_block_path
392
- path = fixture_path('bzipped')
393
- [path, Pathname.new(path)].each do |path_param|
394
- Bzip2::FFI::Reader.open(path_param) do |reader|
395
- io = reader.send(:io)
396
- assert_kind_of(File, io)
397
- assert_equal(path, io.path)
398
- assert_raises(IOError) { io.write('test') }
399
- assert_nothing_raised { io.read(1) }
400
- end
629
+ path_or_pathname_tests(:open_block) do |path_param|
630
+ path = fixture_path('compressed.bz2')
631
+ Bzip2::FFI::Reader.open(path_param.call(path)) do |reader|
632
+ io = reader.send(:io)
633
+ assert_kind_of(File, io)
634
+ assert_equal(path.to_s, io.path)
635
+ assert_raises(IOError) { io.write('test') }
636
+ assert_nothing_raised { io.read(1) }
401
637
  end
402
638
  end
403
639
 
404
- def test_open_no_block_path
405
- path = fixture_path('bzipped')
406
- [path, Pathname.new(path)].each do |path_param|
407
- reader = Bzip2::FFI::Reader.open(path_param)
408
- begin
409
- io = reader.send(:io)
410
- assert_kind_of(File, io)
411
- assert_equal(path, io.path)
412
- assert_raises(IOError) { io.write('test') }
413
- assert_nothing_raised { io.read(1) }
414
- ensure
415
- io.close
416
- end
640
+ path_or_pathname_tests(:open_no_block) do |path_param|
641
+ path = fixture_path('compressed.bz2')
642
+ reader = Bzip2::FFI::Reader.open(path_param.call(path))
643
+ begin
644
+ io = reader.send(:io)
645
+ assert_kind_of(File, io)
646
+ assert_equal(path, io.path)
647
+ assert_raises(IOError) { io.write('test') }
648
+ assert_nothing_raised { io.read(1) }
649
+ ensure
650
+ reader.close
417
651
  end
418
652
  end
419
653
 
420
654
  def test_open_block_path_always_autoclosed
421
- Bzip2::FFI::Reader.open(fixture_path('bzipped'), autoclose: false) do |reader|
655
+ Bzip2::FFI::Reader.open(fixture_path('compressed.bz2'), autoclose: false) do |reader|
422
656
  assert_equal(true, reader.autoclose?)
423
657
  end
424
658
  end
425
659
 
426
660
  def test_open_no_block_path_always_autoclosed
427
- reader = Bzip2::FFI::Reader.open(fixture_path('bzipped'), autoclose: false)
661
+ reader = Bzip2::FFI::Reader.open(fixture_path('compressed.bz2'), autoclose: false)
428
662
  begin
429
663
  assert_equal(true, reader.autoclose?)
430
664
  ensure
@@ -444,7 +678,7 @@ class ReaderTest < Minitest::Test
444
678
 
445
679
  def test_open_after_open_file_exception_closes_file
446
680
  Bzip2::FFI::Reader.test_after_open_file_raise_exception = true
447
- assert_raises(RuntimeError) { Bzip2::FFI::Reader.open(fixture_path('bzipped')) }
681
+ assert_raises(RuntimeError) { Bzip2::FFI::Reader.open(fixture_path('compressed.bz2')) }
448
682
  file = Bzip2::FFI::Reader.test_after_open_file_last_io
449
683
  refute_nil(file)
450
684
  assert(file.closed?)
@@ -478,15 +712,9 @@ class ReaderTest < Minitest::Test
478
712
  end
479
713
  end
480
714
 
481
- def test_class_read_path
715
+ path_or_pathname_tests(:class_read) do |path_param|
482
716
  class_read_test('test_path') do |compressed|
483
- Bzip2::FFI::Reader.read(compressed)
484
- end
485
- end
486
-
487
- def test_class_read_pathname
488
- class_read_test('test_pathname') do |compressed|
489
- Bzip2::FFI::Reader.read(Pathname.new(compressed))
717
+ Bzip2::FFI::Reader.read(path_param.call(compressed))
490
718
  end
491
719
  end
492
720