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