test-unit 1.2.3 → 2.0.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.
Files changed (60) hide show
  1. data/History.txt +27 -0
  2. data/Manifest.txt +30 -8
  3. data/README.txt +9 -4
  4. data/Rakefile +16 -1
  5. data/bin/testrb +0 -0
  6. data/lib/test/unit/assertions.rb +148 -48
  7. data/lib/test/unit/attribute.rb +125 -0
  8. data/lib/test/unit/autorunner.rb +101 -71
  9. data/lib/test/unit/collector/descendant.rb +23 -0
  10. data/lib/test/unit/collector/dir.rb +1 -1
  11. data/lib/test/unit/collector/load.rb +135 -0
  12. data/lib/test/unit/color.rb +61 -0
  13. data/lib/test/unit/diff.rb +524 -0
  14. data/lib/test/unit/error.rb +70 -2
  15. data/lib/test/unit/exceptionhandler.rb +39 -0
  16. data/lib/test/unit/failure.rb +63 -4
  17. data/lib/test/unit/fixture.rb +185 -0
  18. data/lib/test/unit/notification.rb +125 -0
  19. data/lib/test/unit/omission.rb +143 -0
  20. data/lib/test/unit/pending.rb +146 -0
  21. data/lib/test/unit/priority.rb +146 -0
  22. data/lib/test/unit/runner/console.rb +46 -0
  23. data/lib/test/unit/runner/emacs.rb +8 -0
  24. data/lib/test/unit/testcase.rb +193 -76
  25. data/lib/test/unit/testresult.rb +37 -28
  26. data/lib/test/unit/testsuite.rb +35 -1
  27. data/lib/test/unit/ui/console/outputlevel.rb +14 -0
  28. data/lib/test/unit/ui/console/testrunner.rb +96 -28
  29. data/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  30. data/lib/test/unit/ui/testrunner.rb +20 -0
  31. data/lib/test/unit/ui/testrunnermediator.rb +28 -19
  32. data/lib/test/unit/ui/testrunnerutilities.rb +2 -7
  33. data/lib/test/unit/util/backtracefilter.rb +2 -1
  34. data/lib/test/unit/version.rb +1 -1
  35. data/test/collector/test_descendant.rb +135 -0
  36. data/test/collector/test_load.rb +333 -0
  37. data/test/run-test.rb +13 -0
  38. data/test/test_assertions.rb +221 -56
  39. data/test/test_attribute.rb +86 -0
  40. data/test/test_color.rb +37 -0
  41. data/test/test_diff.rb +477 -0
  42. data/test/test_emacs_runner.rb +60 -0
  43. data/test/test_fixture.rb +275 -0
  44. data/test/test_notification.rb +33 -0
  45. data/test/test_omission.rb +81 -0
  46. data/test/test_pending.rb +70 -0
  47. data/test/test_priority.rb +89 -0
  48. data/test/test_testcase.rb +160 -5
  49. data/test/test_testresult.rb +61 -52
  50. data/test/testunit_test_util.rb +14 -0
  51. data/test/ui/test_testrunmediator.rb +20 -0
  52. metadata +53 -23
  53. data/lib/test/unit/ui/fox/testrunner.rb +0 -268
  54. data/lib/test/unit/ui/gtk/testrunner.rb +0 -416
  55. data/lib/test/unit/ui/gtk2/testrunner.rb +0 -465
  56. data/lib/test/unit/ui/tk/testrunner.rb +0 -260
  57. data/test/runit/test_assert.rb +0 -402
  58. data/test/runit/test_testcase.rb +0 -91
  59. data/test/runit/test_testresult.rb +0 -144
  60. data/test/runit/test_testsuite.rb +0 -49
@@ -4,6 +4,8 @@
4
4
  # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
5
5
  # License:: Ruby license.
6
6
 
7
+ require 'test/unit/error'
8
+
7
9
  module Test
8
10
  module Unit
9
11
 
@@ -21,18 +23,21 @@ module Test
21
23
  FINISHED = name + "::FINISHED"
22
24
 
23
25
  # Creates a new TestSuite with the given name.
24
- def initialize(name="Unnamed TestSuite")
26
+ def initialize(name="Unnamed TestSuite", test_case=nil)
25
27
  @name = name
26
28
  @tests = []
29
+ @test_case = test_case
27
30
  end
28
31
 
29
32
  # Runs the tests and/or suites contained in this
30
33
  # TestSuite.
31
34
  def run(result, &progress_block)
32
35
  yield(STARTED, name)
36
+ run_startup(result)
33
37
  @tests.each do |test|
34
38
  test.run(result, &progress_block)
35
39
  end
