tap 0.12.4 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|