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
@@ -18,6 +18,7 @@ module Test
18
18
  attr_reader(:test_name, :exception)
19
19
 
20
20
  SINGLE_CHARACTER = 'E'
21
+ LABEL = "Error"
21
22
 
22
23
  # Creates a new Error with the given test_name and
23
24
  # exception.
@@ -31,6 +32,10 @@ module Test
31
32
  SINGLE_CHARACTER
32
33
  end
33
34
 
35
+ def label
36
+ LABEL
37
+ end
38
+
34
39
  # Returns the message associated with the error.
35
40
  def message
36
41
  "#{@exception.class.name}: #{@exception.message}"
@@ -43,8 +48,12 @@ module Test
43
48
 
44
49
  # Returns a verbose version of the error description.
45
50
  def long_display
46
- backtrace = filter_backtrace(@exception.backtrace).join("\n ")
47
- "Error:\n#@test_name:\n#{message}\n #{backtrace}"
51
+ backtrace_display = backtrace.join("\n ")
52
+ "#{label}:\n#@test_name:\n#{message}\n #{backtrace_display}"
53
+ end
54
+
55
+ def backtrace
56
+ filter_backtrace(@exception.backtrace)
48
57
  end
49
58
 
50
59
  # Overridden to return long_display.
@@ -52,5 +61,64 @@ module Test
52
61
  long_display
53
62
  end
54
63
  end
64
+
65
+ module ErrorHandler
66
+ class << self
67
+ def included(base)
68
+ base.exception_handler(:handle_all_exception)
69
+ end
70
+ end
71
+
72
+ PASS_THROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt,
73
+ SystemExit]
74
+ private
75
+ def handle_all_exception(exception)
76
+ case exception
77
+ when *PASS_THROUGH_EXCEPTIONS
78
+ false
79
+ else
80
+ problem_occurred
81
+ add_error(exception)
82
+ true
83
+ end
84
+ end
85
+
86
+ def add_error(exception)
87
+ current_result.add_error(Error.new(name, exception))
88
+ end
89
+ end
90
+
91
+ module TestResultErrorSupport
92
+ attr_reader :errors
93
+
94
+ # Records a Test::Unit::Error.
95
+ def add_error(error)
96
+ @errors << error
97
+ notify_fault(error)
98
+ notify_changed
99
+ end
100
+
101
+ # Returns the number of errors this TestResult has
102
+ # recorded.
103
+ def error_count
104
+ @errors.size
105
+ end
106
+
107
+ def error_occurred?
108
+ not @errors.empty?
109
+ end
110
+
111
+ private
112
+ def initialize_containers
113
+ super
114
+ @errors = []
115
+ @summary_generators << :error_summary
116
+ @problem_checkers << :error_occurred?
117
+ end
118
+
119
+ def error_summary
120
+ "#{error_count} errors"
121
+ end
122
+ end
55
123
  end
56
124
  end
@@ -0,0 +1,39 @@
1
+ module Test
2
+ module Unit
3
+ module ExceptionHandler
4
+ @@exception_handlers = []
5
+ class << self
6
+ def exception_handlers
7
+ @@exception_handlers
8
+ end
9
+
10
+ def included(base)
11
+ base.extend(ClassMethods)
12
+
13
+ observer = Proc.new do |test_case, _, _, value, method_name|
14
+ if value
15
+ @@exception_handlers.unshift(method_name)
16
+ else
17
+ @@exception_handlers -= [method_name]
18
+ end
19
+ end
20
+ base.register_attribute_observer(:exception_handler, &observer)
21
+ end
22
+ end
23
+
24
+ module ClassMethods
25
+ def exception_handlers
26
+ ExceptionHandler.exception_handlers
27
+ end
28
+
29
+ def exception_handler(*method_names)
30
+ attribute(:exception_handler, true, *method_names)
31
+ end
32
+
33
+ def unregister_exception_handler(*method_names)
34
+ attribute(:exception_handler, false, *method_names)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -13,6 +13,7 @@ module Test
13
13
  attr_reader :test_name, :location, :message
14
14
 