40
+ run_shutdown(result)
36
41
  yield(FINISHED, name)
37
42
  end
38
43
 
@@ -71,6 +76,35 @@ module Test
71
76
  return false unless(@name == other.name)
72
77
  @tests == other.tests
73
78
  end
79
+
80
+ private
81
+ def run_startup(result)
82
+ return if @test_case.nil? or !@test_case.respond_to?(:startup)
83
+ begin
84
+ @test_case.startup
85
+ rescue Exception
86
+ raise unless handle_exception($!, result)
87
+ end
88
+ end
89
+
90
+ def run_shutdown(result)
91
+ return if @test_case.nil? or !@test_case.respond_to?(:shutdown)
92
+ begin
93
+ @test_case.shutdown
94
+ rescue Exception
95
+ raise unless handle_exception($!, result)
96
+ end
97
+ end
98
+
99
+ def handle_exception(exception, result)
100
+ case exception
101
+ when *ErrorHandler::PASS_THROUGH_EXCEPTIONS
102
+ false
103
+ else
104
+ result.add_error(Error.new(@test_case.name, exception))
105
+ true
106
+ end
107
+ end
74
108
  end
75
109
  end
76
110
  end
@@ -0,0 +1,14 @@
1
+ module Test
2
+ module Unit
3
+ module UI
4
+ module Console
5
+ module OutputLevel
6
+ SILENT = 0
7
+ PROGRESS_ONLY = 1
8
+ NORMAL = 2
9
+ VERBOSE = 3
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -4,8 +4,10 @@
4
4
  # Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
5
5
  # License:: Ruby license.
6
6
 
7
+ require 'test/unit/color'
8
+ require 'test/unit/ui/testrunner'
7
9
  require 'test/unit/ui/testrunnermediator'
8
- require 'test/unit/ui/testrunnerutilities'
10
+ require 'test/unit/ui/console/outputlevel'
9
11
 
10
12
  module Test
11
13
  module Unit
@@ -13,8 +15,19 @@ module Test
13
15
  module Console
14
16
 
15
17
  # Runs a Test::Unit::TestSuite on the console.
16
- class TestRunner
17
- extend TestRunnerUtilities
18
+ class TestRunner < UI::TestRunner
19
+ include OutputLevel
20
+
21
+ COLOR_SCHEMES = {
22
+ :default => {
23
+ "success" => Color.new("green", :bold => true),
24
+ "failure" => Color.new("red", :bold => true),
25
+ "pending" => Color.new("magenta", :bold => true),
26
+ "omission" => Color.new("blue", :bold => true),
27
+ "notification" => Color.new("cyan", :bold => true),
28
+ "error" => Color.new("yellow", :bold => true),
29
+ },
30
+ }
18
31
 
19
32
  # Creates a new TestRunner for running the passed
20
33
  # suite. If quiet_mode is true, the output while
@@ -22,14 +35,14 @@ module Test
22
35
  # failures, and the final result. io specifies
23
36
  # where runner output should go to; defaults to
24
37
  # STDOUT.
25
- def initialize(suite, output_level=NORMAL, io=STDOUT)
26
- if (suite.respond_to?(:suite))
27
- @suite = suite.suite
28
- else
29
- @suite = suite
30
- end
31
- @output_level = output_level
32
- @io = io
38
+ def initialize(suite, options={})
39
+ super
40
+ @output_level = @options[:output_level] || NORMAL
41
+ @output = @options[:output] || STDOUT
42
+ @use_color = @options[:use_color]
43
+ @use_color = guess_color_availability if @use_color.nil?
44
+ @color_scheme = COLOR_SCHEMES[:default]
45
+ @reset_color = Color.new("reset")
33
46
  @already_outputted = false
34
47
  @faults = []
35
48
  end
@@ -44,13 +57,15 @@ module Test
44
57
  private
45
58
  def setup_mediator
46
59
  @mediator = create_mediator(@suite)
60
+ output_setup_end
61
+ end
62
+
63
+ def output_setup_end
47
64
  suite_name = @suite.to_s
48
- if ( @suite.kind_of?(Module) )
49
- suite_name = @suite.name
50
- end
65
+ suite_name = @suite.name if @suite.kind_of?(Module)
51
66
  output("Loaded suite #{suite_name}")
52
67
  end
53
-
68
+
54
69
  def create_mediator(suite)
55
70
  return TestRunnerMediator.new(suite)
56
71
  end
@@ -69,53 +84,106 @@ module Test
69
84
 
70
85
  def add_fault(fault)
71
86
  @faults << fault
72
- output_single(fault.single_character_display, PROGRESS_ONLY)
87
+ output_single(fault.single_character_display,
88
+ fault_color(fault),
89
+ PROGRESS_ONLY)
73
90
  @already_outputted = true
