bzip2-ffi 1.0.0 → 1.1.0

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/test_helper.rb CHANGED
@@ -1,8 +1,11 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  unless RUBY_ENGINE == 'jruby'
2
5
  require 'simplecov'
3
6
  require 'coveralls'
4
7
 
5
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov.formatters = [
6
9
  SimpleCov::Formatter::HTMLFormatter,
7
10
  Coveralls::SimpleCov::Formatter
8
11
  ]
@@ -17,6 +20,7 @@ require 'bzip2/ffi'
17
20
  require 'fileutils'
18
21
  require 'minitest/autorun'
19
22
  require 'open3'
23
+ require 'pathname'
20
24
 
21
25
  class Bzip2::FFI::IO
22
26
  class << self
@@ -61,6 +65,10 @@ module TestHelper
61
65
  end
62
66
  end
63
67
 
68
+ def skip_slow_test_unless_enabled
69
+ skip('Skipping slow test (enable with RUN_SLOW_TESTS=1)') unless ENV['RUN_SLOW_TESTS'] == '1'
70
+ end
71
+
64
72
  private
65
73
 
66
74
  if File::ALT_SEPARATOR
@@ -74,25 +82,54 @@ module TestHelper
74
82
  end
75
83
 
76
84
  def assert_bzip2_command_successful(*arguments)
77
- out, err, status = Open3.capture3(*(['bzip2'] + arguments))
78
-
79
- args_string = arguments.collect {|a| "'#{a}'" }.join(' ')
80
- assert(err == '', "`bzip2 #{args_string}` returned error: #{err}")
81
- assert(out == '', "`bzip2 #{args_string}` returned output: #{out}")
82
- assert(status.exitstatus == 0, "`bzip2 #{args_string}` exit status was non-zero")
85
+ command_with_arguments = ['bzip2'] + arguments
86
+ begin
87
+ out, err, status = Open3.capture3(*command_with_arguments)
88
+
89
+ args_string = arguments.collect {|a| "'#{a}'" }.join(' ')
90
+ assert(err == '', "`bzip2 #{args_string}` returned error: #{err}")
91
+ assert(out == '', "`bzip2 #{args_string}` returned output: #{out}")
92
+
93
+ # Ruby 1.9.3 on Windows intermittently returns a nil status. Assume that
94
+ # the process completed successfully.
95
+ if status
96
+ assert(status.exitstatus == 0, "`bzip2 #{args_string}` exit status was non-zero")
97
+ else
98
+ puts "`#{command_with_arguments.join(' ')}`: command status was nil, assuming successful"
99
+ end
100
+ rescue Errno::EBADF => e
101
+ # JRuby 1.7 intermittently reports a bad file descriptor when closing
102
+ # one of the input or output streams. Assume that the process completed
103
+ # successfully.
104
+ puts "`#{command_with_arguments.join(' ')}`: Open3.capture3 raised Errno::EBADF, assuming successful"
105
+ puts e.inspect
106
+ puts e.backtrace.join("\n")
107
+ end
83
108
  end
84
109
  end
85
110
 
86
111
  module Fixtures
87
112
  FIXTURES_DIR = File.join(BASE_DIR, 'fixtures')
88
-
113
+
89
114
  def fixture_path(fixture)
90
115
  File.join(FIXTURES_DIR, fixture)
91
116
  end
92
117
  end
118
+
119
+ module TestDefinitions
120
+ def path_or_pathname_tests(name, &block)
121
+ [['path', Proc.new {|p| p }], ['pathname', Proc.new {|p| Pathname.new(p) }]].each do |(description, path_param)|
122
+ define_method("test_#{name}_with_#{description}") do
123
+ instance_exec(path_param, &block)
124
+ end
125
+ end
126
+ end
127
+ end
93
128
  end
94
129
 
95
130
  class Minitest::Test
96
131
  include TestHelper::Assertions
97
132
  include TestHelper::Fixtures
