external 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History +5 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +168 -0
  4. data/lib/ext_arc.rb +108 -0
  5. data/lib/ext_arr.rb +727 -0
  6. data/lib/ext_ind.rb +1120 -0
  7. data/lib/external/base.rb +85 -0
  8. data/lib/external/chunkable.rb +105 -0
  9. data/lib/external/enumerable.rb +137 -0
  10. data/lib/external/io.rb +398 -0
  11. data/lib/external.rb +3 -0
  12. data/test/benchmarks/benchmarks_20070918.txt +45 -0
  13. data/test/benchmarks/benchmarks_20070921.txt +91 -0
  14. data/test/benchmarks/benchmarks_20071006.txt +147 -0
  15. data/test/benchmarks/test_copy_file.rb +80 -0
  16. data/test/benchmarks/test_pos_speed.rb +47 -0
  17. data/test/benchmarks/test_read_time.rb +55 -0
  18. data/test/cached_ext_ind_test.rb +219 -0
  19. data/test/check/benchmark_check.rb +441 -0
  20. data/test/check/namespace_conflicts_check.rb +23 -0
  21. data/test/check/pack_check.rb +90 -0
  22. data/test/ext_arc_test.rb +286 -0
  23. data/test/ext_arr/alt_sep.txt +3 -0
  24. data/test/ext_arr/cr_lf_input.txt +3 -0
  25. data/test/ext_arr/input.index +0 -0
  26. data/test/ext_arr/input.txt +1 -0
  27. data/test/ext_arr/inputb.index +0 -0
  28. data/test/ext_arr/inputb.txt +1 -0
  29. data/test/ext_arr/lf_input.txt +3 -0
  30. data/test/ext_arr/lines.txt +19 -0
  31. data/test/ext_arr/without_index.txt +1 -0
  32. data/test/ext_arr_test.rb +534 -0
  33. data/test/ext_ind_test.rb +1472 -0
  34. data/test/external/base_test.rb +74 -0
  35. data/test/external/chunkable_test.rb +182 -0
  36. data/test/external/index/input.index +0 -0
  37. data/test/external/index/inputb.index +0 -0
  38. data/test/external/io_test.rb +414 -0
  39. data/test/external_test_helper.rb +31 -0
  40. data/test/external_test_suite.rb +4 -0
  41. data/test/test_array.rb +1192 -0
  42. metadata +104 -0
