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.
- data/History +34 -0
- data/README +62 -41
- data/bin/tap +36 -40
- data/cmd/console.rb +14 -6
- data/cmd/manifest.rb +62 -58
- data/cmd/run.rb +49 -31
- data/doc/API +84 -0
- data/doc/Class Reference +83 -115
- data/doc/Examples/Command Line +36 -0
- data/doc/Examples/Workflow +40 -0
- data/lib/tap/app.rb +293 -214
- data/lib/tap/app/node.rb +43 -0
- data/lib/tap/app/queue.rb +77 -0
- data/lib/tap/app/stack.rb +16 -0
- data/lib/tap/app/state.rb +22 -0
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/env.rb +400 -314
- data/lib/tap/env/constant.rb +227 -0
- data/lib/tap/env/gems.rb +63 -0
- data/lib/tap/env/manifest.rb +89 -0
- data/lib/tap/env/minimap.rb +292 -0
- data/lib/tap/{support → env}/string_ext.rb +2 -2
- data/lib/tap/exe.rb +113 -125
- data/lib/tap/join.rb +175 -0
- data/lib/tap/joins.rb +9 -0
- data/lib/tap/joins/switch.rb +44 -0
- data/lib/tap/joins/sync.rb +99 -0
- data/lib/tap/root.rb +100 -491
- data/lib/tap/root/utils.rb +220 -0
- data/lib/tap/{support → root}/versions.rb +31 -29
- data/lib/tap/schema.rb +248 -0
- data/lib/tap/schema/parser.rb +413 -0
- data/lib/tap/schema/utils.rb +82 -0
- data/lib/tap/support/intern.rb +19 -6
- data/lib/tap/support/templater.rb +8 -3
- data/lib/tap/task.rb +175 -171
- data/lib/tap/tasks/dump.rb +58 -0
- data/lib/tap/tasks/load.rb +62 -0
- metadata +30 -73
- data/cmd/destroy.rb +0 -27
- data/cmd/generate.rb +0 -27
- data/doc/Command Reference +0 -105
- data/doc/Syntax Reference +0 -234
- data/doc/Tutorial +0 -348
- data/lib/tap/dump.rb +0 -142
- data/lib/tap/file_task.rb +0 -384
- data/lib/tap/generator/arguments.rb +0 -13
- data/lib/tap/generator/base.rb +0 -176
- data/lib/tap/generator/destroy.rb +0 -60
- data/lib/tap/generator/generate.rb +0 -93
- data/lib/tap/generator/generators/command/command_generator.rb +0 -21
- data/lib/tap/generator/generators/command/templates/command.erb +0 -32
- data/lib/tap/generator/generators/config/config_generator.rb +0 -98
- data/lib/tap/generator/generators/generator/generator_generator.rb +0 -37
- data/lib/tap/generator/generators/generator/templates/task.erb +0 -27
- data/lib/tap/generator/generators/generator/templates/test.erb +0 -26
- data/lib/tap/generator/generators/root/root_generator.rb +0 -84
- data/lib/tap/generator/generators/root/templates/MIT-LICENSE +0 -22
- data/lib/tap/generator/generators/root/templates/README +0 -14
- data/lib/tap/generator/generators/root/templates/Rakefile +0 -84
- data/lib/tap/generator/generators/root/templates/Rapfile +0 -11
- data/lib/tap/generator/generators/root/templates/gemspec +0 -27
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -3
- data/lib/tap/generator/generators/task/task_generator.rb +0 -25
- data/lib/tap/generator/generators/task/templates/task.erb +0 -14
- data/lib/tap/generator/generators/task/templates/test.erb +0 -19
- data/lib/tap/generator/manifest.rb +0 -20
- data/lib/tap/generator/preview.rb +0 -69
- data/lib/tap/load.rb +0 -64
- data/lib/tap/spec.rb +0 -41
- data/lib/tap/support/aggregator.rb +0 -65
- data/lib/tap/support/audit.rb +0 -333
- data/lib/tap/support/constant.rb +0 -143
- data/lib/tap/support/constant_manifest.rb +0 -126
- data/lib/tap/support/dependencies.rb +0 -54
- data/lib/tap/support/dependency.rb +0 -44
- data/lib/tap/support/executable.rb +0 -198
- data/lib/tap/support/executable_queue.rb +0 -125
- data/lib/tap/support/gems.rb +0 -43
- data/lib/tap/support/join.rb +0 -144
- data/lib/tap/support/joins.rb +0 -12
- data/lib/tap/support/joins/switch.rb +0 -27
- data/lib/tap/support/joins/sync_merge.rb +0 -38
- data/lib/tap/support/manifest.rb +0 -171
- data/lib/tap/support/minimap.rb +0 -90
- data/lib/tap/support/node.rb +0 -176
- data/lib/tap/support/parser.rb +0 -450
- data/lib/tap/support/schema.rb +0 -385
- data/lib/tap/support/shell_utils.rb +0 -67
- data/lib/tap/test.rb +0 -77
- data/lib/tap/test/assertions.rb +0 -38
- data/lib/tap/test/env_vars.rb +0 -29
- data/lib/tap/test/extensions.rb +0 -73
- data/lib/tap/test/file_test.rb +0 -362
- data/lib/tap/test/file_test_class.rb +0 -15
- data/lib/tap/test/regexp_escape.rb +0 -87
- data/lib/tap/test/script_test.rb +0 -46
- data/lib/tap/test/script_tester.rb +0 -115
- data/lib/tap/test/subset_test.rb +0 -260
- data/lib/tap/test/subset_test_class.rb +0 -99
- data/lib/tap/test/tap_test.rb +0 -109
- 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:
|
data/lib/tap/test/assertions.rb
DELETED
@@ -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
|
data/lib/tap/test/env_vars.rb
DELETED
@@ -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
|
data/lib/tap/test/extensions.rb
DELETED
@@ -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
|
-
|
data/lib/tap/test/file_test.rb
DELETED
@@ -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
|