1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
5 require "arvados/collection"
6 require "minitest/autorun"
9 class CollectionTest < Minitest::Test
12 TWO_BY_TWO_BLOCKS = SDKFixtures.random_blocks(2, 9)
13 TWO_BY_TWO_MANIFEST_A =
14 [". #{TWO_BY_TWO_BLOCKS.first} 0:5:f1 5:4:f2\n",
15 "./s1 #{TWO_BY_TWO_BLOCKS.last} 0:5:f1 5:4:f3\n"]
16 TWO_BY_TWO_MANIFEST_S = TWO_BY_TWO_MANIFEST_A.join("")
20 def test_empty_construction
21 coll = Arv::Collection.new
22 assert_equal("", coll.manifest_text)
25 def test_successful_construction
26 [:SIMPLEST_MANIFEST, :MULTIBLOCK_FILE_MANIFEST, :MULTILEVEL_MANIFEST].
27 each do |manifest_name|
28 manifest_text = SDKFixtures.const_get(manifest_name)
29 coll = Arv::Collection.new(manifest_text)
30 assert_equal(manifest_text, coll.manifest_text,
31 "did not get same manifest back out from #{manifest_name}")
35 def test_non_manifest_construction_error
36 ["word", ". abc def", ". #{random_block} 0:", ". / !"].each do |m_text|
37 assert_raises(ArgumentError,
38 "built collection from manifest #{m_text.inspect}") do
39 Arv::Collection.new(m_text)
44 def test_file_directory_conflict_construction_error
45 assert_raises(ArgumentError) do
46 Arv::Collection.new(NAME_CONFLICT_MANIFEST)
50 def test_no_implicit_normalization
51 coll = Arv::Collection.new(NONNORMALIZED_MANIFEST)
52 assert_equal(NONNORMALIZED_MANIFEST, coll.manifest_text)
57 def test_non_posix_path_handling
58 m_text = "./.. #{random_block(9)} 0:5:. 5:4:..\n"
59 coll = Arv::Collection.new(m_text.dup)
61 assert_equal(m_text, coll.manifest_text)
64 def test_escaping_through_normalization
65 coll = Arv::Collection.new(MANY_ESCAPES_MANIFEST)
67 # The result should simply duplicate the file spec.
68 # The source file spec has an unescaped backslash in it.
69 # It's OK for the Collection class to properly escape that.
70 expect_text = MANY_ESCAPES_MANIFEST.sub(/ \d+:\d+:\S+/) do |file_spec|
71 file_spec.gsub(/([^\\])(\\[^\\\d])/, '\1\\\\\2')
73 assert_equal(expect_text, coll.manifest_text)
76 def test_concatenation_with_locator_overlap(over_index=0)
77 blocks = random_blocks(4, 2)
78 blocks_s = blocks.join(" ")
79 coll = Arv::Collection.new(". %s 0:8:file\n. %s 0:4:file\n" %
80 [blocks_s, blocks[over_index, 2].join(" ")])
82 assert_equal(". #{blocks_s} 0:8:file #{over_index * 2}:4:file\n",
86 def test_concatenation_with_middle_locator_overlap
87 test_concatenation_with_locator_overlap(1)
90 def test_concatenation_with_end_locator_overlap
91 test_concatenation_with_locator_overlap(2)
94 def test_concatenation_with_partial_locator_overlap
95 blocks = random_blocks(3, 3)
96 coll = Arv::Collection
97 .new(". %s 0:6:overlap\n. %s 0:6:overlap\n" %
98 [blocks[0, 2].join(" "), blocks[1, 2].join(" ")])
100 assert_equal(". #{blocks.join(' ')} 0:6:overlap 3:6:overlap\n",
106 coll = Arv::Collection.new(". #{block} 0:0:f2 0:0:f1\n")
108 assert_equal(". #{block} 0:0:f1 0:0:f2\n", coll.manifest_text)
111 def test_normalization_file_spans_two_whole_blocks(file_specs="0:10:f1",
113 blocks = random_blocks(num_blocks, 5)
114 m_text = ". #{blocks.join(' ')} #{file_specs}\n"
115 coll = Arv::Collection.new(m_text.dup)
117 assert_equal(m_text, coll.manifest_text)
120 def test_normalization_file_fits_beginning_block
121 test_normalization_file_spans_two_whole_blocks("0:7:f1")
124 def test_normalization_file_fits_end_block
125 test_normalization_file_spans_two_whole_blocks("3:7:f1")
128 def test_normalization_file_spans_middle
129 test_normalization_file_spans_two_whole_blocks("3:5:f1")
132 def test_normalization_file_spans_three_whole_blocks
133 test_normalization_file_spans_two_whole_blocks("0:15:f1", 3)
136 def test_normalization_file_skips_bytes
137 test_normalization_file_spans_two_whole_blocks("0:3:f1 5:5:f1")
140 def test_normalization_file_inserts_bytes
141 test_normalization_file_spans_two_whole_blocks("0:3:f1 5:3:f1 3:2:f1")
144 def test_normalization_file_duplicates_bytes
145 test_normalization_file_spans_two_whole_blocks("2:3:f1 2:3:f1", 1)
148 def test_normalization_dedups_locators
149 blocks = random_blocks(2, 5)
150 coll = Arv::Collection.new(". %s %s 1:8:f1 11:8:f1\n" %
151 [blocks.join(" "), blocks.reverse.join(" ")])
153 assert_equal(". #{blocks.join(' ')} 1:8:f1 6:4:f1 0:4:f1\n",
159 def test_simple_file_copy
160 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
161 coll.cp_r("./simple.txt", "./new")
162 assert_equal(SIMPLEST_MANIFEST.sub(" 0:9:", " 0:9:new 0:9:"),
166 def test_copy_file_into_other_stream(target="./s1/f2", basename="f2")
167 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
168 coll.cp_r("./f2", target)
169 expected = "%s./s1 %s 0:5:f1 14:4:%s 5:4:f3\n" %
170 [TWO_BY_TWO_MANIFEST_A.first,
171 TWO_BY_TWO_BLOCKS.reverse.join(" "), basename]
172 assert_equal(expected, coll.manifest_text)
175 def test_implicit_copy_file_into_other_stream
176 test_copy_file_into_other_stream("./s1")
179 def test_copy_file_into_other_stream_with_new_name
180 test_copy_file_into_other_stream("./s1/f2a", "f2a")
183 def test_copy_file_over_in_other_stream(target="./s1/f1")
184 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
185 coll.cp_r("./f1", target)
186 expected = "%s./s1 %s 0:5:f1 14:4:f3\n" %
187 [TWO_BY_TWO_MANIFEST_A.first, TWO_BY_TWO_BLOCKS.join(" ")]
188 assert_equal(expected, coll.manifest_text)
191 def test_implicit_copy_file_over_in_other_stream
192 test_copy_file_over_in_other_stream("./s1")
195 def test_simple_stream_copy
196 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
197 coll.cp_r("./s1", "./sNew")
198 new_line = TWO_BY_TWO_MANIFEST_A.last.sub("./s1 ", "./sNew ")
199 assert_equal(TWO_BY_TWO_MANIFEST_S + new_line, coll.manifest_text)
202 def test_copy_stream_into_other_stream(target="./dir2/subdir",
204 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
205 coll.cp_r("./dir1/subdir", target)
206 new_line = MULTILEVEL_MANIFEST.lines[4].sub("./dir1/subdir ",
207 "./dir2/#{basename} ")
208 assert_equal(MULTILEVEL_MANIFEST + new_line, coll.manifest_text)
211 def test_implicit_copy_stream_into_other_stream
212 test_copy_stream_into_other_stream("./dir2")
215 def test_copy_stream_into_other_stream_with_new_name
216 test_copy_stream_into_other_stream("./dir2/newsub", "newsub")
219 def test_copy_stream_over_empty_stream
220 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
221 (1..3).each do |file_num|
222 coll.rm("./dir0/subdir/file#{file_num}")
224 coll.cp_r("./dir1/subdir", "./dir0")
225 expected = MULTILEVEL_MANIFEST.lines
226 expected[2] = expected[4].sub("./dir1/", "./dir0/")
227 assert_equal(expected.join(""), coll.manifest_text)
230 def test_copy_stream_over_file_raises_ENOTDIR(source="./s1", target="./f2")
231 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
232 assert_raises(Errno::ENOTDIR) do
233 coll.cp_r(source, target)
237 def test_copy_file_under_file_raises_ENOTDIR
238 test_copy_stream_over_file_raises_ENOTDIR("./f1", "./f2/newfile")
241 def test_copy_stream_over_nonempty_stream_merges_and_overwrites
242 blocks = random_blocks(3, 9)
244 ["./subdir #{blocks[0]} 0:1:s1 1:2:zero\n",
245 "./zdir #{blocks[1]} 0:9:zfile\n",
246 "./zdir/subdir #{blocks[2]} 0:1:s2 1:2:zero\n"]
247 coll = Arv::Collection.new(manifest_a.join(""))
248 coll.cp_r("./subdir", "./zdir")
249 manifest_a[2] = "./zdir/subdir %s %s 0:1:s1 9:1:s2 1:2:zero\n" %
250 [blocks[0], blocks[2]]
251 assert_equal(manifest_a.join(""), coll.manifest_text)
254 def test_copy_stream_into_substream(source="./dir1",
255 target="./dir1/subdir/dir1")
256 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
257 coll.cp_r(source, target)
258 expected = MULTILEVEL_MANIFEST.lines.flat_map do |line|
259 [line, line.gsub(/^#{Regexp.escape(source)}([\/ ])/, "#{target}\\1")].uniq
261 assert_equal(expected.sort.join(""), coll.manifest_text)
265 test_copy_stream_into_substream(".", "./root")
268 def test_adding_to_root_after_copy
269 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
270 coll.cp_r(".", "./root")
271 src_coll = Arv::Collection.new(COLON_FILENAME_MANIFEST)
272 coll.cp_r("./file:test.txt", ".", src_coll)
273 got_lines = coll.manifest_text.lines
274 assert_equal(2, got_lines.size)
275 assert_match(/^\. \S{33,} \S{33,} 0:9:file:test\.txt 9:9:simple\.txt\n/,
277 assert_equal(SIMPLEST_MANIFEST.sub(". ", "./root "), got_lines.last)
280 def test_copy_chaining
281 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
282 coll.cp_r("./simple.txt", "./a").cp_r("./a", "./b")
283 assert_equal(SIMPLEST_MANIFEST.sub(" 0:9:", " 0:9:a 0:9:b 0:9:"),
287 def prep_two_collections_for_copy(src_stream, dst_stream)
288 blocks = random_blocks(2, 8)
289 src_text = "#{src_stream} #{blocks.first} 0:8:f1\n"
290 dst_text = "#{dst_stream} #{blocks.last} 0:8:f2\n"
291 return [blocks, src_text, dst_text,
292 Arv::Collection.new(src_text.dup),
293 Arv::Collection.new(dst_text.dup)]
296 def test_copy_file_from_other_collection(src_stream=".", dst_stream="./s1")
297 blocks, src_text, dst_text, src_coll, dst_coll =
298 prep_two_collections_for_copy(src_stream, dst_stream)
299 dst_coll.cp_r("#{src_stream}/f1", dst_stream, src_coll)
300 assert_equal("#{dst_stream} #{blocks.join(' ')} 0:8:f1 8:8:f2\n",
301 dst_coll.manifest_text)
302 assert_equal(src_text, src_coll.manifest_text)
305 def test_copy_file_from_other_collection_to_root
306 test_copy_file_from_other_collection("./s1", ".")
309 def test_copy_stream_from_other_collection
310 blocks, src_text, dst_text, src_coll, dst_coll =
311 prep_two_collections_for_copy("./s2", "./s1")
312 dst_coll.cp_r("./s2", "./s1", src_coll)
313 assert_equal(dst_text + src_text.sub("./s2 ", "./s1/s2 "),
314 dst_coll.manifest_text)
315 assert_equal(src_text, src_coll.manifest_text)
318 def test_copy_stream_from_other_collection_to_root
319 blocks, src_text, dst_text, src_coll, dst_coll =
320 prep_two_collections_for_copy("./s1", ".")
321 dst_coll.cp_r("./s1", ".", src_coll)
322 assert_equal(dst_text + src_text, dst_coll.manifest_text)
323 assert_equal(src_text, src_coll.manifest_text)
326 def test_copy_stream_contents
327 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
328 coll.cp_r("./dir0/subdir/", "./dir1/subdir")
329 expect_lines = MULTILEVEL_MANIFEST.lines
330 expect_lines[4] = expect_lines[2].sub("./dir0/", "./dir1/")
331 assert_equal(expect_lines.join(""), coll.manifest_text)
334 def test_copy_file_into_new_stream_with_implicit_filename
335 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
336 coll.cp_r("./simple.txt", "./new/")
337 assert_equal(SIMPLEST_MANIFEST + SIMPLEST_MANIFEST.sub(". ", "./new "),
341 def test_copy_file_into_new_stream_with_explicit_filename
342 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
343 coll.cp_r("./simple.txt", "./new/newfile.txt")
344 new_line = SIMPLEST_MANIFEST.sub(". ", "./new ").sub(":simple", ":newfile")
345 assert_equal(SIMPLEST_MANIFEST + new_line, coll.manifest_text)
348 def test_copy_stream_contents_into_root
349 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
350 coll.cp_r("./s1/", ".")
351 assert_equal(". %s 0:5:f1 14:4:f2 5:4:f3\n%s" %
352 [TWO_BY_TWO_BLOCKS.reverse.join(" "),
353 TWO_BY_TWO_MANIFEST_A.last],
357 def test_copy_root_contents_into_stream
358 # This is especially fun, because we're copying a parent into its child.
359 # Make sure that happens depth-first.
360 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
361 coll.cp_r("./", "./s1")
362 assert_equal("%s./s1 %s 0:5:f1 5:4:f2 14:4:f3\n%s" %
363 [TWO_BY_TWO_MANIFEST_A.first, TWO_BY_TWO_BLOCKS.join(" "),
364 TWO_BY_TWO_MANIFEST_A.last.sub("./s1 ", "./s1/s1 ")],
368 def test_copy_stream_contents_across_collections
369 block = random_block(8)
370 src_coll = Arv::Collection.new("./s1 #{block} 0:8:f1\n")
371 dst_coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
372 dst_coll.cp_r("./s1/", "./s1", src_coll)
373 assert_equal("%s./s1 %s %s 0:8:f1 13:4:f3\n" %
374 [TWO_BY_TWO_MANIFEST_A.first, block, TWO_BY_TWO_BLOCKS.last],
375 dst_coll.manifest_text)
378 def test_copy_root_contents_across_collections
379 block = random_block(8)
380 src_coll = Arv::Collection.new(". #{block} 0:8:f1\n")
381 dst_coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
382 dst_coll.cp_r("./", ".", src_coll)
383 assert_equal(". %s %s 0:8:f1 13:4:f2\n%s" %
384 [block, TWO_BY_TWO_BLOCKS.first, TWO_BY_TWO_MANIFEST_A.last],
385 dst_coll.manifest_text)
388 def test_copy_root_into_empty_collection
389 block = random_block(8)
390 src_coll = Arv::Collection.new(". #{block} 0:8:f1\n")
391 dst_coll = Arv::Collection.new()
392 dst_coll.cp_r("./", ".", src_coll)
393 assert_equal(". %s 0:8:f1\n" %
395 dst_coll.manifest_text)
398 def test_copy_empty_source_path_raises_ArgumentError(src="", dst="./s1")
399 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
400 assert_raises(ArgumentError) do
405 def test_copy_empty_destination_path_raises_ArgumentError
406 test_copy_empty_source_path_raises_ArgumentError(".", "")
411 def test_each_file_path
412 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
417 coll.each_file_path { |path| result << path }
419 assert_equal(["./f1", "./f2", "./s1/f1", "./s1/f3"], result.sort)
422 def test_each_file_path_without_block
423 test_each_file_path { |coll| coll.each_file_path.to_a }
426 def test_each_file_path_empty_collection
427 assert_empty(Arv::Collection.new.each_file_path.to_a)
430 def test_each_file_path_after_collection_emptied
431 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
432 coll.rm("simple.txt")
433 assert_empty(coll.each_file_path.to_a)
436 def test_each_file_path_deduplicates_manifest_listings
437 coll = Arv::Collection.new(MULTIBLOCK_FILE_MANIFEST)
438 assert_equal(["./repfile", "./s1/repfile", "./s1/uniqfile",
439 "./uniqfile", "./uniqfile2"],
440 coll.each_file_path.to_a.sort)
445 def test_exist(test_method=:assert, path="f2")
446 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
447 send(test_method, coll.exist?(path))
450 def test_file_not_exist
451 test_exist(:refute, "f3")
454 def test_stream_exist
455 test_exist(:assert, "s1")
458 def test_file_inside_stream_exist
459 test_exist(:assert, "s1/f1")
462 def test_path_inside_stream_not_exist
463 test_exist(:refute, "s1/f2")
466 def test_path_under_file_not_exist
467 test_exist(:refute, "f2/nonexistent")
470 def test_deep_substreams_not_exist
471 test_exist(:refute, "a/b/c/d/e/f/g")
476 def test_simple_file_rename
477 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
478 coll.rename("./simple.txt", "./new")
479 assert_equal(SIMPLEST_MANIFEST.sub(":simple.txt", ":new"),
483 def test_rename_file_into_other_stream(target="./s1/f2", basename="f2")
484 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
485 coll.rename("./f2", target)
486 expected = ". %s 0:5:f1\n./s1 %s 0:5:f1 14:4:%s 5:4:f3\n" %
487 [TWO_BY_TWO_BLOCKS.first,
488 TWO_BY_TWO_BLOCKS.reverse.join(" "), basename]
489 assert_equal(expected, coll.manifest_text)
492 def test_implicit_rename_file_into_other_stream
493 test_rename_file_into_other_stream("./s1")
496 def test_rename_file_into_other_stream_with_new_name
497 test_rename_file_into_other_stream("./s1/f2a", "f2a")
500 def test_rename_file_over_in_other_stream(target="./s1/f1")
501 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
502 coll.rename("./f1", target)
503 expected = ". %s 5:4:f2\n./s1 %s 0:5:f1 14:4:f3\n" %
504 [TWO_BY_TWO_BLOCKS.first, TWO_BY_TWO_BLOCKS.join(" ")]
505 assert_equal(expected, coll.manifest_text)
508 def test_implicit_rename_file_over_in_other_stream
509 test_rename_file_over_in_other_stream("./s1")
512 def test_simple_stream_rename
513 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
514 coll.rename("./s1", "./newS")
515 assert_equal(TWO_BY_TWO_MANIFEST_S.sub("\n./s1 ", "\n./newS "),
519 def test_rename_stream_into_other_stream(target="./dir2/subdir",
521 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
522 coll.rename("./dir1/subdir", target)
523 expected = MULTILEVEL_MANIFEST.lines
524 replaced_line = expected.delete_at(4)
525 expected << replaced_line.sub("./dir1/subdir ", "./dir2/#{basename} ")
526 assert_equal(expected.join(""), coll.manifest_text)
529 def test_implicit_rename_stream_into_other_stream
530 test_rename_stream_into_other_stream("./dir2")
533 def test_rename_stream_into_other_stream_with_new_name
534 test_rename_stream_into_other_stream("./dir2/newsub", "newsub")
537 def test_rename_stream_over_empty_stream
538 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
539 (1..3).each do |file_num|
540 coll.rm("./dir0/subdir/file#{file_num}")
542 coll.rename("./dir1/subdir", "./dir0")
543 expected = MULTILEVEL_MANIFEST.lines
544 expected[2] = expected.delete_at(4).sub("./dir1/", "./dir0/")
545 assert_equal(expected.sort.join(""), coll.manifest_text)
548 def test_rename_stream_over_file_raises_ENOTDIR
549 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
550 assert_raises(Errno::ENOTDIR) do
551 coll.rename("./s1", "./f2")
555 def test_rename_stream_over_nonempty_stream_raises_ENOTEMPTY
556 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
557 assert_raises(Errno::ENOTEMPTY) do
558 coll.rename("./dir1/subdir", "./dir0")
562 def test_rename_stream_into_substream(source="./dir1",
563 target="./dir1/subdir/dir1")
564 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
565 coll.rename(source, target)
566 assert_equal(MULTILEVEL_MANIFEST.gsub(/^#{Regexp.escape(source)}([\/ ])/m,
572 test_rename_stream_into_substream(".", "./root")
575 def test_adding_to_root_after_rename
576 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
577 coll.rename(".", "./root")
578 src_coll = Arv::Collection.new(SIMPLEST_MANIFEST)
579 coll.cp_r("./simple.txt", ".", src_coll)
580 assert_equal(SIMPLEST_MANIFEST + SIMPLEST_MANIFEST.sub(". ", "./root "),
584 def test_rename_chaining
585 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
586 coll.rename("./simple.txt", "./x").rename("./x", "./simple.txt")
587 assert_equal(SIMPLEST_MANIFEST, coll.manifest_text)
592 def test_simple_remove
593 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S.dup)
595 assert_equal(TWO_BY_TWO_MANIFEST_S.sub(" 5:4:f2", ""), coll.manifest_text)
598 def empty_stream_and_assert(expect_index=0)
599 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
601 assert_equal(TWO_BY_TWO_MANIFEST_A[expect_index], coll.manifest_text)
604 def test_remove_all_files_in_substream
605 empty_stream_and_assert do |coll|
611 def test_remove_all_files_in_root_stream
612 empty_stream_and_assert(1) do |coll|
618 def test_chaining_removes
619 empty_stream_and_assert do |coll|
620 coll.rm("./s1/f1").rm("./s1/f3")
624 def test_remove_last_file
625 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
626 coll.rm("./simple.txt")
627 assert_equal("", coll.manifest_text)
630 def test_remove_nonexistent_file_raises_ENOENT(path="./NoSuchFile",
632 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
633 assert_raises(Errno::ENOENT) do
634 coll.send(method, path)
638 def test_remove_from_nonexistent_stream_raises_ENOENT
639 test_remove_nonexistent_file_raises_ENOENT("./NoSuchStream/simple.txt")
642 def test_remove_stream_raises_EISDIR(path="./s1")
643 coll = Arv::Collection.new(TWO_BY_TWO_MANIFEST_S)
644 assert_raises(Errno::EISDIR) do
649 def test_remove_root_raises_EISDIR
650 test_remove_stream_raises_EISDIR(".")
653 def test_remove_empty_string_raises_ArgumentError
654 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
655 assert_raises(ArgumentError) do
662 def test_recursive_remove
663 empty_stream_and_assert do |coll|
668 def test_recursive_remove_on_files
669 empty_stream_and_assert do |coll|
675 def test_recursive_remove_root
676 coll = Arv::Collection.new(MULTILEVEL_MANIFEST)
678 assert_equal("", coll.manifest_text)
681 def test_rm_r_nonexistent_file_raises_ENOENT(path="./NoSuchFile")
682 test_remove_nonexistent_file_raises_ENOENT("./NoSuchFile", :rm_r)
685 def test_rm_r_from_nonexistent_stream_raises_ENOENT
686 test_remove_nonexistent_file_raises_ENOENT("./NoSuchStream/file", :rm_r)
689 def test_rm_r_empty_string_raises_ArgumentError
690 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
691 assert_raises(ArgumentError) do
698 def test_new_collection_unmodified(*args)
699 coll = Arv::Collection.new(*args)
700 yield coll if block_given?
701 refute(coll.modified?)
704 def test_collection_unmodified_after_instantiation
705 test_new_collection_unmodified(SIMPLEST_MANIFEST)
708 def test_collection_unmodified_after_mark
709 test_new_collection_unmodified(SIMPLEST_MANIFEST) do |coll|
710 coll.cp_r("./simple.txt", "./copy")
715 def check_collection_modified
716 coll = Arv::Collection.new(SIMPLEST_MANIFEST)
718 assert(coll.modified?)
721 def test_collection_modified_after_copy
722 check_collection_modified do |coll|
723 coll.cp_r("./simple.txt", "./copy")
727 def test_collection_modified_after_remove
728 check_collection_modified do |coll|
729 coll.rm("./simple.txt")
733 def test_collection_modified_after_rename
734 check_collection_modified do |coll|
735 coll.rename("./simple.txt", "./newname")