133
+ extend TestHelper::Fixtures
134
+ extend TestHelper::TestDefinitions
98
135
  end
data/test/version_test.rb CHANGED
@@ -1,4 +1,7 @@
1
- require 'test_helper'
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'test_helper'
2
5
 
3
6
  class VersionTest < Minitest::Test
4
7
  def test_version
data/test/writer_test.rb CHANGED
@@ -1,22 +1,38 @@
1
1
  # encoding: UTF-8
2
+ # frozen_string_literal: true
2
3
 
3
- require 'pathname'
4
- require 'test_helper'
5
4
  require 'tmpdir'
5
+ require_relative 'test_helper'
6
6
 
7
7
  class WriterTest < Minitest::Test
8
8
  class DummyIO
9
9
  attr_reader :written_bytes
10
-
10
+
11
11
  def initialize
12
12
  @written_bytes = 0
13
13
  end
14
-
14
+
15
15
  def write(string)
16
16
  @written_bytes += string.bytesize
17
17
  end
18
18
  end
19
19
 
20
+ class << self
21
+ def read_size_combinations(fixture)
22
+ [16, 1024, 16384, File.size(fixture_path(fixture)), nil].each do |read_size|
23
+ yield read_size, "#{read_size ? "_with_read_size_#{read_size}" : ''}"
24
+ end
25
+ end
26
+
27
+ def bunzip_fixture_tests(name, fixture)
28
+ read_size_combinations(fixture) do |read_size, description|
29
+ define_method("test_fixture_#{name}#{description}") do
30
+ bunzip_test(fixture, read_size: read_size)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
20
36
  def setup
21
37
  Bzip2::FFI::Writer.test_after_open_file_raise_exception = false
22
38
  end
@@ -32,10 +48,12 @@ class WriterTest < Minitest::Test
32
48
  buffer = io.read(read_size)
33
49
  break unless buffer
34
50
  assert_equal(buffer.bytesize, writer.write(buffer))
51
+ assert_equal(io.pos, writer.pos)
35
52
  end
36
53
  else
37
54
  buffer = io.read
38
55
  assert_equal(buffer.bytesize, writer.write(buffer))
56
+ assert_equal(io.pos, writer.pos)
39
57
  end
40
58
  end
41
59
 
@@ -72,8 +90,8 @@ class WriterTest < Minitest::Test
72
90
  end
73
91
  end
74
92
 
75
- def bunzip_test(fixture_or_strings, options = {})
76
- Dir.mktmpdir('bzip2-ffi-test') do |dir|
93
+ def bunzip_test(fixture_or_strings, options = {})
94
+ Dir.mktmpdir('bzip2-ffi-test') do |dir|
77
95
  compressed = File.join(dir, "test.bz2")
78
96
  Bzip2::FFI::Writer.open(compressed, options[:writer_options] || {}) do |writer|
79
97
  if fixture_or_strings
@@ -88,7 +106,7 @@ class WriterTest < Minitest::Test
88
106
  end
89
107
 
90
108
  bunzip_and_compare(compressed, fixture_or_strings)
91
- end
109
+ end
92
110
  end
93
111
 
94
112
  def test_initialize_nil_io
@@ -113,29 +131,10 @@ class WriterTest < Minitest::Test
113
131
  bunzip_test(nil)
114
132
  end
115
133
 
116
- def test_fixture_text
117
- [16, 1024, 16384, nil].each do |read_size|
118
- bunzip_test('lorem.txt', read_size: read_size)
119
- end
120
- end
121
-
122
- def test_fixture_very_compressible
123
- [16, 1024, 16384, nil].each do |read_size|
124
- bunzip_test('zero.txt', read_size: read_size)
125
- end
126
- end
127
-
128
- def test_fixture_uncompressible
129
- [16, 1024, 16384, nil].each do |read_size|
130
- bunzip_test('bzipped', read_size: read_size)
131
- end
132
- end
133
-
134
- def test_fixture_image
135
- [16, 1024, 16384, nil].each do |read_size|
136
- bunzip_test('moon.tiff', read_size: read_size)
137
- end
138
- end
134
+ bunzip_fixture_tests(:text, 'lorem.txt')
135
+ bunzip_fixture_tests(:very_compressible, 'zero.txt')
136
+ bunzip_fixture_tests(:uncompressible, 'compressed.bz2')
137
+ bunzip_fixture_tests(:image, 'moon.tiff')
139
138
 
