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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +33 -2
- data/Gemfile +43 -2
- data/LICENSE +13 -13
- data/README.md +92 -62
- data/Rakefile +24 -0
- data/bzip2-ffi.gemspec +10 -1
- data/lib/bzip2/ffi/error.rb +5 -2
- data/lib/bzip2/ffi/io.rb +59 -47
- data/lib/bzip2/ffi/libbz2.rb +7 -3
- data/lib/bzip2/ffi/reader.rb +210 -104
- data/lib/bzip2/ffi/version.rb +4 -1
- data/lib/bzip2/ffi/writer.rb +81 -62
- data/lib/bzip2/ffi.rb +9 -6
- data/test/error_test.rb +19 -20
- data/test/fixtures/lorem-4096-bytes-compressed.txt.bz2 +0 -0
- data/test/fixtures/lorem-first-structure-4096-bytes.txt.bz2 +0 -0
- data/test/fixtures/two_structures.bz2 +0 -0
- data/test/io_test.rb +34 -32
- data/test/reader_test.rb +339 -111
- data/test/test_helper.rb +45 -8
- data/test/version_test.rb +4 -1
- data/test/writer_test.rb +99 -73
- data.tar.gz.sig +0 -0
- metadata +33 -26
- metadata.gz.sig +2 -1
- /data/test/fixtures/{bzipped → compressed.bz2} +0 -0
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
|
9
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
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
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
-
|
122
|
-
[
|
123
|
-
[false, true].each do |
|
124
|
-
|
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
|
130
|
-
[
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
138
|
-
#
|
139
|
-
#
|
140
|
-
|
141
|
-
|
142
|
-
|
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('
|
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('
|
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('
|
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('
|
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('
|
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('
|
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('
|
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('
|
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('
|
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('
|
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('
|
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
|
-
|
249
|
-
|
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('
|
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('
|
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('
|
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('
|
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('
|
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
|
-
|
392
|
-
path = fixture_path('
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
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
|
-
|
405
|
-
path = fixture_path('
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
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('
|
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('
|
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('
|
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
|
-
|
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
|
|