dfect 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CREDITS +2 -2
- data/HISTORY +306 -0
- data/INSTALL +35 -0
- data/README +95 -0
- data/USAGE +393 -0
- data/doc/api/Dfect.html +3179 -0
- data/doc/api/Object.html +107 -0
- data/doc/api/_index.html +107 -0
- data/doc/api/class_list.html +36 -0
- data/doc/api/css/common.css +1 -0
- data/doc/api/css/full_list.css +50 -0
- data/doc/api/css/style.css +268 -0
- data/doc/api/file.LICENSE.html +73 -0
- data/doc/api/file_list.html +38 -0
- data/doc/api/frames.html +13 -0
- data/doc/api/index.html +72 -13
- data/doc/api/js/app.js +99 -0
- data/doc/api/js/full_list.js +106 -0
- data/doc/api/js/{jquery-1.3.2.min.js → jquery.js} +0 -0
- data/doc/api/method_list.html +339 -0
- data/doc/api/top-level-namespace.html +87 -0
- data/doc/index.erb +16 -9
- data/doc/index.html +1057 -726
- data/lib/dfect.rb +431 -284
- data/lib/dfect/auto.rb +2 -6
- data/lib/dfect/inochi.rb +48 -0
- data/lib/dfect/inochi.yaml +75 -0
- data/lib/dfect/mini.rb +1 -5
- data/lib/dfect/spec.rb +6 -13
- data/lib/dfect/unit.rb +21 -33
- data/test/dfect/inochi_test.rb +17 -0
- data/test/{dfect.rb → dfect_test.rb} +167 -7
- data/test/runner +25 -0
- data/test/test_helper.rb +1 -0
- metadata +43 -55
- data/doc/api/apple-touch-icon.png +0 -0
- data/doc/api/classes/Class.html +0 -73
- data/doc/api/classes/Dfect.html +0 -1245
- data/doc/api/classes/Kernel.html +0 -322
- data/doc/api/classes/Object.html +0 -72
- data/doc/api/created.rid +0 -1
- data/doc/api/css/main.css +0 -263
- data/doc/api/css/panel.css +0 -383
- data/doc/api/css/reset.css +0 -53
- data/doc/api/favicon.ico +0 -0
- data/doc/api/files/CREDITS.html +0 -65
- data/doc/api/files/LICENSE.html +0 -76
- data/doc/api/files/lib/dfect/auto_rb.html +0 -80
- data/doc/api/files/lib/dfect/mini_rb.html +0 -77
- data/doc/api/files/lib/dfect/spec_rb.html +0 -73
- data/doc/api/files/lib/dfect/unit_rb.html +0 -73
- data/doc/api/files/lib/dfect_rb.html +0 -74
- data/doc/api/i/arrows.png +0 -0
- data/doc/api/i/results_bg.png +0 -0
- data/doc/api/i/tree_bg.png +0 -0
- data/doc/api/js/jquery-effect.js +0 -593
- data/doc/api/js/main.js +0 -22
- data/doc/api/js/searchdoc.js +0 -628
- data/doc/api/panel/index.html +0 -71
- data/doc/api/panel/search_index.js +0 -1
- data/doc/api/panel/tree.js +0 -1
- data/doc/history.erb +0 -161
- data/doc/intro.erb +0 -104
- data/doc/setup.erb +0 -107
- data/doc/usage.erb +0 -310
- data/rakefile +0 -21
data/lib/dfect.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright protects this work.
|
3
|
-
# See LICENSE file for details.
|
4
|
-
#++
|
5
|
-
|
6
1
|
require 'yaml'
|
7
2
|
#
|
8
3
|
# YAML raises this error when we try to serialize a class:
|
@@ -11,7 +6,7 @@ require 'yaml'
|
|
11
6
|
#
|
12
7
|
# Work around this by representing a class by its name.
|
13
8
|
#
|
14
|
-
class Class
|
9
|
+
class Class # @private
|
15
10
|
alias __to_yaml__ to_yaml
|
16
11
|
undef to_yaml
|
17
12
|
|
@@ -19,7 +14,6 @@ class Class #:nodoc: all
|
|
19
14
|
begin
|
20
15
|
__to_yaml__
|
21
16
|
rescue TypeError => e
|
22
|
-
warn e
|
23
17
|
self.name.to_yaml opts
|
24
18
|
end
|
25
19
|
end
|
@@ -42,37 +36,40 @@ end
|
|
42
36
|
module Dfect
|
43
37
|
class << self
|
44
38
|
##
|
45
|
-
# Hash of test results, assembled by
|
39
|
+
# Hash of test results, assembled by {Dfect.run}.
|
46
40
|
#
|
47
|
-
# [:
|
41
|
+
# [:trace]
|
48
42
|
# Hierarchical trace of all tests executed, where each test is
|
49
43
|
# represented by its description, is mapped to an Array of
|
50
44
|
# nested tests, and may contain zero or more assertion failures.
|
51
45
|
#
|
52
46
|
# Assertion failures are represented as a Hash:
|
53
47
|
#
|
54
|
-
# [
|
48
|
+
# [:fail]
|
55
49
|
# Description of the assertion failure.
|
56
50
|
#
|
57
|
-
# [
|
51
|
+
# [:code]
|
58
52
|
# Source code surrounding the point of failure.
|
59
53
|
#
|
60
|
-
# [
|
54
|
+
# [:vars]
|
61
55
|
# Local variables visible at the point of failure.
|
62
56
|
#
|
63
|
-
# [
|
57
|
+
# [:call]
|
64
58
|
# Stack trace leading to the point of failure.
|
65
59
|
#
|
66
|
-
# [:
|
60
|
+
# [:stats]
|
67
61
|
# Hash of counts of major events in test execution:
|
68
62
|
#
|
69
|
-
# [:
|
63
|
+
# [:time]
|
64
|
+
# Number of seconds elapsed for test execution.
|
65
|
+
#
|
66
|
+
# [:pass]
|
70
67
|
# Number of assertions that held true.
|
71
68
|
#
|
72
|
-
# [:
|
69
|
+
# [:fail]
|
73
70
|
# Number of assertions that did not hold true.
|
74
71
|
#
|
75
|
-
# [:
|
72
|
+
# [:error]
|
76
73
|
# Number of exceptions that were not rescued.
|
77
74
|
#
|
78
75
|
attr_reader :report
|
@@ -85,7 +82,7 @@ module Dfect
|
|
85
82
|
# during assertion failures so
|
86
83
|
# the user can investigate them.
|
87
84
|
#
|
88
|
-
# The default value is
|
85
|
+
# The default value is $DEBUG.
|
89
86
|
#
|
90
87
|
# [:quiet]
|
91
88
|
# Do not print the report
|
@@ -96,17 +93,20 @@ module Dfect
|
|
96
93
|
attr_accessor :options
|
97
94
|
|
98
95
|
##
|
99
|
-
# Defines a new test
|
96
|
+
# Defines a new test composed of the given
|
100
97
|
# description and the given block to execute.
|
101
98
|
#
|
102
|
-
#
|
99
|
+
# This test may contain nested tests.
|
100
|
+
#
|
101
|
+
# Tests at the outer-most level are automatically
|
102
|
+
# insulated from the top-level Ruby environment.
|
103
103
|
#
|
104
|
-
#
|
104
|
+
# @param [Object, Array<Object>] description
|
105
105
|
#
|
106
|
-
#
|
107
|
-
#
|
106
|
+
# A brief title or a series of objects
|
107
|
+
# that describe the test being defined.
|
108
108
|
#
|
109
|
-
#
|
109
|
+
# @example
|
110
110
|
#
|
111
111
|
# D "a new array" do
|
112
112
|
# D .< { @array = [] }
|
@@ -124,18 +124,54 @@ module Dfect
|
|
124
124
|
# end
|
125
125
|
# end
|
126
126
|
#
|
127
|
-
def D description
|
128
|
-
|
129
|
-
@curr_suite.tests << Suite::Test.new(description.to_s, block)
|
127
|
+
def D *description, &block
|
128
|
+
create_test @tests.empty?, *description, &block
|
130
129
|
end
|
131
130
|
|
132
131
|
##
|
133
|
-
#
|
132
|
+
# Defines a new test that is explicitly insulated from the tests
|
133
|
+
# that contain it and also from the top-level Ruby environment.
|
134
|
+
#
|
135
|
+
# This test may contain nested tests.
|
136
|
+
#
|
137
|
+
# @param description (see Dfect.D)
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
#
|
141
|
+
# D "a root-level test" do
|
142
|
+
# @outside = 1
|
143
|
+
# T { defined? @outside }
|
144
|
+
# T { @outside == 1 }
|
145
|
+
#
|
146
|
+
# D "an inner, non-insulated test" do
|
147
|
+
# T { defined? @outside }
|
148
|
+
# T { @outside == 1 }
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# D! "an inner, insulated test" do
|
152
|
+
# F { defined? @outside }
|
153
|
+
# F { @outside == 1 }
|
154
|
+
#
|
155
|
+
# @inside = 2
|
156
|
+
# T { defined? @inside }
|
157
|
+
# T { @inside == 2 }
|
158
|
+
# end
|
159
|
+
#
|
160
|
+
# F { defined? @inside }
|
161
|
+
# F { @inside == 2 }
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
def D! *description, &block
|
165
|
+
create_test true, *description, &block
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# @overload def <(&block)
|
134
170
|
#
|
135
171
|
# Registers the given block to be executed
|
136
172
|
# before each nested test inside this test.
|
137
173
|
#
|
138
|
-
#
|
174
|
+
# @example
|
139
175
|
#
|
140
176
|
# D .< { puts "before each nested test" }
|
141
177
|
#
|
@@ -146,7 +182,7 @@ module Dfect
|
|
146
182
|
def <(*args, &block)
|
147
183
|
if args.empty?
|
148
184
|
raise ArgumentError, 'block must be given' unless block
|
149
|
-
@
|
185
|
+
@suite.before_each << block
|
150
186
|
else
|
151
187
|
# the < method is being used as a check for inheritance
|
152
188
|
super
|
@@ -157,7 +193,7 @@ module Dfect
|
|
157
193
|
# Registers the given block to be executed
|
158
194
|
# after each nested test inside this test.
|
159
195
|
#
|
160
|
-
#
|
196
|
+
# @example
|
161
197
|
#
|
162
198
|
# D .> { puts "after each nested test" }
|
163
199
|
#
|
@@ -167,14 +203,14 @@ module Dfect
|
|
167
203
|
#
|
168
204
|
def > &block
|
169
205
|
raise ArgumentError, 'block must be given' unless block
|
170
|
-
@
|
206
|
+
@suite.after_each << block
|
171
207
|
end
|
172
208
|
|
173
209
|
##
|
174
210
|
# Registers the given block to be executed
|
175
211
|
# before all nested tests inside this test.
|
176
212
|
#
|
177
|
-
#
|
213
|
+
# @example
|
178
214
|
#
|
179
215
|
# D .<< { puts "before all nested tests" }
|
180
216
|
#
|
@@ -184,14 +220,14 @@ module Dfect
|
|
184
220
|
#
|
185
221
|
def << &block
|
186
222
|
raise ArgumentError, 'block must be given' unless block
|
187
|
-
@
|
223
|
+
@suite.before_all << block
|
188
224
|
end
|
189
225
|
|
190
226
|
##
|
191
227
|
# Registers the given block to be executed
|
192
228
|
# after all nested tests inside this test.
|
193
229
|
#
|
194
|
-
#
|
230
|
+
# @example
|
195
231
|
#
|
196
232
|
# D .>> { puts "after all nested tests" }
|
197
233
|
#
|
@@ -201,84 +237,84 @@ module Dfect
|
|
201
237
|
#
|
202
238
|
def >> &block
|
203
239
|
raise ArgumentError, 'block must be given' unless block
|
204
|
-
@
|
240
|
+
@suite.after_all << block
|
205
241
|
end
|
206
242
|
|
207
243
|
##
|
208
|
-
# Asserts that the
|
209
|
-
#
|
244
|
+
# Asserts that the given condition or the
|
245
|
+
# result of the given block is neither
|
246
|
+
# nil nor false and returns that result.
|
247
|
+
#
|
248
|
+
# @param condition
|
249
|
+
#
|
250
|
+
# The condition to be asserted. A block
|
251
|
+
# may be given in place of this parameter.
|
210
252
|
#
|
211
|
-
#
|
253
|
+
# @param message
|
212
254
|
#
|
213
|
-
# [message]
|
214
255
|
# Optional message to show in the
|
215
256
|
# report if this assertion fails.
|
216
257
|
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
# # no message specified:
|
258
|
+
# @example no message given
|
220
259
|
#
|
221
260
|
# T { true } # passes
|
222
261
|
# T { false } # fails
|
223
262
|
# T { nil } # fails
|
224
263
|
#
|
225
|
-
#
|
264
|
+
# @example message is given
|
226
265
|
#
|
227
|
-
# T(
|
266
|
+
# T("computers do not doublethink") { 2 + 2 != 5 } # passes
|
228
267
|
#
|
229
|
-
def T message = nil, &block
|
230
|
-
assert_yield :assert, message, &block
|
268
|
+
def T condition = nil, message = nil, &block
|
269
|
+
assert_yield :assert, condition, message, &block
|
231
270
|
end
|
232
271
|
|
233
272
|
##
|
234
|
-
# Asserts that the
|
235
|
-
#
|
236
|
-
#
|
237
|
-
# ==== Parameters
|
273
|
+
# Asserts that the given condition or the
|
274
|
+
# result of the given block is either nil
|
275
|
+
# or false and returns that result.
|
238
276
|
#
|
239
|
-
#
|
240
|
-
# Optional message to show in the
|
241
|
-
# report if this assertion fails.
|
277
|
+
# @param condition (see Dfect.T)
|
242
278
|
#
|
243
|
-
#
|
279
|
+
# @param message (see Dfect.T)
|
244
280
|
#
|
245
|
-
#
|
281
|
+
# @example no message given
|
246
282
|
#
|
247
283
|
# T! { true } # fails
|
248
284
|
# T! { false } # passes
|
249
285
|
# T! { nil } # passes
|
250
286
|
#
|
251
|
-
#
|
287
|
+
# @example message is given
|
252
288
|
#
|
253
|
-
# T!(
|
289
|
+
# T!("computers do not doublethink") { 2 + 2 == 5 } # passes
|
254
290
|
#
|
255
|
-
def T! message = nil, &block
|
256
|
-
assert_yield :negate, message, &block
|
291
|
+
def T! condition = nil, message = nil, &block
|
292
|
+
assert_yield :negate, condition, message, &block
|
257
293
|
end
|
258
294
|
|
259
295
|
##
|
260
|
-
# Returns true if the
|
261
|
-
#
|
296
|
+
# Returns true if the given condition or
|
297
|
+
# the result of the given block is neither
|
298
|
+
# nil nor false. Otherwise, returns false.
|
262
299
|
#
|
263
|
-
#
|
300
|
+
# @param condition (see Dfect.T)
|
264
301
|
#
|
265
|
-
#
|
266
|
-
# This parameter is optional and completely ignored.
|
302
|
+
# @param message
|
267
303
|
#
|
268
|
-
#
|
304
|
+
# This parameter is optional and completely ignored.
|
269
305
|
#
|
270
|
-
#
|
306
|
+
# @example no message given
|
271
307
|
#
|
272
308
|
# T? { true } # => true
|
273
309
|
# T? { false } # => false
|
274
310
|
# T? { nil } # => false
|
275
311
|
#
|
276
|
-
#
|
312
|
+
# @example message is given
|
277
313
|
#
|
278
|
-
# T?(
|
314
|
+
# T?("computers do not doublethink") { 2 + 2 != 5 } # => true
|
279
315
|
#
|
280
|
-
def T? message = nil, &block
|
281
|
-
assert_yield :sample, message, &block
|
316
|
+
def T? condition = nil, message = nil, &block
|
317
|
+
assert_yield :sample, condition, message, &block
|
282
318
|
end
|
283
319
|
|
284
320
|
alias F T!
|
@@ -289,20 +325,15 @@ module Dfect
|
|
289
325
|
# Returns true if the result of the given block is
|
290
326
|
# either nil or false. Otherwise, returns false.
|
291
327
|
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
# [message]
|
295
|
-
# This parameter is optional and completely ignored.
|
296
|
-
#
|
297
|
-
# ==== Examples
|
328
|
+
# @param message (see Dfect.T?)
|
298
329
|
#
|
299
|
-
#
|
330
|
+
# @example no message given
|
300
331
|
#
|
301
332
|
# F? { true } # => false
|
302
333
|
# F? { false } # => true
|
303
334
|
# F? { nil } # => true
|
304
335
|
#
|
305
|
-
#
|
336
|
+
# @example message is given
|
306
337
|
#
|
307
338
|
# F?( "computers do not doublethink" ) { 2 + 2 == 5 } # => true
|
308
339
|
#
|
@@ -315,84 +346,67 @@ module Dfect
|
|
315
346
|
# kinds of exceptions is raised
|
316
347
|
# when the given block is executed.
|
317
348
|
#
|
318
|
-
#
|
319
|
-
# then that exception is returned.
|
349
|
+
# @return
|
320
350
|
#
|
321
|
-
#
|
351
|
+
# If the block raises an exception,
|
352
|
+
# then that exception is returned.
|
322
353
|
#
|
323
|
-
#
|
354
|
+
# Otherwise, nil is returned.
|
324
355
|
#
|
325
|
-
# [
|
326
|
-
# Optional message to show in the
|
327
|
-
# report if this assertion fails.
|
356
|
+
# @param [...] kinds_then_message
|
328
357
|
#
|
329
|
-
#
|
330
|
-
#
|
358
|
+
# Exception classes that must be raised by the given block, optionally
|
359
|
+
# followed by a message to show in the report if this assertion fails.
|
331
360
|
#
|
332
|
-
# If
|
333
|
-
#
|
361
|
+
# If no exception classes are given, then
|
362
|
+
# StandardError is assumed (similar to
|
363
|
+
# how a plain 'rescue' statement without
|
364
|
+
# any arguments catches StandardError).
|
334
365
|
#
|
335
|
-
#
|
336
|
-
#
|
337
|
-
# # no exceptions specified:
|
366
|
+
# @example no exceptions given
|
338
367
|
#
|
339
368
|
# E { } # fails
|
340
369
|
# E { raise } # passes
|
341
370
|
#
|
342
|
-
#
|
371
|
+
# @example single exception given
|
343
372
|
#
|
344
|
-
# E(
|
345
|
-
# E( "argument must be invalid"
|
373
|
+
# E(ArgumentError) { raise ArgumentError }
|
374
|
+
# E(ArgumentError, "argument must be invalid") { raise ArgumentError }
|
346
375
|
#
|
347
|
-
#
|
376
|
+
# @example multiple exceptions given
|
348
377
|
#
|
349
|
-
# E(
|
350
|
-
# E( "string must compile"
|
378
|
+
# E(SyntaxError, NameError) { eval "..." }
|
379
|
+
# E(SyntaxError, NameError, "string must compile") { eval "..." }
|
351
380
|
#
|
352
|
-
def E
|
353
|
-
assert_raise :assert,
|
381
|
+
def E *kinds_then_message, &block
|
382
|
+
assert_raise :assert, *kinds_then_message, &block
|
354
383
|
end
|
355
384
|
|
356
385
|
##
|
357
386
|
# Asserts that one of the given kinds of exceptions
|
358
387
|
# is not raised when the given block is executed.
|
359
388
|
#
|
360
|
-
#
|
361
|
-
# then that exception is returned.
|
362
|
-
#
|
363
|
-
# Otherwise, nil is returned.
|
364
|
-
#
|
365
|
-
# ==== Parameters
|
366
|
-
#
|
367
|
-
# [message]
|
368
|
-
# Optional message to show in the
|
369
|
-
# report if this assertion fails.
|
370
|
-
#
|
371
|
-
# [kinds]
|
372
|
-
# Exception classes that must not be raised by the given block.
|
373
|
-
#
|
374
|
-
# If none are given, then StandardError is assumed (similar to how a
|
375
|
-
# plain 'rescue' statement without any arguments catches StandardError).
|
389
|
+
# @return (see Dfect.E)
|
376
390
|
#
|
377
|
-
#
|
391
|
+
# @param kinds_then_message (see Dfect.E)
|
378
392
|
#
|
379
|
-
#
|
393
|
+
# @example no exceptions given
|
380
394
|
#
|
381
395
|
# E! { } # passes
|
382
396
|
# E! { raise } # fails
|
383
397
|
#
|
384
|
-
#
|
398
|
+
# @example single exception given
|
385
399
|
#
|
386
|
-
# E!(
|
387
|
-
# E!( "argument must be invalid"
|
400
|
+
# E!(ArgumentError) { raise ArgumentError } # fails
|
401
|
+
# E!(ArgumentError, "argument must be invalid") { raise ArgumentError }
|
388
402
|
#
|
389
|
-
#
|
403
|
+
# @example multiple exceptions given
|
390
404
|
#
|
391
|
-
# E!(
|
392
|
-
# E!( "string must compile"
|
405
|
+
# E!(SyntaxError, NameError) { eval "..." }
|
406
|
+
# E!(SyntaxError, NameError, "string must compile") { eval "..." }
|
393
407
|
#
|
394
|
-
def E!
|
395
|
-
assert_raise :negate,
|
408
|
+
def E! *kinds_then_message, &block
|
409
|
+
assert_raise :negate, *kinds_then_message, &block
|
396
410
|
end
|
397
411
|
|
398
412
|
##
|
@@ -400,203 +414,306 @@ module Dfect
|
|
400
414
|
# exceptions is raised when the given block
|
401
415
|
# is executed. Otherwise, returns false.
|
402
416
|
#
|
403
|
-
#
|
417
|
+
# @param [...] kinds_then_message
|
404
418
|
#
|
405
|
-
#
|
406
|
-
#
|
407
|
-
#
|
408
|
-
# [kinds]
|
409
|
-
# Exception classes that must be raised by the given block.
|
419
|
+
# Exception classes that must be raised by
|
420
|
+
# the given block, optionally followed by
|
421
|
+
# a message that is completely ignored.
|
410
422
|
#
|
411
|
-
# If
|
412
|
-
#
|
423
|
+
# If no exception classes are given, then
|
424
|
+
# StandardError is assumed (similar to
|
425
|
+
# how a plain 'rescue' statement without
|
426
|
+
# any arguments catches StandardError).
|
413
427
|
#
|
414
|
-
#
|
415
|
-
#
|
416
|
-
# # no exceptions specified:
|
428
|
+
# @example no exceptions given
|
417
429
|
#
|
418
430
|
# E? { } # => false
|
419
431
|
# E? { raise } # => true
|
420
432
|
#
|
421
|
-
#
|
433
|
+
# @example single exception given
|
422
434
|
#
|
423
|
-
# E?(
|
435
|
+
# E?(ArgumentError) { raise ArgumentError } # => true
|
424
436
|
#
|
425
|
-
#
|
437
|
+
# @example multiple exceptions given
|
426
438
|
#
|
427
|
-
# E?(
|
439
|
+
# E?(SyntaxError, NameError) { eval "..." } # => true
|
440
|
+
# E!(SyntaxError, NameError, "string must compile") { eval "..." }
|
428
441
|
#
|
429
|
-
def E?
|
430
|
-
assert_raise :sample,
|
442
|
+
def E? *kinds_then_message, &block
|
443
|
+
assert_raise :sample, *kinds_then_message, &block
|
431
444
|
end
|
432
445
|
|
433
446
|
##
|
434
447
|
# Asserts that the given symbol is thrown
|
435
448
|
# when the given block is executed.
|
436
449
|
#
|
437
|
-
#
|
438
|
-
# with the expected symbol,
|
439
|
-
# then that value is returned.
|
450
|
+
# @return
|
440
451
|
#
|
441
|
-
#
|
452
|
+
# If a value is thrown along
|
453
|
+
# with the expected symbol,
|
454
|
+
# then that value is returned.
|
442
455
|
#
|
443
|
-
#
|
456
|
+
# Otherwise, nil is returned.
|
444
457
|
#
|
445
|
-
# [
|
446
|
-
# Optional message to show in the
|
447
|
-
# report if this assertion fails.
|
458
|
+
# @param [Symbol] symbol
|
448
459
|
#
|
449
|
-
# [symbol]
|
450
460
|
# Symbol that must be thrown by the given block.
|
451
461
|
#
|
452
|
-
#
|
462
|
+
# @param message (see Dfect.T)
|
453
463
|
#
|
454
|
-
#
|
464
|
+
# @example no message given
|
455
465
|
#
|
456
466
|
# C(:foo) { throw :foo, 123 } # passes, => 123
|
457
467
|
# C(:foo) { throw :bar, 456 } # fails, => 456
|
458
468
|
# C(:foo) { } # fails, => nil
|
459
469
|
#
|
460
|
-
#
|
470
|
+
# @example message is given
|
461
471
|
#
|
462
|
-
# C( ":foo must be thrown"
|
472
|
+
# C(:foo, ":foo must be thrown") { throw :bar, 789 } # fails, => nil
|
463
473
|
#
|
464
|
-
def C
|
465
|
-
assert_catch :assert,
|
474
|
+
def C symbol, message = nil, &block
|
475
|
+
assert_catch :assert, symbol, message, &block
|
466
476
|
end
|
467
477
|
|
468
478
|
##
|
469
479
|
# Asserts that the given symbol is not
|
470
480
|
# thrown when the given block is executed.
|
471
481
|
#
|
472
|
-
#
|
473
|
-
#
|
474
|
-
# ==== Parameters
|
482
|
+
# @return nil, always.
|
475
483
|
#
|
476
|
-
# [
|
477
|
-
# Optional message to show in the
|
478
|
-
# report if this assertion fails.
|
484
|
+
# @param [Symbol] symbol
|
479
485
|
#
|
480
|
-
# [symbol]
|
481
486
|
# Symbol that must not be thrown by the given block.
|
482
487
|
#
|
483
|
-
#
|
488
|
+
# @param message (see Dfect.T)
|
484
489
|
#
|
485
|
-
#
|
490
|
+
# @example no message given
|
486
491
|
#
|
487
492
|
# C!(:foo) { throw :foo, 123 } # fails, => nil
|
488
493
|
# C!(:foo) { throw :bar, 456 } # passes, => nil
|
489
494
|
# C!(:foo) { } # passes, => nil
|
490
495
|
#
|
491
|
-
#
|
496
|
+
# @example message is given
|
492
497
|
#
|
493
|
-
# C!( ":foo must be thrown"
|
498
|
+
# C!(:foo, ":foo must be thrown") { throw :bar, 789 } # passes, => nil
|
494
499
|
#
|
495
|
-
def C!
|
496
|
-
assert_catch :negate,
|
500
|
+
def C! symbol, message = nil, &block
|
501
|
+
assert_catch :negate, symbol, message, &block
|
497
502
|
end
|
498
503
|
|
499
504
|
##
|
500
505
|
# Returns true if the given symbol is thrown when the
|
501
506
|
# given block is executed. Otherwise, returns false.
|
502
507
|
#
|
503
|
-
#
|
508
|
+
# @param symbol (see Dfect.C)
|
504
509
|
#
|
505
|
-
#
|
506
|
-
# This parameter is optional and completely ignored.
|
507
|
-
#
|
508
|
-
# [symbol]
|
509
|
-
# Symbol that must be thrown by the given block.
|
510
|
-
#
|
511
|
-
# ==== Examples
|
510
|
+
# @param message (see Dfect.T?)
|
512
511
|
#
|
513
|
-
#
|
512
|
+
# @example no message given
|
514
513
|
#
|
515
514
|
# C?(:foo) { throw :foo, 123 } # => true
|
516
515
|
# C?(:foo) { throw :bar, 456 } # => false
|
517
516
|
# C?(:foo) { } # => false
|
518
517
|
#
|
519
|
-
#
|
518
|
+
# @example message is given
|
520
519
|
#
|
521
|
-
# C?( ":foo must be thrown"
|
520
|
+
# C?(:foo, ":foo must be thrown") { throw :bar, 789 } # => false
|
522
521
|
#
|
523
|
-
def C?
|
524
|
-
assert_catch :sample,
|
522
|
+
def C? symbol, message = nil, &block
|
523
|
+
assert_catch :sample, symbol, message, &block
|
525
524
|
end
|
526
525
|
|
527
526
|
##
|
528
|
-
# Adds the given
|
527
|
+
# Adds the given messages to the report inside
|
529
528
|
# the section of the currently running test.
|
530
529
|
#
|
531
|
-
# You can think of "
|
530
|
+
# You can think of "L" as "to log something".
|
532
531
|
#
|
533
|
-
#
|
532
|
+
# @param messages
|
534
533
|
#
|
535
|
-
# [message]
|
536
534
|
# Objects to be added to the report.
|
537
535
|
#
|
538
|
-
#
|
536
|
+
# @example single message given
|
537
|
+
#
|
538
|
+
# L "establishing connection..."
|
539
|
+
#
|
540
|
+
# @example multiple messages given
|
541
|
+
#
|
542
|
+
# L "beginning calculation...", Math::PI, [1, 2, 3, ['a', 'b', 'c']]
|
543
|
+
#
|
544
|
+
def L *messages
|
545
|
+
@trace.concat messages
|
546
|
+
end
|
547
|
+
|
548
|
+
##
|
549
|
+
# Mechanism for sharing code between tests.
|
550
|
+
#
|
551
|
+
# If a block is given, it is shared under
|
552
|
+
# the given identifier. Otherwise, the
|
553
|
+
# code block that was previously shared
|
554
|
+
# under the given identifier is injected
|
555
|
+
# into the closest insulated Dfect test
|
556
|
+
# that contains the call to this method.
|
557
|
+
#
|
558
|
+
# @param [Symbol, Object] identifier
|
559
|
+
#
|
560
|
+
# An object that identifies shared code. This must be common
|
561
|
+
# knowledge to all parties that want to partake in the sharing.
|
562
|
+
#
|
563
|
+
# @example
|
564
|
+
#
|
565
|
+
# S :knowledge do
|
566
|
+
# #...
|
567
|
+
# end
|
539
568
|
#
|
540
|
-
#
|
569
|
+
# D "some test" do
|
570
|
+
# S :knowledge
|
571
|
+
# end
|
541
572
|
#
|
542
|
-
#
|
573
|
+
# D "another test" do
|
574
|
+
# S :knowledge
|
575
|
+
# end
|
543
576
|
#
|
544
|
-
def S
|
545
|
-
|
577
|
+
def S identifier, &block
|
578
|
+
if block_given?
|
579
|
+
if already_shared = @share[identifier]
|
580
|
+
raise ArgumentError, "A code block #{already_shared.inspect} has already been shared under the identifier #{identifier.inspect}."
|
581
|
+
end
|
582
|
+
|
583
|
+
@share[identifier] = block
|
584
|
+
|
585
|
+
elsif block = @share[identifier]
|
586
|
+
if @tests.empty?
|
587
|
+
raise "Cannot inject code block #{block.inspect} shared under identifier #{identifier.inspect} outside of a Dfect test."
|
588
|
+
else
|
589
|
+
# find the closest insulated parent test; this should always
|
590
|
+
# succeed because root-level tests are insulated by default
|
591
|
+
test = @tests.reverse.find {|t| t.sandbox }
|
592
|
+
test.sandbox.instance_eval(&block)
|
593
|
+
end
|
594
|
+
|
595
|
+
else
|
596
|
+
raise ArgumentError, "No code block is shared under identifier #{identifier.inspect}."
|
597
|
+
end
|
546
598
|
end
|
547
599
|
|
548
600
|
##
|
549
|
-
#
|
601
|
+
# Shares the given code block under the given
|
602
|
+
# identifier and then immediately injects that
|
603
|
+
# code block into the closest insulated Dfect
|
604
|
+
# test that contains the call to this method.
|
605
|
+
#
|
606
|
+
# @param identifier (see Dfect.S)
|
607
|
+
#
|
608
|
+
# @example
|
550
609
|
#
|
551
|
-
#
|
610
|
+
# D "some test" do
|
611
|
+
# S! :knowledge do
|
612
|
+
# #...
|
613
|
+
# end
|
614
|
+
# end
|
615
|
+
#
|
616
|
+
# D "another test" do
|
617
|
+
# S :knowledge
|
618
|
+
# end
|
619
|
+
#
|
620
|
+
def S! identifier, &block
|
621
|
+
raise 'block must be given' unless block_given?
|
622
|
+
S identifier, &block
|
623
|
+
S identifier
|
624
|
+
end
|
625
|
+
|
626
|
+
##
|
627
|
+
# Checks whether any code has been shared under the given identifier.
|
628
|
+
#
|
629
|
+
def S? identifier
|
630
|
+
@share.key? identifier
|
631
|
+
end
|
632
|
+
|
633
|
+
##
|
634
|
+
# Executes all tests defined thus far and
|
635
|
+
# stores the results in {Dfect.report}.
|
636
|
+
#
|
637
|
+
# @param [Boolean] continue
|
552
638
|
#
|
553
|
-
# [continue]
|
554
639
|
# If true, results from previous executions will not be cleared.
|
555
640
|
#
|
556
641
|
def run continue = true
|
557
642
|
# clear previous results
|
558
643
|
unless continue
|
559
|
-
@
|
560
|
-
@
|
561
|
-
@
|
644
|
+
@stats.clear
|
645
|
+
@trace.clear
|
646
|
+
@tests.clear
|
562
647
|
end
|
563
648
|
|
564
649
|
# make new results
|
650
|
+
start = Time.now
|
565
651
|
catch(:stop_dfect_execution) { execute }
|
652
|
+
finish = Time.now
|
653
|
+
@stats[:time] = finish - start
|
566
654
|
|
567
655
|
# print new results
|
568
|
-
|
656
|
+
unless @stats.key? :fail or @stats.key? :error
|
657
|
+
#
|
658
|
+
# show execution trace only if all tests passed.
|
659
|
+
# otherwise, we will be repeating already printed
|
660
|
+
# failure details and obstructing the developer!
|
661
|
+
#
|
662
|
+
display @trace
|
663
|
+
end
|
664
|
+
|
665
|
+
display @stats
|
569
666
|
end
|
570
667
|
|
571
668
|
##
|
572
|
-
# Stops the execution of the
|
573
|
-
# exception if that method is not currently executing.
|
669
|
+
# Stops the execution of the {Dfect.run} method or raises
|
670
|
+
# an exception if that method is not currently executing.
|
574
671
|
#
|
575
672
|
def stop
|
576
673
|
throw :stop_dfect_execution
|
577
674
|
end
|
578
675
|
|
676
|
+
##
|
677
|
+
# Returns the details of the failure that
|
678
|
+
# is currently being debugged by the user.
|
679
|
+
#
|
680
|
+
def info
|
681
|
+
@trace.last
|
682
|
+
end
|
683
|
+
|
579
684
|
private
|
580
685
|
|
581
|
-
def
|
686
|
+
def create_test insulate, *description, &block
|
582
687
|
raise ArgumentError, 'block must be given' unless block
|
583
688
|
|
584
|
-
|
689
|
+
description = description.join(' ')
|
690
|
+
sandbox = Object.new if insulate
|
691
|
+
|
692
|
+
@suite.tests << Suite::Test.new(description, block, sandbox)
|
693
|
+
end
|
694
|
+
|
695
|
+
def assert_yield mode, condition = nil, message = nil, &block
|
696
|
+
# first parameter is actually the message when block is given
|
697
|
+
message = condition if block
|
698
|
+
|
699
|
+
message ||= (
|
700
|
+
prefix = block ? 'block must yield' : 'condition must be'
|
585
701
|
case mode
|
586
|
-
when :assert then
|
587
|
-
when :negate then
|
702
|
+
when :assert then "#{prefix} true (!nil && !false)"
|
703
|
+
when :negate then "#{prefix} false (nil || false)"
|
588
704
|
end
|
705
|
+
)
|
589
706
|
|
590
707
|
passed = lambda do
|
591
|
-
@
|
708
|
+
@stats[:pass] += 1
|
592
709
|
end
|
593
710
|
|
594
711
|
failed = lambda do
|
595
|
-
@
|
712
|
+
@stats[:fail] += 1
|
596
713
|
debug block, message
|
597
714
|
end
|
598
715
|
|
599
|
-
result = call(block)
|
716
|
+
result = block ? call(block) : condition
|
600
717
|
|
601
718
|
case mode
|
602
719
|
when :sample then return result ? true : false
|
@@ -607,11 +724,14 @@ module Dfect
|
|
607
724
|
result
|
608
725
|
end
|
609
726
|
|
610
|
-
def assert_raise mode,
|
727
|
+
def assert_raise mode, *kinds_then_message, &block
|
611
728
|
raise ArgumentError, 'block must be given' unless block
|
612
729
|
|
613
|
-
|
614
|
-
|
730
|
+
message = kinds_then_message.pop
|
731
|
+
kinds = kinds_then_message
|
732
|
+
|
733
|
+
if message.kind_of? Class
|
734
|
+
kinds << message
|
615
735
|
message = nil
|
616
736
|
end
|
617
737
|
|
@@ -624,11 +744,11 @@ module Dfect
|
|
624
744
|
end
|
625
745
|
|
626
746
|
passed = lambda do
|
627
|
-
@
|
747
|
+
@stats[:pass] += 1
|
628
748
|
end
|
629
749
|
|
630
750
|
failed = lambda do |exception|
|
631
|
-
@
|
751
|
+
@stats[:fail] += 1
|
632
752
|
|
633
753
|
if exception
|
634
754
|
# debug the uncaught exception...
|
@@ -665,25 +785,18 @@ module Dfect
|
|
665
785
|
exception
|
666
786
|
end
|
667
787
|
|
668
|
-
def assert_catch mode,
|
788
|
+
def assert_catch mode, symbol, message = nil, &block
|
669
789
|
raise ArgumentError, 'block must be given' unless block
|
670
790
|
|
671
|
-
if message.is_a? Symbol and not symbol
|
672
|
-
symbol = message
|
673
|
-
message = nil
|
674
|
-
end
|
675
|
-
|
676
|
-
raise ArgumentError, 'symbol must be given' unless symbol
|
677
|
-
|
678
791
|
symbol = symbol.to_sym
|
679
792
|
message ||= "block must throw #{symbol.inspect}"
|
680
793
|
|
681
794
|
passed = lambda do
|
682
|
-
@
|
795
|
+
@stats[:pass] += 1
|
683
796
|
end
|
684
797
|
|
685
798
|
failed = lambda do
|
686
|
-
@
|
799
|
+
@stats[:fail] += 1
|
687
800
|
debug block, message
|
688
801
|
end
|
689
802
|
|
@@ -718,40 +831,50 @@ module Dfect
|
|
718
831
|
result
|
719
832
|
end
|
720
833
|
|
834
|
+
##
|
835
|
+
# Prints the given object in YAML format.
|
836
|
+
#
|
837
|
+
def display object
|
838
|
+
unless @options[:quiet]
|
839
|
+
# stringify symbols in YAML output for better readability
|
840
|
+
puts object.to_yaml.gsub(/^([[:blank:]]*(- )?):(?=@?\w+: )/, '\1')
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
721
844
|
##
|
722
845
|
# Executes the current test suite recursively.
|
723
846
|
#
|
724
847
|
def execute
|
725
|
-
suite = @
|
726
|
-
trace = @
|
848
|
+
suite = @suite
|
849
|
+
trace = @trace
|
727
850
|
|
728
851
|
suite.before_all.each {|b| call b }
|
729
852
|
|
730
853
|
suite.tests.each do |test|
|
731
854
|
suite.before_each.each {|b| call b }
|
732
855
|
|
733
|
-
@
|
856
|
+
@tests.push test
|
734
857
|
|
735
858
|
begin
|
736
859
|
# create nested suite
|
737
|
-
@
|
738
|
-
@
|
860
|
+
@suite = Suite.new
|
861
|
+
@trace = []
|
739
862
|
|
740
863
|
# populate nested suite
|
741
|
-
call test.block
|
864
|
+
call test.block, test.sandbox
|
742
865
|
|
743
866
|
# execute nested suite
|
744
867
|
execute
|
745
868
|
|
746
869
|
ensure
|
747
870
|
# restore outer values
|
748
|
-
@
|
871
|
+
@suite = suite
|
749
872
|
|
750
|
-
trace <<
|
751
|
-
@
|
873
|
+
trace << build_exec_trace(@trace)
|
874
|
+
@trace = trace
|
752
875
|
end
|
753
876
|
|
754
|
-
@
|
877
|
+
@tests.pop
|
755
878
|
|
756
879
|
suite.after_each.each {|b| call b }
|
757
880
|
end
|
@@ -763,36 +886,51 @@ module Dfect
|
|
763
886
|
# Invokes the given block and debugs any
|
764
887
|
# exceptions that may arise as a result.
|
765
888
|
#
|
766
|
-
def call block
|
889
|
+
def call block, sandbox = nil
|
767
890
|
begin
|
768
|
-
block
|
891
|
+
@calls.push block
|
892
|
+
|
893
|
+
if sandbox
|
894
|
+
sandbox.instance_eval(&block)
|
895
|
+
else
|
896
|
+
block.call
|
897
|
+
end
|
898
|
+
|
769
899
|
rescue Exception => e
|
770
900
|
debug_uncaught_exception block, e
|
901
|
+
|
902
|
+
ensure
|
903
|
+
@calls.pop
|
771
904
|
end
|
772
905
|
end
|
773
906
|
|
774
|
-
INTERNALS = File.dirname(__FILE__)
|
907
|
+
INTERNALS = File.dirname(__FILE__) # @private
|
775
908
|
|
776
909
|
##
|
777
910
|
# Adds debugging information to the report.
|
778
911
|
#
|
779
|
-
#
|
912
|
+
# @param [Binding, Proc, #binding] context
|
913
|
+
#
|
914
|
+
# Binding of code being debugged. This can be either a Binding or
|
915
|
+
# Proc object, or nil if no binding is available---in which case,
|
916
|
+
# the binding of the inner-most enclosing test or hook will be used.
|
780
917
|
#
|
781
|
-
#
|
782
|
-
# Binding of code being debugged. This
|
783
|
-
# can be either a Binding or Proc object.
|
918
|
+
# @param message
|
784
919
|
#
|
785
|
-
# [message]
|
786
920
|
# Message describing the failure
|
787
921
|
# in the code being debugged.
|
788
922
|
#
|
789
|
-
# [backtrace
|
923
|
+
# @param [Array<String>] backtrace
|
924
|
+
#
|
790
925
|
# Stack trace corresponding to point of
|
791
926
|
# failure in the code being debugged.
|
792
927
|
#
|
793
928
|
def debug context, message = nil, backtrace = caller
|
929
|
+
# inherit binding of enclosing test or hook
|
930
|
+
context ||= @calls.last
|
931
|
+
|
794
932
|
# allow a Proc to be passed instead of a binding
|
795
|
-
if context.respond_to? :binding
|
933
|
+
if context and context.respond_to? :binding
|
796
934
|
context = context.binding
|
797
935
|
end
|
798
936
|
|
@@ -800,21 +938,16 @@ module Dfect
|
|
800
938
|
backtrace = backtrace.reject {|s| s.include? INTERNALS }
|
801
939
|
|
802
940
|
# record failure details in the report
|
803
|
-
#
|
804
|
-
# NOTE: using string keys here instead
|
805
|
-
# of symbols because they make
|
806
|
-
# the YAML output easier to read
|
807
|
-
#
|
808
941
|
details = {
|
809
942
|
# user message
|
810
|
-
|
943
|
+
:fail => message,
|
811
944
|
|
812
945
|
# code snippet
|
813
|
-
|
946
|
+
:code => (
|
814
947
|
if frame = backtrace.first
|
815
948
|
file, line = frame.scan(/(.+?):(\d+(?=:|\z))/).first
|
816
949
|
|
817
|
-
if source = @
|
950
|
+
if source = @files[file]
|
818
951
|
line = line.to_i
|
819
952
|
|
820
953
|
radius = 5 # number of surrounding lines to show
|
@@ -838,31 +971,35 @@ module Dfect
|
|
838
971
|
),
|
839
972
|
|
840
973
|
# variable values
|
841
|
-
|
842
|
-
names = eval('::Kernel.local_variables', context, __FILE__, __LINE__)
|
974
|
+
:vars => if context
|
975
|
+
names = eval('::Kernel.local_variables + self.instance_variables', context, __FILE__, __LINE__)
|
843
976
|
|
844
977
|
pairs = names.inject([]) do |pair, name|
|
845
978
|
variable = name.to_s
|
846
979
|
value = eval(variable, context, __FILE__, __LINE__)
|
847
980
|
|
848
|
-
pair.push variable, value
|
981
|
+
pair.push variable.to_sym, value
|
849
982
|
end
|
850
983
|
|
851
984
|
Hash[*pairs]
|
852
|
-
|
985
|
+
end,
|
853
986
|
|
854
987
|
# stack trace
|
855
|
-
|
988
|
+
:call => backtrace,
|
856
989
|
}
|
857
990
|
|
858
|
-
@
|
991
|
+
@trace << details
|
859
992
|
|
860
993
|
# allow user to investigate the failure
|
861
|
-
if @options[:debug]
|
862
|
-
# show the
|
863
|
-
|
994
|
+
if @options[:debug] and context
|
995
|
+
# show only the most helpful subset of the
|
996
|
+
# failure details, because the rest can be
|
997
|
+
# queried (on demand) inside the debugger
|
998
|
+
overview = details.dup
|
999
|
+
overview.delete :vars
|
1000
|
+
overview.delete :call
|
1001
|
+
display build_fail_trace(overview)
|
864
1002
|
|
865
|
-
# start the investigation
|
866
1003
|
if Kernel.respond_to? :debugger
|
867
1004
|
eval '::Kernel.debugger', context, __FILE__, __LINE__
|
868
1005
|
else
|
@@ -876,6 +1013,9 @@ module Dfect
|
|
876
1013
|
irb.eval_input
|
877
1014
|
end
|
878
1015
|
end
|
1016
|
+
else
|
1017
|
+
# show all failure details to the user
|
1018
|
+
display build_fail_trace(details)
|
879
1019
|
end
|
880
1020
|
|
881
1021
|
nil
|
@@ -885,7 +1025,7 @@ module Dfect
|
|
885
1025
|
# Debugs the given uncaught exception inside the given context.
|
886
1026
|
#
|
887
1027
|
def debug_uncaught_exception context, exception
|
888
|
-
@
|
1028
|
+
@stats[:error] += 1
|
889
1029
|
debug context, exception, exception.backtrace
|
890
1030
|
end
|
891
1031
|
|
@@ -893,17 +1033,25 @@ module Dfect
|
|
893
1033
|
# Returns a report that associates the given
|
894
1034
|
# failure details with the currently running test.
|
895
1035
|
#
|
896
|
-
def
|
897
|
-
if @
|
1036
|
+
def build_exec_trace details
|
1037
|
+
if @tests.empty?
|
898
1038
|
details
|
899
1039
|
else
|
900
|
-
{ @
|
1040
|
+
{ @tests.last.desc => details }
|
901
1041
|
end
|
902
1042
|
end
|
903
1043
|
|
904
|
-
|
1044
|
+
##
|
1045
|
+
# Returns a report that qualifies the given
|
1046
|
+
# failure details with the current test stack.
|
1047
|
+
#
|
1048
|
+
def build_fail_trace details
|
1049
|
+
@tests.reverse.inject(details) do |inner, outer|
|
1050
|
+
{ outer.desc => inner }
|
1051
|
+
end
|
1052
|
+
end
|
905
1053
|
|
906
|
-
class Suite
|
1054
|
+
class Suite # @private
|
907
1055
|
attr_reader :tests, :before_each, :after_each, :before_all, :after_all
|
908
1056
|
|
909
1057
|
def initialize
|
@@ -914,26 +1062,25 @@ module Dfect
|
|
914
1062
|
@after_all = []
|
915
1063
|
end
|
916
1064
|
|
917
|
-
Test = Struct.new
|
1065
|
+
Test = Struct.new(:desc, :block, :sandbox) # @private
|
918
1066
|
end
|
919
|
-
|
920
|
-
#:startdoc:
|
921
1067
|
end
|
922
1068
|
|
923
|
-
@options
|
924
|
-
|
925
|
-
@exec_stats = Hash.new {|h,k| h[k] = 0 }
|
926
|
-
@exec_trace = []
|
927
|
-
@report = {:execution => @exec_trace, :statistics => @exec_stats}.freeze
|
1069
|
+
@options = {:debug => $DEBUG, :quiet => false}
|
928
1070
|
|
929
|
-
@
|
1071
|
+
@stats = Hash.new {|h,k| h[k] = 0 }
|
1072
|
+
@trace = []
|
1073
|
+
@report = {:trace => @trace, :stats => @stats}.freeze
|
930
1074
|
|
931
|
-
@
|
932
|
-
@
|
1075
|
+
@suite = class << self; Suite.new; end
|
1076
|
+
@share = {}
|
1077
|
+
@tests = []
|
1078
|
+
@calls = []
|
1079
|
+
@files = Hash.new {|h,k| h[k] = File.readlines(k) rescue nil }
|
933
1080
|
|
934
1081
|
##
|
935
|
-
# Allows before and after hooks to be specified via
|
936
|
-
#
|
1082
|
+
# Allows before and after hooks to be specified via the
|
1083
|
+
# following method syntax when this module is mixed-in:
|
937
1084
|
#
|
938
1085
|
# D .<< { puts "before all nested tests" }
|
939
1086
|
# D .< { puts "before each nested test" }
|
@@ -943,11 +1090,11 @@ module Dfect
|
|
943
1090
|
D = self
|
944
1091
|
|
945
1092
|
# provide mixin-able assertion methods
|
946
|
-
methods(false).grep(/^[[:upper:]][[:punct:]]
|
1093
|
+
methods(false).grep(/^[[:upper:]]?[[:punct:]]*$/).each do |name|
|
947
1094
|
#
|
948
1095
|
# XXX: using eval() on a string because Ruby 1.8's
|
949
1096
|
# define_method() cannot take a block parameter
|
950
1097
|
#
|
951
|
-
|
1098
|
+
module_eval "def #{name}(*a, &b) ::#{self.name}.#{name}(*a, &b) end", __FILE__, __LINE__
|
952
1099
|
end
|
953
1100
|
end
|