15
15
  SINGLE_CHARACTER = 'F'
16
+ LABEL = "Failure"
16
17
 
17
18
  # Creates a new Failure with the given location and
18
19
  # message.
@@ -27,6 +28,10 @@ module Test
27
28
  SINGLE_CHARACTER
28
29
  end
29
30
 
31
+ def label
32
+ LABEL
33
+ end
34
+
30
35
  # Returns a brief version of the error description.
31
36
  def short_display
32
37
  "#@test_name: #{@message.split("\n")[0]}"
@@ -34,12 +39,12 @@ module Test
34
39
 
35
40
  # Returns a verbose version of the error description.
36
41
  def long_display
37
- location_display = if(location.size == 1)
38
- location[0].sub(/\A(.+:\d+).*/, ' [\\1]')
42
+ if location.size == 1
43
+ location_display = location[0].sub(/\A(.+:\d+).*/, ' [\\1]')
39
44
  else
40
- "\n [#{location.join("\n ")}]"
45
+ location_display = "\n [#{location.join("\n ")}]"
41
46
  end
42
- "Failure:\n#@test_name#{location_display}:\n#@message"
47
+ "#{label}:\n#@test_name#{location_display}:\n#@message"
43
48
  end
44
49
 
45
50
  # Overridden to return long_display.
@@ -47,5 +52,59 @@ module Test
47
52
  long_display
48
53
  end
49
54
  end
55
+
56
+ module FailureHandler
57
+ class << self
58
+ def included(base)
59
+ base.exception_handler(:handle_assertion_failed_error)
60
+ end
61
+ end
62
+
63
+ private
64
+ def handle_assertion_failed_error(exception)
65
+ return false unless exception.is_a?(AssertionFailedError)
66
+ problem_occurred
67
+ add_failure(exception.message, exception.backtrace)
68
+ true
69
+ end
70
+
71
+ def add_failure(message, backtrace)
72
+ failure = Failure.new(name, filter_backtrace(backtrace), message)
73
+ current_result.add_failure(failure)
74
+ end
75
+ end
76
+
77
+ module TestResultFailureSupport
78
+ attr_reader :failures
79
+
80
+ # Records a Test::Unit::Failure.
81
+ def add_failure(failure)
82
+ @failures << failure
83
+ notify_fault(failure)
84
+ notify_changed
85
+ end
86
+
87
+ # Returns the number of failures this TestResult has
88
+ # recorded.
89
+ def failure_count
90
+ @failures.size
91
+ end
92
+
93
+ def failure_occurred?
94
+ not @failures.empty?
95
+ end
96
+
97
+ private
98
+ def initialize_containers
99
+ super
100
+ @failures = []
101
+ @summary_generators << :failure_summary
102
+ @problem_checkers << :failure_occurred?
103
+ end
104
+
105
+ def failure_summary
106
+ "#{failure_count} failures"
107
+ end
108
+ end
50
109
  end
51
110
  end
