rubysl-test-unit 1.0.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,68 +0,0 @@
1
- #--
2
- #
3
- # Author:: Nathaniel Talbott.
4
- # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
- # License:: Ruby license.
6
-
7
- require 'test/unit'
8
- require 'test/unit/util/observable'
9
- require 'test/unit/testresult'
10
-
11
- module Test
12
- module Unit
13
- module UI
14
-
15
- # Provides an interface to write any given UI against,
16
- # hopefully making it easy to write new UIs.
17
- class TestRunnerMediator
18
- RESET = name + "::RESET"
19
- STARTED = name + "::STARTED"
20
- FINISHED = name + "::FINISHED"
21
-
22
- include Util::Observable
23
-
24
- # Creates a new TestRunnerMediator initialized to run
25
- # the passed suite.
26
- def initialize(suite)
27
- @suite = suite
28
- end
29
-
30
- # Runs the suite the TestRunnerMediator was created
31
- # with.
32
- def run_suite
33
- Unit.run = true
34
- begin_time = Time.now
35
- notify_listeners(RESET, @suite.size)
36
- 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)
40
- end
41
-
42
- fault_listener = result.add_listener(TestResult::FAULT) do |fault|
43
- notify_listeners(TestResult::FAULT, fault)
44
- end
45
-
46
- @suite.run(result) do |channel, value|
47
- notify_listeners(channel, value)
48
- 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
56
- end
57
-
58
- private
59
- # A factory method to create the result the mediator
60
- # should run with. Can be overridden by subclasses if
61
- # one wants to use a different result.
62
- def create_result
63
- return TestResult.new
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,46 +0,0 @@
1
- #--
2
- #
3
- # Author:: Nathaniel Talbott.
4
- # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
- # License:: Ruby license.
6
-
7
- module Test
8
- module Unit
9
- module UI
10
-
11
- SILENT = 0
12
- PROGRESS_ONLY = 1
13
- NORMAL = 2
14
- VERBOSE = 3
15
-
16
- # Provides some utilities common to most, if not all,
17
- # TestRunners.
18
- #
19
- #--
20
- #
21
- # Perhaps there ought to be a TestRunner superclass? There
22
- # seems to be a decent amount of shared code between test
23
- # runners.
24
-
25
- module TestRunnerUtilities
26
-
27
- # Creates a new TestRunner and runs the suite.
28
- def run(suite, output_level=NORMAL)
29
- return new(suite, output_level).start
30
- end
31
-
32
- # Takes care of the ARGV parsing and suite
33
- # determination necessary for running one of the
34
- # TestRunners from the command line.
35
- def start_command_line_test
36
- if ARGV.empty?
37
- puts "You should supply the name of a test suite file to the runner"
38
- exit
39
- end
40
- require ARGV[0].gsub(/.+::/, '')
41
- new(eval(ARGV[0])).start
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,260 +0,0 @@
1
- #--
2
- #
3
- # Original Author:: Nathaniel Talbott.
4
- # Author:: Kazuhiro NISHIYAMA.
5
- # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
6
- # Copyright:: Copyright (c) 2003 Kazuhiro NISHIYAMA. All rights reserved.
7
- # License:: Ruby license.
8
-
9
- require 'tk'
10
- require 'test/unit/ui/testrunnermediator'
11
- require 'test/unit/ui/testrunnerutilities'
12
-
13
- module Test
14
- module Unit
15
- module UI
16
- module Tk
17
-
18
- # Runs a Test::Unit::TestSuite in a Tk UI. Obviously,
19
- # this one requires you to have Tk
20
- # and the Ruby Tk extension installed.
21
- class TestRunner
22
- extend TestRunnerUtilities
23
-
24
- # Creates a new TestRunner for running the passed
25
- # suite.
26
- def initialize(suite, output_level = NORMAL)
27
- if (suite.respond_to?(:suite))
28
- @suite = suite.suite
29
- else
30
- @suite = suite
31
- end
32
- @result = nil
33
-
34
- @red = false
35
- @fault_detail_list = []
36
- @runner = Thread.current
37
- @restart_signal = Class.new(Exception)
38
- @viewer = Thread.start do
39
- @runner.join rescue @runner.run
40
- ::Tk.mainloop
41
- end
42
- @viewer.join rescue nil # wait deadlock to handshake
43
- end
44
-
45
- # Begins the test run.
46
- def start
47
- setup_ui
48
- setup_mediator
49
- attach_to_mediator
50
- start_ui
51
- @result
52
- end
53
-
54
- private
55
- def setup_mediator
56
- @mediator = TestRunnerMediator.new(@suite)
57
- suite_name = @suite.to_s
58
- if ( @suite.kind_of?(Module) )
59
- suite_name = @suite.name
60
- end
61
- @suite_name_entry.value = suite_name
62
- end
63
-
64
- def attach_to_mediator
65
- @run_button.command(method(:run_test))
66
- @fault_list.bind('ButtonPress-1', proc{|y|
67
- fault = @fault_detail_list[@fault_list.nearest(y)]
68
- if fault
69
- show_fault(fault)
70
- end
71
- }, '%y')
72
- @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
73
- @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
74
- @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
75
- @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
76
- @mediator.add_listener(TestCase::STARTED, &method(:test_started))
77
- @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
78
- end
79
-
80
- def run_test
81
- @runner.raise(@restart_signal)
82
- end
83
-
84
- def start_ui
85
- @viewer.run
86
- running = false
87
- begin
88
- loop do
89
- if (running ^= true)
90
- @run_button.configure('text'=>'Stop')
91
- @mediator.run_suite
92
- else
93
- @run_button.configure('text'=>'Run')
94
- @viewer.join
95
- break
96
- end
97
- end
98
- rescue @restart_signal
99
- retry
100
- rescue
101
- end
102
- end
103
-
104
- def stop
105
- ::Tk.exit
106
- end
107
-
108
- def reset_ui(count)
109
- @test_total_count = count.to_f
110
- @test_progress_bar.configure('background'=>'green')
111
- @test_progress_bar.place('relwidth'=>(count.zero? ? 0 : 0/count))
112
- @red = false
113
-
114
- @test_count_label.value = 0
115
- @assertion_count_label.value = 0
116
- @failure_count_label.value = 0
117
- @error_count_label.value = 0
118
-
119
- @fault_list.delete(0, 'end')
120
- @fault_detail_list = []
121
- clear_fault
122
- end
123
-
124
- def add_fault(fault)
125
- if ( ! @red )
126
- @test_progress_bar.configure('background'=>'red')
127
- @red = true
128
- end
129
- @fault_detail_list.push fault
130
- @fault_list.insert('end', fault.short_display)
131
- end
132
-
133
- def show_fault(fault)
134
- raw_show_fault(fault.long_display)
135
- end
136
-
137
- def raw_show_fault(string)
138
- @detail_text.value = string
139
- end
140
-
141
- def clear_fault
142
- raw_show_fault("")
143
- end
144
-
145
- def result_changed(result)
146
- @test_count_label.value = result.run_count
147
- @test_progress_bar.place('relwidth'=>result.run_count/@test_total_count)
148
- @assertion_count_label.value = result.assertion_count
149
- @failure_count_label.value = result.failure_count
150
- @error_count_label.value = result.error_count
151
- end
152
-
153
- def started(result)
154
- @result = result
155
- output_status("Started...")
156
- end
157
-
158
- def test_started(test_name)
159
- output_status("Running #{test_name}...")
160
- end
161
-
162
- def finished(elapsed_time)
163
- output_status("Finished in #{elapsed_time} seconds")
164
- end
165
-
166
- def output_status(string)
167
- @status_entry.value = string
168
- end
169
-
170
- def setup_ui
171
- @status_entry = TkVariable.new
172
- l = TkLabel.new(nil, 'textvariable'=>@status_entry, 'relief'=>'sunken')
173
- l.pack('side'=>'bottom', 'fill'=>'x')
174
-
175
- suite_frame = TkFrame.new.pack('fill'=>'x')
176
-
177
- @run_button = TkButton.new(suite_frame, 'text'=>'Run')
178
- @run_button.pack('side'=>'right')
179
-
180
- TkLabel.new(suite_frame, 'text'=>'Suite:').pack('side'=>'left')
181
- @suite_name_entry = TkVariable.new
182
- l = TkLabel.new(suite_frame, 'textvariable'=>@suite_name_entry, 'relief'=>'sunken')
183
- l.pack('side'=>'left', 'fill'=>'x', 'expand'=>true)
184
-
185
- f = TkFrame.new(nil, 'relief'=>'sunken', 'borderwidth'=>3, 'height'=>20).pack('fill'=>'x', 'padx'=>1)
186
- @test_progress_bar = TkFrame.new(f, 'background'=>'green').place('anchor'=>'nw', 'relwidth'=>0.0, 'relheight'=>1.0)
187
-
188
- info_frame = TkFrame.new.pack('fill'=>'x')
189
- @test_count_label = create_count_label(info_frame, 'Tests:')
190
- @assertion_count_label = create_count_label(info_frame, 'Assertions:')
191
- @failure_count_label = create_count_label(info_frame, 'Failures:')
192
- @error_count_label = create_count_label(info_frame, 'Errors:')
193
-
194
- if (::Tk.info('command', TkPanedWindow::TkCommandNames[0]) != "")
195
- # use panedwindow
196
- paned_frame = TkPanedWindow.new("orient"=>"vertical").pack('fill'=>'both', 'expand'=>true)
197
-
198
- fault_list_frame = TkFrame.new(paned_frame)
199
- detail_frame = TkFrame.new(paned_frame)
200
-
201
- paned_frame.add(fault_list_frame, detail_frame)
202
- else
203
- # no panedwindow
204
- paned_frame = nil
205
- fault_list_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)
206
- detail_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)
207
- end
208
-
209
- TkGrid.rowconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0)
210
- TkGrid.columnconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0)
211
-
212
- fault_scrollbar_y = TkScrollbar.new(fault_list_frame)
213
- fault_scrollbar_x = TkScrollbar.new(fault_list_frame)
214
- @fault_list = TkListbox.new(fault_list_frame)
215
- @fault_list.yscrollbar(fault_scrollbar_y)
216
- @fault_list.xscrollbar(fault_scrollbar_x)
217
-
218
- TkGrid.rowconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0)
219
- TkGrid.columnconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0)
220
-
221
- ::Tk.grid(@fault_list, fault_scrollbar_y, 'sticky'=>'news')
222
- ::Tk.grid(fault_scrollbar_x, 'sticky'=>'news')
223
-
224
- detail_scrollbar_y = TkScrollbar.new(detail_frame)
225
- detail_scrollbar_x = TkScrollbar.new(detail_frame)
226
- @detail_text = TkText.new(detail_frame, 'height'=>10, 'wrap'=>'none') {
227
- bindtags(bindtags - [TkText])
228
- }
229
- @detail_text.yscrollbar(detail_scrollbar_y)
230
- @detail_text.xscrollbar(detail_scrollbar_x)
231
-
232
- ::Tk.grid(@detail_text, detail_scrollbar_y, 'sticky'=>'news')
233
- ::Tk.grid(detail_scrollbar_x, 'sticky'=>'news')
234
-
235
- # rubber-style pane
236
- if paned_frame
237
- ::Tk.update
238
- @height = paned_frame.winfo_height
239
- paned_frame.bind('Configure', proc{|h|
240
- paned_frame.sash_place(0, 0, paned_frame.sash_coord(0)[1] * h / @height)
241
- @height = h
242
- }, '%h')
243
- end
244
- end
245
-
246
- def create_count_label(parent, label)
247
- TkLabel.new(parent, 'text'=>label).pack('side'=>'left', 'expand'=>true)
248
- v = TkVariable.new(0)
249
- TkLabel.new(parent, 'textvariable'=>v).pack('side'=>'left', 'expand'=>true)
250
- v
251
- end
252
- end
253
- end
254
- end
255
- end
256
- end
257
-
258
- if __FILE__ == $0
259
- Test::Unit::UI::Tk::TestRunner.start_command_line_test
260
- end
@@ -1,40 +0,0 @@
1
- module Test
2
- module Unit
3
- module Util
4
- module BacktraceFilter
5
- TESTUNIT_FILE_SEPARATORS = %r{[\\/:]}
6
- TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3]
7
- TESTUNIT_RB_FILE = /\.rb\Z/
8
-
9
- def filter_backtrace(backtrace, prefix=nil)
10
- return ["No backtrace"] unless(backtrace)
11
- split_p = if(prefix)
12
- prefix.split(TESTUNIT_FILE_SEPARATORS)
13
- else
14
- TESTUNIT_PREFIX
15
- end
16
- match = proc do |e|
17
- split_e = e.split(TESTUNIT_FILE_SEPARATORS)[0, split_p.size]
18
- next false unless(split_e[0..-2] == split_p[0..-2])
19
- split_e[-1].sub(TESTUNIT_RB_FILE, '') == split_p[-1]
20
- end
21
- return backtrace unless(backtrace.detect(&match))
22
- found_prefix = false
23
- new_backtrace = backtrace.reverse.reject do |e|
24
- if(match[e])
25
- found_prefix = true
26
- true
27
- elsif(found_prefix)
28
- false
29
- else
30
- true
31
- end
32
- end.reverse
33
- new_backtrace = (new_backtrace.empty? ? backtrace : new_backtrace)
34
- new_backtrace = new_backtrace.reject(&match)
35
- new_backtrace.empty? ? backtrace : new_backtrace
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,90 +0,0 @@
1
- #--
2
- #
3
- # Author:: Nathaniel Talbott.
4
- # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
- # License:: Ruby license.
6
-
7
- require 'test/unit/util/procwrapper'
8
-
9
- module Test
10
- module Unit
11
- module Util
12
-
13
- # This is a utility class that allows anything mixing
14
- # it in to notify a set of listeners about interesting
15
- # events.
16
- module Observable
17
- # We use this for defaults since nil might mean something
18
- NOTHING = "NOTHING/#{__id__}"
19
-
20
- # Adds the passed proc as a listener on the
21
- # channel indicated by channel_name. listener_key
22
- # is used to remove the listener later; if none is
23
- # specified, the proc itself is used.
24
- #
25
- # Whatever is used as the listener_key is
26
- # returned, making it very easy to use the proc
27
- # itself as the listener_key:
28
- #
29
- # listener = add_listener("Channel") { ... }
30
- # remove_listener("Channel", listener)
31
- def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value
32
- unless(block_given?)
33
- raise ArgumentError.new("No callback was passed as a listener")
34
- end
35
-
36
- key = listener_key
37
- if (listener_key == NOTHING)
38
- listener_key = listener
39
- key = ProcWrapper.new(listener)
40
- end
41
-
42
- channels[channel_name] ||= {}
43
- channels[channel_name][key] = listener
44
- return listener_key
45
- end
46
-
47
- # Removes the listener indicated by listener_key
48
- # from the channel indicated by
49
- # channel_name. Returns the registered proc, or
50
- # nil if none was found.
51
- def remove_listener(channel_name, listener_key)
52
- channel = channels[channel_name]
53
- return nil unless (channel)
54
- key = listener_key
55
- if (listener_key.instance_of?(Proc))
56
- key = ProcWrapper.new(listener_key)
57
- end
58
- if (channel.has_key?(key))
59
- return channel.delete(key)
60
- end
61
- return nil
62
- end
63
-
64
- # Calls all the procs registered on the channel
65
- # indicated by channel_name. If value is
66
- # specified, it is passed in to the procs,
67
- # otherwise they are called with no arguments.
68
- #
69
- #--
70
- #
71
- # Perhaps this should be private? Would it ever
72
- # make sense for an external class to call this
73
- # method directly?
74
- def notify_listeners(channel_name, *arguments)
75
- channel = channels[channel_name]
76
- return 0 unless (channel)
77
- listeners = channel.values
78
- listeners.each { |listener| listener.call(*arguments) }
79
- return listeners.size
80
- end
81
-
82
- private
83
- def channels
84
- @channels ||= {}
85
- return @channels
86
- end
87
- end
88
- end
89
- end
90
- end