test-unit 1.2.3 → 2.0.0

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