tap 0.12.4 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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