test-unit 2.2.0 → 2.3.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.
@@ -0,0 +1,15 @@
1
+ module Test
2
+ module Unit
3
+ AutoRunner.register_runner(:xml) do |auto_runner|
4
+ require 'test/unit/ui/xml/testrunner'
5
+ Test::Unit::UI::XML::TestRunner
6
+ end
7
+
8
+ AutoRunner.setup_option do |auto_runner, opts|
9
+ opts.on("--output-file-descriptor=FD", Integer,
10
+ "Outputs to file descriptor FD") do |fd|
11
+ auto_runner.runner_options[:output_file_descriptor] = fd
12
+ end
13
+ end
14
+ end
15
+ end
@@ -3,7 +3,7 @@
3
3
  # Author:: Nathaniel Talbott.
4
4
  # Copyright::
5
5
  # * Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
6
- # * Copyright (c) 2008-2009 Kouhei Sutou <tt><kou@clear-code.com></tt>
6
+ # * Copyright (c) 2008-2011 Kouhei Sutou <tt><kou@clear-code.com></tt>
7
7
  # License:: Ruby license.
8
8
 
9
9
  require 'test/unit/attribute'
@@ -16,7 +16,9 @@ require 'test/unit/pending'
16
16
  require 'test/unit/omission'
17
17
  require 'test/unit/notification'
18
18
  require 'test/unit/priority'
19
+ require 'test/unit/data'
19
20
  require 'test/unit/testsuite'
21
+ require 'test/unit/testsuitecreator'
20
22
  require 'test/unit/assertionfailederror'
21
23
  require 'test/unit/util/backtracefilter'
22
24
  require 'test/unit/util/output'
@@ -49,6 +51,10 @@ module Test
49
51
  # ...
50
52
  # end
51
53
  #
54
+ # def cleanup
55
+ # ...
56
+ # end
57
+ #
52
58
  # def teardown
53
59
  # ...
54
60
  # end
@@ -66,9 +72,11 @@ module Test
66
72
  # * startup
67
73
  # * setup
68
74
  # * test_my_method1
75
+ # * cleanup
69
76
  # * teardown
70
77
  # * setup
71
78
  # * test_my_method2
79
+ # * cleanup
72
80
  # * teardown
73
81
  # * shutdown
74
82
  class TestCase
@@ -81,12 +89,15 @@ module Test
81
89
  include TestCaseOmissionSupport
82
90
  include TestCaseNotificationSupport
83
91
  include Priority
92
+ include Data
84
93
  include Assertions
85
94
  include Util::BacktraceFilter
86
95
  include Util::Output
87
96
 
88
97
  STARTED = name + "::STARTED" # :nodoc:
89
98
  FINISHED = name + "::FINISHED" # :nodoc:
99
+ STARTED_OBJECT = name + "::STARTED::OBJECT" # :nodoc:
100
+ FINISHED_OBJECT = name + "::FINISHED::OBJECT" # :nodoc:
90
101
 
91
102
  DESCENDANTS = [] # :nodoc:
92
103
  AVAILABLE_ORDERS = [:alphabetic, :random, :defined] # :nodoc:
@@ -99,30 +110,24 @@ module Test
99
110
  @@added_methods = {}
100
111
  def method_added(name) # :nodoc:
101
112
  super
102
- added_methods = (@@added_methods[self] ||= [])
113
+ _added_methods = added_methods
103
114
  stringified_name = name.to_s
104
- if added_methods.include?(stringified_name)
115
+ if _added_methods.include?(stringified_name)
105
116
  attribute(:redefined, true, {}, stringified_name)
106
117
  end
107
- added_methods << stringified_name
118
+ _added_methods << stringified_name
119
+ end
120
+
121
+ def added_methods # :nodoc:
122
+ @@added_methods[self] ||= []
108
123
  end
109
124
 
110
125
  # Rolls up all of the test* methods in the fixture into
111
126
  # one suite, creating a new instance of the fixture for