140
139
  def test_encoding_handling
141
140
  bunzip_test(['áÁçÇðÐéÉ'.encode(Encoding::UTF_8), 'áÁçÇðÐéÉ'.encode(Encoding::ISO_8859_1)])
@@ -148,11 +147,11 @@ class WriterTest < Minitest::Test
148
147
  def test_block_size
149
148
  sizes = [1, 9].collect do |block_size|
150
149
  io = DummyIO.new
151
-
150
+
152
151
  Bzip2::FFI::Writer.open(io, block_size: block_size) do |writer|
153
152
  write_fixture(writer, 'lorem.txt')
154
153
  end
155
-
154
+
156
155
  io.written_bytes
157
156
  end
158
157
 
@@ -177,11 +176,8 @@ class WriterTest < Minitest::Test
177
176
  assert_equal(explicit_io.written_bytes, default_io.written_bytes)
178
177
  end
179
178
 
180
- def test_work_factor
181
- # Not trivial to check if the value passed has any effect. Just check that
182
- # there are no failures for values within the acceptable range.
183
-
184
- [0, 100, 250].each do |work_factor|
179
+ [0, 100, 250].each do |work_factor|
180
+ define_method("test_work_factor_#{work_factor}") do
185
181
  bunzip_test('lorem.txt', writer_options: {work_factor: work_factor})
186
182
  end
187
183
  end
@@ -230,6 +226,40 @@ class WriterTest < Minitest::Test
230
226
  assert_nil(writer.close)
231
227
  end
232
228
 
229
+ def test_pos_returns_uncompressed_position
230
+ Bzip2::FFI::Writer.open(DummyIO.new) do |writer|
231
+ assert_equal(0, writer.pos)
232
+ writer.write('Test')
233
+ assert_equal(4, writer.pos)
234
+ writer.write('Complete')
235
+ assert_equal(12, writer.pos)
236
+ end
237
+ end
238
+
239
+ def test_pos_returns_uncompressed_64bit_position
240
+ skip_slow_test_unless_enabled
241
+
242
+ # The position is read from separate 32-bit low and high words.
243
+ Bzip2::FFI::Writer.open(DummyIO.new) do |writer|
244
+ buffer_bits = 12
245
+ buffer = "\0".encode(Encoding::ASCII_8BIT) * 2**buffer_bits
246
+
247
+ (2**(32 - buffer_bits)).times do |i|
248
+ writer.write(buffer)
249
+ end
250
+
251
+ assert_equal(2**32, writer.pos)
252
+ writer.write(buffer)
253
+ assert_equal(2**32 + buffer.bytesize, writer.pos)
254
+ end
255
+ end
256
+
257
+ def test_pos_raises_io_error_when_closed
258
+ writer = Bzip2::FFI::Writer.new(DummyIO.new)
259
+ writer.close
260
+ assert_raises(IOError) { writer.pos }
261
+ end
262
+
233
263
  def test_finalizer
234
264
  # Code coverage will verify that the finalizer was called.
235
265
  10.times { Bzip2::FFI::Writer.new(DummyIO.new) }
@@ -244,14 +274,16 @@ class WriterTest < Minitest::Test
244
274
  assert_raises(ArgumentError) { Bzip2::FFI::Writer.open(Object.new) }
245
275
  end
246
276
 
