adsp 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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +1 -0
  3. data/LICENSE +21 -0
  4. data/README.md +300 -0
  5. data/lib/adsp/error.rb +14 -0
  6. data/lib/adsp/file.rb +76 -0
  7. data/lib/adsp/option.rb +51 -0
  8. data/lib/adsp/stream/abstract.rb +206 -0
  9. data/lib/adsp/stream/delegates.rb +39 -0
  10. data/lib/adsp/stream/raw/abstract.rb +69 -0
  11. data/lib/adsp/stream/raw/compressor.rb +110 -0
  12. data/lib/adsp/stream/raw/decompressor.rb +80 -0
  13. data/lib/adsp/stream/raw/native_compressor.rb +58 -0
  14. data/lib/adsp/stream/raw/native_decompressor.rb +44 -0
  15. data/lib/adsp/stream/reader.rb +234 -0
  16. data/lib/adsp/stream/reader_helpers.rb +219 -0
  17. data/lib/adsp/stream/stat.rb +80 -0
  18. data/lib/adsp/stream/writer.rb +206 -0
  19. data/lib/adsp/stream/writer_helpers.rb +102 -0
  20. data/lib/adsp/string.rb +58 -0
  21. data/lib/adsp/validation.rb +46 -0
  22. data/lib/adsp/version.rb +7 -0
  23. data/lib/adsp.rb +8 -0
  24. data/test/common.rb +108 -0
  25. data/test/coverage_helper.rb +18 -0
  26. data/test/file.test.rb +120 -0
  27. data/test/minitest.rb +20 -0
  28. data/test/mock/common.rb +57 -0
  29. data/test/mock/file.rb +60 -0
  30. data/test/mock/stream/raw/compressor.rb +20 -0
  31. data/test/mock/stream/raw/decompressor.rb +20 -0
  32. data/test/mock/stream/raw/native_compressor.rb +82 -0
  33. data/test/mock/stream/raw/native_decompressor.rb +70 -0
  34. data/test/mock/stream/reader.rb +18 -0
  35. data/test/mock/stream/writer.rb +18 -0
  36. data/test/mock/string.rb +44 -0
  37. data/test/option.rb +66 -0
  38. data/test/stream/abstract.rb +125 -0
  39. data/test/stream/minitar.test.rb +50 -0
  40. data/test/stream/raw/abstract.rb +45 -0
  41. data/test/stream/raw/compressor.test.rb +166 -0
  42. data/test/stream/raw/decompressor.test.rb +166 -0
  43. data/test/stream/reader.test.rb +643 -0
  44. data/test/stream/reader_helpers.test.rb +421 -0
  45. data/test/stream/writer.test.rb +610 -0
  46. data/test/stream/writer_helpers.test.rb +267 -0
  47. data/test/string.test.rb +95 -0
  48. data/test/validation.rb +71 -0
  49. data/test/version.test.rb +18 -0
  50. metadata +274 -0
