imw 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/.gitignore +15 -0
  2. data/CHANGELOG +0 -0
  3. data/LICENSE +674 -0
  4. data/README.rdoc +101 -0
  5. data/Rakefile +20 -0
  6. data/VERSION +1 -0
  7. data/etc/imwrc.rb +76 -0
  8. data/lib/imw.rb +42 -0
  9. data/lib/imw/boot.rb +58 -0
  10. data/lib/imw/dataset.rb +233 -0
  11. data/lib/imw/dataset/datamapper.rb +66 -0
  12. data/lib/imw/dataset/datamapper/time_and_user_stamps.rb +37 -0
  13. data/lib/imw/dataset/loaddump.rb +50 -0
  14. data/lib/imw/dataset/old/file_collection.rb +88 -0
  15. data/lib/imw/dataset/old/file_collection_utils.rb +71 -0
  16. data/lib/imw/dataset/scaffold.rb +132 -0
  17. data/lib/imw/dataset/scraped_uri.rb +305 -0
  18. data/lib/imw/dataset/scrub/old_working_scrubber.rb +87 -0
  19. data/lib/imw/dataset/scrub/scrub.rb +147 -0
  20. data/lib/imw/dataset/scrub/scrub_simple_url.rb +38 -0
  21. data/lib/imw/dataset/scrub/scrub_test.rb +60 -0
  22. data/lib/imw/dataset/scrub/slug.rb +101 -0
  23. data/lib/imw/dataset/stats.rb +73 -0
  24. data/lib/imw/dataset/stats/counter.rb +23 -0
  25. data/lib/imw/dataset/task.rb +38 -0
  26. data/lib/imw/dataset/workflow.rb +81 -0
  27. data/lib/imw/files.rb +110 -0
  28. data/lib/imw/files/archive.rb +113 -0
  29. data/lib/imw/files/basicfile.rb +122 -0
  30. data/lib/imw/files/binary.rb +28 -0
  31. data/lib/imw/files/compressed_file.rb +93 -0
  32. data/lib/imw/files/compressed_files_and_archives.rb +348 -0
  33. data/lib/imw/files/compressible.rb +103 -0
  34. data/lib/imw/files/csv.rb +112 -0
  35. data/lib/imw/files/json.rb +41 -0
  36. data/lib/imw/files/sgml.rb +65 -0
  37. data/lib/imw/files/text.rb +68 -0
  38. data/lib/imw/files/yaml.rb +46 -0
  39. data/lib/imw/packagers.rb +8 -0
  40. data/lib/imw/packagers/archiver.rb +108 -0
  41. data/lib/imw/packagers/s3_mover.rb +28 -0
  42. data/lib/imw/parsers.rb +7 -0
  43. data/lib/imw/parsers/html_parser.rb +382 -0
  44. data/lib/imw/parsers/html_parser/matchers.rb +306 -0
  45. data/lib/imw/parsers/line_parser.rb +87 -0
  46. data/lib/imw/parsers/regexp_parser.rb +72 -0
  47. data/lib/imw/utils.rb +24 -0
  48. data/lib/imw/utils/components.rb +61 -0
  49. data/lib/imw/utils/config.rb +46 -0
  50. data/lib/imw/utils/error.rb +54 -0
  51. data/lib/imw/utils/extensions/array.rb +125 -0
  52. data/lib/imw/utils/extensions/class/attribute_accessors.rb +8 -0
  53. data/lib/imw/utils/extensions/core.rb +43 -0
  54. data/lib/imw/utils/extensions/dir.rb +24 -0
  55. data/lib/imw/utils/extensions/file_core.rb +64 -0
  56. data/lib/imw/utils/extensions/hash.rb +218 -0
  57. data/lib/imw/utils/extensions/hpricot.rb +48 -0
  58. data/lib/imw/utils/extensions/string.rb +49 -0
  59. data/lib/imw/utils/extensions/struct.rb +42 -0
  60. data/lib/imw/utils/extensions/symbol.rb +28 -0
  61. data/lib/imw/utils/extensions/typed_struct.rb +22 -0
  62. data/lib/imw/utils/extensions/uri.rb +59 -0
  63. data/lib/imw/utils/log.rb +67 -0
  64. data/lib/imw/utils/misc.rb +63 -0
  65. data/lib/imw/utils/paths.rb +115 -0
  66. data/lib/imw/utils/uri.rb +59 -0
  67. data/lib/imw/utils/uuid.rb +33 -0
  68. data/lib/imw/utils/validate.rb +38 -0
  69. data/lib/imw/utils/version.rb +12 -0
  70. data/lib/imw/utils/view.rb +113 -0
  71. data/lib/imw/utils/view/dump_csv.rb +112 -0
  72. data/lib/imw/utils/view/dump_csv_older.rb +117 -0
  73. data/spec/data/sample.csv +131 -0
  74. data/spec/data/sample.tsv +131 -0
  75. data/spec/data/sample.txt +131 -0
  76. data/spec/data/sample.xml +653 -0
  77. data/spec/data/sample.yaml +652 -0
  78. data/spec/imw/dataset/datamapper/uri_spec.rb +43 -0
  79. data/spec/imw/dataset/datamapper_spec_helper.rb +11 -0
  80. data/spec/imw/files/archive_spec.rb +118 -0
  81. data/spec/imw/files/basicfile_spec.rb +121 -0
  82. data/spec/imw/files/bz2_spec.rb +32 -0
  83. data/spec/imw/files/compressed_file_spec.rb +96 -0
  84. data/spec/imw/files/compressible_spec.rb +100 -0
  85. data/spec/imw/files/file_spec.rb +144 -0
  86. data/spec/imw/files/gz_spec.rb +32 -0
  87. data/spec/imw/files/rar_spec.rb +33 -0
  88. data/spec/imw/files/tar_spec.rb +31 -0
  89. data/spec/imw/files/text_spec.rb +23 -0
  90. data/spec/imw/files/zip_spec.rb +31 -0
  91. data/spec/imw/files_spec.rb +38 -0
  92. data/spec/imw/packagers/archiver_spec.rb +125 -0
  93. data/spec/imw/packagers/s3_mover_spec.rb +7 -0
  94. data/spec/imw/parsers/line_parser_spec.rb +96 -0
  95. data/spec/imw/parsers/regexp_parser_spec.rb +42 -0
  96. data/spec/imw/utils/extensions/file_core_spec.rb +72 -0
  97. data/spec/imw/utils/extensions/find_spec.rb +113 -0
  98. data/spec/imw/utils/paths_spec.rb +38 -0
  99. data/spec/imw/workflow/rip/local_spec.rb +89 -0
  100. data/spec/imw/workflow/rip_spec.rb +27 -0
  101. data/spec/rcov.opts +1 -0
  102. data/spec/spec.opts +4 -0
  103. data/spec/spec_helper.rb +32 -0
  104. data/spec/support/archive_contents_matcher.rb +94 -0
  105. data/spec/support/custom_matchers.rb +21 -0
  106. data/spec/support/directory_contents_matcher.rb +61 -0
  107. data/spec/support/extensions.rb +18 -0
  108. data/spec/support/file_contents_matcher.rb +50 -0
  109. data/spec/support/random.rb +210 -0
  110. data/spec/support/without_regard_to_order_matcher.rb +58 -0
  111. metadata +196 -0
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe IMW::Packagers::S3Mover do
4
+ it { pending }
5
+ end
6
+
7
+
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+ require 'ostruct'
3
+
4
+ describe IMW::Parsers::LineParser do
5
+
6
+ before do
7
+ @path = File.dirname(__FILE__) + "/../../data/sample.csv"
8
+ @file = File.new(@path)
9
+ @fields = [:id, :name, :genus, :species]
10
+ end
11
+
12
+ describe "without an implemented parsing method" do
13
+
14
+ before do
15
+ @parser = IMW::Parsers::LineParser.new
16
+ end
17
+
18
+ it "should raise an error when attempting to parse a line" do
19
+ lambda { @parser.parse_line "wahtever" }.should raise_error(IMW::NotImplementedError)
20
+ end
21
+
22
+ end
23
+
24
+ describe "with an implemented parsing method" do
25
+
26
+ before do
27
+
28
+ @parser_class = Class.new(IMW::Parsers::LineParser)
29
+ @parser_class.class_eval do
30
+ def parse_line line
31
+ id, name, genus, species = line.chomp.split(',')
32
+ { :id => id, :name => name, :genus => genus, :species => species }
33
+ end
34
+ end
35
+
36
+ @parser = @parser_class.new
37
+ end
38
+
39
+ it "should skip lines as needed" do
40
+ @parser.skip_first = 1
41
+ results = @parser.parse!(@file)
42
+ results.length.should == 130
43
+ end
44
+
45
+ it "should read as many lines as it's asked" do
46
+ results = @parser.parse!(@file, :lines => 10)
47
+ results.length.should == 10
48
+ end
49
+
50
+ describe "when parsing into hashes" do
51
+
52
+ it "should return an array of hashes when called without a block" do
53
+ results = @parser.parse!(@file)
54
+ results.length.should == 131
55
+ results.first.should == { :id => "ID", :name => "Name", :genus => "Genus", :species => "Species" }
56
+ end
57
+
58
+ it "should pass each hash to a block when given one" do
59
+ results = returning([]) do |array|
60
+ @parser.parse!(@file) do |hsh|
61
+ hsh.delete(:id)
62
+ array << hsh
63
+ end
64
+ end
65
+ results.length.should == 131
66
+ results.first.should == { :name => "Name", :genus => "Genus", :species => "Species" }
67
+ end
68
+ end
69
+
70
+ describe "when parsing into objects" do
71
+ before { @parser.klass = OpenStruct }
72
+
73
+ it "should return an array of objects when defined with a class" do
74
+ results = @parser.parse!(@file)
75
+ results.length.should == 131
76
+ results.first.class.should == OpenStruct
77
+ end
78
+
79
+ it "should pass each object to a block when given one and defined with a class" do
80
+ @parser.klass = OpenStruct
81
+ results = returning([]) do |array|
82
+ @parser.parse!(@file) do |obj|
83
+ obj.genus = nil
84
+ array << obj
85
+ end
86
+ end
87
+ results.length.should == 131
88
+ results.first.class.should == OpenStruct
89
+ results.first.genus.should be_blank
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+
96
+
@@ -0,0 +1,42 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+ require 'ostruct'
3
+
4
+ describe IMW::Parsers::RegexpParser do
5
+
6
+ before do
7
+ @path = "foobar.dat"
8
+ @text = <<EOF
9
+ 151.199.53.145 14-Oct-2007:13:34:34-0500 GET /phpmyadmin/main.php HTTP/1.0
10
+ 81.227.179.120 14-Oct-2007:13:34:34-0500 GET /phpmyadmin/libraries/select_lang.lib.php HTTP/1.0
11
+ 81.3.107.173 14-Oct-2007:13:54:26-0500 GET / HTTP/1.1
12
+ EOF
13
+ File.open(@path, 'w') { |f| f.write(@text) }
14
+ @file = File.new(@path)
15
+
16
+ @regexp = %r{^([\d\.]+) (\d{2}-\w{3}-\d{4}:\d{2}:\d{2}:\d{2}-\d{4}) (\w+) ([^\s]+) HTTP/([\d.]{3})$}
17
+ @fields = [:ip, :timestamp, :verb, :url, :version]
18
+
19
+ @parser = IMW::Parsers::RegexpParser.new :by_regexp => @regexp, :into_fields => @fields
20
+ end
21
+
22
+ describe "parsing a line which matches its regexp" do
23
+ it "should return an appropriate hash" do
24
+ @parser.parse_line(@file.readline).should == {:ip => '151.199.53.145', :timestamp => '14-Oct-2007:13:34:34-0500', :verb => 'GET', :url => '/phpmyadmin/main.php', :version => "1.0"}
25
+ end
26
+ end
27
+
28
+ describe "parsing a line which doesn't match its regexp" do
29
+ before { @parser.regexp = /foobar/ }
30
+
31
+ it "return an empty hash if not parsing strictly" do
32
+ @parser.parse_line(@file.readline).should == {}
33
+ end
34
+
35
+ it "should raise an error if parsing strictly" do
36
+ @parser.strict = true
37
+ lambda { @parser.parse_line(@file.readline) }.should raise_error IMW::ParseError
38
+ end
39
+ end
40
+ end
41
+
42
+
@@ -0,0 +1,72 @@
1
+ #
2
+ # h2. spec/imw/utils/extensions/file_core_spec.rb -- spec for extensions to core file module
3
+ #
4
+ # Author:: (Philip flip Kromer, Dhruv Bansal) for Infinite Monkeywrench Project (mailto:coders@infochimps.org)
5
+ # Copyright:: Copyright (c) 2008 infochimps.org
6
+ # License:: GPL 3.0
7
+ # Website:: http://infinitemonkeywrench.org/
8
+ #
9
+
10
+ require File.join(File.dirname(__FILE__),'../../../spec_helper')
11
+
12
+ require 'fileutils'
13
+
14
+ require 'imw/utils/random'
15
+
16
+ describe File do
17
+
18
+ it "should return the 'name' of a file with 'name_of_file'" do
19
+ File.name_of_file("/path/to/some_file.txt").should eql("some_file")
20
+ end
21
+
22
+ describe "when finding the handle corresponding to a path" do
23
+
24
+ it "should correctly identify paths with the processing instruction suffix" do
25
+ File.handle("/path/to/the_handle#{IMW::PROCESSING_INSTRUCTION_SUFFIX}.yaml").should eql(:the_handle)
26
+ end
27
+
28
+ it "should correctly identify paths with the metadata instruction suffix" do
29
+ File.handle("/path/to/the_handle#{IMW::METADATA_SUFFIX}.yaml").should eql(:the_handle)
30
+ end
31
+
32
+ it "should raise an error if the path does not correspond to a handle" do
33
+ lambda {File.handle("/path/to/the_handle.txt")}.should raise_error(IMW::PathError)
34
+ end
35
+ end
36
+
37
+ describe "when creating unique filenames" do
38
+
39
+ before(:each) do
40
+ @root_directory = IMW::DIRECTORIES[:dump] + "/file_core_spec"
41
+ @file0 = @root_directory + "/the_original.txt"
42
+ @file1 = @root_directory + "/the_original.txt.1"
43
+ @file2 = @root_directory + "/the_original.txt.2"
44
+ FileUtils.mkdir(@root_directory)
45
+ end
46
+
47
+ after(:each) do
48
+ FileUtils.rm_rf @root_directory
49
+ end
50
+
51
+ it "should return the given path if there is no such file already" do
52
+ File.uniquify(@file0).should eql(@file0)
53
+ end
54
+
55
+ it "should return the given path with a numerical suffix of `.1' if the file exists" do
56
+ IMW::Random.file(@file0)
57
+ File.uniquify(@file0).should eql(@file1)
58
+ end
59
+
60
+ it "should return the given path with a numerical suffix o `.2' if the file exists and a file with a suffix of `.1' also exists" do
61
+ IMW::Random.file(@file0)
62
+ IMW::Random.file(@file1)
63
+ File.uniquify(@file0).should eql(@file2)
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+
71
+
72
+ # puts "#{File.basename(__FILE__)}: You bend the file folder almost in half and watch as it springs back to shape." # at bottom
@@ -0,0 +1,113 @@
1
+ #
2
+ # h2. spec/imw/utils/extensions/find_spec.rb -- spec for find.rb
3
+ #
4
+ # == About
5
+ #
6
+ # Author:: (Philip flip Kromer, Dhruv Bansal) for Infinite Monkeywrench Project (mailto:coders@infochimps.org)
7
+ # Copyright:: Copyright (c) 2008 infochimps.org
8
+ # License:: GPL 3.0
9
+ # Website:: http://infinitemonkeywrench.org/
10
+ #
11
+
12
+ require File.join(File.dirname(__FILE__),'../../../spec_helper')
13
+ require IMW_SPEC_DIR + "/imw/matchers/without_regard_to_order_matcher"
14
+
15
+ require 'fileutils'
16
+ require 'set'
17
+
18
+ require 'imw/utils'
19
+ require 'imw/utils/random'
20
+ require 'imw/utils/extensions/find'
21
+
22
+ describe Find do
23
+
24
+ include Spec::Matchers::IMW
25
+
26
+ def create_sample_files
27
+ FileUtils.mkdir_p(@subsubdirectory)
28
+ [@file1,@file2,@file3,@file4,@file5,@file6].each {|path| IMW::Random.file path}
29
+ end
30
+
31
+ before(:all) do
32
+ @root_directory = IMW::DIRECTORIES[:dump] + "/find_extension_spec"
33
+ @subdirectory = @root_directory + "/subdir"
34
+ @subsubdirectory = @subdirectory + "/subsubdir"
35
+ @fake_directory = @root_directory + "/notreal"
36
+ @file1 = @root_directory + "/my_file1.txt"
37
+ @file2 = @root_directory + "/my_file2.csv"
38
+ @file3 = @root_directory + "/my_file3.dat"
39
+ @file4 = @subdirectory + "/your_file4.html"
40
+ @file5 = @subdirectory + "/your_file5.csv"
41
+ @file6 = @subdirectory + "/your_file5"
42
+ end
43
+
44
+ before(:each) do
45
+ create_sample_files
46
+ end
47
+
48
+ after(:each) do
49
+ FileUtils.rm_rf @root_directory
50
+ end
51
+
52
+ describe "when listing files with absolute paths contained in a directory" do
53
+
54
+ it "should raise an error when listing a non-exsiting directory" do
55
+ lambda {Find.files_in_directory(@fake_directory) }.should raise_error(IMW::PathError)
56
+ end
57
+
58
+ it "should find every file by default" do
59
+ Find.files_in_directory(@root_directory).should match_without_regard_to_order([@file1,@file2,@file3,@file4,@file5,@file6])
60
+ end
61
+
62
+ it "should only find files which match its :include argument" do
63
+ Find.files_in_directory(@root_directory, :include => /.*\.csv$/).should match_without_regard_to_order([@file2,@file5])
64
+ end
65
+
66
+ it "should not find files which match its :exclude argument" do
67
+ Find.files_in_directory(@root_directory, :exclude => /.*\.csv$/).should match_without_regard_to_order([@file1,@file3,@file4,@file6])
68
+ end
69
+
70
+ it "should only find files which match its :include argument and don't match its :exclude argument" do
71
+ Find.files_in_directory(@root_directory, :include => /my/, :exclude => /.*\.csv$/).should match_without_regard_to_order([@file1,@file3])
72
+ end
73
+ end
74
+
75
+ describe "when listing files with relative paths contained in a directory" do
76
+
77
+ def strip_root_directory array
78
+ array.map {|item| item[@root_directory.length + 1,item.size]}
79
+ end
80
+
81
+ it "should raise an error when listing a non-exsiting directory" do
82
+ lambda {Find.files_in_directory(@fake_directory) }.should raise_error(IMW::PathError)
83
+ end
84
+
85
+ it "should find every file by default" do
86
+ Find.files_relative_to_directory(@root_directory).should match_without_regard_to_order(strip_root_directory([@file1,@file2,@file3,@file4,@file5,@file6]))
87
+ end
88
+
89
+ it "should only find files which match its :include argument" do
90
+ Find.files_relative_to_directory(@root_directory, :include => /.*\.csv$/).should match_without_regard_to_order(strip_root_directory([@file2,@file5]))
91
+ end
92
+
93
+ it "should not find files which match its :exclude argument" do
94
+ Find.files_relative_to_directory(@root_directory, :exclude => /.*\.csv$/).should match_without_regard_to_order(strip_root_directory([@file1,@file3,@file4,@file6]))
95
+ end
96
+
97
+ it "should only find files which match its :include argument and don't match its :exclude argument" do
98
+ Find.files_relative_to_directory(@root_directory, :include => /^my/, :exclude => /.*\.csv$/).should match_without_regard_to_order(strip_root_directory([@file1,@file3]))
99
+ end
100
+
101
+ end
102
+
103
+ describe "when listing handles in a directory" do
104
+
105
+ it "should return a unique set of handles" do
106
+ Find.handles_in_directory(@root_directory, :include => /your/).should match_without_regard_to_order([:your_file4, :your_file5])
107
+ end
108
+ end
109
+
110
+
111
+ end
112
+
113
+ # puts "#{File.basename(__FILE__)}: You throw your Monkeywrench backwards over your shoulder and run like mad to go find it. Again, and again, and again." # at bottom
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(__FILE__),'../../spec_helper')
2
+ require 'imw'
3
+ require 'imw/utils/paths'
4
+
5
+ describe IMW do
6
+ include IMW
7
+ before(:each) do
8
+ IMW::PATHS = {
9
+ :data => '/data',
10
+ :weather => 'ftp.ncdc.noaa.gov/pub/data/noaa',
11
+ :first => ['1', :second, 'last'],
12
+ :second => ['2', :third],
13
+ :third => ['3'],
14
+ }
15
+ end
16
+
17
+ it 'is idempotent on a string' do
18
+ path_to('hi').should == 'hi'
19
+ end
20
+
21
+ it 'has an absolute path to the data dir' do
22
+ path_to(:data).should =~ %r{^/}
23
+ end
24
+
25
+ it 'handles mixed array and sym args' do
26
+ path_to( [:data, 'hi'], [[['there']]]).should == '/data/hi/there'
27
+ end
28
+
29
+ it 'expands to later generations' do
30
+ path_to(:first).should == File.join('1/2/3/last')
31
+ end
32
+
33
+ it 'expands interior symbols' do
34
+ path_to(['hadoop1:/working', :data, :weather]).should ==
35
+ File.join('hadoop1:/working/data/ftp.ncdc.noaa.gov/pub/data/noaa')
36
+ end
37
+
38
+ end
@@ -0,0 +1,89 @@
1
+ #
2
+ # h2. spec/imw/workflow/rip/local_spec.rb -- specs for copying files from local disk
3
+ #
4
+ # == About
5
+ #
6
+ # Author:: (Philip flip Kromer, Dhruv Bansal) for Infinite Monkeywrench Project (mailto:coders@infochimps.org)
7
+ # Copyright:: Copyright (c) 2008 infochimps.org
8
+ # License:: GPL 3.0
9
+ # Website:: http://infinitemonkeywrench.org/
10
+ #
11
+ require File.join(File.dirname(__FILE__),'../../../spec_helper')
12
+ require IMW_SPEC_DIR + "/imw/matchers/without_regard_to_order_matcher.rb"
13
+
14
+ require 'fileutils'
15
+
16
+ require 'imw/utils/random'
17
+ require 'imw/utils/extensions/find'
18
+ require 'imw/workflow/rip/local'
19
+
20
+ describe "Ripping from local disk" do
21
+
22
+ include Spec::Matchers::IMW
23
+
24
+ before(:all) do
25
+ @root_directory = IMW::DIRECTORIES[:dump] + "/local_spec"
26
+ @file1 = @root_directory + "/first.csv"
27
+
28
+ @source_directory1 = @root_directory + "/source1"
29
+ @file2 = @source_directory1 + "/second.txt"
30
+ @file3 = @source_directory1 + "/third.csv"
31
+
32
+ @source_directory2 = @root_directory + "/source2"
33
+ @file4 = @source_directory2 + "/fourth.txt"
34
+ @file5a = @source_directory2 + "/fifth-shared.yaml"
35
+
36
+ @source_directory3 = @source_directory2 + "/source3-nested"
37
+ @file5b = @source_directory3 + "/fifth-shared.yaml"
38
+
39
+ @target_directory = @root_directory + "/target"
40
+ end
41
+
42
+ before(:each) do
43
+ FileUtils.mkdir([@root_directory,@source_directory1,@source_directory2,@source_directory3,@target_directory])
44
+ [@file1,@file2,@file3,@file4,@file5a,@file5b].each {|file| IMW::Random.file(file)}
45
+ end
46
+
47
+ after(:each) do
48
+ FileUtils.rm_rf @root_directory
49
+ end
50
+
51
+
52
+ def basenames_of files
53
+ files.map {|file| File.basename file}
54
+ end
55
+
56
+ it "should raise an error when attempting to copy to a non-existent target directory" do
57
+ FileUtils.rm_rf @target_directory
58
+ lambda { IMW::Rip.from_local_disk(@target_directory,@source_directory1)}.should raise_error(IMW::PathError)
59
+ end
60
+
61
+ it "should copy all files in all directories and paths recursively to the target directory without any hierarchy" do
62
+ IMW::Rip.from_local_disk(@target_directory,@file1,@source_directory1,@source_directory2)
63
+ Find.files_relative_to_directory(@target_directory).should match_without_regard_to_order(basenames_of([@file1,@file2,@file3,@file4,@file5a]))
64
+ end
65
+
66
+ it "should accept a block which establishes a hierarchy to be created in the target directory and which skips copying certain files if it returns nil" do
67
+
68
+ # complicated block to copy files to sub-directories of the target
69
+ # directory depending on their extension
70
+ IMW::Rip.from_local_disk(@target_directory,@file1,@source_directory1,@source_directory2) do |path|
71
+ if File.extname(path) == '.txt' then
72
+ File.join('txt',File.basename(path)) # put text files in txt
73
+ elsif File.extname(path) == '.csv' then
74
+ File.join("csv",File.basename(path)) # put csv files in csv
75
+ else
76
+ nil # don't copy other extensions
77
+ end
78
+ end
79
+
80
+ # what we would expect to see from that block
81
+ txt = [@file2,@file4].map {|path| File.join("txt",File.basename(path))}
82
+ csv = [@file1,@file3].map {|path| File.join("csv",File.basename(path))}
83
+
84
+ Find.files_relative_to_directory(@target_directory).should match_without_regard_to_order(txt + csv)
85
+ end
86
+
87
+ end
88
+
89
+ # puts "#{File.basename(__FILE__)}: Having found the platter you were looking for, you stare at it, examining your reflection. What a handsome chimp you are!" # at bottom