112
127
  # each method.
113
128
  def suite
114
- suite = TestSuite.new(name, self)
115
- collect_test_names.each do |test|
116
- catch(:invalid_test) do
117
- suite << new(test)
118
- end
119
- end
120
- if suite.empty?
121
- catch(:invalid_test) do
122
- suite << new("default_test")
123
- end
124
- end
125
- suite
129
+ suite_creator = TestSuiteCreator.new(self)
130
+ suite_creator.create
126
131
  end
127
132
 
128
133
  # Called before every test case runs. Can be used
@@ -219,9 +224,11 @@ module Test
219
224
  @@test_orders[self] = order
220
225
  end
221
226
 
222
- # Defines a test in declarative syntax.
227
+ # Defines a test in declarative syntax or marks
228
+ # following method as a test method.
223
229
  #
224
- # The following two test definitions are the same:
230
+ # In declarative syntax usage, the following two
231
+ # test definitions are the almost same:
225
232
  #
226
233
  # description "register user"
227
234
  # def test_register_user
@@ -231,11 +238,33 @@ module Test
231
238
  # test "register user" do
232
239
  # ...
233
240
  # end
234
- def test(test_description, &block)
235
- normalized_description = test_description.gsub(/[^a-zA-Z\d_]+/, '_')
236
- method_name = "test_#{normalized_description}".to_sym
237
- define_method(method_name, &block)
238
- description(test_description, method_name)
241
+ #
242
+ # In test method mark usage, the "my_test_method" is
243
+ # treated as a test method:
244
+ #
245
+ # test
246
+ # def my_test_method
247
+ # assert_equal("call me", ...)
248
+ # end
249
+ def test(*test_description_or_targets, &block)
250
+ if block_given?
251
+ test_description = test_description_or_targets.first
252
+ if test_description.nil?
253
+ raise ArgumentError, "test description is missing"
254
+ end
255
+ n_arguments = test_description_or_targets.size
256
+ if n_arguments > 1
257
+ message = "wrong number of arguments (#{n_arguments} for 1)"
258
+ raise ArgumentError, message
259
+ end
260
+ method_name = test_description
261
+ define_method(method_name, &block)
262
+ description(test_description, method_name)
263
+ attribute(:test, true, {}, method_name)
264
+ else
265
+ targets = test_description_or_targets
266
+ attribute(:test, true, {}, *targets)
267
+ end
239
268
  end
240
269
 
241
270
  # Describes a test.
@@ -251,44 +280,6 @@ module Test
251
280
  def description(value, target=nil)
252
281
  attribute(:description, value, {}, target || [])
253
282
  end
254
-
255
- # :stopdoc:
256
- private
257
- def collect_test_names
258
- method_names = public_instance_methods(true).collect do |name|
259
- name.to_s
260
- end
261
- test_names = method_names.find_all do |method_name|
262
- method_name =~ /^test./
263
- end
264
- send("sort_test_names_in_#{test_order}_order", test_names)
265
- end
266
-
267
- def sort_test_names_in_alphabetic_order(test_names)
268
- test_names.sort
269
- end
270
-
271
- def sort_test_names_in_random_order(test_names)
272
- test_names.sort_by {rand(test_names.size)}
273
- end
274
-
275
- def sort_test_names_in_defined_order(test_names)
276
- added_methods = @@added_methods[self]
277
- test_names.sort do |test1, test2|
278
- test1_defined_order = added_methods.index(test1)
279
- test2_defined_order = added_methods.index(test2)
280
- if test1_defined_order and test2_defined_order
281
- test1_defined_order <=> test2_defined_order
282
- elsif test1_defined_order
283
- 1
284
- elsif test2_defined_order
285
- -1
286
- else
287
- test1 <=> test2
288
- end
289
- end
290
- end
291
- # :startdoc:
292
283
  end
293
284
 
294
285
  attr_reader :method_name
