tap 0.12.4 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/History +34 -0
  2. data/README +62 -41
  3. data/bin/tap +36 -40
  4. data/cmd/console.rb +14 -6
  5. data/cmd/manifest.rb +62 -58
  6. data/cmd/run.rb +49 -31
  7. data/doc/API +84 -0
  8. data/doc/Class Reference +83 -115
  9. data/doc/Examples/Command Line +36 -0
  10. data/doc/Examples/Workflow +40 -0
  11. data/lib/tap/app.rb +293 -214
  12. data/lib/tap/app/node.rb +43 -0
  13. data/lib/tap/app/queue.rb +77 -0
  14. data/lib/tap/app/stack.rb +16 -0
  15. data/lib/tap/app/state.rb +22 -0
  16. data/lib/tap/constants.rb +2 -2
  17. data/lib/tap/env.rb +400 -314
  18. data/lib/tap/env/constant.rb +227 -0
  19. data/lib/tap/env/gems.rb +63 -0
  20. data/lib/tap/env/manifest.rb +89 -0
  21. data/lib/tap/env/minimap.rb +292 -0
  22. data/lib/tap/{support → env}/string_ext.rb +2 -2
  23. data/lib/tap/exe.rb +113 -125
  24. data/lib/tap/join.rb +175 -0
  25. data/lib/tap/joins.rb +9 -0
  26. data/lib/tap/joins/switch.rb +44 -0
  27. data/lib/tap/joins/sync.rb +99 -0
  28. data/lib/tap/root.rb +100 -491
  29. data/lib/tap/root/utils.rb +220 -0
  30. data/lib/tap/{support → root}/versions.rb +31 -29
  31. data/lib/tap/schema.rb +248 -0
  32. data/lib/tap/schema/parser.rb +413 -0
  33. data/lib/tap/schema/utils.rb +82 -0
  34. data/lib/tap/support/intern.rb +19 -6
  35. data/lib/tap/support/templater.rb +8 -3
  36. data/lib/tap/task.rb +175 -171
  37. data/lib/tap/tasks/dump.rb +58 -0
  38. data/lib/tap/tasks/load.rb +62 -0
  39. metadata +30 -73
  40. data/cmd/destroy.rb +0 -27
  41. data/cmd/generate.rb +0 -27
  42. data/doc/Command Reference +0 -105
  43. data/doc/Syntax Reference +0 -234
  44. data/doc/Tutorial +0 -348
  45. data/lib/tap/dump.rb +0 -142
  46. data/lib/tap/file_task.rb +0 -384
  47. data/lib/tap/generator/arguments.rb +0 -13
  48. data/lib/tap/generator/base.rb +0 -176
  49. data/lib/tap/generator/destroy.rb +0 -60
  50. data/lib/tap/generator/generate.rb +0 -93
  51. data/lib/tap/generator/generators/command/command_generator.rb +0 -21
  52. data/lib/tap/generator/generators/command/templates/command.erb +0 -32
  53. data/lib/tap/generator/generators/config/config_generator.rb +0 -98
  54. data/lib/tap/generator/generators/generator/generator_generator.rb +0 -37
  55. data/lib/tap/generator/generators/generator/templates/task.erb +0 -27
  56. data/lib/tap/generator/generators/generator/templates/test.erb +0 -26
  57. data/lib/tap/generator/generators/root/root_generator.rb +0 -84
  58. data/lib/tap/generator/generators/root/templates/MIT-LICENSE +0 -22
  59. data/lib/tap/generator/generators/root/templates/README +0 -14
  60. data/lib/tap/generator/generators/root/templates/Rakefile +0 -84
  61. data/lib/tap/generator/generators/root/templates/Rapfile +0 -11
  62. data/lib/tap/generator/generators/root/templates/gemspec +0 -27
  63. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -3
  64. data/lib/tap/generator/generators/task/task_generator.rb +0 -25
  65. data/lib/tap/generator/generators/task/templates/task.erb +0 -14
  66. data/lib/tap/generator/generators/task/templates/test.erb +0 -19
  67. data/lib/tap/generator/manifest.rb +0 -20
  68. data/lib/tap/generator/preview.rb +0 -69
  69. data/lib/tap/load.rb +0 -64
  70. data/lib/tap/spec.rb +0 -41
  71. data/lib/tap/support/aggregator.rb +0 -65
  72. data/lib/tap/support/audit.rb +0 -333
  73. data/lib/tap/support/constant.rb +0 -143
  74. data/lib/tap/support/constant_manifest.rb +0 -126
  75. data/lib/tap/support/dependencies.rb +0 -54
  76. data/lib/tap/support/dependency.rb +0 -44
  77. data/lib/tap/support/executable.rb +0 -198
  78. data/lib/tap/support/executable_queue.rb +0 -125
  79. data/lib/tap/support/gems.rb +0 -43
  80. data/lib/tap/support/join.rb +0 -144
  81. data/lib/tap/support/joins.rb +0 -12
  82. data/lib/tap/support/joins/switch.rb +0 -27
  83. data/lib/tap/support/joins/sync_merge.rb +0 -38
  84. data/lib/tap/support/manifest.rb +0 -171
  85. data/lib/tap/support/minimap.rb +0 -90
  86. data/lib/tap/support/node.rb +0 -176
  87. data/lib/tap/support/parser.rb +0 -450
  88. data/lib/tap/support/schema.rb +0 -385
  89. data/lib/tap/support/shell_utils.rb +0 -67
  90. data/lib/tap/test.rb +0 -77
  91. data/lib/tap/test/assertions.rb +0 -38
  92. data/lib/tap/test/env_vars.rb +0 -29
  93. data/lib/tap/test/extensions.rb +0 -73
  94. data/lib/tap/test/file_test.rb +0 -362
  95. data/lib/tap/test/file_test_class.rb +0 -15
  96. data/lib/tap/test/regexp_escape.rb +0 -87
  97. data/lib/tap/test/script_test.rb +0 -46
  98. data/lib/tap/test/script_tester.rb +0 -115
  99. data/lib/tap/test/subset_test.rb +0 -260
  100. data/lib/tap/test/subset_test_class.rb +0 -99
  101. data/lib/tap/test/tap_test.rb +0 -109
  102. data/lib/tap/test/utils.rb +0 -231