@@ -0,0 +1,74 @@
1
+ require File.join(File.dirname(__FILE__), '../external_test_helper.rb')
2
+ require 'external/base'
3
+ require 'tempfile'
4
+
5
+ class BaseTest < Test::Unit::TestCase
6
+ include Benchmark
7
+ include External
8
+
9
+ acts_as_file_test
10
+
11
+ attr_reader :array, :ab, :tempfile
12
+
13
+ def setup
14
+ @array = ('a'..'z').to_a
15
+ @tempfile = Tempfile.new("abtest")
16
+ @tempfile << array.to_s
17
+ @ab = Base.new(@tempfile)
18
+ end
19
+
20
+ def teardown
21
+ tempfile.close unless tempfile.closed?
22
+ end
23
+
24
+ #
25
+ # setup tests
26
+ #
27
+
28
+ def test_setup
29
+ assert_equal ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"], array
30
+ assert_equal "abcdefghijklmnopqrstuvwxyz", array.to_s
31
+
32
+ tempfile.pos = 0
33
+ assert_equal "abcdefghijklmnopqrstuvwxyz", tempfile.read
34
+ end
35
+
36
+ #
37
+ # initialize test
38
+ #
39
+
40
+ def test_io_points_to_tempfile_when_io_is_nil
41
+ begin
42
+ ab = Base.new(nil)
43
+ assert ab.io != nil
44
+ assert_equal Tempfile, ab.io.class
45
+ assert ab.io.path =~ Regexp.new("^" + Dir.tmpdir)
46
+ ensure
47
+ ab.close if ab
48
+ end
49
+ end
50
+
51
+ # def test_options_are_set_during_initialize
52
+ # assert_equal 10000, ab.max_gap
53
+ # assert_equal 1000000, ab.max_chunk_size
54
+ #
55
+ # ab = Base.new(nil, :max_gap => 1, :max_chunk_size => 10)
56
+ # assert_equal 1, ab.max_gap
57
+ # assert_equal 10, ab.max_chunk_size
58
+ # end
59
+
60
+ #
61
+ # close, closed? test
62
+ #
63
+
64
+ def test_close_closes_io
65
+ assert !ab.io.closed?
66
+ ab.close
67
+ assert ab.io.closed?
68
+ end
69
+
70
+ def test_closed_returns_closed_state_of_io
71
+ ab.io.close
72
+ assert ab.closed?
73
+ end
74
+ end
@@ -0,0 +1,182 @@
1
+ require File.join(File.dirname(__FILE__), '../external_test_helper.rb')
2
+ require 'external/chunkable'
3
+ require 'pp'
4
+
5
+ class ChunkableTest < Test::Unit::TestCase
6
+ include Benchmark
7
+ include External::Chunkable
8
+
9
+ def setup
10
+ @default_blksize = 100
11
+ @length = 10
12
+ end
13
+
14
+ def pps(obj)
15
+ PP.singleline_pp(obj, "")
16
+ end
17
+
18
+ def test_setup
19
+ assert_equal 100, default_blksize
20
+ assert_equal 10, length
21
+ end
22
+
23
+ #
24
+ # default_span
25
+ #
26
+
27
+ def test_default_span_is_zero_to_length
28
+ assert_equal [0,length], default_span
29
+ end
30
+
31
+ #
32
+ # split_range
33
+ #
34
+
35
+ def test_split_range_doc
36
+ assert_equal 10, length
37
+ assert_equal [0,10], split_range(0..10)
38
+ assert_equal [0,9], split_range(0...10)
39
+ assert_equal [9,1], split_range(-1..10)
40
+ assert_equal [0,9], split_range(0..-1)
41
+ end
42
+
43
+ def test_split_range
44
+ {
45
+ 0..100 => [0,100],
46
+ 0...100 => [0, 99],
47
+ 1..100 => [1,99],
48
+ 1...100 => [1,98]
49
+ }.each_pair do |range, expected|
50
+ assert_equal expected, split_range(range), range
51
+ end
52
+ end
53
+
54
+ def test_split_range_for_negative_indicies_counts_back_from_length
55
+ assert_equal 10, length
56
+ {
57
+ # for begin index
58
+ -1..100 => [9,91], # equivalent to 9..100
59
+ -1...100 => [9,90],
60
+ -2..100 => [8,92],
61
+ -2...100 => [8,91],
62
+ -11..100 => [-1,101],
63
+ -11...100 => [-1,100],
64
+
65
+ # for end index
66
+ 0..-1 => [0,9], # equivalent to 0..9
67
+ 0...-1 => [0,8],
68
+ 0..-10 => [0,0]
69
+ }.each_pair do |range, expected|
70
+ assert_equal expected, split_range(range), range
71
+ end
72
+ end
73
+
74
+ def test_split_range_for_zero_cases
75
+ {
76
+ 0..0 => [0,0],
77
+ 0...0 => [0,-1],
78
+ -0..-0 => [0,0],
79
+ -0...-0 => [0,-1]
80
+ }.each_pair do |range, expected|
81
+ assert_equal expected, split_range(range), range
82
+ end
83
+ end
84
+
85
+ #
86
+ # chunk tests
87
+ #
88
+
89
+ def test_chunk_documentation
90
+ assert_equal 100, default_blksize
91
+ assert_equal [[0,100],[100,100],[200,50]], chunk(0..250)
92
+
93
+ results = []
94
+ chunk([10,190]) {|offset, length| results << [offset, length]}
95
+ assert_equal [[10,100],[110,90]], results
96
+ end
97
+
98
+ def test_chunk_returns_offset_and_length_of_each_chunk
99
+ assert_equal [[0,99]], chunk([0,99])
100
+ assert_equal [[0,100]], chunk([0,100])
101
+ assert_equal [[0,100],[100,1]], chunk([0,101])
102
+ assert_equal [[0,100],[100,100],[200,100]], chunk([0,300])
103
+ assert_equal [[50,100],[150,100],[250,50]], chunk([50,250])
104
+
105
+ # zero or neg length
106
+ assert_equal [], chunk([0,0])
107
+ assert_equal [], chunk([0,-1])
108
+
109
+ # neg index
110
+ assert_equal [[9,100]], chunk([-1,100])
111
+ assert_equal [[0,100]], chunk([-10,100])
112
+ assert_raise(ArgumentError) { chunk([-11,100]) }
113
+ assert_raise(ArgumentError) { chunk([-11,0]) }
114
+ end
115
+
116
+ def test_chunk_uses_default_span_without_inputs
117
+ assert_equal [0,10], default_span
118
+ assert_equal [[0,10]], chunk
119
+
120
+ self.length = 300
121
+ assert_equal [0, 300], default_span
122
+ assert_equal [[0,100],[100,100],[200,100]], chunk
123
+ end
124
+
125
+ def test_chunk_passes_results_to_block_if_given
126
+ results = []
127
+ chunk([0,300]) do |offset, length|
128
+ results << [offset, length]
129
+ end
130
+
131
+ assert_equal [[0,100],[100, 100],[200, 100]], results
132
+ end
133
+
134
+ #
135
+ # reverse chunk tests
136
+ #
137
+
138
+ def test_reverse_chunk_documentation
139
+ assert_equal 100, default_blksize
140
+ assert_equal [[150,100],[50,100],[0,50]], reverse_chunk(0..250)
141
+
142
+ results = []
143
+ reverse_chunk([10,190]) {|offset, length| results << [offset, length]}
144
+ assert_equal [[100,100],[10,90]], results
145
+ end
146
+
147
+ def test_reverse_chunk_returns_offset_and_length_of_each_chunk
148
+ assert_equal [[0,99]], reverse_chunk([0,99])
149
+ assert_equal [[0,100]], reverse_chunk([0,100])
150
+ assert_equal [[1,100],[0,1]], reverse_chunk([0,101])
151
+ assert_equal [[200,100],[100,100],[0,100]], reverse_chunk([0,300])
152
+ assert_equal [[200,100],[100,100],[50,50]], reverse_chunk([50,250])
153
+
154
+ # zero or neg length
155
+ assert_equal [], reverse_chunk([0,0])
156
+ assert_equal [], reverse_chunk([0,-1])
157
+
158
+ # neg index
159
+ assert_equal [[9,100]], reverse_chunk([-1,100])
160
+ assert_equal [[0,100]], reverse_chunk([-10,100])
161
+ assert_raise(ArgumentError) { reverse_chunk([-11,100]) }
162
+ assert_raise(ArgumentError) { reverse_chunk([-11,0]) }
163
+ end
164
+
165
+ def test_reverse_chunk_uses_default_span_without_inputs
166
+ assert_equal [0,10], default_span
167
+ assert_equal [[0,10]], reverse_chunk
168
+
169
+ self.length = 300
170
+ assert_equal [0,300], default_span
171
+ assert_equal [[200,100],[100,100],[0,100]], reverse_chunk
172
+ end
173
+
174
+ def test_reverse_chunk_passes_results_to_block_if_given
175
+ results = []
176
+ reverse_chunk([0,300]) do |offset, length|
177
+ results << [offset, length]
178
+ end
179
+
180
+ assert_equal [[200,100],[100,100],[0,100]], results
181
+ end
182
+ end
Binary file
Binary file
@@ -0,0 +1,414 @@
1
+ require File.join(File.dirname(__FILE__), '../external_test_helper.rb')
2
+ require 'external/io'
3
+
4
+ class IOTest < Test::Unit::TestCase
5
+ include External
6
+
7
+ def std_class_test(data)
8
+ Tempfile.open("file_test") do |tempfile|
9
+ tempfile << data
10
+ tempfile.flush
11
+
12
+ File.open(tempfile.path, "r+") do |file|
13
+ file.extend IO
14
+ yield(file)
15
+ end
16
+ end
17
+
18
+ Tempfile.open("tempfile_test") do |tempfile|
19
+ tempfile << data
20
+ tempfile.extend IO
21
+
22
+ yield(tempfile)
23
+ end
24
+
25
+ Tempfile.open("strio_test") do |tempfile|
26
+ tempfile << data
27
+ tempfile.flush
28
+
29
+ tempfile.pos = 0
30
+ StringIO.open(tempfile.read, "r+") do |file|
31
+ file.extend IO
32
+ yield(file)
33
+ end
34
+ end
35
+ end
36
+
37
+ #
38
+ # length test
39
+ #
40
+
41
+ def test_length_is_set_to_file_size_upon_extend_for_file
42
+ # File
43
+ t = Tempfile.new "position_test"
44
+ t << "abcd"
45
+ t.close
46
+
47
+ File.open(t.path, "r+") do |file|
48
+ file.extend IO
49
+ assert_equal 4, file.length
50
+ assert_equal 4, File.size(file.path)
51
+ end
52
+
53
+ # Tempfile
54
+ t = Tempfile.new "position_test"
55
+ t << "abcd"
56
+ t.fsync
57
+ assert_equal 4, File.size(t.path)
58
+
59
+ t.extend IO
60
+ assert_equal 4, t.length
61
+
62
+ t.close
63
+ end
64
+
65
+ def test_length_does_NOT_automatically_correspond_to_file_size
66
+ t = Tempfile.new "position_test"
67
+ t.close
68
+
69
+ assert_equal 0, File.size(t.path)
70
+ File.open(t.path, "r+") do |file|
71
+ file.extend IO
72
+
73
+ assert_equal 0, file.length
74
+ assert_equal 0, File.size(t.path)
75
+
76
+ file << "abcd"
77
+ file.fsync
78
+
79
+ assert_equal 0, file.length
80
+ assert_equal 4, File.size(t.path)
81
+ end
82
+
83
+
84
+ # Tempfile
85
+ t = Tempfile.new "position_test"
86
+ t.extend IO
87
+
88
+ assert_equal 0, t.length
89
+ assert_equal 0, File.size(t.path)
90
+
91
+ t << "abcd"
92
+ t.fsync
93
+
94
+ assert_equal 0, t.length
95
+ assert_equal 4, File.size(t.path)
96
+
97
+ t.close
98
+ end
99
+
100
+ #
101
+ # reset length test
102
+ #
103
+
104
+ def test_reset_length_resets_length_to_file_size
105
+ # File
106
+ t = Tempfile.new "position_test"
107
+ t.close
108
+
109
+ File.open(t.path, "r+") do |file|
110
+ file.extend IO
111
+
112
+ assert_equal 0, file.length
113
+ assert_equal 0, File.size(file.path)
114
+
115
+ file << "abcd"
116
+ file.fsync
117
+
118
+ assert_equal 0, file.length
119
+ assert_equal 4, File.size(t.path)
120
+
121
+ file.reset_length
122
+
123
+ assert_equal 4, file.length
124
+ end
125
+
126
+ # Tempfile
127
+ t = Tempfile.new "position_test"
128
+ t.extend IO
129
+
130
+ assert_equal 0, t.length
131
+ assert_equal 0, File.size(t.path)
132
+
133
+ t << "abcd"
134
+ t.fsync
135
+
136
+ assert_equal 0, t.length
137
+ assert_equal 4, File.size(t.path)
138
+
139
+ t.reset_length
140
+
141
+ assert_equal 4, t.length
142
+
143
+ t.close
144
+ end
145
+
146
+ #
147
+ # position test
148
+ #
149
+
150
+ def two_gb_size
151
+ 2147483647
152
+ end
153
+
154
+ def test_position_mswin
155
+ platform_test('mswin') do
156
+ prompt_test(:path_to_large_file) do |path|
157
+ path = $1 if path =~ /^"([^"]*)"$/
158
+
159
+ File.open(path) do |file|
160
+ file.extend IO
161
+
162
+ # stat.size < 0 due to windows bug
163
+ assert file.stat.size < 0, "File size must be > 2GB (only #{file.length/two_gb_size})"
164
+ assert file.length > two_gb_size + 5, "File size must be > 2GB (only #{file.length/two_gb_size})"
165
+
166
+ file.pos = two_gb_size
167
+ assert_equal two_gb_size, file.pos
168
+ ten_bytes = file.read(10)
169
+
170
+ file.pos = two_gb_size + 5
171
+ assert_equal two_gb_size + 5, file.pos
172
+ five_bytes = file.read(5)
173
+
174
+ assert_equal ten_bytes[5..-1], five_bytes
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ def test_position
181
+ platform_test('non_mswin') do
182
+ prompt_test(:path_to_large_file) do |path|
183
+ path = $1 if path =~ /^"([^"]*)"$/
184
+
185
+ File.open(path) do |file|
186
+ file.extend IO
187
+
188
+ assert file.length > (two_gb_size + 5), "File size must be > 2GB (only #{file.length/two_gb_size})"
189
+
190
+ file.pos = two_gb_size
191
+ assert_equal two_gb_size, file.pos
192
+ ten_bytes = file.read(10)
193
+
194
+ file.pos = two_gb_size + 5
195
+ assert_equal two_gb_size + 5, file.pos
196
+ five_bytes = file.read(5)
197
+
198
+ assert_equal ten_bytes[5..-1], five_bytes
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ #
205
+ # generic_mode test
206
+ #
207
+
208
+ def test_generic_modes_are_determined_correctly
209
+ {
210
+ "r" => "r",
211
+ "r+" => "r+",
212
+ "w" => "w",
213
+ "w+" => "r+",
214
+ "a" => "w",
215
+ "a+" => "r+"
216
+ }.each_pair do |mode, expected|
217
+ Tempfile.open("position_test") do |t|
218
+ File.open(t.path, mode) do |file|
219
+ file.extend IO
220
+ assert_equal expected, file.generic_mode, mode
221
+ assert !file.closed?
222
+ end
223
+ end
224
+
225
+ StringIO.open("", mode) do |file|
226
+ file.extend IO
227
+ assert_equal expected, file.generic_mode, mode
228
+ assert !file.closed?
229
+ end
230
+ end
231
+ end
232
+
233
+ #
234
+ # quick_compare test
235
+ #
236
+
237
+ def test_quick_compare_true_if_another_is_self
238
+ std_class_test("") do |io|
239
+ assert io.quick_compare(io)
240
+ end
241
+ end
242
+
243
+ def test_quick_compare_true_if_paths_of_self_and_another_are_the_same
244
+ Tempfile.open("a") do |a|
245
+ a.extend IO
246
+
247
+ File.open(a.path) do |b|
248
+ b.extend IO
249
+
250
+ assert a != b
251
+ assert a.path == b.path
252
+ assert a.quick_compare(b)
253
+ end
254
+ end
255
+ end
256
+
257
+ #
258
+ # <=> test
259
+ #
260
+
261
+ def test_sort_compare_with_self
262
+ std_class_test("") do |io|
263
+ assert_equal 0, (io <=> io)
264
+ end
265
+ end
266
+
267
+ def test_sort_compare_with_same_file
268
+ Tempfile.open("a") do |a|
269
+ a.extend IO
270
+
271
+ File.open(a.path) do |b|
272
+ b.extend IO
273
+
274
+ assert a != b
275
+ assert a.path == b.path
276
+ assert_equal 0, (a <=> b)
277
+ end
278
+ end
279
+ end
280
+
281
+ def test_sort_compare_with_unequal_lengths
282
+ Tempfile.open("a") do |a|
283
+ a << "abcd"
284
+ a.extend IO
285
+
286
+ Tempfile.open("b") do |b|
287
+ b << "abc"
288
+ b.extend IO
289
+
290
+ assert !a.quick_compare(b)
291
+ assert_equal 1, ("abcd" <=> "abc")
292
+ assert_equal 1, (a <=> b)
293
+
294
+ assert_equal -1, ("abc" <=> "abcd")
295
+ assert_equal -1, (b <=> a)
296
+ end
297
+ end
298
+ end
299
+
300
+ def test_sort_compare
301
+ Tempfile.open("a") do |a|
302
+ a << "abcd"
303
+ a.extend IO
304
+
305
+ Tempfile.open("b") do |b|
306
+ b << "abcz"
307
+ b.extend IO
308
+
309
+ assert_equal -1, ("abcd" <=> "abcz")
310
+ assert_equal -1, (a <=> b)
311
+
312
+ assert_equal 1, ("abcz" <=> "abcd")
313
+ assert_equal 1, (b <=> a)
314
+ end
315
+ end
316
+ end
317
+
318
+ def test_sort_compare_same_content
319
+ Tempfile.open("a") do |a|
320
+ a.extend IO
321
+ a << "abcd"
322
+
323
+ Tempfile.open("b") do |b|
324
+ b.extend IO
325
+ b << "abcd"
326
+
327
+ assert a.path != b.path
328
+ assert_equal 0, (a <=> b)
329
+ end
330
+ end
331
+ end
332
+
333
+ def test_sort_compare_no_content
334
+ Tempfile.open("a") do |a|
335
+ a.extend IO
336
+
337
+ Tempfile.open("b") do |b|
338
+ b.extend IO
339
+
340
+ assert a.path != b.path
341
+ assert_equal 0, (a <=> b)
342
+ end
343
+ end
344
+ end
345
+
346
+ def test_sort_compare_with_different_underlying_io_types
347
+ Tempfile.open("a") do |a|
348
+ a << "abcd"
349
+ a.extend IO
350
+
351
+ StringIO.open("abcz") do |b|
352
+ b.extend IO
353
+
354
+ assert_equal -1, ("abcd" <=> "abcz")
355
+ assert_equal -1, (a <=> b)
356
+
357
+ assert_equal 1, ("abcz" <=> "abcd")
358
+ assert_equal 1, (b <=> a)
359
+ end
360
+ end
361
+ end
362
+
363
+ #
364
+ # copy test
365
+ #
366
+
367
+ def test_std_class_test
368
+ classes = []
369
+ std_class_test("some data") do |io|
370
+ assert io.kind_of?(IO)
371
+ assert "r+", io.generic_mode
372
+
373
+ io.pos = 0
374
+ assert_equal "some data", io.read
375
+
376
+ # the new data will throw the previous assertion
377
+ # if the ios are not independent
378
+ io << " new data"
379
+ io.pos = 0
380
+ assert_equal "some data new data", io.read
381
+
382
+ classes << io.class
383
+ end
384
+
385
+ assert_equal [File, Tempfile, StringIO], classes
386
+ end
387
+
388
+ def test_copy_opens_a_copy_in_read_mode
389
+ data = "test data"
390
+
391
+ std_class_test(data) do |io|
392
+ copy_path = nil
393
+ io.copy do |copy|
394
+ assert_equal "r", copy.generic_mode
395
+ assert_equal data, copy.read
396
+
397
+ copy_path = copy.path
398
+ assert_not_equal io.path, copy_path
399
+ end
400
+
401
+ assert !copy_path.nil?
402
+ assert !File.exists?(copy_path)
403
+ end
404
+ end
405
+
406
+ def test_copy_opens_copy_in_mode_if_provided
407
+ std_class_test("") do |io|
408
+ assert_equal "r+", io.generic_mode
409
+ io.copy("w") do |copy|
410
+ assert_equal "w", copy.generic_mode
411
+ end
412
+ end
413
+ end
414
+ end
@@ -0,0 +1,31 @@
1
+ require 'tap'
2
+ require 'tap/test/file_methods'
3
+ require 'tap/test/subset_methods'
4
+
5
+ require File.join(File.dirname(__FILE__), 'test_array.rb')
6
+
7
+ class Test::Unit::TestCase
8
+ include Tap::Test::SubsetMethods
9
+
10
+ # method to duplicate one of the source files to a target file
11
+ def dup_file(source_base, target_base)
12
+ filepath = tempfile(target_base)
13
+ FileUtils.cp(source_base + '.txt', filepath + ".txt")
14
+ FileUtils.cp(source_base + '.index', filepath + ".index")
15
+
16
+ filepath + ".txt"
17
+ end
18
+
19
+ #
20
+ # The default data
21
+ #
22
+
23
+ def string
24
+ "abcdefgh"
25
+ end
26
+
27
+ def array
28
+ ["a", "b", "c", "d", "e", "f", "g", "h"]
29
+ end
30
+
31
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '../lib')
2
+
3
+ #ENV["ALL"] = 'true'
4
+ Dir.glob("./**/*_test.rb").each {|test| require test}