1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
|
#--
#
# Author:: Kenta MURATA.
# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved.
# License:: Ruby license.
require "gtk2"
require "test/unit/ui/testrunnermediator"
require "test/unit/ui/testrunnerutilities"
module Test
module Unit
module UI
module GTK2 # :nodoc: all
Gtk.init
class EnhancedLabel < Gtk::Label # :nodoc: all
def set_text(text)
super(text.gsub(/\n\t/, "\n "))
end
end
class FaultList < Gtk::TreeView # :nodoc: all
def initialize
@faults = []
@model = Gtk::ListStore.new(String, String)
super(@model)
column = Gtk::TreeViewColumn.new
column.visible = false
append_column(column)
renderer = Gtk::CellRendererText.new
column = Gtk::TreeViewColumn.new("Failures", renderer, {:text => 1})
append_column(column)
selection.mode = Gtk::SELECTION_SINGLE
set_rules_hint(true)
set_headers_visible(false)
end # def initialize
def add_fault(fault)
@faults.push(fault)
iter = @model.append
iter.set_value(0, (@faults.length - 1).to_s)
iter.set_value(1, fault.short_display)
end # def add_fault(fault)
def get_fault(iter)
@faults[iter.get_value(0).to_i]
end # def get_fault
def clear
model.clear
end # def clear
end
class TestRunner
extend TestRunnerUtilities
def lazy_initialize(symbol) # :nodoc:
if !instance_eval("defined?(@#{symbol})") then
yield
end
return instance_eval("@#{symbol}")
end
private :lazy_initialize
def status_entry # :nodoc:
lazy_initialize(:status_entry) do
@status_entry = Gtk::Entry.new
@status_entry.editable = false
end
end
private :status_entry
def status_panel # :nodoc:
lazy_initialize(:status_panel) do
@status_panel = Gtk::HBox.new
@status_panel.border_width = 10
@status_panel.pack_start(status_entry, true, true, 0)
end
end
private :status_panel
def fault_detail_label # :nodoc:
lazy_initialize(:fault_detail_label) do
@fault_detail_label = EnhancedLabel.new("")
# style = Gtk::Style.new
# font = Gdk::Font.
# font_load("-*-Courier 10 Pitch-medium-r-normal--*-120-*-*-*-*-*-*")
# style.set_font(font)
# @fault_detail_label.style = style
@fault_detail_label.justify = Gtk::JUSTIFY_LEFT
@fault_detail_label.wrap = false
end
end
private :fault_detail_label
def inner_detail_sub_panel # :nodoc:
lazy_initialize(:inner_detail_sub_panel) do
@inner_detail_sub_panel = Gtk::HBox.new
@inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0)
end
end
private :inner_detail_sub_panel
def outer_detail_sub_panel # :nodoc:
lazy_initialize(:outer_detail_sub_panel) do
@outer_detail_sub_panel = Gtk::VBox.new
@outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0)
end
end
private :outer_detail_sub_panel
def detail_scrolled_window # :nodoc:
lazy_initialize(:detail_scrolled_window) do
@detail_scrolled_window = Gtk::ScrolledWindow.new
@detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
@detail_scrolled_window.
set_size_request(400, @detail_scrolled_window.allocation.height)
@detail_scrolled_window.add_with_viewport(outer_detail_sub_panel)
end
end
private :detail_scrolled_window
def detail_panel # :nodoc:
lazy_initialize(:detail_panel) do
@detail_panel = Gtk::HBox.new
@detail_panel.border_width = 10
@detail_panel.pack_start(detail_scrolled_window, true, true, 0)
end
end
private :detail_panel
def fault_list # :nodoc:
lazy_initialize(:fault_list) do
@fault_list = FaultList.new
end
end
private :fault_list
def list_scrolled_window # :nodoc:
lazy_initialize(:list_scrolled_window) do
@list_scrolled_window = Gtk::ScrolledWindow.new
@list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
@list_scrolled_window.
set_size_request(@list_scrolled_window.allocation.width, 150)
@list_scrolled_window.add_with_viewport(fault_list)
end
end
private :list_scrolled_window
def list_panel # :nodoc:
lazy_initialize(:list_panel) do
@list_panel = Gtk::HBox.new
@list_panel.border_width = 10
@list_panel.pack_start(list_scrolled_window, true, true, 0)
end
end
private :list_panel
def error_count_label # :nodoc:
lazy_initialize(:error_count_label) do
@error_count_label = Gtk::Label.new("0")
@error_count_label.justify = Gtk::JUSTIFY_LEFT
end
end
private :error_count_label
def failure_count_label # :nodoc:
lazy_initialize(:failure_count_label) do
@failure_count_label = Gtk::Label.new("0")
@failure_count_label.justify = Gtk::JUSTIFY_LEFT
end
end
private :failure_count_label
def assertion_count_label # :nodoc:
lazy_initialize(:assertion_count_label) do
@assertion_count_label = Gtk::Label.new("0")
@assertion_count_label.justify = Gtk::JUSTIFY_LEFT
end
end
private :assertion_count_label
def run_count_label # :nodoc:
lazy_initialize(:run_count_label) do
@run_count_label = Gtk::Label.new("0")
@run_count_label.justify = Gtk::JUSTIFY_LEFT
end
end
private :run_count_label
def info_panel # :nodoc:
lazy_initialize(:info_panel) do
@info_panel = Gtk::HBox.new(false, 0)
@info_panel.border_width = 10
@info_panel.pack_start(Gtk::Label.new("Runs:"), false, false, 0)
@info_panel.pack_start(run_count_label, true, false, 0)
@info_panel.pack_start(Gtk::Label.new("Assertions:"), false, false, 0)
@info_panel.pack_start(assertion_count_label, true, false, 0)
@info_panel.pack_start(Gtk::Label.new("Failures:"), false, false, 0)
@info_panel.pack_start(failure_count_label, true, false, 0)
@info_panel.pack_start(Gtk::Label.new("Errors:"), false, false, 0)
@info_panel.pack_start(error_count_label, true, false, 0)
end
end # def info_panel
private :info_panel
def green_style # :nodoc:
lazy_initialize(:green_style) do
@green_style = Gtk::Style.new
@green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000)
end
end # def green_style
private :green_style
def red_style # :nodoc:
lazy_initialize(:red_style) do
@red_style = Gtk::Style.new
@red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000)
end
end # def red_style
private :red_style
def test_progress_bar # :nodoc:
lazy_initialize(:test_progress_bar) {
@test_progress_bar = Gtk::ProgressBar.new
@test_progress_bar.fraction = 0.0
@test_progress_bar.
set_size_request(@test_progress_bar.allocation.width,
info_panel.size_request[1])
@test_progress_bar.style = green_style
}
end # def test_progress_bar
private :test_progress_bar
def progress_panel # :nodoc:
lazy_initialize(:progress_panel) do
@progress_panel = Gtk::HBox.new(false, 10)
@progress_panel.border_width = 10
@progress_panel.pack_start(test_progress_bar, true, true, 0)
end
end # def progress_panel
def run_button # :nodoc:
lazy_initialize(:run_button) do
@run_button = Gtk::Button.new("Run")
end
end # def run_button
def suite_name_entry # :nodoc:
lazy_initialize(:suite_name_entry) do
@suite_name_entry = Gtk::Entry.new
@suite_name_entry.editable = false
end
end # def suite_name_entry
private :suite_name_entry
def suite_panel # :nodoc:
lazy_initialize(:suite_panel) do
@suite_panel = Gtk::HBox.new(false, 10)
@suite_panel.border_width = 10
@suite_panel.pack_start(Gtk::Label.new("Suite:"), false, false, 0)
@suite_panel.pack_start(suite_name_entry, true, true, 0)
@suite_panel.pack_start(run_button, false, false, 0)
end
end # def suite_panel
private :suite_panel
def main_panel # :nodoc:
lazy_initialize(:main_panel) do
@main_panel = Gtk::VBox.new(false, 0)
@main_panel.pack_start(suite_panel, false, false, 0)
@main_panel.pack_start(progress_panel, false, false, 0)
@main_panel.pack_start(info_panel, false, false, 0)
@main_panel.pack_start(list_panel, false, false, 0)
@main_panel.pack_start(detail_panel, true, true, 0)
@main_panel.pack_start(status_panel, false, false, 0)
end
end # def main_panel
private :main_panel
def main_window # :nodoc:
lazy_initialize(:main_window) do
@main_window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
@main_window.set_title("Test::Unit TestRunner")
@main_window.set_default_size(800, 600)
@main_window.set_resizable(true)
@main_window.add(main_panel)
end
end # def main_window
private :main_window
def setup_ui # :nodoc:
main_window.signal_connect("destroy", nil) { stop }
main_window.show_all
fault_list.selection.signal_connect("changed", nil) do
|selection, data|
if selection.selected then
show_fault(fault_list.get_fault(selection.selected))
else
clear_fault
end
end
end # def setup_ui
private :setup_ui
def output_status(string) # :nodoc:
status_entry.set_text(string)
end # def output_status(string)
private :output_status
def finished(elapsed_time) # :nodoc:
test_progress_bar.fraction = 1.0
output_status("Finished in #{elapsed_time} seconds")
end # def finished(elapsed_time)
private :finished
def test_started(test_name) # :nodoc:
output_status("Running #{test_name}...")
end # def test_started(test_name)
private :test_started
def started(result) # :nodoc:
@result = result
output_status("Started...")
end # def started(result)
private :started
def test_finished(result) # :nodoc:
test_progress_bar.fraction += 1.0 / @count
end # def test_finished(result)
def result_changed(result) # :nodoc:
run_count_label.label = result.run_count.to_s
assertion_count_label.label = result.assertion_count.to_s
failure_count_label.label = result.failure_count.to_s
error_count_label.label = result.error_count.to_s
end # def result_changed(result)
private :result_changed
def clear_fault # :nodoc:
raw_show_fault("")
end # def clear_fault
private :clear_fault
def raw_show_fault(string) # :nodoc:
fault_detail_label.set_text(string)
outer_detail_sub_panel.queue_resize
end # def raw_show_fault(string)
private :raw_show_fault
def show_fault(fault) # :nodoc:
raw_show_fault(fault.long_display)
end # def show_fault(fault)
private :show_fault
def add_fault(fault) # :nodoc:
if not @red then
test_progress_bar.style = red_style
@red = true
end
fault_list.add_fault(fault)
end # def add_fault(fault)
private :add_fault
def reset_ui(count) # :nodoc:
test_progress_bar.style = green_style
test_progress_bar.fraction = 0.0
@count = count + 1
@red = false
run_count_label.set_text("0")
assertion_count_label.set_text("0")
failure_count_label.set_text("0")
error_count_label.set_text("0")
fault_list.clear
end # def reset_ui(count)
private :reset_ui
def stop # :nodoc:
Gtk.main_quit
end # def stop
private :stop
def run_test
@runner.raise(@restart_signal)
end
private :run_test
def start_ui # :nodoc
@viewer.run
running = false
begin
loop do
if (running ^= true)
run_button.child.text = "Stop"
@mediator.run_suite
else
run_button.child.text = "Run"
@viewer.join
break
end
end
rescue @restart_signal
retry
rescue
end
end # def start_ui
private :start_ui
def attach_to_mediator
run_button.signal_connect("clicked", nil) { run_test }
@mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
@mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
@mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
@mediator.add_listener(TestResult::FAULT, &method(:add_fault))
@mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
@mediator.add_listener(TestCase::STARTED, &method(:test_started))
@mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
end # def attach_to_mediator
private :attach_to_mediator
def setup_mediator
@mediator = TestRunnerMediator.new(@suite)
suite_name = @suite.to_s
if @suite.kind_of?(Module) then
suite_name = @suite.name
end
suite_name_entry.set_text(suite_name)
end # def setup_mediator
private :setup_mediator
def start
setup_mediator
setup_ui
attach_to_mediator
start_ui
@result
end # def start
def initialize(suite, output_level = NORMAL)
if suite.respond_to?(:suite) then
@suite = suite.suite
else
@suite = suite
end
@result = nil
@runner = Thread.current
@restart_signal = Class.new(Exception)
@viewer = Thread.start do
@runner.join rescue @runner.run
Gtk.main
end
@viewer.join rescue nil # wait deadlock to handshake
end # def initialize(suite)
end # class TestRunner
end # module GTK2
end # module UI
end # module Unit
end # module Test
|