test-unit 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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