247
- def test_open_invalid_block_size
248
- assert_raises(RangeError) { Bzip2::FFI::Writer.open(DummyIO.new, block_size: 0) }
249
- assert_raises(RangeError) { Bzip2::FFI::Writer.open(DummyIO.new, block_size: 10) }
277
+ [0, 10].each do |block_size|
278
+ define_method("test_open_invalid_block_size_#{block_size}") do
279
+ assert_raises(RangeError) { Bzip2::FFI::Writer.open(DummyIO.new, block_size: block_size) }
280
+ end
250
281
  end
251
282
 
252
- def test_open_invalid_work_factor
253
- assert_raises(RangeError) { Bzip2::FFI::Writer.open(DummyIO.new, work_factor: -1) }
254
- assert_raises(RangeError) { Bzip2::FFI::Writer.open(DummyIO.new, work_factor: 251) }
283
+ [-1, 251].each do |work_factor|
284
+ define_method("test_open_invalid_work_factor_#{work_factor}") do
285
+ assert_raises(RangeError) { Bzip2::FFI::Writer.open(DummyIO.new, work_factor: work_factor) }
286
+ end
255
287
  end
256
288
 
257
289
  def test_open_block_io
@@ -273,42 +305,38 @@ class WriterTest < Minitest::Test
273
305
  end
274
306
  end
275
307
 
276
- def test_open_block_path
308
+ path_or_pathname_tests(:open_block) do |path_param|
277
309
  Dir.mktmpdir('bzip2-ffi-test') do |dir|
278
310
  path = File.join(dir, 'test')
279
- [path, Pathname.new(path)].each do |path_param|
280
- Bzip2::FFI::Writer.open(path_param) do |writer|
281
- io = writer.send(:io)
282
- assert_kind_of(File, io)
283
- assert_equal(path, io.path)
284
- assert_raises(IOError) { io.read(1) }
285
- assert_nothing_raised { io.write('test') }
286
- end
311
+ Bzip2::FFI::Writer.open(path_param.call(path)) do |writer|
312
+ io = writer.send(:io)
313
+ assert_kind_of(File, io)
314
+ assert_equal(path, io.path)
315
+ assert_raises(IOError) { io.read(1) }
316
+ assert_nothing_raised { io.write('test') }
287
317
  end
288
318
  end
289
319
  end
290
320
 
291
- def test_open_no_block_path
321
+ path_or_pathname_tests(:open_no_block) do |path_param|
292
322
  Dir.mktmpdir('bzip2-ffi-test') do |dir|
293
323
  path = File.join(dir, 'test')
294
- [path, Pathname.new(path)].each do |path_param|
295
- writer = Bzip2::FFI::Writer.open(path_param)
296
- begin
297
- io = writer.send(:io)
298
- assert_kind_of(File, io)
299
- assert_equal(path, io.path)
300
- assert_raises(IOError) { io.read(1) }
301
- assert_nothing_raised { io.write('test') }
302
- ensure
303
- writer.close
304
- end
324
+ writer = Bzip2::FFI::Writer.open(path_param.call(path))
325
+ begin
326
+ io = writer.send(:io)
327
+ assert_kind_of(File, io)
328
+ assert_equal(path, io.path)
329
+ assert_raises(IOError) { io.read(1) }
330
+ assert_nothing_raised { io.write('test') }
331
+ ensure
332
+ writer.close
305
333
  end
306
334
  end
307
335
  end
308
336
 
309
337
  def test_open_block_path_always_autoclosed
310
338
  Dir.mktmpdir('bzip2-ffi-test') do |dir|
311
- Bzip2::FFI::Writer.open(File.join(dir, 'test'), autoclose: false) do |writer|
339
+ Bzip2::FFI::Writer.open(File.join(dir, 'test'), autoclose: false) do |writer|
312
340
  assert_equal(true, writer.autoclose?)
313
341
  end
314
342
  end
@@ -405,15 +433,9 @@ class WriterTest < Minitest::Test
405
433
  end
406
434
  end
407
435
 