data/lib/tap/test.rb DELETED
@@ -1,77 +0,0 @@
1
- $:.unshift File.expand_path("#{File.dirname(__FILE__)}/..")
2
- require 'tap/test/extensions'
3
- require 'test/unit'
4
-
5
- # :stopdoc:
6
- # Methods extending TestCase. For more information see:
7
- # - Tap::Test::SubsetTest
8
- # - Tap::Test::FileTest
9
- # - Tap::Test::TapTest
10
- #
11
- #--
12
- #See the TestTutorial for more information.
13
- class Test::Unit::TestCase
14
- extend Tap::Test::Extensions
15
-
16
- class << self
17
- # Causes a test suite to be skipped. If a message is given, it will
18
- # print and notify the user the test suite has been skipped.
19
- def skip_test(msg=nil)
20
- @@test_suites.delete(self)
21
- puts "Skipping #{self}#{msg.empty? ? '' : ': ' + msg}"
22
- end
23
- end
24
- end
25
-
26
- class Test::Unit::TestCase
27
- class << self
28
- alias tap_original_test_case_inherited inherited
29
-
30
- def inherited(child)
31
- super
32
- tap_original_test_case_inherited(child)
33
- child.instance_variable_set(:@skip_messages, [])
34
- child.instance_variable_set(:@run_test_suite, true)
35
- end
36
-
37
- # Indicates when the test suite should be run or skipped.
38
- attr_accessor :run_test_suite
39
-
40
- # An array of messages printed when a test is skipped
41
- # by setting run_test_suite to false.
42
- attr_reader :skip_messages
43
-
44
- undef_method :skip_test
45
-
46
- def skip_test(msg=nil)
47
- self.run_test_suite = false
48
- skip_messages << msg
49
- end
50
-
51
- alias :original_suite :suite
52
-
53
- # Modifies the default suite method to skip the suit unless
54
- # run_test_suite is true. If the test is skipped, the skip_messages
55
- # will be printed along with the default 'Skipping <Test>' message.
56
- def suite # :nodoc:
57
- if run_test_suite
58
- original_suite
59
- else
60
- skip_message = skip_messages.compact.join(', ')
61
- puts "Skipping #{name}#{skip_message.empty? ? '' : ': ' + skip_message}"
62
-
63
- # return an empty test suite of the appropriate name
64
- Test::Unit::TestSuite.new(name)
65
- end
66
- end
67
- end
68
- end unless Object.const_defined?(:MiniTest)
69
-
70
- if Object.const_defined?(:MiniTest)
71
- # MiniTest renames method_name name, so it has to be added back here.
72
- class MiniTest::Unit::TestCase
73
- undef_method :method_name if method_defined?(:method_name)
74
- alias method_name name
75
- end
76
- end
77
- # :startdoc:
@@ -1,38 +0,0 @@
1
- require 'tap/test/utils'
2
-
3
- module Tap
4
- module Test
5
- module Assertions
6
- def assert_output_equal(a, b, msg=nil)
7
- a = a[1..-1] if a[0] == ?\n
8
- if a == b
9
- assert true
10
- else
11
- flunk %Q{
12
- #{msg}
13
- ==================== expected output ====================
14
- #{Utils.whitespace_escape(a)}
15
- ======================== but was ========================
16
- #{Utils.whitespace_escape(b)}
17
- =========================================================
18
- }
19
- end
20
- end
21
-
22
- def assert_alike(a, b, msg=nil)
23
- if b =~ a
24
- assert true
25
- else
26
- flunk %Q{
27
- #{msg}
28
- ================= expected output like ==================
29
- #{Utils.whitespace_escape(a)}
30
- ======================== but was ========================
31
- #{Utils.whitespace_escape(b)}
32
- =========================================================
33
- }
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,29 +0,0 @@
1
- module Tap
2
- module Test
3
-
4
- # Provides for case-insensitive access to the ENV variables
5
- module EnvVars
6
-
7
- # Access to the case-insensitive ENV variables. Raises an error
8
- # if multiple case-insensitive values are defined in ENV.
9
- def env_var(type)
10
- type = type.downcase
11
-
12
- # ENV.select in ruby 1.9 returns a hash instead of an array
13
- selected = ENV.select {|key, value| key.downcase == type}.to_a
14
-
15
- case selected.length
16
- when 0 then nil
17
- when 1 then selected[0][1]
18
- else
19
- raise "Multiple env values for '#{type}'"
20
- end
21
- end
22
-
23
- # Returns true if the env_var(var) is set and matches /^true$/i
24
- def env_true?(var)
25
- (env_var(var) && env_var(var) =~ /^true$/i) ? true : false
26
- end
27
- end
28
- end
29
- end
@@ -1,73 +0,0 @@
1
- module Tap
2
- module Test
3
- autoload(:SubsetTest, 'tap/test/subset_test')
4
- autoload(:FileTest, 'tap/test/file_test')
5
- autoload(:TapTest, 'tap/test/tap_test')
6
- autoload(:ScriptTest, 'tap/test/script_test')
7
- autoload(:Utils, 'tap/test/utils')
8
-
9
- module Extensions
10
- def acts_as_subset_test
11
- include Tap::Test::SubsetTest
12
- end
13
-
14
- # Causes a TestCase to act as a file test, by including FileTest and
15
- # instantiating class_test_root (a Tap::Root). The root, relative_paths,
16
- # and absolute_paths used by class_test_root may be specified as options.
17
- #
18
- # Note: by default acts_as_file_test determines a root directory
19
- # <em>based on the calling file</em>. Be sure to specify the root
20
- # directory manually if you call acts_as_file_test from a file that
21
- # isn't the test file.
22
- def acts_as_file_test(options={})
23
- include Tap::Test::FileTest
24
-
25
- self.class_test_root = Tap::Root.new(
26
- options[:root] || test_root_dir,
27
- options[:relative_paths] || {},
28
- options[:absolute_paths] || {})
29
- end
30
-
31
- # Causes a unit test to act as a tap test -- resulting in the following:
32
- # - setup using acts_as_file_test
33
- # - inclusion of Tap::Test::SubsetTest
34
- # - inclusion of Tap::Test::InstanceMethods
35
- #
36
- # Note: by default acts_as_tap_test determines a root directory
37
- # <em>based on the calling file</em>. Be sure to specify the root
38
- # directory manually if you call acts_as_file_test from a file that
39
- # isn't the test file.
40
- def acts_as_tap_test(options={})
41
- options[:root] ||= test_root_dir
42
-
43
- acts_as_subset_test
44
- acts_as_file_test(options)
45
-
46
- include Tap::Test::TapTest
47
- end
48
-
49
- def acts_as_script_test(options={})
50
- options[:root] ||= test_root_dir
51
- acts_as_file_test(options)
52
-
53
- include Tap::Test::ScriptTest
54
- end
55
-
56
- private
57
-
58
- # Infers the test root directory from the calling file.
59
- # 'some_class.rb' => 'some_class'
60
- # 'some_class_test.rb' => 'some_class'
61
- def test_root_dir # :nodoc:
62
- # caller[1] is considered the calling file (which should be the test case)
63
- # note that caller entries are like this:
64
- # ./path/to/file.rb:10
65
- # ./path/to/file.rb:10:in 'method'
66
-
67
- calling_file = caller[1].gsub(/:\d+(:in .*)?$/, "")
68
- calling_file.chomp(File.extname(calling_file)).chomp("_test")
69
- end
70
- end
71
- end
72
- end
73
-
@@ -1,362 +0,0 @@
1
- require 'tap/test/env_vars'
2
- require 'tap/test/assertions'
3
- require 'tap/test/regexp_escape'
4
- require 'tap/test/file_test_class'
5
-
6
- module Tap
7
- module Test
8
-
9
- # FileTest facilitates access and utilization of test-specific files and
10
- # directories. FileTest provides each test method with a Tap::Root
11
- # (method_root) specific for the method, and defines a new assertion method
12
- # (assert_files) to facilitate tests which involve the production and/or
13
- # modification of files.
14
- #
15
- # [file_test_doc_test.rb]
16
- # class FileTestDocTest < Test::Unit::TestCase
17
- # acts_as_file_test
18
- #
19
- # def test_something
20
- # # each test class has a class test root (ctr)
21
- # # and each test method has a method-specific
22
- # # root (method_root)
23
- #
24
- # ctr.root # => File.expand_path(__FILE__.chomp('_test.rb'))
25
- # method_root.root # => File.join(ctr.root, "/test_something")
26
- # method_root[:input] # => File.join(ctr.root, "/test_something/input")
27
- #
28
- # # files in the :output and :tmp directories are cleared
29
- # # before and after each test; this passes each time the
30
- # # test is run with no additional cleanup:
31
- #
32
- # assert !File.exists?(method_root[:tmp])
33
- #
34
- # tmp_file = method_root.prepare(:tmp, 'sample.txt') {|file| file << "content" }
35
- # assert_equal "content", File.read(tmp_file)
36
- #
37
- # # the assert_files method compares files produced
38
- # # by the block the expected files, ensuring they
39
- # # are the same (see the documentation for the
40
- # # simplest use of assert_files)
41
- #
42
- # expected_file = method_root.prepare(:expected, 'output.txt') {|file| file << 'expected output' }
43
- #
44
- # # passes
45
- # assert_files do
46
- # method_root.prepare(:output, 'output.txt') {|file| file << 'expected output' }
47
- # end
48
- # end
49
- # end
50
- #
51
- # See {Test::Unit::TestCase}[link:classes/Test/Unit/TestCase.html] and
52
- # FileTestClass for more information.
53
- module FileTest
54
- include Tap::Test::EnvVars
55
- include Tap::Test::Assertions
56
-
57
- def self.included(base) # :nodoc:
58
- super
59
- base.extend FileTestClass
60
- base.cleanup_dirs = [:output, :tmp]
61
- end
62
-
63
- # Convenience method to access the class_test_root.
64
- def ctr
65
- self.class.class_test_root or raise "setup failure: no class_test_root has been set for #{self.class}"
66
- end
67
-
68
- # The test-method-specific Tap::Root which may be used to
69
- # access test files. method_root is a duplicate of ctr
70
- # reconfigured so that method_root.root is ctr[method_name.to_sym]
71
- attr_reader :method_root
72
-
73
- # Sets up method_root and calls cleanup. Be sure to call super when
74
- # overriding this method.
75
- def setup
76
- super
77
- @method_root = ctr.dup.reconfigure(:root => ctr[method_name.to_sym])
78
- cleanup
79
- end
80
-
81
- # Cleans up the method_root.root directory by removing the class
82
- # cleanup_dirs (by default :tmp and :output). The root directory
83
- # will also be removed if it is empty.
84
- #
85
- # Override as necessary in subclasses.
86
- def cleanup
87
- self.class.cleanup_dirs.each do |dir|
88
- Utils.clear_dir(method_root[dir])
89
- end
90
- Utils.try_remove_dir(method_root.root)
91
- end
92
-
93
- # Calls cleanup unless flagged otherwise by an ENV variable. To prevent
94
- # cleanup (when debugging for example), set the 'KEEP_OUTPUTS' or
95
- # 'KEEP_FAILURES' ENV variables:
96
- #
97
- # % rap test KEEP_OUTPUTS=true
98
- # % rap test KEEP_FAILURES=true
99
- #
100
- # Cleanup is only suppressed for failing tests when KEEP_FAILURES is
101
- # specified. Be sure to call super when overriding this method.
102
- def teardown
103
- # check that method_root still exists (nil may
104
- # indicate setup was overridden without super)
105
- unless method_root
106
- raise "teardown failure: method_root is nil (check a class_test_root has been set and ensure setup calls super)"
107
- end
108
-
109
- # clear out the output folder if it exists, unless flagged otherwise
110
- unless env_var("KEEP_OUTPUTS") || (!passed? && env_var("KEEP_FAILURES"))
111
- begin
112
- cleanup
113
- rescue
114
- raise("cleanup failure: #{$!.message}")
115
- end
116
- end
117
-
118
- Utils.try_remove_dir(ctr.root)
119
- end
120
-
121
- # Returns method_name as a string (Ruby 1.9 symbolizes method_name)
122
- def method_name_str
123
- method_name.to_s
124
- end
125
-
126
- # Runs a file-based test that compares files created by the block with
127
- # files in an expected directory. The block receives files from the
128
- # input directory, and should return a list of files relative to the
129
- # output directory. Only the files returned by the block are compared;
130
- # additional files in the output directory are effectively ignored.
131
- #
132
- # === Example
133
- # Lets define a test that transforms input files into output files in a
134
- # trivial way, simply by replacing 'input' with 'output' in the file.
135
- #
136
- # class FileTestDocTest < Test::Unit::TestCase
137
- # acts_as_file_test
138
- #
139
- # def test_assert_files
140
- # assert_files do |input_files|
141
- # input_files.collect do |filepath|
142
- # input = File.read(filepath)
143
- # output_file = method_root.filepath(:output, File.basename(filepath))
144
- #
145
- # File.open(output_file, "w") do |f|
146
- # f << input.gsub(/input/, "output")
147
- # end
148
- #
149
- # output_file
150
- # end
151
- # end
152
- # end
153
- # end
154
- #
155
- # Now say you had some input and expected files for test_assert_files:
156
- #
157
- # file_test_doc/test_assert_files
158
- # |- expected
159
- # | |- one.txt
160
- # | `- two.txt
161
- # `- input
162
- # |- one.txt
163
- # `- two.txt
164
- #
165
- # [input/one.txt]
166
- # test input 1
167
- #
168
- # [input/two.txt]
169
- # test input 2
170
- #
171
- # [expected/one.txt]
172
- # test output 1
173
- #
174
- # [expected/two.txt]
175
- # test output 2
176
- #
177
- # When you run the test, the assert_files passes the input files to the
178
- # block. When the block completes, assert_files compares the output
179
- # files returned by the block with the files in the expected directory.
180
- # In this case, the files are equal and the test passes.
181
- #
182
- # Say you changed the content of one of the expected files:
183
- #
184
- # [expected/one.txt]
185
- # test flunk 1
186
- #
187
- # Now the test fails because the output files aren't equal to the
188
- # expected files. The test also fails if there are missing or extra
189
- # files.
190
- #
191
- # === Options
192
- # A variety of options adjust the behavior of assert_files:
193
- #
194
- # :input_dir specify the directory to glob for input files
195
- # (default method_root[:input])
196
- # :output_dir specify the output directory
197
- # (default method_root[:output])
198
- # :expected_dir specify the directory to glob for expected files
199
- # (default method_root[:expected])
200
- # :input_files directly specify the input files for the block
201
- # :expected_files directly specify the expected files for comparison
202
- # :include_input_directories specifies directories to be included in the
203
- # input_files array (by default dirs are excluded)
204
- # :include_expected_directories specifies directories to be included in the
205
- # expected-output file list comparison
206
- # (by default dirs are excluded)
207
- #
208
- # assert_files will fail if <tt>:expected_files</tt> was not specified
209
- # in the options and no files were found in <tt>:expected_dir</tt>. This
210
- # check tries to prevent silent false-positive results when you forget to
211
- # put expected files in their place.
212
- #
213
- # === File References
214
- #
215
- # Sometimes the same files will get used across multiple tests. To allow
216
- # separate management of test files and prevent duplication, file
217
- # references can be provided in place of test files. For instance, with a
218
- # test directory like:
219
- #
220
- # method_root
221
- # |- expected
222
- # | |- one.txt.ref
223
- # | `- two.txt.ref
224
- # |- input
225
- # | |- one.txt.ref
226
- # | `- two.txt.ref
227
- # `- ref
228
- # |- one.txt
229
- # `- two.txt
230
- #
231
- # The input and expected files (all references in this case) can be
232
- # dereferenced to the 'ref' filepaths like so:
233
- #
234
- # assert_files :reference_dir => method_root[:ref] do |input_files|
235
- # input_files # => ['method_root/ref/one.txt', 'method_root/ref/two.txt']
236
- #
237
- # input_files.collect do |input_file|
238
- # output_file = method_root.filepath(:output, File.basename(input_file)
239
- # FileUtils.cp(input_file, output_file)
240
- # output_file
241
- # end
242
- # end
243
- #
244
- # Dereferencing occurs relative to the input_dir/expected_dir
245
- # configurations; a reference_dir must be specified for dereferencing to
246
- # occur (see Utils.dereference for more details).
247
- #
248
- # === Keeping Outputs
249
- #
250
- # By default FileTest cleans up everything under method_root except the
251
- # input and expected directories. For ease in debugging, ENV variable
252
- # flags can be specified to prevent cleanup for all tests (KEEP_OUTPUTS)
253
- # or just tests that fail (KEEP_FAILURES). These flags can be specified
254
- # from the command line if you're running the tests with rake or rap:
255
- #
256
- # % rake test keep_outputs=true
257
- # % rap test keep_failures=true
258
- #
259
- #--
260
- # TODO:
261
- # * add debugging information to indicate, for instance,
262
- # when dereferencing is going on.
263
- def assert_files(options={}, &block) # :yields: input_files
264
- transform_test(block, options) do |expected_file, output_file|
265
- unless FileUtils.cmp(expected_file, output_file)
266
- flunk "<#{expected_file}> not equal to\n<#{output_file}>"
267
- end
268
- end
269
- end
270
-
271
- def assert_files_alike(options={}, &block) # :yields: input_files
272
- transform_test(block, options) do |expected_file, output_file|
273
- regexp = RegexpEscape.new(File.read(expected_file))
274
- str = File.read(output_file)
275
- assert_alike(regexp, str, "<#{expected_file}> not equal to\n<#{output_file}>")
276
- end
277
- end
278
-
279
- # The default assert_files options
280
- def default_assert_files_options
281
- {
282
- :input_dir => method_root[:input],
283
- :output_dir => method_root[:output],
284
- :expected_dir => method_root[:expected],
285
-
286
- :input_files => nil,
287
- :expected_files => nil,
288
- :include_input_directories => false,
289
- :include_expected_directories => false,
290
-
291
- :reference_dir => nil,
292
- :reference_extname => '.ref'
293
- }
294
- end
295
-
296
- private
297
-
298
- def transform_test(block, options={}) # :yields: expected_files, output_files
299
- options = default_assert_files_options.merge(options)
300
- input_dir = options[:input_dir]
301
- output_dir = options[:output_dir]
302
- expected_dir = options[:expected_dir]
303
-
304
- reference_dir = options[:reference_dir]
305
- reference_pattern = options[:reference_pattern]
306
-
307
- Utils.dereference([input_dir, expected_dir], reference_dir, reference_pattern || '**/*.ref') do
308
-
309
- # Get the input and expected files in this manner:
310
- # - look for manually specified files
311
- # - glob for files if none were specified
312
- # - expand paths and sort
313
- # - remove directories unless specified not to do so
314
- input_files, expected_files = [:input, :expected].collect do |key|
315
- files = options["#{key}_files".to_sym]
316
- if files.nil?
317
- pattern = File.join(options["#{key}_dir".to_sym], "**/*")
318
- files = Dir.glob(pattern)
319
- end
320
- files = [files].flatten.collect {|file| File.expand_path(file) }.sort
321
-
322
- unless options["include_#{key}_directories".to_sym]
323
- files.delete_if {|file| File.directory?(file)}
324
- end
325
-
326
- files
327
- end
328
-
329
- # check at least one expected file was found
330
- if expected_files.empty? && options[:expected_files] == nil
331
- flunk "No expected files specified."
332
- end
333
-
334
- # get output files from the block, expand and sort
335
- output_files = [*block.call(input_files)].collect do |output_file|
336
- File.expand_path(output_file)
337
- end.sort
338
-
339
- # check that the expected and output filepaths are the same
340
- translated_expected_files = expected_files.collect do |expected_file|
341
- Tap::Root.translate(expected_file, expected_dir, output_dir)
342
- end
343
- assert_equal translated_expected_files, output_files, "Missing, extra, or unexpected output files"
344
-
345
- # check that the expected and output file contents are equal
346
- errors = []
347
- Utils.each_pair(expected_files, output_files) do |expected_file, output_file|
348
- unless (File.directory?(expected_file) && File.directory?(output_file)) || FileUtils.cmp(expected_file, output_file)
349
- begin
350
- yield(expected_file, output_file)
351
- rescue
352
- errors << $!
353
- end
354
- end
355
- end
356
- flunk "File compare failed:\n" + errors.join("\n") unless errors.empty?
357
- end
358
- end
359
-
360
- end
361
- end
362
- end