74
91
  end
75
92
 
76
93
  def started(result)
77
94
  @result = result
95
+ output_started
96
+ end
97
+
98
+ def output_started
78
99
  output("Started")
79
100
  end
80
-
101
+
81
102
  def finished(elapsed_time)
103
+ nl if output?(NORMAL) and !output?(VERBOSE)
82
104
  nl
83
105
  output("Finished in #{elapsed_time} seconds.")
84
106
  @faults.each_with_index do |fault, index|
85
107
  nl
86
- output("%3d) %s" % [index + 1, fault.long_display])
108
+ output_single("%3d) " % (index + 1))
109
+ label, detail = format_fault(fault).split(/\r?\n/, 2)
110
+ output(label, fault_color(fault))
111
+ output(detail)
87
112
  end
88
113
  nl
89
- output(@result)
114
+ output(@result, result_color)
115
+ end
116
+
117
+ def format_fault(fault)
118
+ fault.long_display
90
119
  end
91
120
 
92
121
  def test_started(name)
93
- output_single(name + ": ", VERBOSE)
122
+ output_single(name + ": ", nil, VERBOSE)
94
123
  end
95
124
 
96
125
  def test_finished(name)
97
- output_single(".", PROGRESS_ONLY) unless (@already_outputted)
126
+ unless @already_outputted
127
+ output_single(".", @color_scheme["success"], PROGRESS_ONLY)
128
+ end
98
129
  nl(VERBOSE)
99
130
  @already_outputted = false
100
131
  end
101
132
 
102
133
  def nl(level=NORMAL)
103
- output("", level)
134
+ output("", nil, level)
104
135
  end
105
136
 
106
- def output(something, level=NORMAL)
107
- @io.puts(something) if (output?(level))
108
- @io.flush
137
+ def output(something, color=nil, level=NORMAL)
138
+ return unless output?(level)
139
+ output_single(something, color, level)
140
+ @output.puts
109
141
  end
110
142
 
111
- def output_single(something, level=NORMAL)
112
- @io.write(something) if (output?(level))
113
- @io.flush
143
+ def output_single(something, color=nil, level=NORMAL)
144
+ return unless output?(level)
145
+ if @use_color and color
146
+ something = "%s%s%s" % [color.escape_sequence,
147
+ something,
148
+ @reset_color.escape_sequence]
149
+ end
150
+ @output.write(something)
151
+ @output.flush
114
152
  end
115
153
 
116
154
  def output?(level)
117
155
  level <= @output_level
118
156
  end
157
+
158
+ def fault_color(fault)
159
+ @color_scheme[fault.class.name.split(/::/).last.downcase]
160
+ end
161
+
162
+ def result_color
163
+ if @result.passed?
164
+ if @result.pending_count > 0
165
+ @color_scheme["pending"]
166
+ elsif @result.omission_count > 0
167
+ @color_scheme["omission"]
168
+ elsif @result.notification_count > 0
169
+ @color_scheme["notification"]
170
+ else
171
+ @color_scheme["success"]
172
+ end
173
+ elsif @result.error_count > 0
174
+ @color_scheme["error"]
175
+ elsif @result.failure_count > 0
176
+ @color_scheme["failure"]
177
+ end
178
+ end
179
+
180
+ def guess_color_availability
181
+ return false unless @output.tty?
182
+ term = ENV["TERM"]
183
+ return true if term and (/term\z/ =~ term or term == "screen")
184
+ return true if ENV["EMACS"] == "t"
185
+ false
186
+ end
119
187
  end
120
188
  end
121
189
  end
@@ -0,0 +1,49 @@
1
+ require 'test/unit/ui/console/testrunner'
2
+
3
+ module Test
4
+ module Unit
5
+ module UI
6
+ module Emacs
7
+ class TestRunner < Console::TestRunner
8
+ private
9
+ def output_setup_end
10
+ end
11
+
12
+ def output_started
13
+ end
14
+
15
+ def format_fault(fault)
16
+ return super unless fault.respond_to?(:label)
17
+ format_method_name = "format_fault_#{fault.label.downcase}"
18
+ if respond_to?(format_method_name, true)
19
+ send(format_method_name, fault)
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ def format_fault_failure(failure)
26
+ if failure.location.size == 1
27
+ location = failure.location[0]
28
+ location_display = location.sub(/\A(.+:\d+).*/, ' [\\1]')
29
+ else
30
+ location_display = "\n" + failure.location.join("\n")
31
+ end
32
+ result = "#{failure.label}:\n"
33
+ result << "#{failure.test_name}#{location_display}:\n"
34
+ result << failure.message
35
+ result
36
+ end
37
+
38
+ def format_fault_error(error)
39
+ result = "#{error.label}:\n"
40
+ result << "#{error.test_name}:\n"
41
+ result << "#{error.message}\n"
42
+ result << error.backtrace.join("\n")
43
+ result
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ require 'test/unit/ui/testrunnerutilities'
2
+
3
+ module Test
4
+ module Unit
5
+ module UI
6
+ class TestRunner
7
+ extend TestRunnerUtilities
8
+
9
+ def initialize(suite, options={})
10
+ if suite.respond_to?(:suite)
11
+ @suite = suite.suite
12
+ else
13
+ @suite = suite
14
+ end
15
+ @options = options
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -31,28 +31,31 @@ module Test
31
31
  # with.
