test-unit 3.2.0 → 3.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/COPYING +4 -1
  3. data/README.md +11 -11
  4. data/Rakefile +10 -1
  5. data/doc/text/getting-started.md +246 -0
  6. data/doc/text/news.md +372 -1
  7. data/lib/test/unit.rb +171 -157
  8. data/lib/test/unit/assertions.rb +187 -149
  9. data/lib/test/unit/attribute.rb +71 -2
  10. data/lib/test/unit/autorunner.rb +65 -32
  11. data/lib/test/unit/code-snippet-fetcher.rb +7 -7
  12. data/lib/test/unit/collector/load.rb +8 -13
  13. data/lib/test/unit/data-sets.rb +116 -0
  14. data/lib/test/unit/data.rb +121 -12
  15. data/lib/test/unit/diff.rb +11 -11
  16. data/lib/test/unit/fixture.rb +3 -0
  17. data/lib/test/unit/notification.rb +9 -7
  18. data/lib/test/unit/omission.rb +34 -31
  19. data/lib/test/unit/pending.rb +12 -11
  20. data/lib/test/unit/priority.rb +7 -3
  21. data/lib/test/unit/runner/console.rb +25 -0
  22. data/lib/test/unit/test-suite-creator.rb +22 -8
  23. data/lib/test/unit/testcase.rb +270 -182
  24. data/lib/test/unit/ui/console/testrunner.rb +90 -35
  25. data/lib/test/unit/ui/emacs/testrunner.rb +5 -5
  26. data/lib/test/unit/util/observable.rb +2 -2
  27. data/lib/test/unit/util/output.rb +5 -4
  28. data/lib/test/unit/util/procwrapper.rb +4 -4
  29. data/lib/test/unit/version.rb +1 -1
  30. data/test/collector/test-descendant.rb +4 -0
  31. data/test/collector/test-load.rb +35 -2
  32. data/test/collector/test_dir.rb +5 -4
  33. data/test/collector/test_objectspace.rb +7 -5
  34. data/test/test-assertions.rb +128 -101
  35. data/test/test-code-snippet.rb +42 -0
  36. data/test/test-data.rb +195 -79
  37. data/test/test-priority.rb +19 -8
  38. data/test/test-test-case.rb +111 -3
  39. data/test/test-test-suite.rb +1 -0
  40. data/test/testunit-test-util.rb +2 -0
  41. metadata +38 -37
@@ -5,6 +5,8 @@
5
5
  # * Copyright (c) 2011 Kouhei Sutou <tt><kou@clear-code.com></tt>
6
6
  # License:: Ruby license.
7
7
 
8
+ require "test/unit/data-sets"
9
+
8
10
  module Test
9
11
  module Unit
10
12
  class TestSuiteCreator # :nodoc:
@@ -22,15 +24,11 @@ module Test
22
24
  def create
23
25
  suite = TestSuite.new(@test_case.name, @test_case)
24
26
  collect_test_names.each do |test_name|
25
- data_sets = @test_case.find_attribute(test_name, :data,
26
- :recursive => false)
27
+ data_sets = extract_data_sets(test_name)
27
28
  if data_sets
28
- data_sets.each do |data_set|
29
- data_set = data_set.call if data_set.respond_to?(:call)
30
- data_set.each do |label, data|
31
- append_test(suite, test_name) do |test|
32
- test.assign_test_data(label, data)
33
- end
29
+ data_sets.each do |label, data|
30
+ append_test(suite, test_name) do |test|
31
+ test.assign_test_data(label, data)
34
32
  end
35
33
  end
36
34
  else
@@ -42,6 +40,22 @@ module Test
42
40
  end
43
41
 
44
42
  private
43
+ def extract_data_sets(test_name)
44
+ data_sets = @test_case.find_attribute(test_name,
45
+ :data,
46
+ :recursive => false)
47
+ data_method_name = "data_#{test_name}"
48
+ test = @test_case.new(test_name)
49
+ if test.respond_to?(data_method_name)
50
+ data_method = test.method(data_method_name)
51
+ if data_method.arity <= 0
52
+ data_sets ||= DataSets.new
53
+ data_sets << data_method
54
+ end
55
+ end
56
+ data_sets
57
+ end
58
+
45
59
  def append_test(suite, test_name)
