adsp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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