dfect 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|
|