@@ -296,16 +287,29 @@ module Test
296
287
  # Creates a new instance of the fixture for running the
297
288
  # test represented by test_method_name.
298
289
  def initialize(test_method_name)
299
- throw :invalid_test unless respond_to?(test_method_name)
300
- test_method = method(test_method_name)
301
- throw :invalid_test if test_method.arity > 0
302
- owner = Util::MethodOwnerFinder.find(self, test_method_name)
290
+ @method_name = test_method_name
291
+ @internal_data = InternalData.new
292
+ end
293
+
294
+ # Assigns test data to the test. It is used in internal.
295
+ def assign_test_data(label, data) # :nodoc:
296
+ @internal_data.assign_test_data(label, data)
297
+ end
298
+
299
+ # Returns the test is valid test. It is used in internal.
300
+ def valid? # :nodoc:
301
+ return false unless respond_to?(@method_name)
302
+ test_method = method(@method_name)
303
+ if @internal_data.have_test_data?
304
+ return false unless test_method.arity == 1
305
+ else
306
+ return false unless test_method.arity <= 0
307
+ end
308
+ owner = Util::MethodOwnerFinder.find(self, @method_name)
303
309
  if owner.class != Module and self.class != owner
304
- throw :invalid_test
310
+ return false
305
311
  end
306
- @method_name = test_method_name
307
- @test_passed = true
308
- @interrupted = false
312
+ true
309
313
  end
310
314
 
311
315
  # Runs the individual test method represented by this
@@ -314,12 +318,16 @@ module Test
314
318
  def run(result)
315
319
  begin
316
320
  @_result = result
321
+ @internal_data.test_started
317
322
  yield(STARTED, name)
323
+ yield(STARTED_OBJECT, self)
318
324
  begin
319
325
  run_setup
320
326
  run_test
327
+ run_cleanup
328
+ add_pass
321
329
  rescue Exception
322
- @interrupted = true
330
+ @internal_data.interrupted
323
331
  raise unless handle_exception($!)
324
332
  ensure
325
333
  begin
@@ -328,8 +336,10 @@ module Test
328
336
  raise unless handle_exception($!)
329
337
  end
330
338
  end
339
+ @internal_data.test_finished
331
340
  result.add_run
332
341
  yield(FINISHED, name)
342
+ yield(FINISHED_OBJECT, self)
333
343
  ensure
334
344
  # @_result = nil # For test-spec's after_all :<
335
345
  end
@@ -368,6 +378,41 @@ module Test
368
378
  def setup
369
379
  end
370
380
 
381
+ # Called after every test method runs but the test
382
+ # method isn't marked as 'passed'. Can be used to
383
+ # clean up and/or verify tested condition.
384
+ # e.g. Can be used to verify mock.
385
+ #
386
+ # You can add additional cleanup tasks by the following
387
+ # code:
388
+ # class TestMyClass < Test::Unit::TestCase
389
+ # def cleanup
390
+ # ...
391
+ # end
392
+ #
393
+ # cleanup
394
+ # def my_cleanup1
395
+ # ...
396
+ # end
397
+ #
398
+ # cleanup
399
+ # def my_cleanup2
400
+ # ...
401
+ # end
402
+ #
403
+ # def test_my_class
404
+ # ...
405
+ # end
406
+ # end
407
+ #
408
+ # Here is a call order:
409
+ # * test_my_class
410
+ # * my_cleanup2
411
+ # * my_cleanup1
412
+ # * cleanup
413
+ def cleanup
414
+ end
415
+
371
416
  # Called after every test method runs. Can be used to tear
372
417
  # down fixture information.
373
418
  #
@@ -409,10 +454,21 @@ module Test
409
454
  1
410
455
  end
411
456
 
457
+ # Returns a label of test data for the test. If the
458
+ # test isn't associated with any test data, it returns
459
+ # +nil+.
460
+ def data_label
461
+ @internal_data.test_data_label
462
+ end
463
+
412
464
  # Returns a human-readable name for the specific test that