@@ -0,0 +1,185 @@
1
+ module Test
2
+ module Unit
3
+ module Fixture
4
+ class << self
5
+ def included(base)
6
+ base.extend(ClassMethods)
7
+
8
+ [:setup, :teardown].each do |fixture|
9
+ observer = Proc.new do |test_case, _, _, value, method_name|
10
+ if value.nil?
11
+ test_case.send("unregister_#{fixture}_method", method_name)
12
+ else
13
+ test_case.send("register_#{fixture}_method", method_name,
14
+ value)
15
+ end
16
+ end
17
+ base.register_attribute_observer(fixture, &observer)
18
+ end
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ def setup(*method_names)
24
+ register_fixture(:setup, *method_names)
25
+ end
26
+
27
+ def unregister_setup(*method_names)
28
+ unregister_fixture(:setup, *method_names)
29
+ end
30
+
31
+ def teardown(*method_names)
32
+ register_fixture(:teardown, *method_names)
33
+ end
34
+
35
+ def unregister_teardown(*method_names)
36
+ unregister_fixture(:teardown, *method_names)
37
+ end
38
+
39
+ def register_setup_method(method_name, options)
40
+ register_fixture_method(:setup, method_name, options, :after, :append)
41
+ end
42
+
43
+ def unregister_setup_method(method_name)
44
+ unregister_fixture_method(:setup, method_name)
45
+ end
46
+
47
+ def register_teardown_method(method_name, options)
48
+ register_fixture_method(:teardown, method_name, options,
49
+ :before, :prepend)
50
+ end
51
+
52
+ def unregister_teardown_method(method_name)
53
+ unregister_fixture_method(:teardown, method_name)
54
+ end
55
+
56
+ def before_setup_methods
57
+ collect_fixture_methods(:setup, :before)
58
+ end
59
+
60
+ def after_setup_methods
61
+ collect_fixture_methods(:setup, :after)
62
+ end
63
+
64
+ def before_teardown_methods
65
+ collect_fixture_methods(:teardown, :before)
66
+ end
67
+
68
+ def after_teardown_methods
69
+ collect_fixture_methods(:teardown, :after)
70
+ end
71
+
72
+ private
73
+ def register_fixture(fixture, *method_names)
74
+ options = {}
75
+ options = method_names.pop if method_names.last.is_a?(Hash)
76
+ attribute(fixture, options, *method_names)
77
+ end
78
+
79
+ def unregister_fixture(fixture, *method_names)
80
+ attribute(fixture, nil, *method_names)
81
+ end
82
+
83
+ def valid_register_fixture_options?(options)
84
+ return true if options.empty?
85
+ return false if options.size > 1
86
+
87
+ key = options.keys.first
88
+ [:before, :after].include?(key) and
89
+ [:prepend, :append].include?(options[key])
90
+ end
91
+
92
+ def add_fixture_method_name(how, variable_name, method_name)
93
+ unless self.instance_variable_defined?(variable_name)
94
+ self.instance_variable_set(variable_name, [])
95
+ end
96
+ methods = self.instance_variable_get(variable_name)
97
+
98
+ if how == :prepend
99
+ methods = [method_name] | methods
100
+ else
101
+ methods = methods | [method_name]
102
+ end
103
+ self.instance_variable_set(variable_name, methods)
104
+ end
105
+
106
+ def registered_methods_variable_name(fixture, order)
107
+ "@#{order}_#{fixture}_methods"
108
+ end
109
+
110
+ def unregistered_methods_variable_name(fixture)
111
+ "@unregistered_#{fixture}_methods"
112
+ end
113
+
114
+ def register_fixture_method(fixture, method_name, options,
115
+ default_order, default_how)
116
+ unless valid_register_fixture_options?(options)
117
+ message = "must be {:before => :prepend}, " +
118
+ "{:before => :append}, {:after => :prepend} or " +
119
+ "{:after => :append}: #{options.inspect}"
120
+ raise ArgumentError, message
121
+ end
122
+
123
+ if options.empty?
124
+ order, how = default_order, default_how
125
+ else
126
+ order, how = options.to_a.first
127
+ end
128
+ variable_name = registered_methods_variable_name(fixture, order)
129
+ add_fixture_method_name(how, variable_name, method_name)
130
+ end
131
+
132
+ def unregister_fixture_method(fixture, method_name)
133
+ variable_name = unregistered_methods_variable_name(fixture)
134
+ add_fixture_method_name(:append, variable_name, method_name)
135
+ end
136
+
137
+ def collect_fixture_methods(fixture, order)
138
+ methods_variable = registered_methods_variable_name(fixture, order)
139
+ unregistered_methods_variable =
140
+ unregistered_methods_variable_name(fixture)
141
+
142
+ base_index = ancestors.index(Fixture)
143
+ interested_ancestors = ancestors[0, base_index].reverse
144
+ interested_ancestors.inject([]) do |result, ancestor|
145
+ if ancestor.is_a?(Class)
146
+ ancestor.class_eval do
147
+ methods = []
148
+ unregistered_methods = []
149
+ if instance_variable_defined?(methods_variable)
150
+ methods = instance_variable_get(methods_variable)
151
+ end
152
+ if instance_variable_defined?(unregistered_methods_variable)
153
+ unregistered_methods =
154
+ instance_variable_get(unregistered_methods_variable)
155
+ end
156
+ result + methods - unregistered_methods
157
+ end
158
+ else
159
+ []
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ private
166
+ def run_fixture(fixture)
167
+ [
168
+ self.class.send("before_#{fixture}_methods"),
169
+ fixture,
170
+ self.class.send("after_#{fixture}_methods")
171
+ ].flatten.each do |method_name|
172
+ send(method_name) if respond_to?(method_name, true)
173
+ end
174
+ end
175
+
176
+ def run_setup
177
+ run_fixture(:setup)
178
+ end
179
+
180
+ def run_teardown
181
+ run_fixture(:teardown)
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,125 @@
1
+ require 'test/unit/util/backtracefilter'
2
+
3
+ module Test
4
+ module Unit
5
+ class Notification
6
+ include Util::BacktraceFilter
7
+ attr_reader :test_name, :location, :message
8
+
9
+ SINGLE_CHARACTER = 'N'
10
+ LABEL = "Notification"
11
+
12
+ # Creates a new Notification with the given location and
13
+ # message.
14
+ def initialize(test_name, location, message)
15
+ @test_name = test_name
16
+ @location = location
17
+ @message = message
18
+ end
19
+
20
+ # Returns a single character representation of a notification.
21
+ def single_character_display
22
+ SINGLE_CHARACTER
23
+ end
24
+
25
+ def label
26
+ LABEL
27
+ end
28
+
29
+ # Returns a brief version of the error description.
30
+ def short_display
31
+ "#{@test_name}: #{@message.split("\n")[0]}"
32
+ end
33
+
34
+ # Returns a verbose version of the error description.
35
+ def long_display
36
+ backtrace = filter_backtrace(location).join("\n")
37
+ "#{label}: #{@message}\n#{@test_name}\n#{backtrace}"
38
+ end
39
+
40
+ # Overridden to return long_display.
41
+ def to_s
42
+ long_display
43
+ end
44
+ end
45
+
46
+ class NotifiedError < StandardError
47
+ end
48
+
49
+
50
+ module TestCaseNotificationSupport
51
+ class << self
52
+ def included(base)
53
+ base.class_eval do
54
+ include NotificationHandler
55
+ end
56
+ end
57
+ end
58
+
59
+ # Notify some information.
60
+ #
61
+ # Example:
62
+ # def test_notification
63
+ # notify("I'm here!")
64
+ # # Reached here
65
+ # notify("Special!") if special_case?
66
+ # # Reached here too
67
+ # end
68
+ def notify(message, &block)
69
+ notification = Notification.new(name, filter_backtrace(caller), message)
70
+ add_notification(notification)
71
+ end
72
+
73
+ private
74
+ def add_notification(notification)
75
+ current_result.add_notification(notification)
76
+ end
77
+ end
78
+
79
+ module NotificationHandler
80
+ class << self
81
+ def included(base)
82
+ base.exception_handler(:handle_Notified_error)
83
+ end
84
+ end
85
+
86
+ private
87
+ def handle_Notified_error(exception)
88
+ return false unless exception.is_a?(NotifiedError)
89
+ notification = Notification.new(name,
90
+ filter_backtrace(exception.backtrace),
91
+ exception.message)
92
+ add_notification(notification)
93
+ true
94
+ end
95
+ end
96
+
97
+ module TestResultNotificationSupport
98
+ attr_reader :notifications
99
+
100
+ # Records a Test::Unit::Notification.
101
+ def add_notification(notification)
102
+ @notifications << notification
103
+ notify_fault(notification)
104
+ notify_changed
105
+ end
106
+
107
+ # Returns the number of notifications this TestResult has
108
+ # recorded.
109
+ def notification_count
110
+ @notifications.size
111
+ end
112
+
113
+ private
114
+ def initialize_containers
115
+ super
116
+ @notifications = []
117
+ @summary_generators << :notification_summary
118
+ end
119
+
120
+ def notification_summary
121
+ "#{notification_count} notifications"
122
+ end
123
+ end
124
+ end
125
+ end