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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +2 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +192 -0
  6. data/README.md +279 -0
  7. data/Rakefile +96 -0
  8. data/bin/rbsc +306 -0
  9. data/certs/djberg96_pub.pem +26 -0
  10. data/compress-bsc.gemspec +45 -0
  11. data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_asc.png +0 -0
  12. data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_asc_disabled.png +0 -0
  13. data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_both.png +0 -0
  14. data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_desc.png +0 -0
  15. data/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_desc_disabled.png +0 -0
  16. data/coverage/assets/0.13.2/application.css +1 -0
  17. data/coverage/assets/0.13.2/application.js +7 -0
  18. data/coverage/assets/0.13.2/colorbox/border.png +0 -0
  19. data/coverage/assets/0.13.2/colorbox/controls.png +0 -0
  20. data/coverage/assets/0.13.2/colorbox/loading.gif +0 -0
  21. data/coverage/assets/0.13.2/colorbox/loading_background.png +0 -0
  22. data/coverage/assets/0.13.2/favicon_green.png +0 -0
  23. data/coverage/assets/0.13.2/favicon_red.png +0 -0
  24. data/coverage/assets/0.13.2/favicon_yellow.png +0 -0
  25. data/coverage/assets/0.13.2/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  26. data/coverage/assets/0.13.2/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  27. data/coverage/assets/0.13.2/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  28. data/coverage/assets/0.13.2/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  29. data/coverage/assets/0.13.2/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  30. data/coverage/assets/0.13.2/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  31. data/coverage/assets/0.13.2/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  32. data/coverage/assets/0.13.2/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  33. data/coverage/assets/0.13.2/images/ui-icons_222222_256x240.png +0 -0
  34. data/coverage/assets/0.13.2/images/ui-icons_2e83ff_256x240.png +0 -0
  35. data/coverage/assets/0.13.2/images/ui-icons_454545_256x240.png +0 -0
  36. data/coverage/assets/0.13.2/images/ui-icons_888888_256x240.png +0 -0
  37. data/coverage/assets/0.13.2/images/ui-icons_cd0a0a_256x240.png +0 -0
  38. data/coverage/assets/0.13.2/loading.gif +0 -0
  39. data/coverage/assets/0.13.2/magnify.png +0 -0
  40. data/coverage/index.html +4779 -0
  41. data/examples/usage_example.rb +215 -0
  42. data/lib/compress/bsc/compressor.rb +81 -0
  43. data/lib/compress/bsc/decompressor.rb +159 -0
  44. data/lib/compress/bsc/error.rb +18 -0
  45. data/lib/compress/bsc/library.rb +100 -0
  46. data/lib/compress/bsc/version.rb +5 -0
  47. data/lib/compress/bsc.rb +26 -0
  48. data/lib/compress-bsc.rb +5 -0
  49. data/spec/compressor_spec.rb +124 -0
  50. data/spec/decompressor_spec.rb +135 -0
  51. data/spec/error_spec.rb +63 -0
  52. data/spec/examples.txt +60 -0
  53. data/spec/ffi_bsc_spec.rb +101 -0
  54. data/spec/library_spec.rb +97 -0
  55. data/spec/spec_helper.rb +53 -0
  56. data.tar.gz.sig +0 -0
  57. metadata +232 -0
  58. 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
@@ -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
@@ -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