compress-bsc 1.0.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +8 -0
- data/LICENSE +192 -0
- data/README.md +279 -0
- data/Rakefile +96 -0
- data/bin/rbsc +306 -0
- data/certs/djberg96_pub.pem +26 -0
- data/compress-bsc.gemspec +45 -0
- data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_asc.png +0 -0
- data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_asc_disabled.png +0 -0
- data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_both.png +0 -0
- data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_desc.png +0 -0
- data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_desc_disabled.png +0 -0
- data/coverage/assets/0.13.2/application.css +1 -0
- data/coverage/assets/0.13.2/application.js +7 -0
- data/coverage/assets/0.13.2/colorbox/border.png +0 -0
- data/coverage/assets/0.13.2/colorbox/controls.png +0 -0
- data/coverage/assets/0.13.2/colorbox/loading.gif +0 -0
- data/coverage/assets/0.13.2/colorbox/loading_background.png +0 -0
- data/coverage/assets/0.13.2/favicon_green.png +0 -0
- data/coverage/assets/0.13.2/favicon_red.png +0 -0
- data/coverage/assets/0.13.2/favicon_yellow.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.13.2/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.13.2/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.13.2/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.13.2/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.13.2/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.13.2/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/assets/0.13.2/loading.gif +0 -0
- data/coverage/assets/0.13.2/magnify.png +0 -0
- data/coverage/index.html +4779 -0
- data/examples/usage_example.rb +215 -0
- data/lib/compress/bsc/compressor.rb +81 -0
- data/lib/compress/bsc/decompressor.rb +159 -0
- data/lib/compress/bsc/error.rb +18 -0
- data/lib/compress/bsc/library.rb +100 -0
- data/lib/compress/bsc/version.rb +5 -0
- data/lib/compress/bsc.rb +26 -0
- data/lib/compress-bsc.rb +5 -0
- data/spec/compressor_spec.rb +124 -0
- data/spec/decompressor_spec.rb +135 -0
- data/spec/error_spec.rb +63 -0
- data/spec/examples.txt +60 -0
- data/spec/ffi_bsc_spec.rb +101 -0
- data/spec/library_spec.rb +97 -0
- data/spec/spec_helper.rb +53 -0
- data.tar.gz.sig +0 -0
- metadata +232 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Compress::BSC::Compressor do
|
4
|
+
let(:test_data) { "Hello, World! This is a test for BSC compression." * 50 }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'creates a compressor with default options' do
|
8
|
+
compressor = Compress::BSC::Compressor.new
|
9
|
+
expect(compressor.lzp_hash_size).to eq(0)
|
10
|
+
expect(compressor.lzp_min_len).to eq(0)
|
11
|
+
expect(compressor.block_sorter).to eq(Compress::BSC::Library::LIBBSC_DEFAULT_BLOCKSORTER)
|
12
|
+
expect(compressor.coder).to eq(Compress::BSC::Library::LIBBSC_DEFAULT_CODER)
|
13
|
+
expect(compressor.features).to eq(Compress::BSC::Library::LIBBSC_DEFAULT_FEATURES)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'creates a compressor with custom options' do
|
17
|
+
options = {
|
18
|
+
lzp_hash_size: 16,
|
19
|
+
lzp_min_len: 64,
|
20
|
+
block_sorter: Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT,
|
21
|
+
coder: Compress::BSC::Library::LIBBSC_CODER_QLFC_ADAPTIVE,
|
22
|
+
features: Compress::BSC::Library::LIBBSC_FEATURE_FASTMODE
|
23
|
+
}
|
24
|
+
|
25
|
+
compressor = Compress::BSC::Compressor.new(options)
|
26
|
+
expect(compressor.lzp_hash_size).to eq(16)
|
27
|
+
expect(compressor.lzp_min_len).to eq(64)
|
28
|
+
expect(compressor.block_sorter).to eq(Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT)
|
29
|
+
expect(compressor.coder).to eq(Compress::BSC::Library::LIBBSC_CODER_QLFC_ADAPTIVE)
|
30
|
+
expect(compressor.features).to eq(Compress::BSC::Library::LIBBSC_FEATURE_FASTMODE)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#compress' do
|
35
|
+
let(:compressor) { Compress::BSC::Compressor.new }
|
36
|
+
|
37
|
+
it 'compresses data successfully' do
|
38
|
+
result = compressor.compress(test_data)
|
39
|
+
expect(result).to be_a(String)
|
40
|
+
expect(result.bytesize).to be > 0
|
41
|
+
expect(result.bytesize).to be <= test_data.bytesize + Compress::BSC::Library::LIBBSC_HEADER_SIZE
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'handles empty data' do
|
45
|
+
result = compressor.compress("")
|
46
|
+
expect(result).to eq("")
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'handles small data' do
|
50
|
+
small_data = "Hi"
|
51
|
+
result = compressor.compress(small_data)
|
52
|
+
expect(result).to be_a(String)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'raises error for nil input' do
|
56
|
+
expect { compressor.compress(nil) }.to raise_error(ArgumentError, "Input data cannot be nil")
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'raises error for non-string input' do
|
60
|
+
expect { compressor.compress(123) }.to raise_error(ArgumentError, "Input data must be a string")
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with different compression settings' do
|
64
|
+
it 'compresses with LZP enabled' do
|
65
|
+
compressor = Compress::BSC::Compressor.new(
|
66
|
+
lzp_hash_size: Compress::BSC::Library::LIBBSC_DEFAULT_LZPHASHSIZE,
|
67
|
+
lzp_min_len: Compress::BSC::Library::LIBBSC_DEFAULT_LZPMINLEN
|
68
|
+
)
|
69
|
+
|
70
|
+
result = compressor.compress(test_data)
|
71
|
+
expect(result).to be_a(String)
|
72
|
+
expect(result.bytesize).to be > 0
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'compresses with different block sorters' do
|
76
|
+
[
|
77
|
+
Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT,
|
78
|
+
Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST3,
|
79
|
+
Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST4
|
80
|
+
].each do |sorter|
|
81
|
+
compressor = Compress::BSC::Compressor.new(block_sorter: sorter)
|
82
|
+
result = compressor.compress(test_data)
|
83
|
+
expect(result).to be_a(String)
|
84
|
+
expect(result.bytesize).to be > 0
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'compresses with different coders' do
|
89
|
+
[
|
90
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_STATIC,
|
91
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_ADAPTIVE,
|
92
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_FAST
|
93
|
+
].each do |coder|
|
94
|
+
compressor = Compress::BSC::Compressor.new(coder: coder)
|
95
|
+
result = compressor.compress(test_data)
|
96
|
+
expect(result).to be_a(String)
|
97
|
+
expect(result.bytesize).to be > 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#compress_file' do
|
104
|
+
let(:compressor) { Compress::BSC::Compressor.new }
|
105
|
+
let(:input_file) { 'spec/test_input.txt' }
|
106
|
+
let(:output_file) { 'spec/test_output.bsc' }
|
107
|
+
|
108
|
+
before do
|
109
|
+
File.write(input_file, test_data)
|
110
|
+
end
|
111
|
+
|
112
|
+
after do
|
113
|
+
[input_file, output_file].each { |f| File.delete(f) if File.exist?(f) }
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'compresses a file successfully' do
|
117
|
+
result_size = compressor.compress_file(input_file, output_file)
|
118
|
+
|
119
|
+
expect(File.exist?(output_file)).to be true
|
120
|
+
expect(result_size).to be > 0
|
121
|
+
expect(result_size).to eq(File.size(output_file))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Compress::BSC::Decompressor do
|
4
|
+
let(:test_data) { "Hello, World! This is a test for BSC decompression." * 50 }
|
5
|
+
let(:compressor) { Compress::BSC::Compressor.new }
|
6
|
+
let(:compressed_data) { compressor.compress(test_data) }
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'creates a decompressor with default options' do
|
10
|
+
decompressor = Compress::BSC::Decompressor.new
|
11
|
+
expect(decompressor.features).to eq(Compress::BSC::Library::LIBBSC_DEFAULT_FEATURES)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'creates a decompressor with custom options' do
|
15
|
+
decompressor = Compress::BSC::Decompressor.new(features: Compress::BSC::Library::LIBBSC_FEATURE_FASTMODE)
|
16
|
+
expect(decompressor.features).to eq(Compress::BSC::Library::LIBBSC_FEATURE_FASTMODE)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#decompress' do
|
21
|
+
let(:decompressor) { Compress::BSC::Decompressor.new }
|
22
|
+
|
23
|
+
it 'decompresses data successfully' do
|
24
|
+
result = decompressor.decompress(compressed_data)
|
25
|
+
expect(result).to eq(test_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'handles empty data' do
|
29
|
+
result = decompressor.decompress("")
|
30
|
+
expect(result).to eq("")
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'raises error for nil input' do
|
34
|
+
expect { decompressor.decompress(nil) }.to raise_error(ArgumentError, "Compressed data cannot be nil")
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'raises error for non-string input' do
|
38
|
+
expect { decompressor.decompress(123) }.to raise_error(ArgumentError, "Compressed data must be a string")
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'raises error for data too small to contain header' do
|
42
|
+
small_data = "x" * (Compress::BSC::Library::LIBBSC_HEADER_SIZE - 1)
|
43
|
+
expect { decompressor.decompress(small_data) }.to raise_error(Compress::BSC::Error)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'raises error for corrupted data' do
|
47
|
+
corrupted_data = "corrupted" + "\x00" * (Compress::BSC::Library::LIBBSC_HEADER_SIZE - 9)
|
48
|
+
expect { decompressor.decompress(corrupted_data) }.to raise_error(Compress::BSC::Error)
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with different compression settings' do
|
52
|
+
it 'decompresses data compressed with LZP' do
|
53
|
+
lzp_compressor = Compress::BSC::Compressor.new(
|
54
|
+
lzp_hash_size: Compress::BSC::Library::LIBBSC_DEFAULT_LZPHASHSIZE,
|
55
|
+
lzp_min_len: Compress::BSC::Library::LIBBSC_DEFAULT_LZPMINLEN
|
56
|
+
)
|
57
|
+
|
58
|
+
lzp_compressed = lzp_compressor.compress(test_data)
|
59
|
+
result = decompressor.decompress(lzp_compressed)
|
60
|
+
expect(result).to eq(test_data)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'decompresses data compressed with different block sorters' do
|
64
|
+
[
|
65
|
+
Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT,
|
66
|
+
Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST3,
|
67
|
+
Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST4
|
68
|
+
].each do |sorter|
|
69
|
+
sorter_compressor = Compress::BSC::Compressor.new(block_sorter: sorter)
|
70
|
+
sorter_compressed = sorter_compressor.compress(test_data)
|
71
|
+
result = decompressor.decompress(sorter_compressed)
|
72
|
+
expect(result).to eq(test_data)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'decompresses data compressed with different coders' do
|
77
|
+
[
|
78
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_STATIC,
|
79
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_ADAPTIVE,
|
80
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_FAST
|
81
|
+
].each do |coder|
|
82
|
+
coder_compressor = Compress::BSC::Compressor.new(coder: coder)
|
83
|
+
coder_compressed = coder_compressor.compress(test_data)
|
84
|
+
result = decompressor.decompress(coder_compressed)
|
85
|
+
expect(result).to eq(test_data)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#decompress_file' do
|
92
|
+
let(:decompressor) { Compress::BSC::Decompressor.new }
|
93
|
+
let(:input_file) { 'spec/test_compressed.bsc' }
|
94
|
+
let(:output_file) { 'spec/test_decompressed.txt' }
|
95
|
+
|
96
|
+
before do
|
97
|
+
File.binwrite(input_file, compressed_data)
|
98
|
+
end
|
99
|
+
|
100
|
+
after do
|
101
|
+
[input_file, output_file].each { |f| File.delete(f) if File.exist?(f) }
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'decompresses a file successfully' do
|
105
|
+
result_size = decompressor.decompress_file(input_file, output_file)
|
106
|
+
|
107
|
+
expect(File.exist?(output_file)).to be true
|
108
|
+
expect(result_size).to eq(test_data.bytesize)
|
109
|
+
expect(File.binread(output_file)).to eq(test_data)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '.block_info' do
|
114
|
+
it 'returns correct block information' do
|
115
|
+
info = Compress::BSC::Decompressor.block_info(compressed_data)
|
116
|
+
|
117
|
+
expect(info).to be_a(Hash)
|
118
|
+
expect(info[:block_size]).to be > 0
|
119
|
+
expect(info[:data_size]).to eq(test_data.bytesize)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'raises error for nil input' do
|
123
|
+
expect { Compress::BSC::Decompressor.block_info(nil) }.to raise_error(ArgumentError)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'raises error for non-string input' do
|
127
|
+
expect { Compress::BSC::Decompressor.block_info(123) }.to raise_error(ArgumentError)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'raises error for data too small' do
|
131
|
+
small_data = "x" * (Compress::BSC::Library::LIBBSC_HEADER_SIZE - 1)
|
132
|
+
expect { Compress::BSC::Decompressor.block_info(small_data) }.to raise_error(Compress::BSC::Error)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
data/spec/error_spec.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Compress::BSC::Error do
|
4
|
+
describe '#initialize' do
|
5
|
+
it 'creates an error with code and message' do
|
6
|
+
error = Compress::BSC::Error.new(Compress::BSC::Library::LIBBSC_BAD_PARAMETER)
|
7
|
+
|
8
|
+
expect(error.code).to eq(Compress::BSC::Library::LIBBSC_BAD_PARAMETER)
|
9
|
+
expect(error.error_name).to eq('LIBBSC_BAD_PARAMETER')
|
10
|
+
expect(error.message).to include('LIBBSC_BAD_PARAMETER')
|
11
|
+
expect(error.message).to include(Compress::BSC::Library::LIBBSC_BAD_PARAMETER.to_s)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'handles unknown error codes' do
|
15
|
+
unknown_code = -999
|
16
|
+
error = Compress::BSC::Error.new(unknown_code)
|
17
|
+
|
18
|
+
expect(error.code).to eq(unknown_code)
|
19
|
+
expect(error.error_name).to eq("UNKNOWN_ERROR(#{unknown_code})")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '.check_result' do
|
24
|
+
it 'returns the result for successful operations' do
|
25
|
+
result = Compress::BSC::Error.check_result(Compress::BSC::Library::LIBBSC_NO_ERROR)
|
26
|
+
expect(result).to eq(Compress::BSC::Library::LIBBSC_NO_ERROR)
|
27
|
+
|
28
|
+
positive_result = Compress::BSC::Error.check_result(100)
|
29
|
+
expect(positive_result).to eq(100)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'raises error for negative error codes' do
|
33
|
+
expect {
|
34
|
+
Compress::BSC::Error.check_result(Compress::BSC::Library::LIBBSC_BAD_PARAMETER)
|
35
|
+
}.to raise_error(Compress::BSC::Error) do |error|
|
36
|
+
expect(error.code).to eq(Compress::BSC::Library::LIBBSC_BAD_PARAMETER)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'handles all defined error codes' do
|
41
|
+
error_codes = [
|
42
|
+
Compress::BSC::Library::LIBBSC_BAD_PARAMETER,
|
43
|
+
Compress::BSC::Library::LIBBSC_NOT_ENOUGH_MEMORY,
|
44
|
+
Compress::BSC::Library::LIBBSC_NOT_COMPRESSIBLE,
|
45
|
+
Compress::BSC::Library::LIBBSC_NOT_SUPPORTED,
|
46
|
+
Compress::BSC::Library::LIBBSC_UNEXPECTED_EOB,
|
47
|
+
Compress::BSC::Library::LIBBSC_DATA_CORRUPT,
|
48
|
+
Compress::BSC::Library::LIBBSC_GPU_ERROR,
|
49
|
+
Compress::BSC::Library::LIBBSC_GPU_NOT_SUPPORTED,
|
50
|
+
Compress::BSC::Library::LIBBSC_GPU_NOT_ENOUGH_MEMORY
|
51
|
+
]
|
52
|
+
|
53
|
+
error_codes.each do |code|
|
54
|
+
expect {
|
55
|
+
Compress::BSC::Error.check_result(code)
|
56
|
+
}.to raise_error(Compress::BSC::Error) do |error|
|
57
|
+
expect(error.code).to eq(code)
|
58
|
+
expect(error.error_name).not_to include('UNKNOWN_ERROR')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/spec/examples.txt
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
example_id | status | run_time |
|
2
|
+
------------------------------------ | ------ | --------------- |
|
3
|
+
./spec/compressor_spec.rb[1:1:1] | passed | 0.00046 seconds |
|
4
|
+
./spec/compressor_spec.rb[1:1:2] | passed | 0.00007 seconds |
|
5
|
+
./spec/compressor_spec.rb[1:2:1] | passed | 0.00191 seconds |
|
6
|
+
./spec/compressor_spec.rb[1:2:2] | passed | 0.00008 seconds |
|
7
|
+
./spec/compressor_spec.rb[1:2:3] | passed | 0.0009 seconds |
|
8
|
+
./spec/compressor_spec.rb[1:2:4] | passed | 0.00011 seconds |
|
9
|
+
./spec/compressor_spec.rb[1:2:5] | passed | 0.00008 seconds |
|
10
|
+
./spec/compressor_spec.rb[1:2:6:1] | passed | 0.00207 seconds |
|
11
|
+
./spec/compressor_spec.rb[1:2:6:2] | passed | 0.00662 seconds |
|
12
|
+
./spec/compressor_spec.rb[1:2:6:3] | passed | 0.00215 seconds |
|
13
|
+
./spec/compressor_spec.rb[1:3:1] | passed | 0.0103 seconds |
|
14
|
+
./spec/decompressor_spec.rb[1:1:1] | passed | 0.00005 seconds |
|
15
|
+
./spec/decompressor_spec.rb[1:1:2] | passed | 0.00007 seconds |
|
16
|
+
./spec/decompressor_spec.rb[1:2:1] | passed | 0.00274 seconds |
|
17
|
+
./spec/decompressor_spec.rb[1:2:2] | passed | 0.00009 seconds |
|
18
|
+
./spec/decompressor_spec.rb[1:2:3] | passed | 0.00024 seconds |
|
19
|
+
./spec/decompressor_spec.rb[1:2:4] | passed | 0.00016 seconds |
|
20
|
+
./spec/decompressor_spec.rb[1:2:5] | passed | 0.00009 seconds |
|
21
|
+
./spec/decompressor_spec.rb[1:2:6] | passed | 0.00013 seconds |
|
22
|
+
./spec/decompressor_spec.rb[1:2:7:1] | passed | 0.00278 seconds |
|
23
|
+
./spec/decompressor_spec.rb[1:2:7:2] | passed | 0.00569 seconds |
|
24
|
+
./spec/decompressor_spec.rb[1:2:7:3] | passed | 0.00429 seconds |
|
25
|
+
./spec/decompressor_spec.rb[1:3:1] | passed | 0.00213 seconds |
|
26
|
+
./spec/decompressor_spec.rb[1:4:1] | passed | 0.00091 seconds |
|
27
|
+
./spec/decompressor_spec.rb[1:4:2] | passed | 0.0001 seconds |
|
28
|
+
./spec/decompressor_spec.rb[1:4:3] | passed | 0.00009 seconds |
|
29
|
+
./spec/decompressor_spec.rb[1:4:4] | passed | 0.00006 seconds |
|
30
|
+
./spec/error_spec.rb[1:1:1] | passed | 0.005 seconds |
|
31
|
+
./spec/error_spec.rb[1:1:2] | passed | 0.00146 seconds |
|
32
|
+
./spec/error_spec.rb[1:2:1] | passed | 0.00006 seconds |
|
33
|
+
./spec/error_spec.rb[1:2:2] | passed | 0.00174 seconds |
|
34
|
+
./spec/error_spec.rb[1:2:3] | passed | 0.00035 seconds |
|
35
|
+
./spec/ffi_bsc_spec.rb[1:1:1] | passed | 0.00062 seconds |
|
36
|
+
./spec/ffi_bsc_spec.rb[1:2:1:1] | passed | 0.00368 seconds |
|
37
|
+
./spec/ffi_bsc_spec.rb[1:2:2:1] | passed | 0.00042 seconds |
|
38
|
+
./spec/ffi_bsc_spec.rb[1:2:3:1] | passed | 0.00041 seconds |
|
39
|
+
./spec/ffi_bsc_spec.rb[1:2:4:1] | passed | 0.00197 seconds |
|
40
|
+
./spec/ffi_bsc_spec.rb[1:2:4:2] | passed | 0.0017 seconds |
|
41
|
+
./spec/ffi_bsc_spec.rb[1:2:5:1] | passed | 0.00048 seconds |
|
42
|
+
./spec/ffi_bsc_spec.rb[1:2:5:2] | passed | 0.00057 seconds |
|
43
|
+
./spec/ffi_bsc_spec.rb[1:2:5:3] | passed | 0.00041 seconds |
|
44
|
+
./spec/ffi_bsc_spec.rb[1:3:1] | passed | 0.00036 seconds |
|
45
|
+
./spec/ffi_bsc_spec.rb[1:3:2] | passed | 0.00102 seconds |
|
46
|
+
./spec/ffi_bsc_spec.rb[1:3:3] | passed | 0.00164 seconds |
|
47
|
+
./spec/ffi_bsc_spec.rb[1:3:4] | passed | 0.00207 seconds |
|
48
|
+
./spec/ffi_bsc_spec.rb[1:3:5] | passed | 0.00164 seconds |
|
49
|
+
./spec/ffi_bsc_spec.rb[1:3:6] | passed | 0.00033 seconds |
|
50
|
+
./spec/library_spec.rb[1:1:1] | passed | 0.00006 seconds |
|
51
|
+
./spec/library_spec.rb[1:1:2] | passed | 0.00007 seconds |
|
52
|
+
./spec/library_spec.rb[1:1:3] | passed | 0.00035 seconds |
|
53
|
+
./spec/library_spec.rb[1:1:4] | passed | 0.00006 seconds |
|
54
|
+
./spec/library_spec.rb[1:1:5] | passed | 0.00006 seconds |
|
55
|
+
./spec/library_spec.rb[1:1:6] | passed | 0.00006 seconds |
|
56
|
+
./spec/library_spec.rb[1:1:7] | passed | 0.00005 seconds |
|
57
|
+
./spec/library_spec.rb[1:2:1] | passed | 0.00038 seconds |
|
58
|
+
./spec/library_spec.rb[1:2:2] | passed | 0.00006 seconds |
|
59
|
+
./spec/library_spec.rb[1:3:1] | passed | 0.00232 seconds |
|
60
|
+
./spec/library_spec.rb[1:3:2] | passed | 0.00044 seconds |
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Compress::BSC do
|
4
|
+
let(:bsc) { Compress::BSC.new }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'initializes the BSC library without error' do
|
8
|
+
expect { Compress::BSC.new }.not_to raise_error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#compress and #decompress' do
|
13
|
+
let(:test_data) { "Hello, World! This is a test string for BSC compression." * 100 }
|
14
|
+
let(:empty_data) { "" }
|
15
|
+
let(:small_data) { "Hi" }
|
16
|
+
|
17
|
+
context 'with regular data' do
|
18
|
+
it 'compresses and decompresses data correctly' do
|
19
|
+
compressed = bsc.compress(test_data)
|
20
|
+
expect(compressed).to be_a(String)
|
21
|
+
expect(compressed.bytesize).to be > 0
|
22
|
+
|
23
|
+
decompressed = bsc.decompress(compressed)
|
24
|
+
expect(decompressed).to eq(test_data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with empty data' do
|
29
|
+
it 'handles empty data correctly' do
|
30
|
+
compressed = bsc.compress(empty_data)
|
31
|
+
expect(compressed).to eq(empty_data)
|
32
|
+
|
33
|
+
decompressed = bsc.decompress(empty_data)
|
34
|
+
expect(decompressed).to eq(empty_data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with small data' do
|
39
|
+
it 'handles small data correctly' do
|
40
|
+
compressed = bsc.compress(small_data)
|
41
|
+
expect(compressed).to be_a(String)
|
42
|
+
|
43
|
+
decompressed = bsc.decompress(compressed)
|
44
|
+
expect(decompressed).to eq(small_data)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with different compression options' do
|
49
|
+
it 'compresses with BWT block sorter' do
|
50
|
+
compressed = bsc.compress(test_data, block_sorter: Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT)
|
51
|
+
decompressed = bsc.decompress(compressed)
|
52
|
+
expect(decompressed).to eq(test_data)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'compresses with different coders' do
|
56
|
+
Compress::BSC::Library::LIBBSC_CODER_QLFC_STATIC.tap do |coder|
|
57
|
+
compressed = bsc.compress(test_data, coder: coder)
|
58
|
+
decompressed = bsc.decompress(compressed)
|
59
|
+
expect(decompressed).to eq(test_data)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'error handling' do
|
65
|
+
it 'raises error for nil input' do
|
66
|
+
expect { bsc.compress(nil) }.to raise_error(ArgumentError)
|
67
|
+
expect { bsc.decompress(nil) }.to raise_error(ArgumentError)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'raises error for non-string input' do
|
71
|
+
expect { bsc.compress(123) }.to raise_error(ArgumentError)
|
72
|
+
expect { bsc.decompress(123) }.to raise_error(ArgumentError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'raises error for corrupted compressed data' do
|
76
|
+
corrupted_data = "corrupted" + "\x00" * 20
|
77
|
+
expect { bsc.decompress(corrupted_data) }.to raise_error(Compress::BSC::Error)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'round-trip compression with various data types' do
|
83
|
+
test_data = [
|
84
|
+
"Simple ASCII text",
|
85
|
+
"Unicode text: 你好世界 🌍",
|
86
|
+
"\x00\x01\x02\x03" * 100, # Binary data
|
87
|
+
"A" * 10000, # Repetitive data
|
88
|
+
Random.bytes(1000), # Random data
|
89
|
+
"Mixed\x00data\xFF\x80with\x01binary"
|
90
|
+
]
|
91
|
+
|
92
|
+
test_data.each_with_index do |data, index|
|
93
|
+
it "correctly handles test case #{index + 1}" do
|
94
|
+
compressed = bsc.compress(data)
|
95
|
+
decompressed = bsc.decompress(compressed)
|
96
|
+
expect(decompressed).to eq(data)
|
97
|
+
expect(decompressed.encoding).to eq(data.encoding)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Compress::BSC::Library do
|
4
|
+
describe 'constants' do
|
5
|
+
it 'defines version constants' do
|
6
|
+
expect(Compress::BSC::Library::LIBBSC_VERSION_MAJOR).to eq(3)
|
7
|
+
expect(Compress::BSC::Library::LIBBSC_VERSION_MINOR).to eq(3)
|
8
|
+
expect(Compress::BSC::Library::LIBBSC_VERSION_PATCH).to eq(9)
|
9
|
+
expect(Compress::BSC::Library::LIBBSC_VERSION_STRING).to eq("3.3.9")
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'defines error constants' do
|
13
|
+
expect(Compress::BSC::Library::LIBBSC_NO_ERROR).to eq(0)
|
14
|
+
expect(Compress::BSC::Library::LIBBSC_BAD_PARAMETER).to eq(-1)
|
15
|
+
expect(Compress::BSC::Library::LIBBSC_NOT_ENOUGH_MEMORY).to eq(-2)
|
16
|
+
expect(Compress::BSC::Library::LIBBSC_NOT_COMPRESSIBLE).to eq(-3)
|
17
|
+
expect(Compress::BSC::Library::LIBBSC_NOT_SUPPORTED).to eq(-4)
|
18
|
+
expect(Compress::BSC::Library::LIBBSC_UNEXPECTED_EOB).to eq(-5)
|
19
|
+
expect(Compress::BSC::Library::LIBBSC_DATA_CORRUPT).to eq(-6)
|
20
|
+
expect(Compress::BSC::Library::LIBBSC_GPU_ERROR).to eq(-7)
|
21
|
+
expect(Compress::BSC::Library::LIBBSC_GPU_NOT_SUPPORTED).to eq(-8)
|
22
|
+
expect(Compress::BSC::Library::LIBBSC_GPU_NOT_ENOUGH_MEMORY).to eq(-9)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'defines block sorter constants' do
|
26
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_NONE).to eq(0)
|
27
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT).to eq(1)
|
28
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST3).to eq(3)
|
29
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST4).to eq(4)
|
30
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST5).to eq(5)
|
31
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST6).to eq(6)
|
32
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST7).to eq(7)
|
33
|
+
expect(Compress::BSC::Library::LIBBSC_BLOCKSORTER_ST8).to eq(8)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'defines coder constants' do
|
37
|
+
expect(Compress::BSC::Library::LIBBSC_CODER_NONE).to eq(0)
|
38
|
+
expect(Compress::BSC::Library::LIBBSC_CODER_QLFC_STATIC).to eq(1)
|
39
|
+
expect(Compress::BSC::Library::LIBBSC_CODER_QLFC_ADAPTIVE).to eq(2)
|
40
|
+
expect(Compress::BSC::Library::LIBBSC_CODER_QLFC_FAST).to eq(3)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'defines feature constants' do
|
44
|
+
expect(Compress::BSC::Library::LIBBSC_FEATURE_NONE).to eq(0)
|
45
|
+
expect(Compress::BSC::Library::LIBBSC_FEATURE_FASTMODE).to eq(1)
|
46
|
+
expect(Compress::BSC::Library::LIBBSC_FEATURE_MULTITHREADING).to eq(2)
|
47
|
+
expect(Compress::BSC::Library::LIBBSC_FEATURE_LARGEPAGES).to eq(4)
|
48
|
+
expect(Compress::BSC::Library::LIBBSC_FEATURE_CUDA).to eq(8)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'defines default constants' do
|
52
|
+
expect(Compress::BSC::Library::LIBBSC_DEFAULT_LZPHASHSIZE).to eq(15)
|
53
|
+
expect(Compress::BSC::Library::LIBBSC_DEFAULT_LZPMINLEN).to eq(128)
|
54
|
+
expect(Compress::BSC::Library::LIBBSC_DEFAULT_BLOCKSORTER).to eq(Compress::BSC::Library::LIBBSC_BLOCKSORTER_BWT)
|
55
|
+
expect(Compress::BSC::Library::LIBBSC_DEFAULT_CODER).to eq(Compress::BSC::Library::LIBBSC_CODER_QLFC_STATIC)
|
56
|
+
expect(Compress::BSC::Library::LIBBSC_DEFAULT_FEATURES).to eq(
|
57
|
+
Compress::BSC::Library::LIBBSC_FEATURE_FASTMODE | Compress::BSC::Library::LIBBSC_FEATURE_MULTITHREADING
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'defines header size constant' do
|
62
|
+
expect(Compress::BSC::Library::LIBBSC_HEADER_SIZE).to eq(28)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '.error_name' do
|
67
|
+
it 'returns correct error names for known codes' do
|
68
|
+
expect(Compress::BSC::Library.error_name(Compress::BSC::Library::LIBBSC_NO_ERROR)).to eq('LIBBSC_NO_ERROR')
|
69
|
+
expect(Compress::BSC::Library.error_name(Compress::BSC::Library::LIBBSC_BAD_PARAMETER)).to eq('LIBBSC_BAD_PARAMETER')
|
70
|
+
expect(Compress::BSC::Library.error_name(Compress::BSC::Library::LIBBSC_NOT_ENOUGH_MEMORY)).to eq('LIBBSC_NOT_ENOUGH_MEMORY')
|
71
|
+
expect(Compress::BSC::Library.error_name(Compress::BSC::Library::LIBBSC_DATA_CORRUPT)).to eq('LIBBSC_DATA_CORRUPT')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'returns unknown error format for unknown codes' do
|
75
|
+
expect(Compress::BSC::Library.error_name(-999)).to eq('UNKNOWN_ERROR(-999)')
|
76
|
+
expect(Compress::BSC::Library.error_name(123)).to eq('UNKNOWN_ERROR(123)')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'function bindings' do
|
81
|
+
it 'has the required function bindings' do
|
82
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_init)
|
83
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_init_full)
|
84
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_compress)
|
85
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_decompress)
|
86
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_block_info)
|
87
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_malloc)
|
88
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_zero_malloc)
|
89
|
+
expect(Compress::BSC::Library).to respond_to(:bsc_free)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'can call bsc_init successfully' do
|
93
|
+
result = Compress::BSC::Library.bsc_init(Compress::BSC::Library::LIBBSC_DEFAULT_FEATURES)
|
94
|
+
expect(result).to eq(Compress::BSC::Library::LIBBSC_NO_ERROR)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Coverage reporting setup
|
2
|
+
if ENV['COVERAGE']
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start do
|
5
|
+
add_filter '/spec/'
|
6
|
+
add_filter '/examples/'
|
7
|
+
add_filter '/bin/'
|
8
|
+
coverage_dir 'coverage'
|
9
|
+
|
10
|
+
add_group 'Library', 'lib'
|
11
|
+
|
12
|
+
# Minimum coverage thresholds
|
13
|
+
minimum_coverage 80
|
14
|
+
minimum_coverage_by_file 70
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require_relative '../lib/compress/bsc'
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.expect_with :rspec do |expectations|
|
22
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
23
|
+
end
|
24
|
+
|
25
|
+
config.mock_with :rspec do |mocks|
|
26
|
+
mocks.verify_partial_doubles = true
|
27
|
+
end
|
28
|
+
|
29
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
30
|
+
config.filter_run_when_matching :focus
|
31
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
32
|
+
config.disable_monkey_patching!
|
33
|
+
config.warnings = true
|
34
|
+
|
35
|
+
config.default_formatter = "doc" if config.files_to_run.one?
|
36
|
+
|
37
|
+
config.profile_examples = 10
|
38
|
+
config.order = :random
|
39
|
+
Kernel.srand config.seed
|
40
|
+
|
41
|
+
# Initialize BSC library before running tests
|
42
|
+
config.before(:suite) do
|
43
|
+
begin
|
44
|
+
Compress::BSC.new
|
45
|
+
rescue Compress::BSC::Error => e
|
46
|
+
warn "Warning: Could not initialize BSC library: #{e.message}"
|
47
|
+
warn "Some tests may fail. Please ensure libbsc is installed."
|
48
|
+
rescue LoadError => e
|
49
|
+
warn "Warning: Could not load BSC library: #{e.message}"
|
50
|
+
warn "Please install libbsc library. See README for instructions."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|