| Class | Test::Unit::UI::Tk::TestRunner |
| In: |
lib/test/unit/ui/tk/testrunner.rb
|
| Parent: | Object |
Runs a Test::Unit::TestSuite in a Tk UI. Obviously, this one requires you to have Tk and the Ruby Tk extension installed.
Creates a new TestRunner for running the passed suite.
# File lib/test/unit/ui/tk/testrunner.rb, line 26
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
Begins the test run.
# File lib/test/unit/ui/tk/testrunner.rb, line 46
46: def start
47: setup_ui
48: setup_mediator
49: attach_to_mediator
50: start_ui
51: @result
52: end
# File lib/test/unit/ui/tk/testrunner.rb, line 124
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
# File lib/test/unit/ui/tk/testrunner.rb, line 64
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
# File lib/test/unit/ui/tk/testrunner.rb, line 141
141: def clear_fault
142: raw_show_fault("")
143: end
# File lib/test/unit/ui/tk/testrunner.rb, line 246
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
# File lib/test/unit/ui/tk/testrunner.rb, line 162
162: def finished(elapsed_time)
163: output_status("Finished in #{elapsed_time} seconds")
164: end
# File lib/test/unit/ui/tk/testrunner.rb, line 166
166: def output_status(string)
167: @status_entry.value = string
168: end
# File lib/test/unit/ui/tk/testrunner.rb, line 137
137: def raw_show_fault(string)
138: @detail_text.value = string
139: end
# File lib/test/unit/ui/tk/testrunner.rb, line 108
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
# File lib/test/unit/ui/tk/testrunner.rb, line 145
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
# File lib/test/unit/ui/tk/testrunner.rb, line 80
80: def run_test
81: @runner.raise(@restart_signal)
82: end
# File lib/test/unit/ui/tk/testrunner.rb, line 55
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
# File lib/test/unit/ui/tk/testrunner.rb, line 170
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
# File lib/test/unit/ui/tk/testrunner.rb, line 133
133: def show_fault(fault)
134: raw_show_fault(fault.long_display)
135: end
# File lib/test/unit/ui/tk/testrunner.rb, line 84
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
# File lib/test/unit/ui/tk/testrunner.rb, line 153
153: def started(result)
154: @result = result
155: output_status("Started...")
156: end