413
465
  # this instance of TestCase represents.
414
466
  def name
415
- "#{@method_name}(#{self.class.name})"
467
+ if @internal_data.have_test_data?
468
+ "#{@method_name}[#{data_label}](#{self.class.name})"
469
+ else
470
+ "#{@method_name}(#{self.class.name})"
471
+ end
416
472
  end
417
473
 
418
474
  # Returns a description for the test. A description
@@ -431,13 +487,31 @@ module Test
431
487
 
432
488
  # It's handy to be able to compare TestCase instances.
433
489
  def ==(other)
434
- return false unless(other.kind_of?(self.class))
435
- return false unless(@method_name == other.method_name)
490
+ return false unless other.kind_of?(self.class)
491
+ return false unless @method_name == other.method_name
436
492
  self.class == other.class
437
493
  end
438
494
 
495
+ # Returns a Time at the test was started.
496
+ def start_time
497
+ @internal_data.start_time
498
+ end
499
+
500
+ # Returns elapsed time for the test was ran.
501
+ def elapsed_time
502
+ @internal_data.elapsed_time
503
+ end
504
+
505
+ # Returns whether the test is interrupted.
439
506
  def interrupted?
440
- @interrupted
507
+ @internal_data.interrupted?
508
+ end
509
+
510
+ # Returns whether this individual test passed or
511
+ # not. Primarily for use in teardown so that artifacts
512
+ # can be left behind if the test fails.
513
+ def passed?
514
+ @internal_data.passed?
441
515
  end
442
516
 
443
517
  private
@@ -446,11 +520,14 @@ module Test
446
520
  end
447
521
 
448
522
  def run_test
449
- if self.class.get_attribute(@method_name, :redefined)
523
+ if self[:redefined]
450
524
  notify("#{self.class}\##{@method_name} was redefined")
451
525
  end
452
- __send__(@method_name)
453
- add_pass
526
+ if @internal_data.have_test_data?
527
+ __send__(@method_name, @internal_data.test_data)
528
+ else
529
+ __send__(@method_name)
530
+ end
454
531
  end
455
532
 
456
533
  def handle_exception(exception)
@@ -460,15 +537,8 @@ module Test
460
537
  false
461
538
  end
462
539
 
463
- # Returns whether this individual test passed or
464
- # not. Primarily for use in teardown so that artifacts
465
- # can be left behind if the test fails.
466
- def passed?
467
- @test_passed
468
- end
469
-
470
540
  def problem_occurred
471
- @test_passed = false
541
+ @internal_data.problem_occurred
472
542
  end
473
543
 
474
544
  def add_assertion
@@ -478,6 +548,52 @@ module Test
478
548
  def add_pass
479
549
  current_result.add_pass
480
550
  end
551
+
552
+ class InternalData
553
+ attr_reader :start_time, :elapsed_time
554
+ attr_reader :test_data_label, :test_data
555
+ def initialize
556
+ @start_time = nil
557
+ @elapsed_time = nil
558
+ @passed = true
559
+ @interrupted = false
560
+ @test_data_label = nil
561
+ @test_data = nil
562
+ end
563
+
564
+ def passed?
565
+ @passed
566
+ end
567
+
568
+ def interrupted?
569
+ @interrupted
570
+ end
571
+
572
+ def assign_test_data(label, data)
573
+ @test_data_label = label
574
+ @test_data = data
575
+ end
576
+
577
+ def have_test_data?
578
+ not @test_data_label.nil?
579
+ end
580
+
581
+ def test_started
582
+ @start_time = Time.now
583
+ end
584
+
585
+ def test_finished
586
+ @elapsed_time = Time.now - @start_time
587
+ end
588
+
589
+ def problem_occurred
590
+ @passed = false
591
+ end
592
+
593
+ def interrupted
594
+ @interrupted = true
595
+ end
596
+ end
481
597
  end
482
598
  end
483
599
  end