408
- def test_class_write_path
436
+ path_or_pathname_tests(:class_write) do |path_param|
409
437
  class_write_test('test_path') do |compressed, content|
410
- Bzip2::FFI::Writer.write(compressed, content)
411
- end
412
- end
413
-
414
- def test_class_write_pathname
415
- class_write_test('test_pathname') do |compressed, content|
416
- Bzip2::FFI::Writer.write(Pathname.new(compressed), content)
438
+ Bzip2::FFI::Writer.write(path_param.call(compressed), content)
417
439
  end
418
440
  end
419
441
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bzip2-ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Ross
@@ -10,27 +10,26 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAlwaGls
14
- LnJvc3MxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
15
- bTAeFw0xNDA5MjgxOTA4MDdaFw0xNTA5MjgxOTA4MDdaMEAxEjAQBgNVBAMMCXBo
16
- aWwucm9zczEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
17
- Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkZzB+qfhmyY+XRvU
18
- u310LMTGsTkR4/8JFCMF0YeQX6ZKmLr1fKzF3At1+DlI+v0t/G2FS6Dic0V3l8MK
19
- JczyFh72NANOaQhAo0GHh8WkaeCf2DLL5K6YJeLpvkvp39oxzn00A4zosnzxM50f
20
- Xrjx2HmurcJQurzafeCDj67QccaNE+5H+mcIVAJlsA1h1f5QFZ3SqQ4mf8St40pE
21
- 6YR4ev/Eq6Hb8aUoUq30otxbeHAEHh8cdVhTNFq7sPWb0psQRF2D/+o0MLgHt8PY
22
- EUm49szlLsnjVXAMCHU7wH9CmDR/5Lzcrgqh3DgyI8ay6DnlSQ213eYZH/Nkn1Yz
23
- TcNLCQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
24
- D5nzO9/MG4B6ygch/Pv6PF9Q5x8wHgYDVR0RBBcwFYETcGhpbC5yb3NzQGdtYWls
25
- LmNvbTAeBgNVHRIEFzAVgRNwaGlsLnJvc3NAZ21haWwuY29tMA0GCSqGSIb3DQEB
26
- BQUAA4IBAQCI4Ucln0W425HOc2mIaXkAiHWNs1Fv/rCPrBIwBYhjStVYUEPCIhEf
27
- MRCqpeOog3+b31SMIqqHQcNnjY9/YHeJCQ5vsRyN/A7+nafQ+PjI+E5HIl5Bd8Hk
28
- nbizkcvM/qE8w2IWuadTRzGzeBolzVp4gl/GLP9wT1H+cTjC7zCjgbxnwM7zLnxA
29
- F4XcKGArAMYd8GgHUTVwMsYP4XkM3CGWtuk8pmgCo2CKZA4PDrWYiuo+vtwFsgYJ
30
- hKe67BDNyG4DxJTu6tP979ZXanCYEDWmxJMSm4Ih9tObHryZc6xp1SsM4jPR6Mbt
31
- OWpW9iGQHkfCktjw+bYdDKVK8c0WU5PN
13
+ MIIDPDCCAiSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAkMSIwIAYDVQQDDBlwaGls
14
+ LnJvc3MvREM9Z21haWwvREM9Y29tMB4XDTE5MTIyNDE0NTU0N1oXDTM5MTIyNDE0
15
+ NTU0N1owJDEiMCAGA1UEAwwZcGhpbC5yb3NzL0RDPWdtYWlsL0RDPWNvbTCCASIw
16
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJGcwfqn4ZsmPl0b1Lt9dCzExrE5
17
+ EeP/CRQjBdGHkF+mSpi69XysxdwLdfg5SPr9LfxthUug4nNFd5fDCiXM8hYe9jQD
18
+ TmkIQKNBh4fFpGngn9gyy+SumCXi6b5L6d/aMc59NAOM6LJ88TOdH1648dh5rq3C
19
+ ULq82n3gg4+u0HHGjRPuR/pnCFQCZbANYdX+UBWd0qkOJn/EreNKROmEeHr/xKuh
20
+ 2/GlKFKt9KLcW3hwBB4fHHVYUzRau7D1m9KbEERdg//qNDC4B7fD2BFJuPbM5S7J
21
+ 41VwDAh1O8B/Qpg0f+S83K4Kodw4MiPGsug55UkNtd3mGR/zZJ9WM03DSwkCAwEA
22
+ AaN5MHcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFA+Z8zvfzBuA
23
+ esoHIfz7+jxfUOcfMB4GA1UdEQQXMBWBE3BoaWwucm9zc0BnbWFpbC5jb20wHgYD
24
+ VR0SBBcwFYETcGhpbC5yb3NzQGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA
25
+ J80xgZ3gGdQVA8N+8NJANU5HLuZIU9jOaAlziU9ImoTgPiOHKGZC4as1TwT4kBt1
26
+ Qcnu7YSANYRrxP5tpOHsWPF/MQYgerAFCZS5+PzOTudwZ+7OsMW4/EMHy6aCVHEd
27
+ c7HzQRC4mSrDRpWxzyBnZ5nX5OAmIkKA8NgeKybT/4Ku6iFPPUQwlyxQaO+Wlxdo
28
+ FqHwpjRyoiVSpe4RUTNK3d3qesWPYi7Lxn6k6ZZeEdvG6ya33AXktE3jmmF+jPR1
29
+ J3Zn/kSTjTekiaspyGbczC3PUaeJNxr+yCvR4sk71Xmk/GaKKGOHedJ1uj/LAXrA
30
+ MR0mpl7b8zCg0PFC1J73uw==
32
31
  -----END CERTIFICATE-----
