dfect 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CREDITS +1 -0
- data/doc/api/{files/ANN_txt.html → classes/Class.html} +21 -28
- data/doc/api/classes/Dfect.html +446 -139
- data/doc/api/created.rid +1 -1
- data/doc/api/files/CREDITS.html +62 -0
- data/doc/api/files/LICENSE.html +4 -2
- data/doc/api/files/lib/dfect/auto_rb.html +4 -2
- data/doc/api/files/lib/dfect_rb.html +3 -1
- data/doc/api/js/searchdoc.js +1 -2
- data/doc/api/panel/search_index.js +1 -1
- data/doc/history.erb +31 -2
- data/doc/index.xhtml +773 -0
- data/doc/intro.erb +28 -15
- data/doc/setup.erb +4 -4
- data/doc/usage.erb +105 -46
- data/lib/dfect.rb +385 -87
- data/rakefile +4 -2
- data/test/dfect.rb +168 -15
- metadata +21 -19
data/lib/dfect.rb
CHANGED
@@ -4,6 +4,18 @@
|
|
4
4
|
#++
|
5
5
|
|
6
6
|
require 'yaml'
|
7
|
+
#
|
8
|
+
# YAML raises this error when we try to serialize a class:
|
9
|
+
#
|
10
|
+
# TypeError: can't dump anonymous class Class
|
11
|
+
#
|
12
|
+
# Work around this by representing a class by its name.
|
13
|
+
#
|
14
|
+
class Class #:nodoc: all
|
15
|
+
def to_yaml opts = {}
|
16
|
+
name.to_yaml opts
|
17
|
+
end
|
18
|
+
end
|
7
19
|
|
8
20
|
# load interactive debugger
|
9
21
|
begin
|
@@ -110,6 +122,8 @@ module Dfect
|
|
110
122
|
end
|
111
123
|
|
112
124
|
##
|
125
|
+
# :call-seq: <(&block)
|
126
|
+
#
|
113
127
|
# Registers the given block to be executed
|
114
128
|
# before each nested test inside this test.
|
115
129
|
#
|
@@ -121,9 +135,14 @@ module Dfect
|
|
121
135
|
# puts "before each nested test"
|
122
136
|
# end
|
123
137
|
#
|
124
|
-
def < &block
|
125
|
-
|
126
|
-
|
138
|
+
def <(*args, &block)
|
139
|
+
if args.empty?
|
140
|
+
raise ArgumentError, 'block must be given' unless block
|
141
|
+
@curr_suite.before_each << block
|
142
|
+
else
|
143
|
+
# the < method is being used as a check for inheritance
|
144
|
+
super
|
145
|
+
end
|
127
146
|
end
|
128
147
|
|
129
148
|
##
|
@@ -192,7 +211,6 @@ module Dfect
|
|
192
211
|
# # no message specified:
|
193
212
|
#
|
194
213
|
# T { true } # passes
|
195
|
-
#
|
196
214
|
# T { false } # fails
|
197
215
|
# T { nil } # fails
|
198
216
|
#
|
@@ -200,17 +218,8 @@ module Dfect
|
|
200
218
|
#
|
201
219
|
# T( "computers do not doublethink" ) { 2 + 2 != 5 } # passes
|
202
220
|
#
|
203
|
-
def T message =
|
204
|
-
|
205
|
-
|
206
|
-
if result = call(block)
|
207
|
-
@exec_stats[:passed_assertions] += 1
|
208
|
-
else
|
209
|
-
@exec_stats[:failed_assertions] += 1
|
210
|
-
debug block, message
|
211
|
-
end
|
212
|
-
|
213
|
-
result
|
221
|
+
def T message = nil, &block
|
222
|
+
assert_block :assert, message, &block
|
214
223
|
end
|
215
224
|
|
216
225
|
##
|
@@ -227,31 +236,81 @@ module Dfect
|
|
227
236
|
#
|
228
237
|
# # no message specified:
|
229
238
|
#
|
230
|
-
#
|
239
|
+
# T! { true } # fails
|
240
|
+
# T! { false } # passes
|
241
|
+
# T! { nil } # passes
|
242
|
+
#
|
243
|
+
# # message specified:
|
244
|
+
#
|
245
|
+
# T!( "computers do not doublethink" ) { 2 + 2 == 5 } # passes
|
231
246
|
#
|
232
|
-
|
233
|
-
|
247
|
+
def T! message = nil, &block
|
248
|
+
assert_block :negate, message, &block
|
249
|
+
end
|
250
|
+
|
251
|
+
##
|
252
|
+
# Returns true if the result of the given block is
|
253
|
+
# neither nil nor false. Otherwise, returns false.
|
254
|
+
#
|
255
|
+
# ==== Parameters
|
256
|
+
#
|
257
|
+
# [message]
|
258
|
+
# This parameter is optional and completely ignored.
|
259
|
+
#
|
260
|
+
# ==== Examples
|
261
|
+
#
|
262
|
+
# # no message specified:
|
263
|
+
#
|
264
|
+
# T? { true } # => true
|
265
|
+
# T? { false } # => false
|
266
|
+
# T? { nil } # => false
|
234
267
|
#
|
235
268
|
# # message specified:
|
236
269
|
#
|
237
|
-
#
|
270
|
+
# T?( "computers do not doublethink" ) { 2 + 2 != 5 } # => true
|
238
271
|
#
|
239
|
-
def
|
240
|
-
|
272
|
+
def T? message = nil, &block
|
273
|
+
assert_block :sample, message, &block
|
274
|
+
end
|
241
275
|
|
242
|
-
|
243
|
-
@exec_stats[:failed_assertions] += 1
|
244
|
-
debug block, message
|
245
|
-
else
|
246
|
-
@exec_stats[:passed_assertions] += 1
|
247
|
-
end
|
276
|
+
alias F T!
|
248
277
|
|
249
|
-
|
278
|
+
alias F! T
|
279
|
+
|
280
|
+
##
|
281
|
+
# Returns true if the result of the given block is
|
282
|
+
# either nil or false. Otherwise, returns false.
|
283
|
+
#
|
284
|
+
# ==== Parameters
|
285
|
+
#
|
286
|
+
# [message]
|
287
|
+
# This parameter is optional and completely ignored.
|
288
|
+
#
|
289
|
+
# ==== Examples
|
290
|
+
#
|
291
|
+
# # no message specified:
|
292
|
+
#
|
293
|
+
# F? { true } # => false
|
294
|
+
# F? { false } # => true
|
295
|
+
# F? { nil } # => true
|
296
|
+
#
|
297
|
+
# # message specified:
|
298
|
+
#
|
299
|
+
# F?( "computers do not doublethink" ) { 2 + 2 == 5 } # => true
|
300
|
+
#
|
301
|
+
def F? message = nil, &block
|
302
|
+
not T? message, &block
|
250
303
|
end
|
251
304
|
|
252
305
|
##
|
253
|
-
# Asserts that one of the given
|
254
|
-
#
|
306
|
+
# Asserts that one of the given
|
307
|
+
# kinds of exceptions is raised
|
308
|
+
# when the given block is executed.
|
309
|
+
#
|
310
|
+
# If the block raises an exception,
|
311
|
+
# then that exception is returned.
|
312
|
+
#
|
313
|
+
# Otherwise, nil is returned.
|
255
314
|
#
|
256
315
|
# ==== Parameters
|
257
316
|
#
|
@@ -283,39 +342,95 @@ module Dfect
|
|
283
342
|
# E( "string must compile", SyntaxError, NameError ) { eval "..." }
|
284
343
|
#
|
285
344
|
def E message = nil, *kinds, &block
|
286
|
-
|
287
|
-
|
288
|
-
if message.is_a? Class
|
289
|
-
kinds.unshift message
|
290
|
-
message = nil
|
291
|
-
end
|
292
|
-
|
293
|
-
kinds << StandardError if kinds.empty?
|
294
|
-
message ||= "block must raise #{kinds.join ' or '}"
|
295
|
-
|
296
|
-
begin
|
297
|
-
block.call
|
298
|
-
|
299
|
-
rescue *kinds => raised
|
300
|
-
@exec_stats[:passed_assertions] += 1
|
301
|
-
|
302
|
-
rescue Exception => raised
|
303
|
-
@exec_stats[:failed_assertions] += 1
|
304
|
-
|
305
|
-
# debug the uncaught exception...
|
306
|
-
debug_uncaught_exception block, raised
|
345
|
+
assert_raise :assert, message, *kinds, &block
|
346
|
+
end
|
307
347
|
|
308
|
-
|
309
|
-
|
310
|
-
|
348
|
+
##
|
349
|
+
# Asserts that one of the given kinds of exceptions
|
350
|
+
# is not raised when the given block is executed.
|
351
|
+
#
|
352
|
+
# If the block raises an exception,
|
353
|
+
# then that exception is returned.
|
354
|
+
#
|
355
|
+
# Otherwise, nil is returned.
|
356
|
+
#
|
357
|
+
# ==== Parameters
|
358
|
+
#
|
359
|
+
# [message]
|
360
|
+
# Optional message to show in the
|
361
|
+
# report if this assertion fails.
|
362
|
+
#
|
363
|
+
# [kinds]
|
364
|
+
# Exception classes that must not be raised by the given block.
|
365
|
+
#
|
366
|
+
# If none are given, then StandardError is assumed (similar to how a
|
367
|
+
# plain 'rescue' statement without any arguments catches StandardError).
|
368
|
+
#
|
369
|
+
# ==== Examples
|
370
|
+
#
|
371
|
+
# # no exceptions specified:
|
372
|
+
#
|
373
|
+
# E! { } # passes
|
374
|
+
# E! { raise } # fails
|
375
|
+
#
|
376
|
+
# # single exception specified:
|
377
|
+
#
|
378
|
+
# E!( ArgumentError ) { raise ArgumentError } # fails
|
379
|
+
# E!( "argument must be invalid", ArgumentError ) { raise ArgumentError }
|
380
|
+
#
|
381
|
+
# # multiple exceptions specified:
|
382
|
+
#
|
383
|
+
# E!( SyntaxError, NameError ) { eval "..." }
|
384
|
+
# E!( "string must compile", SyntaxError, NameError ) { eval "..." }
|
385
|
+
#
|
386
|
+
def E! message = nil, *kinds, &block
|
387
|
+
assert_raise :negate, message, *kinds, &block
|
388
|
+
end
|
311
389
|
|
312
|
-
|
390
|
+
##
|
391
|
+
# Returns true if one of the given kinds of
|
392
|
+
# exceptions is raised when the given block
|
393
|
+
# is executed. Otherwise, returns false.
|
394
|
+
#
|
395
|
+
# ==== Parameters
|
396
|
+
#
|
397
|
+
# [message]
|
398
|
+
# This parameter is optional and completely ignored.
|
399
|
+
#
|
400
|
+
# [kinds]
|
401
|
+
# Exception classes that must be raised by the given block.
|
402
|
+
#
|
403
|
+
# If none are given, then StandardError is assumed (similar to how a
|
404
|
+
# plain 'rescue' statement without any arguments catches StandardError).
|
405
|
+
#
|
406
|
+
# ==== Examples
|
407
|
+
#
|
408
|
+
# # no exceptions specified:
|
409
|
+
#
|
410
|
+
# E? { } # => false
|
411
|
+
# E? { raise } # => true
|
412
|
+
#
|
413
|
+
# # single exception specified:
|
414
|
+
#
|
415
|
+
# E?( ArgumentError ) { raise ArgumentError } # => true
|
416
|
+
#
|
417
|
+
# # multiple exceptions specified:
|
418
|
+
#
|
419
|
+
# E?( SyntaxError, NameError ) { eval "..." } # => true
|
420
|
+
#
|
421
|
+
def E? message = nil, *kinds, &block
|
422
|
+
assert_raise :sample, message, *kinds, &block
|
313
423
|
end
|
314
424
|
|
315
425
|
##
|
316
|
-
# Asserts that the given symbol is thrown
|
317
|
-
# the given block is executed
|
318
|
-
#
|
426
|
+
# Asserts that the given symbol is thrown
|
427
|
+
# when the given block is executed.
|
428
|
+
#
|
429
|
+
# If a value is thrown along
|
430
|
+
# with the expected symbol,
|
431
|
+
# then that value is returned.
|
432
|
+
#
|
433
|
+
# Otherwise, nil is returned.
|
319
434
|
#
|
320
435
|
# ==== Parameters
|
321
436
|
#
|
@@ -330,39 +445,75 @@ module Dfect
|
|
330
445
|
#
|
331
446
|
# # no message specified:
|
332
447
|
#
|
333
|
-
# C(:foo) { throw :foo } # passes
|
334
|
-
#
|
335
|
-
# C(:foo) {
|
336
|
-
# C(:foo) { } # fails
|
448
|
+
# C(:foo) { throw :foo, 123 } # passes, => 123
|
449
|
+
# C(:foo) { throw :bar, 456 } # fails, => 456
|
450
|
+
# C(:foo) { } # fails, => nil
|
337
451
|
#
|
338
452
|
# # message specified:
|
339
453
|
#
|
340
|
-
# C( ":foo must be thrown", :foo ) { throw :bar } # fails
|
454
|
+
# C( ":foo must be thrown", :foo ) { throw :bar, 789 } # fails, => nil
|
341
455
|
#
|
342
456
|
def C message = nil, symbol = nil, &block
|
343
|
-
|
344
|
-
|
345
|
-
if message.is_a? Symbol and not symbol
|
346
|
-
symbol = message
|
347
|
-
message = nil
|
348
|
-
end
|
349
|
-
|
350
|
-
raise ArgumentError, 'symbol must be given' unless symbol
|
351
|
-
|
352
|
-
symbol = symbol.to_sym
|
353
|
-
message ||= "block must throw #{symbol.inspect}"
|
457
|
+
assert_catch :assert, message, symbol, &block
|
458
|
+
end
|
354
459
|
|
355
|
-
|
356
|
-
|
357
|
-
|
460
|
+
##
|
461
|
+
# Asserts that the given symbol is not
|
462
|
+
# thrown when the given block is executed.
|
463
|
+
#
|
464
|
+
# Returns nil, always.
|
465
|
+
#
|
466
|
+
# ==== Parameters
|
467
|
+
#
|
468
|
+
# [message]
|
469
|
+
# Optional message to show in the
|
470
|
+
# report if this assertion fails.
|
471
|
+
#
|
472
|
+
# [symbol]
|
473
|
+
# Symbol that must not be thrown by the given block.
|
474
|
+
#
|
475
|
+
# ==== Examples
|
476
|
+
#
|
477
|
+
# # no message specified:
|
478
|
+
#
|
479
|
+
# C!(:foo) { throw :foo, 123 } # fails, => nil
|
480
|
+
# C!(:foo) { throw :bar, 456 } # passes, => nil
|
481
|
+
# C!(:foo) { } # passes, => nil
|
482
|
+
#
|
483
|
+
# # message specified:
|
484
|
+
#
|
485
|
+
# C!( ":foo must be thrown", :foo ) { throw :bar, 789 } # passes, => nil
|
486
|
+
#
|
487
|
+
def C! message = nil, symbol = nil, &block
|
488
|
+
assert_catch :negate, message, symbol, &block
|
489
|
+
end
|
358
490
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
491
|
+
##
|
492
|
+
# Returns true if the given symbol is thrown when the
|
493
|
+
# given block is executed. Otherwise, returns false.
|
494
|
+
#
|
495
|
+
# ==== Parameters
|
496
|
+
#
|
497
|
+
# [message]
|
498
|
+
# This parameter is optional and completely ignored.
|
499
|
+
#
|
500
|
+
# [symbol]
|
501
|
+
# Symbol that must be thrown by the given block.
|
502
|
+
#
|
503
|
+
# ==== Examples
|
504
|
+
#
|
505
|
+
# # no message specified:
|
506
|
+
#
|
507
|
+
# C?(:foo) { throw :foo, 123 } # => true
|
508
|
+
# C?(:foo) { throw :bar, 456 } # => false
|
509
|
+
# C?(:foo) { } # => false
|
510
|
+
#
|
511
|
+
# # message specified:
|
512
|
+
#
|
513
|
+
# C?( ":foo must be thrown", :foo ) { throw :bar, 789 } # => false
|
514
|
+
#
|
515
|
+
def C? message = nil, symbol = nil, &block
|
516
|
+
assert_catch :sample, message, symbol, &block
|
366
517
|
end
|
367
518
|
|
368
519
|
##
|
@@ -393,6 +544,146 @@ module Dfect
|
|
393
544
|
|
394
545
|
private
|
395
546
|
|
547
|
+
def assert_block mode, message = nil, &block
|
548
|
+
raise ArgumentError, 'block must be given' unless block
|
549
|
+
|
550
|
+
message ||=
|
551
|
+
case mode
|
552
|
+
when :assert then 'block must yield true (!nil && !false)'
|
553
|
+
when :negate then 'block must yield false (nil || false)'
|
554
|
+
end
|
555
|
+
|
556
|
+
passed = lambda do
|
557
|
+
@exec_stats[:passed_assertions] += 1
|
558
|
+
end
|
559
|
+
|
560
|
+
failed = lambda do
|
561
|
+
@exec_stats[:failed_assertions] += 1
|
562
|
+
debug block, message
|
563
|
+
end
|
564
|
+
|
565
|
+
result = call(block)
|
566
|
+
|
567
|
+
case mode
|
568
|
+
when :sample then return result ? true : false
|
569
|
+
when :assert then result ? passed.call : failed.call
|
570
|
+
when :negate then result ? failed.call : passed.call
|
571
|
+
end
|
572
|
+
|
573
|
+
result
|
574
|
+
end
|
575
|
+
|
576
|
+
def assert_raise mode, message = nil, *kinds, &block
|
577
|
+
raise ArgumentError, 'block must be given' unless block
|
578
|
+
|
579
|
+
if message.is_a? Class
|
580
|
+
kinds.unshift message
|
581
|
+
message = nil
|
582
|
+
end
|
583
|
+
|
584
|
+
kinds << StandardError if kinds.empty?
|
585
|
+
|
586
|
+
message ||=
|
587
|
+
case mode
|
588
|
+
when :assert then "block must raise #{kinds.join ' or '}"
|
589
|
+
when :negate then "block must not raise #{kinds.join ' or '}"
|
590
|
+
end
|
591
|
+
|
592
|
+
passed = lambda do
|
593
|
+
@exec_stats[:passed_assertions] += 1
|
594
|
+
end
|
595
|
+
|
596
|
+
failed = lambda do |exception|
|
597
|
+
@exec_stats[:failed_assertions] += 1
|
598
|
+
|
599
|
+
if exception
|
600
|
+
# debug the uncaught exception...
|
601
|
+
debug_uncaught_exception block, exception
|
602
|
+
|
603
|
+
# ...in addition to debugging this assertion
|
604
|
+
debug block, [message, {'block raised' => exception}]
|
605
|
+
|
606
|
+
else
|
607
|
+
debug block, message
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
begin
|
612
|
+
block.call
|
613
|
+
|
614
|
+
rescue Exception => exception
|
615
|
+
expected = kinds.any? {|k| exception.kind_of? k }
|
616
|
+
|
617
|
+
case mode
|
618
|
+
when :sample then return expected
|
619
|
+
when :assert then expected ? passed.call : failed.call(exception)
|
620
|
+
when :negate then expected ? failed.call(exception) : passed.call
|
621
|
+
end
|
622
|
+
|
623
|
+
else # nothing was raised
|
624
|
+
case mode
|
625
|
+
when :sample then return false
|
626
|
+
when :assert then failed.call nil
|
627
|
+
when :negate then passed.call
|
628
|
+
end
|
629
|
+
end
|
630
|
+
|
631
|
+
exception
|
632
|
+
end
|
633
|
+
|
634
|
+
def assert_catch mode, message = nil, symbol = nil, &block
|
635
|
+
raise ArgumentError, 'block must be given' unless block
|
636
|
+
|
637
|
+
if message.is_a? Symbol and not symbol
|
638
|
+
symbol = message
|
639
|
+
message = nil
|
640
|
+
end
|
641
|
+
|
642
|
+
raise ArgumentError, 'symbol must be given' unless symbol
|
643
|
+
|
644
|
+
symbol = symbol.to_sym
|
645
|
+
message ||= "block must throw #{symbol.inspect}"
|
646
|
+
|
647
|
+
passed = lambda do
|
648
|
+
@exec_stats[:passed_assertions] += 1
|
649
|
+
end
|
650
|
+
|
651
|
+
failed = lambda do
|
652
|
+
@exec_stats[:failed_assertions] += 1
|
653
|
+
debug block, message
|
654
|
+
end
|
655
|
+
|
656
|
+
# if nothing was thrown, the result of catch()
|
657
|
+
# is simply the result of executing the block
|
658
|
+
result = catch(symbol) do
|
659
|
+
begin
|
660
|
+
block.call
|
661
|
+
|
662
|
+
rescue Exception => e
|
663
|
+
debug_uncaught_exception block, e unless
|
664
|
+
# ignore error about the wrong symbol being thrown
|
665
|
+
#
|
666
|
+
# NOTE: Ruby 1.8 formats the thrown value in `quotes'
|
667
|
+
# whereas Ruby 1.9 formats it like a :symbol
|
668
|
+
#
|
669
|
+
e.message =~ /\Auncaught throw (`.*?'|:.*)\z/
|
670
|
+
end
|
671
|
+
|
672
|
+
self # unlikely that block will throw *this* object
|
673
|
+
end
|
674
|
+
|
675
|
+
caught = result != self
|
676
|
+
result = nil unless caught
|
677
|
+
|
678
|
+
case mode
|
679
|
+
when :sample then return caught
|
680
|
+
when :assert then caught ? passed.call : failed.call
|
681
|
+
when :negate then caught ? failed.call : passed.call
|
682
|
+
end
|
683
|
+
|
684
|
+
result
|
685
|
+
end
|
686
|
+
|
396
687
|
##
|
397
688
|
# Executes the current test suite recursively.
|
398
689
|
#
|
@@ -514,9 +805,16 @@ module Dfect
|
|
514
805
|
|
515
806
|
# variable values
|
516
807
|
'vars' => (
|
517
|
-
|
808
|
+
names = eval('::Kernel.local_variables', context, __FILE__, __LINE__)
|
809
|
+
|
810
|
+
pairs = names.inject([]) do |pair, name|
|
811
|
+
variable = name.to_s
|
812
|
+
value = eval(variable, context, __FILE__, __LINE__)
|
813
|
+
|
814
|
+
pair.push variable, value
|
815
|
+
end
|
518
816
|
|
519
|
-
Hash[*
|
817
|
+
Hash[*pairs]
|
520
818
|
),
|
521
819
|
|
522
820
|
# stack trace
|
@@ -611,7 +909,7 @@ module Dfect
|
|
611
909
|
D = self
|
612
910
|
|
613
911
|
# provide mixin-able assertion methods
|
614
|
-
methods(false).grep(/^[[:upper:]]
|
912
|
+
methods(false).grep(/^[[:upper:]][[:punct:]]?$/).each do |name|
|
615
913
|
#
|
616
914
|
# XXX: using eval() on a string because Ruby 1.8's
|
617
915
|
# define_method() cannot take a block parameter
|
data/rakefile
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
# See the LICENSE file for details.
|
4
4
|
#++
|
5
5
|
|
6
|
+
require 'rubygems'
|
7
|
+
gem 'inochi', '~> 1'
|
6
8
|
require 'inochi'
|
7
9
|
|
8
10
|
Inochi.init :Dfect,
|
9
|
-
:version => '0.
|
10
|
-
:release => '2009-04-
|
11
|
+
:version => '0.1.0',
|
12
|
+
:release => '2009-04-28',
|
11
13
|
:website => 'http://snk.tuxfamily.org/lib/dfect',
|
12
14
|
:tagline => 'Assertion testing library for Ruby'
|
13
15
|
|