46
60
  test = @test_case.new(test_name)
47
61
  yield(test) if block_given?
@@ -37,49 +37,70 @@ module Test
37
37
  # You can run two hooks before/after a TestCase run.
38
38
  #
39
39
  # Example:
40
- # class TestMyClass < Test::Unit::TestCase
41
- # class << self
42
- # def startup
40
+ #
41
+ # class TestMyClass < Test::Unit::TestCase
42
+ # class << self
43
+ # def startup
44
+ # ...
45
+ # end
46
+ #
47
+ # def shutdown
48
+ # ...
49
+ # end
50
+ # end
51
+ #
52
+ # def setup
43
53
  # ...
44
54
  # end
45
55
  #
46
- # def shutdown
56
+ # def cleanup
47
57
  # ...
48
58
  # end
49
- # end
50
59
  #
51
- # def setup
52
- # ...
53
- # end
60
+ # def teardown
61
+ # ...
62
+ # end
54
63
  #
55
- # def cleanup
56
- # ...
57
- # end
64
+ # def test_my_method1
65
+ # ...
66
+ # end
58
67
  #
59
- # def teardown
60
- # ...
68
+ # def test_my_method2
69
+ # ...
70
+ # end
61
71
  # end
62
72
  #
63
- # def test_my_method1
64
- # ...
65
- # end
73
+ # Here is a call order:
66
74
  #
67
- # def test_my_method2
68
- # ...
69
- # end
70
- # end
75
+ # 1. startup
76
+ # 1. setup
77
+ # 1. test_my_method1
78
+ # 1. cleanup
79
+ # 1. teardown
80
+ # 1. setup
81
+ # 1. test_my_method2
82
+ # 1. cleanup
83
+ # 1. teardown
84
+ # 1. shutdown
71
85
  #
72
- # Here is a call order:
73
- # * startup
74
- # * setup
75
- # * test_my_method1
76
- # * cleanup
77
- # * teardown
78
- # * setup
79
- # * test_my_method2
80
- # * cleanup
81
- # * teardown
82
- # * shutdown
86
+ # You can set an attribute to each test.
87
+ #
88
+ # Example:
89
+ #
90
+ # class TestMyClass < Test::Unit::TestCase
91
+ # attribute :speed, :fast
92
+ # def test_my_fast_method
93
+ # # You can get the attribute via `self[]`
94
+ # self[:speed] # => :fast
95
+ # ...
96
+ # end
97
+ #
98
+ # attribute :speed, :slow
99
+ # def test_my_slow_method
100
+ # self[:speed] # => :slow
101
+ # ...
102
+ # end
103
+ # end
83
104
  class TestCase
84
105
  include Attribute
85
106
  include Fixture
@@ -109,6 +130,15 @@ module Test
109
130
  super
110
131
  end
111
132
 
133
+ def include(*modules, &block) # :nodoc:
134
+ super
135
+ modules.each do |mod|
136
+ mod.public_instance_methods(false).each do |method_name|
137
+ AutoRunnerLoader.check(self, method_name.to_s)
138
+ end
139
+ end
140
+ end
141
+
112
142
  @@added_method_names = {}
113
143
  def method_added(name) # :nodoc:
114
144
  super
@@ -129,11 +159,12 @@ module Test
129
159
  path, line, = caller[0].split(/:(\d+)/, 2)
130
160
  line = line.to_i if line
131
161
  end