33
- date: 2015-02-28 00:00:00.000000000 Z
32
+ date: 2021-02-27 00:00:00.000000000 Z
34
33
  dependencies:
35
34
  - !ruby/object:Gem::Dependency
36
35
  name: ffi
@@ -74,9 +73,12 @@ files:
74
73
  - lib/bzip2/ffi/version.rb
75
74
  - lib/bzip2/ffi/writer.rb
76
75
  - test/error_test.rb
77
- - test/fixtures/bzipped
76
+ - test/fixtures/compressed.bz2
77
+ - test/fixtures/lorem-4096-bytes-compressed.txt.bz2
78
+ - test/fixtures/lorem-first-structure-4096-bytes.txt.bz2
78
79
  - test/fixtures/lorem.txt
79
80
  - test/fixtures/moon.tiff
81
+ - test/fixtures/two_structures.bz2
80
82
  - test/fixtures/zero.txt
81
83
  - test/io_test.rb
82
84
  - test/reader_test.rb
@@ -86,7 +88,12 @@ files:
86
88
  homepage: https://github.com/philr/bzip2-ffi
87
89
  licenses:
88
90
  - MIT
89
- metadata: {}
91
+ metadata:
92
+ bug_tracker_uri: https://github.com/philr/bzip2-ffi/issues
93
+ changelog_uri: https://github.com/philr/bzip2-ffi/blob/master/CHANGES.md
94
+ documentation_uri: https://rubydoc.info/gems/bzip2-ffi/1.1.0
95
+ homepage_uri: https://github.com/philr/bzip2-ffi
96
+ source_code_uri: https://github.com/philr/bzip2-ffi/tree/v1.1.0
90
97
  post_install_message:
91
98
  rdoc_options:
92
99
  - "--title"
@@ -109,8 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
116
  version: '0'
110
117
  requirements:
111
118
  - libbz2.(so|dll|dylib) available on the library search path
112
- rubyforge_project:
113
- rubygems_version: 2.4.5
119
+ rubygems_version: 3.2.3
114
120
  signing_key:
115
121
  specification_version: 4
116
122
  summary: Reads and writes bzip2 compressed data using FFI bindings for libbz2.