32
32
  def run_suite
33
33
  Unit.run = true
34
- begin_time = Time.now
35
- notify_listeners(RESET, @suite.size)
34
+
36
35
  result = create_result
37
- notify_listeners(STARTED, result)
38
- result_listener = result.add_listener(TestResult::CHANGED) do |updated_result|
39
- notify_listeners(TestResult::CHANGED, updated_result)
36
+ result_listener = result.add_listener(TestResult::CHANGED) do |*args|
37
+ notify_listeners(TestResult::CHANGED, *args)
40
38
  end
41
-
42
- fault_listener = result.add_listener(TestResult::FAULT) do |fault|
43
- notify_listeners(TestResult::FAULT, fault)
39
+ fault_listener = result.add_listener(TestResult::FAULT) do |*args|
40
+ notify_listeners(TestResult::FAULT, *args)
44
41
  end
45
-
46
- @suite.run(result) do |channel, value|
47
- notify_listeners(channel, value)
42
+
43
+ start_time = Time.now
44
+ begin
45
+ notify_listeners(RESET, @suite.size)
46
+ notify_listeners(STARTED, result)
47
+
48
+ @suite.run(result) do |channel, value|
49
+ notify_listeners(channel, value)
50
+ end
51
+ ensure
52
+ elapsed_time = Time.now - start_time
53
+ result.remove_listener(TestResult::FAULT, fault_listener)
54
+ result.remove_listener(TestResult::CHANGED, result_listener)
55
+ notify_listeners(FINISHED, elapsed_time)
48
56
  end
49
-
50
- result.remove_listener(TestResult::FAULT, fault_listener)
51
- result.remove_listener(TestResult::CHANGED, result_listener)
52
- end_time = Time.now
53
- elapsed_time = end_time - begin_time
54
- notify_listeners(FINISHED, elapsed_time) #"Finished in #{elapsed_time} seconds.")
55
- return result
57
+
58
+ result
56
59
  end
57
60
 
58
61
  private
@@ -60,7 +63,13 @@ module Test
60
63
  # should run with. Can be overridden by subclasses if
61
64
  # one wants to use a different result.
62
65
  def create_result
63
- return TestResult.new
66
+ TestResult.new
67
+ end
68
+
69
+ def measure_time
70
+ begin_time = Time.now
71
+ yield
72
+ Time.now - begin_time
64
73
  end
65
74
  end
66
75
  end
@@ -8,11 +8,6 @@ module Test
8
8
  module Unit
9
9
  module UI
10
10
 
11
- SILENT = 0
12
- PROGRESS_ONLY = 1
13
- NORMAL = 2
14
- VERBOSE = 3
15
-
16
11
  # Provides some utilities common to most, if not all,
17
12
  # TestRunners.
18
13
  #
@@ -25,8 +20,8 @@ module Test
25
20
  module TestRunnerUtilities
26
21
 
27
22
  # Creates a new TestRunner and runs the suite.
28
- def run(suite, output_level=NORMAL)
29
- return new(suite, output_level).start
23
+ def run(suite, options={})
24
+ return new(suite, options).start
30
25
  end
31
26
 
32
27
  # Takes care of the ARGV parsing and suite
@@ -5,7 +5,8 @@ module Test
5
5
  TESTUNIT_FILE_SEPARATORS = %r{[\\/:]}
6
6
  TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3]
7
7
  TESTUNIT_RB_FILE = /\.rb\Z/
8
-
8
+
9
+ module_function
9
10
  def filter_backtrace(backtrace, prefix=nil)
10
11
  return ["No backtrace"] unless(backtrace)
11
12
  split_p = if(prefix)
@@ -2,6 +2,6 @@
2
2
  # HACK: quick and dirty to get integrated into the new project - ryan
3
3
  module Test
4
4
  module Unit
5
- VERSION = '1.2.3'
5
+ VERSION = '2.0.0'
6
6
  end
7
7
  end