132
- method_locations << {
162
+ location = {
133
163
  :method_name => stringified_name,
134
164
  :path => File.expand_path(path),
135
165
  :line => line,
136
166
  }
167
+ add_method_location(location)
137
168
  added_method_names[stringified_name] = true
138
169
  AutoRunnerLoader.check(self, stringified_name)
139
170
  end
@@ -155,27 +186,29 @@ module Test
155
186
  # scope.
156
187
  #
157
188
  # Here is an example test case:
158
- # class TestMyClass < Test::Unit::TestCase
159
- # class << self
160
- # def startup
161
- # ...
189
+ #
190
+ # class TestMyClass < Test::Unit::TestCase
191
+ # class << self
192
+ # def startup
193
+ # ...
194
+ # end
162
195
  # end
163
- # end
164
196
  #
165
- # def setup
166
- # ...
167
- # end
197
+ # def setup
198
+ # ...
199
+ # end
168
200
  #
169
- # def test_my_class1
170
- # ...
171
- # end
201
+ # def test_my_class1
202
+ # ...
203
+ # end
172
204
  #
173
- # def test_my_class2
174
- # ...
205
+ # def test_my_class2
206
+ # ...
207
+ # end
175
208
  # end
176
- # end
177
209
  #
178
210
  # Here is a call order:
211
+ #
179
212
  # * startup
180
213
  # * setup
181
214
  # * test_my_class1 (or test_my_class2)
@@ -191,27 +224,29 @@ module Test
191
224
  # down fixture information used in test case scope.
192
225
  #
193
226
  # Here is an example test case:
194
- # class TestMyClass < Test::Unit::TestCase
195
- # class << self
196
- # def shutdown
197
- # ...
227
+ #
228
+ # class TestMyClass < Test::Unit::TestCase
229
+ # class << self
230
+ # def shutdown
231
+ # ...
232
+ # end
198
233
  # end
199
- # end
200
234
  #
201
- # def teardown
202
- # ...
203
- # end
235
+ # def teardown
236
+ # ...
237
+ # end
204
238
  #
205
- # def test_my_class1
206
- # ...
207
- # end
239
+ # def test_my_class1
240
+ # ...
241
+ # end
208
242
  #
209
- # def test_my_class2
210
- # ...
243
+ # def test_my_class2
244
+ # ...
245
+ # end
211
246
  # end
212
- # end
213
247
  #
214
248
  # Here is a call order:
249
+ #
215
250
  # * test_my_class1 (or test_my_class2)
216
251
  # * teardown
217
252
  # * test_my_class2 (or test_my_class1)
@@ -226,20 +261,27 @@ module Test
226
261
  @@test_orders = {}
227
262
 
228
263
  # Returns the current test order. This returns
229
- # +:alphabetic+ by default.
264
+ # `:alphabetic` by default.
230
265
  def test_order
231
- @@test_orders[self] || AVAILABLE_ORDERS.first
266
+ ancestors.each do |ancestor|
267
+ order = @@test_orders[ancestor]
268
+ return order if order
269
+ end
270
+ AVAILABLE_ORDERS.first
232
271
  end
233
272
 
234
273
  # Sets the current test order.
235
274
  #
236
275
  # Here are the available _order_:
237
- # [:alphabetic]
238
- # Default. Tests are sorted in alphabetic order.
239
- # [:random]
240
- # Tests are sorted in random order.
241
- # [:defined]
242
- # Tests are sorted in defined order.
276
+ #
277
+ # :alphabetic
278
+ # : Default. Tests are sorted in alphabetic order.
279
+ #
280
+ # :random
281
+ # : Tests are sorted in random order.
282
+ #
283
+ # :defined
284
+ # : Tests are sorted in defined order.
243
285
  def test_order=(order)
244
286
  @@test_orders[self] = order
245
287
  end
@@ -250,22 +292,22 @@ module Test
250
292
  # In declarative syntax usage, the following two
251
293
  # test definitions are the almost same:
252
294
  #
253
- # description "register user"
254
- # def test_register_user
255
- # ...
256
- # end
295
+ # description "register user"
296
+ # def test_register_user
297
+ # ...
298
+ # end
257
299
  #
258
- # test "register user" do
259
- # ...
260
- # end
300
+ # test "register user" do
301
+ # ...
302
+ # end
261
303
  #
262
304
  # In test method mark usage, the "my_test_method" is
263
305
  # treated as a test method:
264
306
  #
265
- # test
266
- # def my_test_method
267
- # assert_equal("call me", ...)
268
- # end
307
+ # test
308
+ # def my_test_method
309
+ # assert_equal("call me", ...)
310
+ # end
269
311
  def test(*test_description_or_targets, &block)
270
312
  if block_given?
271
313
  test_description = test_description_or_targets.first
@@ -299,10 +341,10 @@ module Test
299
341
  # normal user" description with "test_register"
300
342
  # test.
301
343
  #
302
- # description "register a normal user"
303
- # def test_register
304
- # ...
305
- # end
344
+ # description "register a normal user"
345
+ # def test_register
346
+ # ...
347
+ # end
306
348
  def description(value, target=nil)
307
349
  targets = [target].compact
308
350
  attribute(:description, value, {}, *targets)
@@ -314,20 +356,22 @@ module Test
314
356
  # the same in meaning:
315
357
  #
316
358
  # Standard:
317
- # class TestParent < Test::UnitTestCase
318
- # class TestChild < self
319
- # def test_in_child
359
+ #
360
+ # class TestParent < Test::Unit::TestCase
361
+ # class TestChild < self
362
+ # def test_in_child
363
+ # end
320
364
  # end
321
365
  # end
322
- # end
323
366
  #
324
367
  # Syntax sugar:
325
- # class TestParent < Test::UnitTestCase
326
- # sub_test_case("TestChild") do
327
- # def test_in_child
368
+ #
369
+ # class TestParent < Test::Unit::TestCase
370
+ # sub_test_case("TestChild") do
371
+ # def test_in_child
372
+ # end
328
373
  # end
329
374
  # end
330
- # end
331
375
  #
332
376
  # The difference of them are the following:
333
377
  #
@@ -365,6 +409,11 @@ module Test
365
409
  # @option query [String] :method_name (nil)
366
410
  # the method name for a test.
367
411
  def test_defined?(query)
412
+ locations = find_locations(query)
413
+ not locations.empty?
414
+ end
415
+
416
+ def find_locations(query)
368
417
  query_path = query[:path]
369
418
  query_line = query[:line]
370
419
  query_method_name = query[:method_name]
@@ -377,49 +426,62 @@ module Test
377
426
  available_location = available_locations.find do |location|
378
427
  query_line >= location[:line]
379
428
  end
380
- return false if available_location.nil?
381
- return false if available_location[:test_case] != self
429
+ return [] if available_location.nil?
430
+ return [] if available_location[:test_case] != self
382
431
  available_locations = [available_location]
383
432
  end
384
433
  if query_method_name
385
434
  available_location = available_locations.find do |location|
386
- query_method_name == location[:method_name]
435
+ location[:test_case] == self and
436
+ query_method_name == location[:method_name]
387
437
  end
388
- return false if available_location.nil?
438
+ return [] if available_location.nil?
389
439
  available_locations = [available_location]
390
440
  end
391
441
 
392
- not available_locations.empty?
442
+ available_locations
393
443
  end
394
444
 
395
445
  private
396
446
  # @private
397
447
  @@method_locations = {}
448
+ # @private
449
+ @@method_location_mutex = Mutex.new
450
+
398
451
  # @private
399
452
  def method_locations
400
453
  @@method_locations[self] ||= []
401
454
  end
402
455
 
403
456
  # @private
404
- def target_method_locations(path)
405
- if path.nil?
406
- self_location = method_locations.first
407
- path = self_location[:path] if self_location
457
+ def add_method_location(location)
458
+ @@method_location_mutex.synchronize do
459
+ method_locations << location
408
460
  end
409
- return [] if path.nil?
410
-
411
- target_locations = []
412
- @@method_locations.each do |test_case, locations|
413
- locations.each do |location|
414
- absolete_path = File.expand_path(path)
415
- location_path = location[:path]
416
- location_basename = File.basename(location_path)
417
- if location_path == absolete_path or location_basename == path
418
- target_locations << location.merge(:test_case => test_case)
461
+ end
462
+
463
+ # @private
464
+ def target_method_locations(path)
465
+ @@method_location_mutex.synchronize do
466
+ if path.nil?
467
+ self_location = method_locations.first
468
+ path = self_location[:path] if self_location
469
+ end
470
+ return [] if path.nil?
471
+
472
+ target_locations = []
473
+ @@method_locations.each do |test_case, locations|
474
+ locations.each do |location|
475
+ absolete_path = File.expand_path(path)
476
+ location_path = location[:path]
477
+ location_basename = File.basename(location_path)
478
+ if location_path == absolete_path or location_basename == path
479
+ target_locations << location.merge(:test_case => test_case)
480
+ end
419
481
  end
420
482
  end
483
+ target_locations
421
484
  end
422
- target_locations
423
485
  end
424
486
  end
425
487
 
@@ -441,9 +503,7 @@ module Test
441
503
  def valid? # :nodoc:
442
504
  return false unless respond_to?(@method_name)
443
505
  test_method = method(@method_name)
444
- if @internal_data.have_test_data?
445
- return false unless test_method.arity == 1
446
- else
506
+ unless @internal_data.have_test_data?
447
507
  return false unless test_method.arity <= 0
448
508
  end
449
509
  owner = Util::MethodOwnerFinder.find(self, @method_name)
@@ -508,35 +568,37 @@ module Test
508
568
  #
509
569
  # You can add additional setup tasks by the following
510
570
  # code:
511
- # class TestMyClass < Test::Unit::TestCase
512
- # def setup
513
- # ...
514
- # end
515
571
  #
516
- # setup
517
- # def my_setup1
518
- # ...
519
- # end
572
+ # class TestMyClass < Test::Unit::TestCase
573
+ # def setup
574
+ # ...
575
+ # end
520
576
  #
521
- # setup do
522
- # ... # setup callback1
523
- # end
577
+ # setup
578
+ # def my_setup1
579
+ # ...
580
+ # end
524
581
  #
525
- # setup
526
- # def my_setup2
527
- # ...
528
- # end
582
+ # setup do
583
+ # ... # setup callback1
584
+ # end
529
585
  #
530
- # setup do
531
- # ... # setup callback2
532
- # end
586
+ # setup
587
+ # def my_setup2
588
+ # ...
589
+ # end
590
+ #
591
+ # setup do
592
+ # ... # setup callback2
593
+ # end
533
594
  #
534
- # def test_my_class
535
- # ...
595
+ # def test_my_class
596
+ # ...
597
+ # end
536
598
  # end
537
- # end
538
599
  #
539
600
  # Here is a call order:
601
+ #
540
602
  # * setup
541
603
  # * my_setup1
542
604
  # * setup callback1
@@ -553,35 +615,37 @@ module Test
553
615
  #
554
616
  # You can add additional cleanup tasks by the following
555
617
  # code:
556
- # class TestMyClass < Test::Unit::TestCase
557
- # def cleanup
558
- # ...
559
- # end
560
618
  #
561
- # cleanup
562
- # def my_cleanup1
563
- # ...
564
- # end
619
+ # class TestMyClass < Test::Unit::TestCase
620
+ # def cleanup
621
+ # ...
622
+ # end
565
623
  #
566
- # cleanup do
567
- # ... # cleanup callback1
568
- # end
624
+ # cleanup
625
+ # def my_cleanup1
626
+ # ...
627
+ # end
569
628
  #
570
- # cleanup
571
- # def my_cleanup2
572
- # ...
573
- # end
629
+ # cleanup do
630
+ # ... # cleanup callback1
631
+ # end
574
632
  #
575
- # cleanup do
576
- # ... # cleanup callback2
577
- # end
633
+ # cleanup
634
+ # def my_cleanup2
635
+ # ...
636
+ # end
637
+ #
638
+ # cleanup do
639
+ # ... # cleanup callback2
640
+ # end
578
641
  #
579
- # def test_my_class
580
- # ...
642
+ # def test_my_class
643
+ # ...
644
+ # end
581
645
  # end
582
- # end
583
646
  #
584
647
  # Here is a call order:
648
+ #
585
649
  # * test_my_class
586
650
  # * cleanup callback2
587
651
  # * my_cleanup2
@@ -596,35 +660,37 @@ module Test
596
660
  #
597
661
  # You can add additional teardown tasks by the following
598
662
  # code:
599
- # class TestMyClass < Test::Unit::TestCase
600
- # def teardown
601
- # ...
602
- # end
603
663
  #
604
- # teardown
605
- # def my_teardown1
606
- # ...
607
- # end
664
+ # class TestMyClass < Test::Unit::TestCase
665
+ # def teardown
666
+ # ...
667
+ # end
608
668
  #
609
- # teardown do
610
- # ... # teardown callback1
611
- # end
669
+ # teardown
670
+ # def my_teardown1
671
+ # ...
672
+ # end
612
673
  #
613
- # teardown
614
- # def my_teardown2
615
- # ...
616
- # end
674
+ # teardown do
675
+ # ... # teardown callback1
676
+ # end
617
677
  #
618
- # teardown do
619
- # ... # teardown callback2
620
- # end
678
+ # teardown
679
+ # def my_teardown2
680
+ # ...
681
+ # end
682
+ #
683
+ # teardown do
684
+ # ... # teardown callback2
685
+ # end
621
686
  #
622
- # def test_my_class
623
- # ...
687
+ # def test_my_class
688
+ # ...
689
+ # end
624
690
  # end
625
- # end
626
691
  #
627
692
  # Here is a call order:
693
+ #
628
694
  # * test_my_class
629
695
  # * teardown callback2
630
696
  # * my_teardown2
@@ -644,18 +710,33 @@ module Test
644
710
 
645
711
  # Returns a label of test data for the test. If the
646
712
  # test isn't associated with any test data, it returns
647
- # +nil+.
713
+ # `nil`.
648
714
  def data_label
649
715
  @internal_data.test_data_label
650
716
  end
651
717
 
718
+ # Returns test data for the test. If the test isn't associated
719
+ # with any test data, it returns `nil`.
720
+ def data
721
+ @internal_data.test_data
722
+ end
723
+
652
724
  # Returns a human-readable name for the specific test that
653
725
  # this instance of TestCase represents.
654
726
  def name
727
+ "#{local_name}(#{self.class.name})"
728
+ end
729
+
730
+ # Returns a human-readable name for the specific test that this
731
+ # instance of TestCase represents.
732
+ #
733
+ # `#local_name` doesn't include class name. `#name` includes
734
+ # class name.
735
+ def local_name
655
736
  if @internal_data.have_test_data?
656
- "#{@method_name}[#{data_label}](#{self.class.name})"
737
+ "#{@method_name}[#{data_label}]"
657
738
  else
658
- "#{@method_name}(#{self.class.name})"
739
+ @method_name.to_s
659
740
  end
660
741
  end
661
742
 
@@ -733,13 +814,20 @@ module Test
733
814
  end
734
815
 
735
816
  def run_test
817
+ signature = "#{self.class}\##{@method_name}"
736
818
  redefined_info = self[:redefined]
737
819
  if redefined_info
738
- notify("#{self.class}\##{@method_name} was redefined",
820
+ notify("<#{signature}> was redefined",
739
821
  :backtrace => redefined_info[:backtrace])
740
822
  end
741
823
  if @internal_data.have_test_data?
742
- __send__(@method_name, @internal_data.test_data)
824
+ test_method = method(@method_name)
825
+ arity = test_method.arity
826
+ if arity.zero?
827
+ __send__(@method_name)
828
+ else
829
+ __send__(@method_name, @internal_data.test_data)
830
+ end
743
831
  else
744
832
  __send__(@method_name)
745
833
  end