@@ -0,0 +1,267 @@
1
+ # Abstract data stream processor.
2
+ # Copyright (c) 2021 AUTHORS, MIT License.
3
+
4
+ require "English"
5
+ require "stringio"
6
+
7
+ require_relative "../common"
8
+ require_relative "../minitest"
9
+ require_relative "../option"
10
+ require_relative "../validation"
11
+ require_relative "../mock/stream/writer"
12
+ require_relative "../mock/string"
13
+
14
+ module ADSP
15
+ module Test
16
+ module Stream
17
+ class WriterHelpers < Minitest::Test
18
+ Target = Mock::Stream::Writer
19
+ String = Mock::String
20
+
21
+ ARCHIVE_PATH = Common::ARCHIVE_PATH
22
+ TEXTS = Common::TEXTS
23
+ LARGE_TEXTS = Common::LARGE_TEXTS
24
+ PORTION_LENGTHS = Common::PORTION_LENGTHS
25
+ LARGE_PORTION_LENGTHS = Common::LARGE_PORTION_LENGTHS
26
+
27
+ BUFFER_LENGTH_NAMES = %i[destination_buffer_length].freeze
28
+ BUFFER_LENGTH_MAPPING = { :destination_buffer_length => :destination_buffer_length }.freeze
29
+
30
+ def test_write
31
+ parallel_compressor_options do |compressor_options, worker_index|
32
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
33
+
34
+ TEXTS.each do |text|
35
+ PORTION_LENGTHS.each do |portion_length|
36
+ sources = get_sources text, portion_length
37
+
38
+ Target.open archive_path, compressor_options do |instance|
39
+ sources.each { |current_source| instance << current_source }
40
+ end
41
+
42
+ compressed_text = ::File.read archive_path, :mode => "rb"
43
+
44
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
45
+ check_text text, compressed_text, decompressor_options
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def test_print
53
+ parallel_compressor_options do |compressor_options, worker_index|
54
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
55
+
56
+ TEXTS.reject(&:empty?).each do |text|
57
+ PORTION_LENGTHS.each do |portion_length|
58
+ sources = get_sources text, portion_length
59
+ field_separator = " ".encode text.encoding
60
+ record_separator = "\n".encode text.encoding
61
+
62
+ target_text = "".encode text.encoding
63
+ sources.each { |source| target_text << (source + field_separator) }
64
+ target_text << record_separator
65
+
66
+ Target.open archive_path, compressor_options do |instance|
67
+ keyword_args = { :field_separator => field_separator, :record_separator => record_separator }
68
+ instance.print(*sources, **keyword_args)
69
+ end
70
+
71
+ compressed_text = ::File.read archive_path, :mode => "rb"
72
+
73
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
74
+ check_text target_text, compressed_text, decompressor_options
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def test_printf
82
+ parallel_compressor_options do |compressor_options, worker_index|
83
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
84
+
85
+ TEXTS.each do |text|
86
+ PORTION_LENGTHS.each do |portion_length|
87
+ sources = get_sources text, portion_length
88
+
89
+ Target.open archive_path, compressor_options do |instance|
90
+ sources.each { |source| instance.printf "%s", source }
91
+ end
92
+
93
+ compressed_text = ::File.read archive_path, :mode => "rb"
94
+
95
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
96
+ check_text text, compressed_text, decompressor_options
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ def test_invalid_putc
104
+ instance = target.new ::StringIO.new
105
+
106
+ Validation::INVALID_CHARS.each do |invalid_char|
107
+ assert_raises ValidateError do
108
+ instance.putc invalid_char
109
+ end
110
+ end
111
+ end
112
+
113
+ def test_putc
114
+ parallel_compressor_options do |compressor_options, worker_index|
115
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
116
+
117
+ TEXTS.each do |text|
118
+ Target.open archive_path, compressor_options do |instance|
119
+ # Putc should process numbers and strings.
120
+ text.chars.each.with_index do |char, index|
121
+ if index.even?
122
+ instance.putc char.ord, :encoding => text.encoding
123
+ else
124
+ instance.putc char
125
+ end
126
+ end
127
+ end
128
+
129
+ compressed_text = ::File.read archive_path, :mode => "rb"
130
+
131
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
132
+ check_text text, compressed_text, decompressor_options
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ def test_puts
139
+ parallel_compressor_options do |compressor_options, worker_index|
140
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
141
+
142
+ TEXTS.each do |text|
143
+ PORTION_LENGTHS.each do |portion_length|
144
+ newline = "\n".encode text.encoding
145
+
146
+ sources = get_sources text, portion_length
147
+ sources = sources.map do |source|
148
+ source.delete_suffix! newline while source.end_with? newline
149
+ source
150
+ end
151
+
152
+ target_text = "".encode text.encoding
153
+ sources.each { |source| target_text << (source + newline) }
154
+
155
+ Target.open archive_path, compressor_options do |instance|
156
+ # Puts should ignore additional newlines and process arrays.
157
+ args = sources.map.with_index do |source, index|
158
+ if index.even?
159
+ source + newline
160
+ else
161
+ [source]
162
+ end
163
+ end
164
+
165
+ instance.puts(*args)
166
+ end
167
+
168
+ compressed_text = ::File.read archive_path, :mode => "rb"
169
+
170
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
171
+ check_text target_text, compressed_text, decompressor_options
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ def test_invalid_open
179
+ Validation::INVALID_STRINGS.each do |invalid_string|
180
+ assert_raises ValidateError do
181
+ Target.open(invalid_string) {} # no-op
182
+ end
183
+ end
184
+
185
+ # Proc is required.
186
+ assert_raises ValidateError do
187
+ Target.open ARCHIVE_PATH
188
+ end
189
+ end
190
+
191
+ def test_open
192
+ parallel_compressor_options do |compressor_options, worker_index|
193
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
194
+
195
+ TEXTS.each do |text|
196
+ Target.open(archive_path, compressor_options) { |instance| instance.write text }
197
+
198
+ compressed_text = ::File.read archive_path, :mode => "rb"
199
+
200
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
201
+ check_text text, compressed_text, decompressor_options
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ def test_open_with_large_texts
208
+ options_generator = OCG.new(
209
+ :text => LARGE_TEXTS,
210
+ :portion_length => LARGE_PORTION_LENGTHS
211
+ )
212
+
213
+ Common.parallel_options options_generator do |options, worker_index|
214
+ text = options[:text]
215
+ portion_length = options[:portion_length]
216
+
217
+ archive_path = Common.get_path ARCHIVE_PATH, worker_index
218
+
219
+ sources = get_sources text, portion_length
220
+
221
+ Target.open archive_path do |instance|
222
+ sources.each { |source| instance.write source }
223
+ end
224
+
225
+ compressed_text = ::File.read archive_path, :mode => "rb"
226
+
227
+ check_text text, compressed_text, {}
228
+ end
229
+ end
230
+
231
+ # -----
232
+
233
+ protected def get_sources(text, portion_length)
234
+ sources = text
235
+ .chars
236
+ .each_slice(portion_length)
237
+ .map(&:join)
238
+
239
+ return [""] if sources.empty?
240
+
241
+ sources
242
+ end
243
+
244
+ protected def check_text(text, compressed_text, decompressor_options)
245
+ decompressed_text = String.decompress compressed_text, decompressor_options
246
+ decompressed_text.force_encoding text.encoding
247
+
248
+ assert_equal text, decompressed_text
249
+ end
250
+
251
+ def parallel_compressor_options(&block)
252
+ Common.parallel_options Option.get_compressor_options_generator(BUFFER_LENGTH_NAMES), &block
253
+ end
254
+
255
+ def get_compatible_decompressor_options(compressor_options, &block)
256
+ Option.get_compatible_decompressor_options compressor_options, BUFFER_LENGTH_MAPPING, &block
257
+ end
258
+
259
+ protected def target
260
+ self.class::Target
261
+ end
262
+ end
263
+
264
+ Minitest << WriterHelpers
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,95 @@
1
+ # Abstract data stream processor.
2
+ # Copyright (c) 2021 AUTHORS, MIT License.
3
+
4
+ require "adsp/string"
5
+
6
+ require_relative "common"
7
+ require_relative "minitest"
8
+ require_relative "mock/string"
9
+ require_relative "option"
10
+ require_relative "validation"
11
+
12
+ module ADSP
13
+ module Test
14
+ class String < Minitest::Test
15
+ Option = Test::Option
16
+ Target = Mock::String
17
+
18
+ TEXTS = Common::TEXTS
19
+ LARGE_TEXTS = Common::LARGE_TEXTS
20
+
21
+ BUFFER_LENGTH_NAMES = %i[destination_buffer_length].freeze
22
+ BUFFER_LENGTH_MAPPING = { :destination_buffer_length => :destination_buffer_length }.freeze
23
+
24
+ def test_invalid_arguments
25
+ Validation::INVALID_STRINGS.each do |invalid_string|
26
+ assert_raises ValidateError do
27
+ Target.compress invalid_string
28
+ end
29
+
30
+ assert_raises ValidateError do
31
+ Target.decompress invalid_string
32
+ end
33
+ end
34
+
35
+ get_invalid_compressor_options do |invalid_options|
36
+ assert_raises ValidateError do
37
+ Target.compress "", invalid_options
38
+ end
39
+ end
40
+
41
+ get_invalid_decompressor_options do |invalid_options|
42
+ assert_raises ValidateError do
43
+ Target.decompress "", invalid_options
44
+ end
45
+ end
46
+ end
47
+
48
+ def test_texts
49
+ parallel_compressor_options do |compressor_options|
50
+ TEXTS.each do |text|
51
+ compressed_text = Target.compress text, compressor_options
52
+
53
+ get_compatible_decompressor_options compressor_options do |decompressor_options|
54
+ decompressed_text = Target.decompress compressed_text, decompressor_options
55
+ decompressed_text.force_encoding text.encoding
56
+
57
+ assert_equal text, decompressed_text
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def test_large_texts
64
+ Common.parallel LARGE_TEXTS do |text|
65
+ compressed_text = Target.compress text
66
+
67
+ decompressed_text = Target.decompress compressed_text
68
+ decompressed_text.force_encoding text.encoding
69
+
70
+ assert_equal text, decompressed_text
71
+ end
72
+ end
73
+
74
+ # -----
75
+
76
+ def get_invalid_compressor_options(&block)
77
+ self.class::Option.get_invalid_compressor_options BUFFER_LENGTH_NAMES, &block
78
+ end
79
+
80
+ def get_invalid_decompressor_options(&block)
81
+ self.class::Option.get_invalid_decompressor_options BUFFER_LENGTH_NAMES, &block
82
+ end
83
+
84
+ def parallel_compressor_options(&block)
85
+ Common.parallel_options self.class::Option.get_compressor_options_generator(BUFFER_LENGTH_NAMES), &block
86
+ end
87
+
88
+ def get_compatible_decompressor_options(compressor_options, &block)
89
+ self.class::Option.get_compatible_decompressor_options compressor_options, BUFFER_LENGTH_MAPPING, &block
90
+ end
91
+ end
92
+
93
+ Minitest << String
94
+ end
95
+ end
@@ -0,0 +1,71 @@
1
+ # Abstract data stream processor.
2
+ # Copyright (c) 2021 AUTHORS, MIT License.
3
+
4
+ require "stringio"
5
+
6
+ module ADSP
7
+ module Test
8
+ module Validation
9
+ NOOP_PROC = proc {} # no-op
10
+
11
+ TYPES = [
12
+ nil,
13
+ 1,
14
+ 1.1,
15
+ "1",
16
+ true,
17
+ "a",
18
+ :a,
19
+ {},
20
+ [],
21
+ $stdout,
22
+ ::StringIO,
23
+ NOOP_PROC
24
+ ]
25
+ .freeze
26
+
27
+ INVALID_INTEGERS = (TYPES - [1]).freeze
28
+ INVALID_NUMBERS = (TYPES - [1, 1.1]).freeze
29
+ INVALID_BOOLS = (TYPES - [true]).freeze
30
+ INVALID_STRINGS = (TYPES - %w[1 a]).freeze
31
+ INVALID_SYMBOLS = (TYPES - %i[a]).freeze
32
+ INVALID_ARRAYS = (TYPES - [[]]).freeze
33
+ INVALID_HASHES = (TYPES - [{}]).freeze
34
+ INVALID_CHARS = (INVALID_NUMBERS & INVALID_STRINGS).freeze
35
+
36
+ INVALID_POSITIVE_INTEGERS = (INVALID_INTEGERS + [0, -1]).freeze
37
+ INVALID_NOT_NEGATIVE_INTEGERS = (INVALID_POSITIVE_INTEGERS - [0]).freeze
38
+
39
+ INVALID_ENCODINGS = %w[
40
+ ISO_8859_0
41
+ UTF-15
42
+ UTF-33
43
+ ]
44
+ .freeze
45
+
46
+ class StringIOWithoutEOF < ::StringIO
47
+ undef :eof?
48
+ end
49
+
50
+ class StringIOWithoutRead < ::StringIO
51
+ undef :read
52
+ end
53
+
54
+ class StringIOWithoutReadNonblock < ::StringIO
55
+ undef :read_nonblock
56
+ end
57
+
58
+ class StringIOWithoutReadpartial < ::StringIO
59
+ undef :readpartial
60
+ end
61
+
62
+ class StringIOWithoutWrite < ::StringIO
63
+ undef :write
64
+ end
65
+
66
+ class StringIOWithoutWriteNonblock < ::StringIO
67
+ undef :write_nonblock
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,18 @@
1
+ # Abstract data stream processor.
2
+ # Copyright (c) 2021 AUTHORS, MIT License.
3
+
4
+ require "adsp"
5
+
6
+ require_relative "minitest"
7
+
8
+ module ADSP
9
+ module Test
10
+ class Version < Minitest::Test
11
+ def test_version
12
+ refute_nil ADSP::VERSION
13
+ end
14
+ end
15
+
16
+ Minitest << Version
17
+ end
18
+ end