test-unit 1.2.3

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 (49) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +48 -0
  3. data/README.txt +27 -0
  4. data/Rakefile +15 -0
  5. data/bin/testrb +5 -0
  6. data/lib/test/unit.rb +280 -0
  7. data/lib/test/unit/assertionfailederror.rb +14 -0
  8. data/lib/test/unit/assertions.rb +622 -0
  9. data/lib/test/unit/autorunner.rb +220 -0
  10. data/lib/test/unit/collector.rb +43 -0
  11. data/lib/test/unit/collector/dir.rb +108 -0
  12. data/lib/test/unit/collector/objectspace.rb +34 -0
  13. data/lib/test/unit/error.rb +56 -0
  14. data/lib/test/unit/failure.rb +51 -0
  15. data/lib/test/unit/testcase.rb +160 -0
  16. data/lib/test/unit/testresult.rb +80 -0
  17. data/lib/test/unit/testsuite.rb +76 -0
  18. data/lib/test/unit/ui/console/testrunner.rb +127 -0
  19. data/lib/test/unit/ui/fox/testrunner.rb +268 -0
  20. data/lib/test/unit/ui/gtk/testrunner.rb +416 -0
  21. data/lib/test/unit/ui/gtk2/testrunner.rb +465 -0
  22. data/lib/test/unit/ui/testrunnermediator.rb +68 -0
  23. data/lib/test/unit/ui/testrunnerutilities.rb +46 -0
  24. data/lib/test/unit/ui/tk/testrunner.rb +260 -0
  25. data/lib/test/unit/util/backtracefilter.rb +40 -0
  26. data/lib/test/unit/util/observable.rb +90 -0
  27. data/lib/test/unit/util/procwrapper.rb +48 -0
  28. data/lib/test/unit/version.rb +7 -0
  29. data/sample/adder.rb +13 -0
  30. data/sample/subtracter.rb +12 -0
  31. data/sample/tc_adder.rb +18 -0
  32. data/sample/tc_subtracter.rb +18 -0
  33. data/sample/ts_examples.rb +7 -0
  34. data/test/collector/test_dir.rb +406 -0
  35. data/test/collector/test_objectspace.rb +98 -0
  36. data/test/runit/test_assert.rb +402 -0
  37. data/test/runit/test_testcase.rb +91 -0
  38. data/test/runit/test_testresult.rb +144 -0
  39. data/test/runit/test_testsuite.rb +49 -0
  40. data/test/test_assertions.rb +528 -0
  41. data/test/test_error.rb +26 -0
  42. data/test/test_failure.rb +33 -0
  43. data/test/test_testcase.rb +275 -0
  44. data/test/test_testresult.rb +104 -0
  45. data/test/test_testsuite.rb +129 -0
  46. data/test/util/test_backtracefilter.rb +41 -0
  47. data/test/util/test_observable.rb +102 -0
  48. data/test/util/test_procwrapper.rb +36 -0
  49. metadata +128 -0
