bahuvrihi-tap 0.11.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rap +2 -3
- data/bin/tap +1 -1
- data/cmd/console.rb +2 -2
- data/cmd/manifest.rb +2 -2
- data/cmd/run.rb +7 -9
- data/cmd/server.rb +5 -5
- data/doc/Class Reference +17 -20
- data/doc/Tutorial +5 -7
- data/lib/tap.rb +2 -0
- data/lib/tap/app.rb +21 -31
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/declarations.rb +85 -97
- data/lib/tap/declarations/declaration_task.rb +58 -0
- data/lib/tap/declarations/description.rb +24 -0
- data/lib/tap/env.rb +20 -16
- data/lib/tap/exe.rb +2 -2
- data/lib/tap/file_task.rb +224 -410
- data/lib/tap/generator/arguments.rb +9 -0
- data/lib/tap/generator/base.rb +105 -28
- data/lib/tap/generator/destroy.rb +29 -12
- data/lib/tap/generator/generate.rb +55 -39
- data/lib/tap/generator/generators/command/templates/command.erb +3 -3
- data/lib/tap/generator/generators/config/config_generator.rb +34 -3
- data/lib/tap/generator/generators/root/root_generator.rb +6 -9
- data/lib/tap/generator/generators/root/templates/Rakefile +4 -4
- data/lib/tap/generator/generators/task/templates/test.erb +1 -1
- data/lib/tap/root.rb +211 -156
- data/lib/tap/support/aggregator.rb +6 -9
- data/lib/tap/support/audit.rb +278 -357
- data/lib/tap/support/constant_manifest.rb +24 -21
- data/lib/tap/support/dependency.rb +1 -1
- data/lib/tap/support/executable.rb +26 -48
- data/lib/tap/support/join.rb +44 -19
- data/lib/tap/support/joins/sync_merge.rb +3 -5
- data/lib/tap/support/parser.rb +1 -1
- data/lib/tap/task.rb +195 -150
- data/lib/tap/tasks/dump.rb +2 -2
- data/lib/tap/test/extensions.rb +11 -13
- data/lib/tap/test/file_test.rb +71 -129
- data/lib/tap/test/file_test_class.rb +4 -1
- data/lib/tap/test/tap_test.rb +26 -154
- metadata +15 -22
- data/lib/tap/patches/optparse/summarize.rb +0 -62
- data/lib/tap/support/assignments.rb +0 -173
- data/lib/tap/support/class_configuration.rb +0 -182
- data/lib/tap/support/configurable.rb +0 -113
- data/lib/tap/support/configurable_class.rb +0 -271
- data/lib/tap/support/configuration.rb +0 -170
- data/lib/tap/support/instance_configuration.rb +0 -173
- data/lib/tap/support/lazydoc.rb +0 -386
- data/lib/tap/support/lazydoc/attributes.rb +0 -48
- data/lib/tap/support/lazydoc/comment.rb +0 -503
- data/lib/tap/support/lazydoc/config.rb +0 -17
- data/lib/tap/support/lazydoc/definition.rb +0 -36
- data/lib/tap/support/lazydoc/document.rb +0 -152
- data/lib/tap/support/lazydoc/method.rb +0 -24
- data/lib/tap/support/tdoc.rb +0 -409
- data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -38
- data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -42
- data/lib/tap/support/validation.rb +0 -479
data/lib/tap/tasks/dump.rb
CHANGED
@@ -41,8 +41,8 @@ module Tap
|
|
41
41
|
app.aggregator.to_hash.each_pair do |src, _results|
|
42
42
|
next if filter && src.to_s !~ filter
|
43
43
|
|
44
|
-
results["#{src} (#{src.object_id})"] = _results.collect {|_audit| _audit.
|
45
|
-
_results.each {|_audit| trails << _audit.
|
44
|
+
results["#{src} (#{src.object_id})"] = _results.collect {|_audit| _audit.value }
|
45
|
+
_results.each {|_audit| trails << _audit.dump }
|
46
46
|
end
|
47
47
|
|
48
48
|
if audit
|
data/lib/tap/test/extensions.rb
CHANGED
@@ -16,8 +16,8 @@ module Tap
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# Causes a TestCase to act as a file test, by including FileTest and
|
19
|
-
# instantiating class_test_root (a Tap::Root). The root
|
20
|
-
# used by class_test_root may be specified as options.
|
19
|
+
# instantiating class_test_root (a Tap::Root). The root, relative_paths,
|
20
|
+
# and absolute_paths used by class_test_root may be specified as options.
|
21
21
|
#
|
22
22
|
# Note: by default acts_as_file_test determines a root directory
|
23
23
|
# <em>based on the calling file</em>. Be sure to specify the root
|
@@ -26,15 +26,10 @@ module Tap
|
|
26
26
|
def acts_as_file_test(options={})
|
27
27
|
include Tap::Test::FileTest
|
28
28
|
|
29
|
-
|
30
|
-
:root
|
31
|
-
:
|
32
|
-
|
33
|
-
:output => 'output',
|
34
|
-
:expected => 'expected'}
|
35
|
-
}.merge(options)
|
36
|
-
|
37
|
-
self.class_test_root = Tap::Root.new(options[:root], options[:directories])
|
29
|
+
self.class_test_root = Tap::Root.new(
|
30
|
+
options[:root] || test_root_dir,
|
31
|
+
options[:relative_paths] || {},
|
32
|
+
options[:absolute_paths] || {})
|
38
33
|
end
|
39
34
|
|
40
35
|
# Causes a unit test to act as a tap test -- resulting in the following:
|
@@ -47,14 +42,17 @@ module Tap
|
|
47
42
|
# directory manually if you call acts_as_file_test from a file that
|
48
43
|
# isn't the test file.
|
49
44
|
def acts_as_tap_test(options={})
|
45
|
+
options[:root] ||= test_root_dir
|
46
|
+
|
50
47
|
acts_as_subset_test
|
51
|
-
acts_as_file_test(
|
48
|
+
acts_as_file_test(options)
|
52
49
|
|
53
50
|
include Tap::Test::TapTest
|
54
51
|
end
|
55
52
|
|
56
53
|
def acts_as_script_test(options={})
|
57
|
-
|
54
|
+
options[:root] ||= test_root_dir
|
55
|
+
acts_as_file_test(options)
|
58
56
|
|
59
57
|
include Tap::Test::ScriptTest
|
60
58
|
end
|
data/lib/tap/test/file_test.rb
CHANGED
@@ -7,7 +7,7 @@ module Tap
|
|
7
7
|
module Test
|
8
8
|
|
9
9
|
# FileTest facilitates access and utilization of test-specific files and
|
10
|
-
# directories. FileTest provides each test method
|
10
|
+
# directories. FileTest provides each test method with a Tap::Root
|
11
11
|
# (method_root) specific for the method, and defines a new assertion method
|
12
12
|
# (assert_files) to facilitate tests which involve the production and/or
|
13
13
|
# modification of files.
|
@@ -25,32 +25,25 @@ module Tap
|
|
25
25
|
# method_root.root # => File.join(ctr.root, "/test_something")
|
26
26
|
# method_root[:input] # => File.join(ctr.root, "/test_something/input")
|
27
27
|
#
|
28
|
-
# # files in the output
|
29
|
-
# # and after each test; this passes each time the
|
28
|
+
# # files in the :output and :tmp directories are cleared
|
29
|
+
# # before and after each test; this passes each time the
|
30
30
|
# # test is run with no additional cleanup:
|
31
31
|
#
|
32
|
-
#
|
33
|
-
# assert !File.exists?(output_file)
|
32
|
+
# assert !File.exists?(method_root[:tmp])
|
34
33
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# assert File.exists?(output_file)
|
34
|
+
# tmp_file = method_root.prepare(:tmp, 'sample.txt') {|file| file << "content" }
|
35
|
+
# assert_equal "content", File.read(tmp_file)
|
39
36
|
#
|
40
37
|
# # the assert_files method compares files produced
|
41
38
|
# # by the block the expected files, ensuring they
|
42
39
|
# # are the same (see the documentation for the
|
43
40
|
# # simplest use of assert_files)
|
44
41
|
#
|
45
|
-
# expected_file = method_root.
|
46
|
-
# File.open(expected_file, 'w') {|file| file << 'expected output' }
|
42
|
+
# expected_file = method_root.prepare(:expected, 'output.txt') {|file| file << 'expected output' }
|
47
43
|
#
|
48
44
|
# # passes
|
49
45
|
# assert_files do
|
50
|
-
#
|
51
|
-
# File.open(output_file, 'w') {|file| file << 'expected output' }
|
52
|
-
#
|
53
|
-
# output_file
|
46
|
+
# method_root.prepare(:output, 'output.txt') {|file| file << 'expected output' }
|
54
47
|
# end
|
55
48
|
# end
|
56
49
|
# end
|
@@ -61,67 +54,51 @@ module Tap
|
|
61
54
|
include Tap::Test::EnvVars
|
62
55
|
include Tap::Test::Assertions
|
63
56
|
|
64
|
-
def self.included(base)
|
57
|
+
def self.included(base) # :nodoc:
|
65
58
|
super
|
66
59
|
base.extend FileTestClass
|
60
|
+
base.cleanup_dirs = [:output, :tmp]
|
67
61
|
end
|
68
62
|
|
69
63
|
# Convenience method to access the class_test_root.
|
70
64
|
def ctr
|
71
65
|
self.class.class_test_root
|
72
66
|
end
|
73
|
-
|
74
|
-
# Creates the method_root.directories.
|
75
|
-
def make_test_directories
|
76
|
-
method_root.directories.values.each do |dir|
|
77
|
-
FileUtils.mkdir_p( method_root[dir] )
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Attempts to remove the method_root.directories, method_root.root,
|
82
|
-
# and ctr.root. Any given directory will not be removed unless empty.
|
83
|
-
def cleanup_test_directories
|
84
|
-
method_root.directories.values.each do |dir|
|
85
|
-
Utils.try_remove_dir(method_root[dir])
|
86
|
-
end
|
87
|
-
|
88
|
-
Utils.try_remove_dir(method_root.root)
|
89
|
-
Utils.try_remove_dir(ctr.root)
|
90
|
-
end
|
91
67
|
|
92
68
|
# The test-method-specific Tap::Root which may be used to
|
93
69
|
# access test files. method_root is a duplicate of ctr
|
94
|
-
# reconfigured so that method_root.root is ctr[
|
70
|
+
# reconfigured so that method_root.root is ctr[method_name.to_sym]
|
95
71
|
attr_reader :method_root
|
96
72
|
|
97
|
-
#
|
98
|
-
#
|
99
|
-
# directory.
|
100
|
-
attr_reader :method_tempfiles
|
101
|
-
|
102
|
-
# Sets up method_root and attempts to cleanup any left overs from a
|
103
|
-
# previous test (ie by deleting method_root[:output] and calling
|
104
|
-
# cleanup_test_directories). Be sure to call super when overriding
|
105
|
-
# this method.
|
73
|
+
# Sets up method_root and calls cleanup. Be sure to call super when
|
74
|
+
# overriding this method.
|
106
75
|
def setup
|
107
76
|
super
|
108
77
|
@method_root = ctr.dup.reconfigure(:root => ctr[method_name.to_sym])
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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)
|
113
91
|
end
|
114
92
|
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# for failing tests, set the 'KEEP_OUTPUTS' or 'KEEP_FAILURES' ENV
|
119
|
-
# variables:
|
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:
|
120
96
|
#
|
121
97
|
# % rap test KEEP_OUTPUTS=true
|
122
98
|
# % rap test KEEP_FAILURES=true
|
123
99
|
#
|
124
|
-
#
|
100
|
+
# Cleanup is only suppressed for failing tests when KEEP_FAILURES is
|
101
|
+
# specified. Be sure to call super when overriding this method.
|
125
102
|
def teardown
|
126
103
|
# check that method_root still exists (nil may
|
127
104
|
# indicate setup was overridden without super)
|
@@ -132,65 +109,34 @@ module Tap
|
|
132
109
|
# clear out the output folder if it exists, unless flagged otherwise
|
133
110
|
unless env("KEEP_OUTPUTS") || (!passed? && env("KEEP_FAILURES"))
|
134
111
|
begin
|
135
|
-
|
112
|
+
cleanup
|
136
113
|
rescue
|
137
|
-
raise("
|
114
|
+
raise("cleanup failure: #{$!.message}")
|
138
115
|
end
|
139
116
|
end
|
140
117
|
|
141
|
-
|
118
|
+
Utils.try_remove_dir(ctr.root)
|
142
119
|
end
|
143
120
|
|
144
121
|
# Returns method_name as a string (Ruby 1.9 symbolizes method_name)
|
145
122
|
def method_name_str
|
146
123
|
method_name.to_s
|
147
124
|
end
|
148
|
-
|
149
|
-
# Generates a temporary filepath formatted like "output_dir\filename.n.ext"
|
150
|
-
# where n is a counter that ensures the filepath is unique and non-existant
|
151
|
-
# (specificaly n is equal to the number of method_tempfiles generated
|
152
|
-
# by the current test, incremented as necessary to achieve a non-existant
|
153
|
-
# filepath).
|
154
|
-
#
|
155
|
-
# Unlike Tempfile, method_tempfile does not create the filepath unless a
|
156
|
-
# block is given, in which case an open File will be passed to the block.
|
157
|
-
# In addition, method_tempfiles are only cleaned up indirectly when the
|
158
|
-
# output directory is removed by teardown; this is both convenient for
|
159
|
-
# testing (when you may want a the file to persist, so you can debug it)
|
160
|
-
# and less enforcing than Tempfile.
|
161
|
-
#
|
162
|
-
# Notes:
|
163
|
-
# - by default filename is the calling method
|
164
|
-
# - the extension is chomped off the end of the filename
|
165
|
-
# - the directory for the file will be created if it does not exist
|
166
|
-
# - like all files in the output directory, tempfiles will be deleted by
|
167
|
-
# the default +teardown+ method
|
168
|
-
def method_tempfile(filename=method_name_str, &block)
|
169
|
-
ext = File.extname(filename)
|
170
|
-
basename = filename.chomp(ext)
|
171
|
-
path = next_indexed_path(method_root.filepath(:output, basename), method_tempfiles.length, ext)
|
172
|
-
dirname = File.dirname(path)
|
173
|
-
|
174
|
-
method_tempfiles << path
|
175
|
-
FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
|
176
|
-
File.open(path, "w", &block) if block_given?
|
177
|
-
path
|
178
|
-
end
|
179
125
|
|
180
|
-
#
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
# are effectively ignored.
|
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.
|
185
131
|
#
|
186
132
|
# === Example
|
187
|
-
# Lets define a test that transforms input files into output files in a
|
188
|
-
# way, simply by replacing 'input' with 'output' in the file.
|
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.
|
189
135
|
#
|
190
136
|
# class FileTestDocTest < Test::Unit::TestCase
|
191
137
|
# acts_as_file_test
|
192
138
|
#
|
193
|
-
# def
|
139
|
+
# def test_assert_files
|
194
140
|
# assert_files do |input_files|
|
195
141
|
# input_files.collect do |filepath|
|
196
142
|
# input = File.read(filepath)
|
@@ -206,9 +152,9 @@ module Tap
|
|
206
152
|
# end
|
207
153
|
# end
|
208
154
|
#
|
209
|
-
# Now say you had some input and expected files for
|
155
|
+
# Now say you had some input and expected files for test_assert_files:
|
210
156
|
#
|
211
|
-
# file_test_doc/
|
157
|
+
# file_test_doc/test_assert_files
|
212
158
|
# |- expected
|
213
159
|
# | |- one.txt
|
214
160
|
# | `- two.txt
|
@@ -229,20 +175,21 @@ module Tap
|
|
229
175
|
# test output 2
|
230
176
|
#
|
231
177
|
# When you run the test, the assert_files passes the input files to the
|
232
|
-
# block. When the block completes, assert_files compares the output
|
233
|
-
# returned by the block with the files in the expected directory.
|
234
|
-
# case, the files are equal and the test passes.
|
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.
|
235
181
|
#
|
236
182
|
# Say you changed the content of one of the expected files:
|
237
183
|
#
|
238
184
|
# [expected/one.txt]
|
239
185
|
# test flunk 1
|
240
186
|
#
|
241
|
-
# Now the test fails because the output files aren't equal to the
|
242
|
-
# files. The test
|
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.
|
243
190
|
#
|
244
191
|
# === Options
|
245
|
-
# A variety of options
|
192
|
+
# A variety of options adjust the behavior of assert_files:
|
246
193
|
#
|
247
194
|
# :input_dir specify the directory to glob for input files
|
248
195
|
# (default method_root[:input])
|
@@ -258,15 +205,17 @@ module Tap
|
|
258
205
|
# expected-output file list comparison
|
259
206
|
# (by default dirs are excluded)
|
260
207
|
#
|
261
|
-
# assert_files will fail if <tt>:expected_files</tt> was not specified
|
262
|
-
# options and no files were found in <tt>:expected_dir</tt>. This
|
263
|
-
# to prevent silent false-positive results when you forget to
|
264
|
-
# in their place.
|
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.
|
265
212
|
#
|
266
213
|
# === File References
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
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:
|
270
219
|
#
|
271
220
|
# method_root
|
272
221
|
# |- expected
|
@@ -279,8 +228,8 @@ module Tap
|
|
279
228
|
# |- one.txt
|
280
229
|
# `- two.txt
|
281
230
|
#
|
282
|
-
# The input and expected files (all references in this case) can be
|
283
|
-
# to the 'ref' filepaths like so:
|
231
|
+
# The input and expected files (all references in this case) can be
|
232
|
+
# dereferenced to the 'ref' filepaths like so:
|
284
233
|
#
|
285
234
|
# assert_files :reference_dir => method_root[:ref] do |input_files|
|
286
235
|
# input_files # => ['method_root/ref/one.txt', 'method_root/ref/two.txt']
|
@@ -292,16 +241,17 @@ module Tap
|
|
292
241
|
# end
|
293
242
|
# end
|
294
243
|
#
|
295
|
-
# Dereferencing occurs relative to the input_dir/expected_dir
|
296
|
-
# reference_dir must be specified for dereferencing to
|
297
|
-
# for more details).
|
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).
|
298
247
|
#
|
299
248
|
# === Keeping Outputs
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
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:
|
305
255
|
#
|
306
256
|
# % rake test keep_outputs=true
|
307
257
|
# % rap test keep_failures=true
|
@@ -346,8 +296,6 @@ module Tap
|
|
346
296
|
private
|
347
297
|
|
348
298
|
def transform_test(block, options={}) # :yields: expected_files, output_files
|
349
|
-
make_test_directories
|
350
|
-
|
351
299
|
options = default_assert_files_options.merge(options)
|
352
300
|
input_dir = options[:input_dir]
|
353
301
|
output_dir = options[:output_dir]
|
@@ -409,12 +357,6 @@ module Tap
|
|
409
357
|
end
|
410
358
|
end
|
411
359
|
|
412
|
-
# utility method for method_tempfile; increments index until the
|
413
|
-
# path base.indexext does not exist.
|
414
|
-
def next_indexed_path(base, index, ext) # :nodoc:
|
415
|
-
path = sprintf('%s.%d%s', base, index, ext)
|
416
|
-
File.exists?(path) ? next_indexed_path(base, index + 1, ext) : path
|
417
|
-
end
|
418
360
|
end
|
419
361
|
end
|
420
362
|
end
|
@@ -4,9 +4,12 @@ module Tap
|
|
4
4
|
# Class methods extending tests which include FileTest.
|
5
5
|
module FileTestClass
|
6
6
|
|
7
|
-
# The class-level test root (a Tap::Root)
|
7
|
+
# The class-level test root (a Tap::Root)
|
8
8
|
attr_accessor :class_test_root
|
9
9
|
|
10
|
+
# An array of directories to be cleaned up by cleanup
|
11
|
+
attr_accessor :cleanup_dirs
|
12
|
+
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
data/lib/tap/test/tap_test.rb
CHANGED
@@ -1,32 +1,6 @@
|
|
1
1
|
module Tap
|
2
2
|
module Test
|
3
3
|
|
4
|
-
# Used during check_audit to hold the sources and values of an audit
|
5
|
-
# in the correct order. Oriented so that the next value to be checked
|
6
|
-
# is at the top of the stack. Used internally.
|
7
|
-
class AuditStack # :nodoc:
|
8
|
-
attr_reader :test
|
9
|
-
|
10
|
-
def initialize(test)
|
11
|
-
@test = test
|
12
|
-
@stack = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def load_audit(values)
|
16
|
-
[values._sources, values._values].transpose.reverse_each do |sv|
|
17
|
-
load(*sv)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def load(source, value)
|
22
|
-
@stack.unshift [source, value]
|
23
|
-
end
|
24
|
-
|
25
|
-
def next
|
26
|
-
@stack.shift
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
4
|
# Tap-specific testing methods to help with testing Tasks, such as the
|
31
5
|
# checking of audits and test-specific modification of application
|
32
6
|
# configuration.
|
@@ -40,7 +14,7 @@ module Tap
|
|
40
14
|
attr_reader :app
|
41
15
|
|
42
16
|
# Setup creates a test-method-specific application that is initialized
|
43
|
-
# to the method_root, and uses the
|
17
|
+
# to the method_root, and uses the relative and absolute paths from
|
44
18
|
# trs (the test root structure, see Tap::Test::FileTest).
|
45
19
|
#
|
46
20
|
# Also makes sure Tap::App.instance returns the test method app.
|
@@ -50,153 +24,51 @@ module Tap
|
|
50
24
|
Tap::App.instance = @app
|
51
25
|
end
|
52
26
|
|
53
|
-
#
|
54
|
-
# audit test methods
|
55
|
-
#
|
56
|
-
|
57
|
-
# Used to define expected audits in Tap::Test::TapTest#assert_audit_equal
|
58
|
-
class ExpAudit < Array
|
59
|
-
end
|
60
|
-
|
61
|
-
# Used to define merged audit trails in Tap::Test::TapTest#assert_audit_equal
|
62
|
-
class ExpMerge < Array
|
63
|
-
end
|
64
|
-
|
65
|
-
class Tracer
|
66
|
-
include Tap::Support::Executable
|
67
|
-
|
68
|
-
class << self
|
69
|
-
def intern(n, app, runlist)
|
70
|
-
Array.new(n) { |index| new(index, app, runlist) }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def initialize(index, app, runlist)
|
75
|
-
@index = index
|
76
|
-
@runlist = runlist
|
77
|
-
|
78
|
-
@app = app
|
79
|
-
@_method_name = :trace
|
80
|
-
@on_complete_block =nil
|
81
|
-
@dependencies = []
|
82
|
-
@batch = [self]
|
83
|
-
end
|
84
|
-
|
85
|
-
def concat(str, id)
|
86
|
-
"#{str} #{id}".strip
|
87
|
-
end
|
88
|
-
|
89
|
-
def trace(trace)
|
90
|
-
id = "#{@index}.#{batch_index}"
|
91
|
-
@runlist << id
|
92
|
-
|
93
|
-
case trace
|
94
|
-
when Array then trace.collect {|str| concat(str, id) }
|
95
|
-
when String then concat(trace, id)
|
96
|
-
else raise "cannot utilize trace: #{trace}"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
27
|
# Asserts that an array of audits are all equal, basically feeding
|
102
28
|
# each pair of audits to assert_audit_equal.
|
103
|
-
def assert_audits_equal(expected, audits)
|
104
|
-
|
105
|
-
Utils.each_pair_with_index(expected, audits
|
106
|
-
assert_audit_equal(exp, audit,
|
29
|
+
def assert_audits_equal(expected, audits, msg=nil, &block)
|
30
|
+
assert_equal expected.length, audits.length, "expected <#{expected.length}> audits, but was <#{audits.length}>"
|
31
|
+
Utils.each_pair_with_index(expected, audits) do |exp, audit, index|
|
32
|
+
assert_audit_equal(exp, audit, &block)
|
107
33
|
end
|
108
34
|
end
|
109
35
|
|
110
|
-
# Asserts that an audit
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
# to provide directly; the Proc will be used to validate the actual
|
115
|
-
# record. Merges must be marked in the ExpAudit using ExpMerge.
|
36
|
+
# Asserts that an audit trail matches the expected trail. By default
|
37
|
+
# the expected trail should be composed of [key, value] arrays
|
38
|
+
# representing each audit, but a block may be provided to collect other
|
39
|
+
# attributes.
|
116
40
|
#
|
117
41
|
# Simple assertion:
|
118
42
|
#
|
119
|
-
# a =
|
120
|
-
#
|
121
|
-
# a._record(:b, 'b')
|
122
|
-
#
|
123
|
-
# e = ExpAudit[[:a, 'a'], [:b, 'b']]
|
124
|
-
# assert_audit_equal(e, a)
|
125
|
-
#
|
126
|
-
# Assertion validating a record with a Proc (any number of
|
127
|
-
# records can be validated with a Proc):
|
128
|
-
#
|
129
|
-
# a = Tap::Support::Audit.new
|
130
|
-
# a._record(:a, 'a')
|
131
|
-
# a._record(:b, 'b')
|
43
|
+
# a = Audit.new(:a, 'a')
|
44
|
+
# b = Audit.new(:b, 'b', a)
|
132
45
|
#
|
133
|
-
# e =
|
134
|
-
#
|
135
|
-
# [:b, 'b']]
|
136
|
-
# assert_audit_equal(e, a)
|
46
|
+
# e = [[:a, 'a'], [:b, 'b']]
|
47
|
+
# assert_audit_equal(e, b)
|
137
48
|
#
|
138
49
|
# Assertion with merge:
|
139
50
|
#
|
140
|
-
# a =
|
141
|
-
#
|
142
|
-
# a._record(:b, 'b')
|
51
|
+
# a = Audit.new(:a, 'a')
|
52
|
+
# b = Audit.new(:b, 'b', a)
|
143
53
|
#
|
144
|
-
#
|
145
|
-
#
|
146
|
-
# b._record(:d, 'd')
|
54
|
+
# c = Audit.new(:c, 'c')
|
55
|
+
# d = Audit.new(:d, 'd', c)
|
147
56
|
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
# c._record(:f, 'f')
|
57
|
+
# e = Audit.new(:e, 'e')
|
58
|
+
# f = Audit.new(:f, 'f', [b,d])
|
151
59
|
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
# e =
|
60
|
+
# eb = [[:a, "a"], [:b, "b"]]
|
61
|
+
# ed = [[:c, "c"], [:d, "d"]]
|
62
|
+
# e = [[eb, ed], [:e, "e"], [:f, "f"]]
|
155
63
|
#
|
156
64
|
# assert_audit_equal(e, c)
|
157
65
|
#
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
# ea = ExpAudit[[:a, "a"], [:b, "FLUNK"]]
|
163
|
-
# eb = ExpAudit[[:c, "c"], [:d, "d"]]
|
164
|
-
# e = ExpAudit[ExpMerge[ea, eb], [:e, "e"], [:f, "f"]]
|
165
|
-
#
|
166
|
-
# The failure message will read something like 'unequal record 0:0:1'
|
167
|
-
# indicating it was e[0][0][1] that failed. Working through it,
|
168
|
-
# remembering that ExpAudit and ExpMerge are just subclasses of
|
169
|
-
# Array:
|
170
|
-
#
|
171
|
-
# e # => ExpAudit[ExpMerge[ea, eb], [:e, "e"], [:f, "f"]]
|
172
|
-
# e[0] # => ExpMerge[ea, eb]
|
173
|
-
# e[0][0] # => ExpAudit[[:a, "a"], [:b, "FLUNK"]]
|
174
|
-
# e[0][0][1] # => [:b, "FLUNK"]
|
175
|
-
#
|
176
|
-
def assert_audit_equal(expected, audit, nesting=[])
|
177
|
-
actual = audit._collect_records {|source, value| [source, value]}
|
178
|
-
assert_audit_records_equal(expected, actual, nesting)
|
66
|
+
def assert_audit_equal(expected, audit, msg=nil, &block)
|
67
|
+
block = lambda {|audit| [audit.key, audit.value] } unless block
|
68
|
+
actual = audit.trail(&block)
|
69
|
+
assert_equal(expected, actual, msg)
|
179
70
|
end
|
180
71
|
|
181
|
-
def assert_audit_records_equal(expected, actual, nesting=[])
|
182
|
-
assert_equal ExpAudit, expected.class
|
183
|
-
assert_equal expected.length, actual.length, "unequal number of records"
|
184
|
-
|
185
|
-
expected.each_with_index do |exp_record, i|
|
186
|
-
case exp_record
|
187
|
-
when ExpMerge
|
188
|
-
flunk "empty merge #{(nesting + [i]).join(':')}" if exp_record.empty?
|
189
|
-
exp_record.each_with_index do |exp_audit, j|
|
190
|
-
assert_audit_records_equal(exp_audit, actual[i][j], nesting + [i,j])
|
191
|
-
end
|
192
|
-
when Proc
|
193
|
-
assert exp_record.call(*actual[i]), "unconfirmed record #{(nesting + [i]).join(':')}"
|
194
|
-
else
|
195
|
-
assert_equal exp_record, actual[i], "unequal record #{(nesting + [i]).join(':')}"
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
72
|
# The configurations used to initialize self.app
|
201
73
|
def app_config
|
202
74
|
method_root.config.to_hash.merge(:quiet => true, :debug => true)
|