@@ -0,0 +1,268 @@
1
+ #--
2
+ #
3
+ # Author:: Nathaniel Talbott.
4
+ # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
+ # License:: Ruby license.
6
+
7
+ require 'fox'
8
+ require 'test/unit/ui/testrunnermediator'
9
+ require 'test/unit/ui/testrunnerutilities'
10
+
11
+ include Fox
12
+
13
+ module Test
14
+ module Unit
15
+ module UI
16
+ module Fox
17
+
18
+ # Runs a Test::Unit::TestSuite in a Fox UI. Obviously,
19
+ # this one requires you to have Fox
20
+ # (http://www.fox-toolkit.org/fox.html) and the Ruby
21
+ # Fox extension (http://fxruby.sourceforge.net/)
22
+ # installed.
23
+ class TestRunner
24
+
25
+ extend TestRunnerUtilities
26
+
27
+ RED_STYLE = FXRGBA(0xFF,0,0,0xFF) #0xFF000000
28
+ GREEN_STYLE = FXRGBA(0,0xFF,0,0xFF) #0x00FF0000
29
+
30
+ # Creates a new TestRunner for running the passed
31
+ # suite.
32
+ def initialize(suite, output_level = NORMAL)
33
+ if (suite.respond_to?(:suite))
34
+ @suite = suite.suite
35
+ else
36
+ @suite = suite
37
+ end
38
+
39
+ @result = nil
40
+ @red = false
41
+ end
42
+
43
+ # Begins the test run.
44
+ def start
45
+ setup_ui
46
+ setup_mediator
47
+ attach_to_mediator
48
+ start_ui
49
+ @result
50
+ end
51
+
52
+ def setup_mediator
53
+ @mediator = TestRunnerMediator.new(@suite)
54
+ suite_name = @suite.to_s
55
+ if ( @suite.kind_of?(Module) )
56
+ suite_name = @suite.name
57
+ end
58
+ @suite_name_entry.text = suite_name
59
+ end
60
+
61
+ def attach_to_mediator
62
+ @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
63
+ @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
64
+ @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
65
+ @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
66
+ @mediator.add_listener(TestCase::STARTED, &method(:test_started))
67
+ @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
68
+ end
69
+
70
+ def start_ui
71
+ @application.create
72
+ @window.show(PLACEMENT_SCREEN)
73
+ @application.addTimeout(1) do
74
+ @mediator.run_suite
75
+ end
76
+ @application.run
77
+ end
78
+
79
+ def stop
80
+ @application.exit(0)
81
+ end
82
+
83
+ def reset_ui(count)
84
+ @test_progress_bar.barColor = GREEN_STYLE
85
+ @test_progress_bar.total = count
86
+ @test_progress_bar.progress = 0
87
+ @red = false
88
+
89
+ @test_count_label.text = "0"
90
+ @assertion_count_label.text = "0"
91
+ @failure_count_label.text = "0"
92
+ @error_count_label.text = "0"
93
+
94
+ @fault_list.clearItems
95
+ end
96
+
97
+ def add_fault(fault)
98
+ if ( ! @red )
99
+ @test_progress_bar.barColor = RED_STYLE
100
+ @red = true
101
+ end
102
+ item = FaultListItem.new(fault)
103
+ @fault_list.appendItem(item)
104
+ end
105
+
106
+ def show_fault(fault)
107
+ raw_show_fault(fault.long_display)
108
+ end
109
+
110
+ def raw_show_fault(string)
111
+ @detail_text.setText(string)
112
+ end
113
+
114
+ def clear_fault
115
+ raw_show_fault("")
116
+ end
117
+
118
+ def result_changed(result)
119
+ @test_progress_bar.progress = result.run_count
120
+
121
+ @test_count_label.text = result.run_count.to_s
122
+ @assertion_count_label.text = result.assertion_count.to_s
123
+ @failure_count_label.text = result.failure_count.to_s
124
+ @error_count_label.text = result.error_count.to_s
125
+
126
+ # repaint now!
127
+ @info_panel.repaint
128
+ @application.flush
129
+ end
130
+
131
+ def started(result)
132
+ @result = result
133
+ output_status("Started...")
134
+ end
135
+
136
+ def test_started(test_name)
137
+ output_status("Running #{test_name}...")
138
+ end
139
+
140
+ def finished(elapsed_time)
141
+ output_status("Finished in #{elapsed_time} seconds")
142
+ end
143
+
144
+ def output_status(string)
145
+ @status_entry.text = string
146
+ @status_entry.repaint
147
+ end
148
+
149
+ def setup_ui
150
+ @application = create_application
151
+ create_tooltip(@application)
152
+
153
+ @window = create_window(@application)
154
+
155
+ @status_entry = create_entry(@window)
156
+
157
+ main_panel = create_main_panel(@window)
158
+
159
+ suite_panel = create_suite_panel(main_panel)
160
+ create_label(suite_panel, "Suite:")
161
+ @suite_name_entry = create_entry(suite_panel)
162
+ create_button(suite_panel, "&Run\tRun the current suite", proc { @mediator.run_suite })
163
+
164
+ @test_progress_bar = create_progress_bar(main_panel)
165
+
166
+ @info_panel = create_info_panel(main_panel)
167
+ create_label(@info_panel, "Tests:")
168
+ @test_count_label = create_label(@info_panel, "0")
169
+ create_label(@info_panel, "Assertions:")
170
+ @assertion_count_label = create_label(@info_panel, "0")
171
+ create_label(@info_panel, "Failures:")
172
+ @failure_count_label = create_label(@info_panel, "0")
173
+ create_label(@info_panel, "Errors:")
174
+ @error_count_label = create_label(@info_panel, "0")
175
+
176
+ list_panel = create_list_panel(main_panel)
177
+ @fault_list = create_fault_list(list_panel)
178
+
179
+ detail_panel = create_detail_panel(main_panel)
180
+ @detail_text = create_text(detail_panel)
181
+ end
182
+
183
+ def create_application
184
+ app = FXApp.new("TestRunner", "Test::Unit")
185
+ app.init([])
186
+ app
187
+ end
188
+
189
+ def create_window(app)
190
+ FXMainWindow.new(app, "Test::Unit TestRunner", nil, nil, DECOR_ALL, 0, 0, 450)
191
+ end
192
+
193
+ def create_tooltip(app)
194
+ FXTooltip.new(app)
195
+ end
196
+
197
+ def create_main_panel(parent)
198
+ panel = FXVerticalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y)
199
+ panel.vSpacing = 10
200
+ panel
201
+ end
202
+
203
+ def create_suite_panel(parent)
204
+ FXHorizontalFrame.new(parent, LAYOUT_SIDE_LEFT | LAYOUT_FILL_X)
205
+ end
206
+
207
+ def create_button(parent, text, action)
208
+ FXButton.new(parent, text).connect(SEL_COMMAND, &action)
209
+ end
210
+
211
+ def create_progress_bar(parent)
212
+ FXProgressBar.new(parent, nil, 0, PROGRESSBAR_NORMAL | LAYOUT_FILL_X)
213
+ end
214
+
215
+ def create_info_panel(parent)
216
+ FXMatrix.new(parent, 1, MATRIX_BY_ROWS | LAYOUT_FILL_X)
217
+ end
218
+
219
+ def create_label(parent, text)
220
+ FXLabel.new(parent, text, nil, JUSTIFY_CENTER_X | LAYOUT_FILL_COLUMN)
221
+ end
222
+
223
+ def create_list_panel(parent)
224
+ FXHorizontalFrame.new(parent, LAYOUT_FILL_X | FRAME_SUNKEN | FRAME_THICK)
225
+ end
226
+
227
+ def create_fault_list(parent)
228
+ list = FXList.new(parent, 10, nil, 0, LIST_SINGLESELECT | LAYOUT_FILL_X) #, 0, 0, 0, 150)
229
+ list.connect(SEL_COMMAND) do |sender, sel, ptr|
230
+ if sender.retrieveItem(sender.currentItem).selected?
231
+ show_fault(sender.retrieveItem(sender.currentItem).fault)
232
+ else
233
+ clear_fault
234
+ end
235
+ end
236
+ list
237
+ end
238
+
239
+ def create_detail_panel(parent)
240
+ FXHorizontalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK)
241
+ end
242
+
243
+ def create_text(parent)
244
+ FXText.new(parent, nil, 0, TEXT_READONLY | LAYOUT_FILL_X | LAYOUT_FILL_Y)
245
+ end
246
+
247
+ def create_entry(parent)
248
+ entry = FXTextField.new(parent, 30, nil, 0, TEXTFIELD_NORMAL | LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X)
249
+ entry.disable
250
+ entry
251
+ end
252
+ end
253
+
254
+ class FaultListItem < FXListItem
255
+ attr_reader(:fault)
256
+ def initialize(fault)
257
+ super(fault.short_display)
258
+ @fault = fault
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
264
+ end
265
+
266
+ if __FILE__ == $0
267
+ Test::Unit::UI::Fox::TestRunner.start_command_line_test
268
+ end
@@ -0,0 +1,416 @@
1
+ #--
2
+ #
3
+ # Author:: Nathaniel Talbott.
4
+ # Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
+ # License:: Ruby license.
6
+
7
+ require 'gtk'
8
+ require 'test/unit/ui/testrunnermediator'
9
+ require 'test/unit/ui/testrunnerutilities'
10
+
11
+ module Test
12
+ module Unit
13
+ module UI
14
+ module GTK
15
+
16
+ # Runs a Test::Unit::TestSuite in a Gtk UI. Obviously,
17
+ # this one requires you to have Gtk
18
+ # (http://www.gtk.org/) and the Ruby Gtk extension
19
+ # (http://ruby-gnome.sourceforge.net/) installed.
20
+ class TestRunner
21
+ extend TestRunnerUtilities
22
+
23
+ # Creates a new TestRunner for running the passed
24
+ # suite.
25
+ def initialize(suite, output_level = NORMAL)
26
+ if (suite.respond_to?(:suite))
27
+ @suite = suite.suite
28
+ else
29
+ @suite = suite
30
+ end
31
+ @result = nil
32
+
33
+ @runner = Thread.current
34
+ @restart_signal = Class.new(Exception)
35
+ @viewer = Thread.start do
36
+ @runner.join rescue @runner.run
37
+ Gtk.main
38
+ end
39
+ @viewer.join rescue nil # wait deadlock to handshake
40
+ end
41
+
42
+ # Begins the test run.
43
+ def start
44
+ setup_mediator
45
+ setup_ui
46
+ attach_to_mediator
47
+ start_ui
48
+ @result
49
+ end
50
+
51
+ private
52
+ def setup_mediator
53
+ @mediator = TestRunnerMediator.new(@suite)
54
+ suite_name = @suite.to_s
55
+ if ( @suite.kind_of?(Module) )
56
+ suite_name = @suite.name
57
+ end
58
+ suite_name_entry.set_text(suite_name)
59
+ end
60
+
61
+ def attach_to_mediator
62
+ run_button.signal_connect("clicked", nil, &method(:run_test))
63
+ @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))
64
+ @mediator.add_listener(TestResult::FAULT, &method(:add_fault))
65
+ @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))
66
+ @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))
67
+ @mediator.add_listener(TestCase::STARTED, &method(:test_started))
68
+ @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))
69
+ @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))
70
+ end
71
+
72
+ def run_test(*)
73
+ @runner.raise(@restart_signal)
74
+ end
75
+
76
+ def start_ui
77
+ @viewer.run
78
+ running = false
79
+ begin
80
+ loop do
81
+ if (running ^= true)
82
+ run_button.child.text = "Stop"
83
+ @mediator.run_suite
84
+ else
85
+ run_button.child.text = "Run"
86
+ @viewer.join
87
+ break
88
+ end
89
+ end
90
+ rescue @restart_signal
91
+ retry
92
+ rescue
93
+ end
94
+ end
95
+
96
+ def stop(*)
97
+ Gtk.main_quit
98
+ end
99
+
100
+ def reset_ui(count)
101
+ test_progress_bar.set_style(green_style)
102
+ test_progress_bar.configure(0, 0, count)
103
+ @red = false
104
+
105
+ run_count_label.set_text("0")
106
+ assertion_count_label.set_text("0")
107
+ failure_count_label.set_text("0")
108
+ error_count_label.set_text("0")
109
+
110
+ fault_list.remove_items(fault_list.children)
111
+ end
112
+
113
+ def add_fault(fault)
114
+ if ( ! @red )
115
+ test_progress_bar.set_style(red_style)
116
+ @red = true
117
+ end
118
+ item = FaultListItem.new(fault)
119
+ item.show
120
+ fault_list.append_items([item])
121
+ end
122
+
123
+ def show_fault(fault)
124
+ raw_show_fault(fault.long_display)
125
+ end
126
+
127
+ def raw_show_fault(string)
128
+ fault_detail_label.set_text(string)
129
+ outer_detail_sub_panel.queue_resize
130
+ end
131
+
132
+ def clear_fault
133
+ raw_show_fault("")
134
+ end
135
+
136
+ def result_changed(result)
137
+ run_count_label.set_text(result.run_count.to_s)
138
+ assertion_count_label.set_text(result.assertion_count.to_s)
139
+ failure_count_label.set_text(result.failure_count.to_s)
140
+ error_count_label.set_text(result.error_count.to_s)
141
+ end
142
+
143
+ def started(result)
144
+ @result = result
145
+ output_status("Started...")
146
+ end
147
+
148
+ def test_started(test_name)
149
+ output_status("Running #{test_name}...")
150
+ end
151
+
152
+ def test_finished(test_name)
153
+ test_progress_bar.set_value(test_progress_bar.get_value + 1)
154
+ end
155
+
156
+ def finished(elapsed_time)
157
+ output_status("Finished in #{elapsed_time} seconds")
158
+ end
159
+
160
+ def output_status(string)
161
+ status_entry.set_text(string)
162
+ end
163
+
164
+ def setup_ui
165
+ main_window.signal_connect("destroy", nil, &method(:stop))
166
+ main_window.show_all
167
+ fault_list.signal_connect("select-child", nil) {
168
+ | list, item, data |
169
+ show_fault(item.fault)
170
+ }
171
+ fault_list.signal_connect("unselect-child", nil) {
172
+ clear_fault
173
+ }
174
+ @red = false
175
+ end
176
+
177
+ def main_window
178
+ lazy_initialize(:main_window) {
179
+ @main_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
180
+ @main_window.set_title("Test::Unit TestRunner")
181
+ @main_window.set_usize(800, 600)
182
+ @main_window.set_uposition(20, 20)
183
+ @main_window.set_policy(true, true, false)
184
+ @main_window.add(main_panel)
185
+ }
186
+ end
187
+
188
+ def main_panel
189
+ lazy_initialize(:main_panel) {
190
+ @main_panel = Gtk::VBox.new(false, 0)
191
+ @main_panel.pack_start(suite_panel, false, false, 0)
192
+ @main_panel.pack_start(progress_panel, false, false, 0)
193
+ @main_panel.pack_start(info_panel, false, false, 0)
194
+ @main_panel.pack_start(list_panel, false, false, 0)
195
+ @main_panel.pack_start(detail_panel, true, true, 0)
196
+ @main_panel.pack_start(status_panel, false, false, 0)
197
+ }
198
+ end
199
+
200
+ def suite_panel
201
+ lazy_initialize(:suite_panel) {
202
+ @suite_panel = Gtk::HBox.new(false, 10)
203
+ @suite_panel.border_width(10)
204
+ @suite_panel.pack_start(Gtk::Label.new("Suite:"), false, false, 0)
205
+ @suite_panel.pack_start(suite_name_entry, true, true, 0)
206
+ @suite_panel.pack_start(run_button, false, false, 0)
207
+ }
208
+ end
209
+
210
+ def suite_name_entry
211
+ lazy_initialize(:suite_name_entry) {
212
+ @suite_name_entry = Gtk::Entry.new
213
+ @suite_name_entry.set_editable(false)
214
+ }
215
+ end
216
+
217
+ def run_button
218
+ lazy_initialize(:run_button) {
219
+ @run_button = Gtk::Button.new("Run")
220
+ }
221
+ end
222
+
223
+ def progress_panel
224
+ lazy_initialize(:progress_panel) {
225
+ @progress_panel = Gtk::HBox.new(false, 10)
226
+ @progress_panel.border_width(10)
227
+ @progress_panel.pack_start(test_progress_bar, true, true, 0)
228
+ }
229
+ end
230
+
231
+ def test_progress_bar
232
+ lazy_initialize(:test_progress_bar) {
233
+ @test_progress_bar = EnhancedProgressBar.new
234
+ @test_progress_bar.set_usize(@test_progress_bar.allocation.width,
235
+ info_panel.size_request.height)
236
+ @test_progress_bar.set_style(green_style)
237
+ }
238
+ end
239
+
240
+ def green_style
241
+ lazy_initialize(:green_style) {
242
+ @green_style = Gtk::Style.new
243
+ @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000)
244
+ }
245
+ end
246
+
247
+ def red_style
248
+ lazy_initialize(:red_style) {
249
+ @red_style = Gtk::Style.new
250
+ @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000)
251
+ }
252
+ end
253
+
254
+ def info_panel
255
+ lazy_initialize(:info_panel) {
256
+ @info_panel = Gtk::HBox.new(false, 0)
257
+ @info_panel.border_width(10)
258
+ @info_panel.pack_start(Gtk::Label.new("Runs:"), false, false, 0)
259
+ @info_panel.pack_start(run_count_label, true, false, 0)
260
+ @info_panel.pack_start(Gtk::Label.new("Assertions:"), false, false, 0)
261
+ @info_panel.pack_start(assertion_count_label, true, false, 0)
262
+ @info_panel.pack_start(Gtk::Label.new("Failures:"), false, false, 0)
263
+ @info_panel.pack_start(failure_count_label, true, false, 0)
264
+ @info_panel.pack_start(Gtk::Label.new("Errors:"), false, false, 0)
265
+ @info_panel.pack_start(error_count_label, true, false, 0)
266
+ }
267
+ end
268
+
269
+ def run_count_label
270
+ lazy_initialize(:run_count_label) {
271
+ @run_count_label = Gtk::Label.new("0")
272
+ @run_count_label.set_justify(Gtk::JUSTIFY_LEFT)
273
+ }
274
+ end
275
+
276
+ def assertion_count_label
277
+ lazy_initialize(:assertion_count_label) {
278
+ @assertion_count_label = Gtk::Label.new("0")
279
+ @assertion_count_label.set_justify(Gtk::JUSTIFY_LEFT)
280
+ }
281
+ end
282
+
283
+ def failure_count_label
284
+ lazy_initialize(:failure_count_label) {
285
+ @failure_count_label = Gtk::Label.new("0")
286
+ @failure_count_label.set_justify(Gtk::JUSTIFY_LEFT)
287
+ }
288
+ end
289
+
290
+ def error_count_label
291
+ lazy_initialize(:error_count_label) {
292
+ @error_count_label = Gtk::Label.new("0")
293
+ @error_count_label.set_justify(Gtk::JUSTIFY_LEFT)
294
+ }
295
+ end
296
+
297
+ def list_panel
298
+ lazy_initialize(:list_panel) {
299
+ @list_panel = Gtk::HBox.new
300
+ @list_panel.border_width(10)
301
+ @list_panel.pack_start(list_scrolled_window, true, true, 0)
302
+ }
303
+ end
304
+
305
+ def list_scrolled_window
306
+ lazy_initialize(:list_scrolled_window) {
307
+ @list_scrolled_window = Gtk::ScrolledWindow.new
308
+ @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
309
+ @list_scrolled_window.set_usize(@list_scrolled_window.allocation.width, 150)
310
+ @list_scrolled_window.add_with_viewport(fault_list)
311
+ }
312
+ end
313
+
314
+ def fault_list
315
+ lazy_initialize(:fault_list) {
316
+ @fault_list = Gtk::List.new
317
+ }
318
+ end
319
+
320
+ def detail_panel
321
+ lazy_initialize(:detail_panel) {
322
+ @detail_panel = Gtk::HBox.new
323
+ @detail_panel.border_width(10)
324
+ @detail_panel.pack_start(detail_scrolled_window, true, true, 0)
325
+ }
326
+ end
327
+
328
+ def detail_scrolled_window
329
+ lazy_initialize(:detail_scrolled_window) {
330
+ @detail_scrolled_window = Gtk::ScrolledWindow.new
331
+ @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
332
+ @detail_scrolled_window.set_usize(400, @detail_scrolled_window.allocation.height)
333
+ @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel)
334
+ }
335
+ end
336
+
337
+ def outer_detail_sub_panel
338
+ lazy_initialize(:outer_detail_sub_panel) {
339
+ @outer_detail_sub_panel = Gtk::VBox.new
340
+ @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0)
341
+ }
342
+ end
343
+
344
+ def inner_detail_sub_panel
345
+ lazy_initialize(:inner_detail_sub_panel) {
346
+ @inner_detail_sub_panel = Gtk::HBox.new
347
+ @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0)
348
+ }
349
+ end
350
+
351
+ def fault_detail_label
352
+ lazy_initialize(:fault_detail_label) {
353
+ @fault_detail_label = EnhancedLabel.new("")
354
+ style = Gtk::Style.new
355
+ font = Gdk::Font.font_load("-*-Courier New-medium-r-normal--*-120-*-*-*-*-*-*")
356
+ begin
357
+ style.set_font(font)
358
+ rescue ArgumentError; end
359
+ @fault_detail_label.set_style(style)
360
+ @fault_detail_label.set_justify(Gtk::JUSTIFY_LEFT)
361
+ @fault_detail_label.set_line_wrap(false)
362
+ }
363
+ end
364
+
365
+ def status_panel
366
+ lazy_initialize(:status_panel) {
367
+ @status_panel = Gtk::HBox.new
368
+ @status_panel.border_width(10)
369
+ @status_panel.pack_start(status_entry, true, true, 0)
370
+ }
371
+ end
372
+
373
+ def status_entry
374
+ lazy_initialize(:status_entry) {
375
+ @status_entry = Gtk::Entry.new
376
+ @status_entry.set_editable(false)
377
+ }
378
+ end
379
+
380
+ def lazy_initialize(symbol)
381
+ if (!instance_eval("defined?(@#{symbol.to_s})"))
382
+ yield
383
+ end
384
+ return instance_eval("@" + symbol.to_s)
385
+ end
386
+ end
387
+
388
+ class EnhancedProgressBar < Gtk::ProgressBar
389
+ def set_style(style)
390
+ super
391
+ hide
392
+ show
393
+ end
394
+ end
395
+
396
+ class EnhancedLabel < Gtk::Label
397
+ def set_text(text)
398
+ super(text.gsub(/\n\t/, "\n" + (" " * 4)))
399
+ end
400
+ end
401
+
402
+ class FaultListItem < Gtk::ListItem
403
+ attr_reader(:fault)
404
+ def initialize(fault)
405
+ super(fault.short_display)
406
+ @fault = fault
407
+ end
408
+ end
409
+ end
410
+ end
411
+ end
412
+ end
413
+
414
+ if __FILE__ == $0
415
+ Test::Unit::UI::GTK::TestRunner.start_command_line_test
416
+ end