wxruby3 0.9.0.pre.rc.1 → 0.9.0.pre.rc.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +73 -22
  3. data/README.md +40 -8
  4. data/assets/hello_button-macos.png +0 -0
  5. data/assets/hello_button-msw.png +0 -0
  6. data/assets/hello_button_clicked-macos.png +0 -0
  7. data/assets/hello_button_clicked-msw.png +0 -0
  8. data/assets/hello_button_clicked_combi.png +0 -0
  9. data/assets/hello_world-macos.png +0 -0
  10. data/assets/hello_world-msw.png +0 -0
  11. data/assets/hello_world_combi.png +0 -0
  12. data/ext/wxruby3/swig/wx.i +2 -0
  13. data/lib/wx/core/brush.rb +6 -0
  14. data/lib/wx/core/event_loop.rb +7 -0
  15. data/lib/wx/core/evthandler.rb +12 -2
  16. data/lib/wx/core/font.rb +22 -14
  17. data/lib/wx/core/helpprovider.rb +2 -2
  18. data/lib/wx/core/image.rb +33 -0
  19. data/lib/wx/core/listctrl.rb +17 -13
  20. data/lib/wx/core/log.rb +90 -0
  21. data/lib/wx/core/menu.rb +5 -0
  22. data/lib/wx/core/pen.rb +6 -0
  23. data/lib/wx/core/window.rb +28 -1
  24. data/lib/wx/doc/app.rb +40 -0
  25. data/lib/wx/doc/bitmap.rb +11 -15
  26. data/lib/wx/doc/brush.rb +17 -0
  27. data/lib/wx/doc/event_loop.rb +7 -0
  28. data/lib/wx/doc/extra/00_starting.md +6 -6
  29. data/lib/wx/doc/extra/02_lifecycles.md +9 -8
  30. data/lib/wx/doc/extra/09_exceptions.md +1 -1
  31. data/lib/wx/doc/extra/11_drawing_and_dc.md +4 -4
  32. data/lib/wx/doc/font.rb +27 -0
  33. data/lib/wx/doc/functions.rb +51 -23
  34. data/lib/wx/doc/gc_dc.rb +1 -1
  35. data/lib/wx/doc/image.rb +42 -12
  36. data/lib/wx/doc/list_ctrl.rb +32 -0
  37. data/lib/wx/doc/log.rb +28 -0
  38. data/lib/wx/doc/pen.rb +17 -0
  39. data/lib/wx/doc/prt/printer_dc.rb +2 -2
  40. data/lib/wx/doc/radio_box.rb +20 -0
  41. data/lib/wx/doc/scaled_dc.rb +1 -1
  42. data/lib/wx/doc/text_validator.rb +12 -0
  43. data/lib/wx/doc/window.rb +27 -0
  44. data/lib/wx/keyword_defs.rb +77 -76
  45. data/lib/wx/prt/keyword_defs.rb +5 -1
  46. data/lib/wx/version.rb +1 -1
  47. data/rakelib/install.rb +17 -6
  48. data/rakelib/lib/config/linux.rb +4 -2
  49. data/rakelib/lib/config/macosx.rb +120 -1
  50. data/rakelib/lib/config/mingw.rb +6 -1
  51. data/rakelib/lib/config/unixish.rb +26 -11
  52. data/rakelib/lib/config.rb +15 -6
  53. data/rakelib/lib/core/mapping.rb +15 -10
  54. data/rakelib/lib/core/package.rb +4 -1
  55. data/rakelib/lib/core/spec.rb +23 -12
  56. data/rakelib/lib/core/spec_helper.rb +6 -0
  57. data/rakelib/lib/director/app.rb +30 -1
  58. data/rakelib/lib/director/aui_toolbar.rb +41 -0
  59. data/rakelib/lib/director/brush.rb +10 -1
  60. data/rakelib/lib/director/combobox.rb +1 -1
  61. data/rakelib/lib/director/context_help_button.rb +23 -0
  62. data/rakelib/lib/director/dialog.rb +33 -2
  63. data/rakelib/lib/director/event_loop.rb +26 -0
  64. data/rakelib/lib/director/font.rb +12 -3
  65. data/rakelib/lib/director/functions.rb +44 -48
  66. data/rakelib/lib/director/help_provider.rb +8 -10
  67. data/rakelib/lib/director/hyperlink_event.rb +22 -0
  68. data/rakelib/lib/director/image.rb +32 -0
  69. data/rakelib/lib/director/list_ctrl.rb +3 -2
  70. data/rakelib/lib/director/log.rb +64 -4
  71. data/rakelib/lib/director/menu.rb +0 -3
  72. data/rakelib/lib/director/menu_bar.rb +3 -0
  73. data/rakelib/lib/director/pen.rb +10 -1
  74. data/rakelib/lib/director/popup_window.rb +18 -0
  75. data/rakelib/lib/director/radio_box.rb +15 -4
  76. data/rakelib/lib/director/searchctrl.rb +2 -1
  77. data/rakelib/lib/director/static_box.rb +1 -1
  78. data/rakelib/lib/director/styled_text_ctrl.rb +1 -1
  79. data/rakelib/lib/director/text_entry.rb +30 -0
  80. data/rakelib/lib/director/text_validator.rb +8 -2
  81. data/rakelib/lib/director/textctrl.rb +1 -1
  82. data/rakelib/lib/director/variant.rb +17 -4
  83. data/rakelib/lib/director/window.rb +37 -1
  84. data/rakelib/lib/extractor/function.rb +7 -7
  85. data/rakelib/lib/extractor/variable.rb +6 -6
  86. data/rakelib/lib/generate/doc/aui_manager.yaml +21 -0
  87. data/rakelib/lib/generate/doc/context_help_button.yaml +16 -0
  88. data/rakelib/lib/generate/doc/event_blocker.yaml +27 -0
  89. data/rakelib/lib/generate/doc/event_filter.yaml +47 -0
  90. data/rakelib/lib/generate/doc/file_dialog.yaml +68 -0
  91. data/rakelib/lib/generate/doc/font.yaml +29 -0
  92. data/rakelib/lib/generate/doc/frame.yaml +23 -0
  93. data/rakelib/lib/generate/doc/fs_file.yaml +11 -0
  94. data/rakelib/lib/generate/doc/gdi_common.yaml +36 -0
  95. data/rakelib/lib/generate/doc/graphics_context.yaml +34 -0
  96. data/rakelib/lib/generate/doc/gui_event_loop.yaml +12 -0
  97. data/rakelib/lib/generate/doc/help_controller.yaml +24 -0
  98. data/rakelib/lib/generate/doc/icon.yaml +11 -0
  99. data/rakelib/lib/generate/doc/image.yaml +87 -0
  100. data/rakelib/lib/generate/doc/keyboard_state.yaml +19 -0
  101. data/rakelib/lib/generate/doc/list_ctrl.yaml +77 -0
  102. data/rakelib/lib/generate/doc/locale.yaml +12 -0
  103. data/rakelib/lib/generate/doc/log.yaml +86 -0
  104. data/rakelib/lib/generate/doc/mdi_frame.yaml +12 -0
  105. data/rakelib/lib/generate/doc/memory_dc.yaml +42 -0
  106. data/rakelib/lib/generate/doc/menu.yaml +17 -0
  107. data/rakelib/lib/generate/doc/menu_item.yaml +43 -0
  108. data/rakelib/lib/generate/doc/message_dialog.yaml +36 -0
  109. data/rakelib/lib/generate/doc/non_owned_window.yaml +14 -0
  110. data/rakelib/lib/generate/doc/notebook.yaml +18 -0
  111. data/rakelib/lib/generate/doc/pen.yaml +11 -0
  112. data/rakelib/lib/generate/doc/picker_base.yaml +19 -0
  113. data/rakelib/lib/generate/doc/platform_info.yaml +15 -0
  114. data/rakelib/lib/generate/doc/property_sheet_dialog.yaml +26 -0
  115. data/rakelib/lib/generate/doc/scroll_bar.yaml +11 -0
  116. data/rakelib/lib/generate/doc/scrolled_canvas.yaml +37 -0
  117. data/rakelib/lib/generate/doc/scrolled_control.yaml +37 -0
  118. data/rakelib/lib/generate/doc/scrolled_window.yaml +37 -0
  119. data/rakelib/lib/generate/doc/sizer.yaml +69 -0
  120. data/rakelib/lib/generate/doc/splash_screen.yaml +18 -0
  121. data/rakelib/lib/generate/doc/static_box.yaml +52 -0
  122. data/rakelib/lib/generate/doc/static_box_sizer.yaml +22 -0
  123. data/rakelib/lib/generate/doc/svg_file_dc.yaml +11 -0
  124. data/rakelib/lib/generate/doc/text_ctrl.yaml +19 -0
  125. data/rakelib/lib/generate/doc/text_entry.yaml +42 -0
  126. data/rakelib/lib/generate/doc/text_entry_dialog.yaml +17 -0
  127. data/rakelib/lib/generate/doc/timer_event.yaml +28 -0
  128. data/rakelib/lib/generate/doc/tool_bar.yaml +35 -0
  129. data/rakelib/lib/generate/doc/top_level_window.yaml +23 -0
  130. data/rakelib/lib/generate/doc/validator.yaml +12 -0
  131. data/rakelib/lib/generate/doc/variant.yaml +29 -0
  132. data/rakelib/lib/generate/doc/window.yaml +249 -0
  133. data/rakelib/lib/generate/doc/wizard_page_simple.yaml +14 -0
  134. data/rakelib/lib/generate/doc/xml_node.yaml +7 -0
  135. data/rakelib/lib/generate/doc/xml_resource.yaml +27 -0
  136. data/rakelib/lib/generate/doc.rb +36 -2
  137. data/rakelib/lib/generate/interface.rb +11 -10
  138. data/rakelib/lib/specs/interfaces.rb +5 -1
  139. data/rakelib/lib/swig_runner.rb +37 -0
  140. data/samples/aui/aui.rb +432 -363
  141. data/samples/propgrid/propgrid.rb +3 -0
  142. data/samples/sampler/editor.rb +33 -25
  143. data/samples/sampler/sample.rb +2 -2
  144. data/samples/sampler/stc_editor.rb +4 -2
  145. data/tests/lib/item_container_tests.rb +82 -0
  146. data/tests/lib/text_entry_tests.rb +80 -0
  147. data/tests/lib/wxapp_runner.rb +12 -0
  148. data/tests/lib/wxframe_runner.rb +89 -4
  149. data/tests/test_art.rb +9 -0
  150. data/tests/test_box_sizer.rb +161 -0
  151. data/tests/test_ext_controls.rb +28 -0
  152. data/tests/test_font.rb +239 -0
  153. data/tests/test_grid_sizer.rb +148 -0
  154. data/tests/test_intl.rb +5 -1
  155. data/tests/test_list_ctrl.rb +53 -0
  156. data/tests/test_log.rb +163 -0
  157. data/tests/test_std_controls.rb +321 -37
  158. data/tests/test_timer.rb +95 -0
  159. data/tests/test_window.rb +340 -0
  160. metadata +85 -2
@@ -603,6 +603,9 @@ class FormMain < Wx::Frame
603
603
  menuHelp = Wx::Menu.new
604
604
 
605
605
  menuHelp.append(ID::ABOUT, '&About', 'Show about dialog')
606
+ if Wx::PLATFORM == 'WXOSX'
607
+ Wx.get_app.mac_about_menu_itemid = ID::ABOUT
608
+ end
606
609
 
607
610
  menuTools1.append(ID::APPENDPROP, 'Append New Property')
608
611
  menuTools1.append(ID::APPENDCAT, "Append New Category\tCtrl-S")
@@ -34,8 +34,8 @@ module WxRuby
34
34
  end
35
35
 
36
36
  class SampleEditPanel
37
- def initialize(parent, sample)
38
- @frame = parent
37
+ def initialize(frame, parent, sample)
38
+ @frame = frame
39
39
  @sample = sample
40
40
  @splitter = Wx::SplitterWindow.new(parent, Wx::ID_ANY)
41
41
 
@@ -67,6 +67,8 @@ module WxRuby
67
67
  @edt_book.set_selection(0)
68
68
  end
69
69
 
70
+ attr_reader :splitter
71
+
70
72
  def add_editor_page(filename, pgnr)
71
73
  panel = Wx::Panel.new(@edt_book, Wx::ID_ANY)
72
74
  edt_sizer = Wx::HBoxSizer.new
@@ -306,30 +308,36 @@ module WxRuby
306
308
  menuBar.append(menuHelp, "&Help")
307
309
  set_menu_bar(menuBar)
308
310
 
309
- tb = create_tool_bar(Wx::TB_HORIZONTAL | Wx::NO_BORDER | Wx::TB_FLAT)
310
- tb.tool_bitmap_size = [ 16, 16 ]
311
- tb.add_tool(ID::SAVE, 'Save', bitmap(:filesave), 'Save the sample to a local folder')
312
- tb.add_tool(ID::RUN, 'Run', bitmap(:play), 'Run the (changed) sample')
313
- tb.add_separator
314
- tb.add_tool(ID::UNDO, 'Undo', bitmap(:undo), 'Undo change')
315
- tb.add_tool(ID::REDO, 'Redo', bitmap(:redo), 'Redo change')
316
- tb.add_separator
317
- tb.add_tool(ID::COPY, 'Copy', bitmap(:copy), 'Copy selection')
318
- tb.add_tool(ID::CUT, 'Cut', bitmap(:cut), 'Cut selection')
319
- tb.add_tool(ID::PASTE, 'Paste', bitmap(:paste), 'Paste selection')
320
- tb.add_separator
321
- tb.add_tool(ID::FIND, 'Find', bitmap(:find), 'Show Find Dialog')
322
- tb.add_tool(ID::FIND_NEXT, 'FindNext', bitmap(:forward), 'Find next occurrence of the search phrase')
323
- tb.add_tool(ID::FIND_PREV, 'FindPrev', bitmap(:back), 'Find previous occurrence of the search phrase')
324
- tb.add_tool(ID::REPLACE, 'Replace', bitmap(:findrepl), 'Show Replace Dialog')
325
- tb.realize
311
+ panel = Wx::Panel.new(self)
312
+ panel_szr = Wx::VBoxSizer.new
313
+ @tbar = Wx::ToolBar.new(panel, style: Wx::TB_HORIZONTAL | Wx::NO_BORDER | Wx::TB_FLAT)
314
+ @tbar.tool_bitmap_size = [ 16, 16 ]
315
+ @tbar.add_tool(ID::SAVE, 'Save', bitmap(:filesave), 'Save the sample to a local folder')
316
+ @tbar.add_tool(ID::RUN, 'Run', bitmap(:play), 'Run the (changed) sample')
317
+ @tbar.add_separator
318
+ @tbar.add_tool(ID::UNDO, 'Undo', bitmap(:undo), 'Undo change')
319
+ @tbar.add_tool(ID::REDO, 'Redo', bitmap(:redo), 'Redo change')
320
+ @tbar.add_separator
321
+ @tbar.add_tool(ID::COPY, 'Copy', bitmap(:copy), 'Copy selection')
322
+ @tbar.add_tool(ID::CUT, 'Cut', bitmap(:cut), 'Cut selection')
323
+ @tbar.add_tool(ID::PASTE, 'Paste', bitmap(:paste), 'Paste selection')
324
+ @tbar.add_separator
325
+ @tbar.add_tool(ID::FIND, 'Find', bitmap(:find), 'Show Find Dialog')
326
+ @tbar.add_tool(ID::FIND_NEXT, 'FindNext', bitmap(:forward), 'Find next occurrence of the search phrase')
327
+ @tbar.add_tool(ID::FIND_PREV, 'FindPrev', bitmap(:back), 'Find previous occurrence of the search phrase')
328
+ @tbar.add_tool(ID::REPLACE, 'Replace', bitmap(:findrepl), 'Show Replace Dialog')
329
+ @tbar.realize
330
+ panel_szr.add(@tbar)
331
+
332
+ # Create the editor panel
333
+ @editors = SampleEditPanel.new(self, panel, @sample)
334
+ panel_szr.add(@editors.splitter, 1, Wx::GROW, 0)
335
+
336
+ panel.set_sizer(panel_szr)
326
337
 
327
338
  create_status_bar(1)
328
339
  set_status_text("Welcome to wxRuby Sample editor.")
329
340
 
330
- # Create the editor panel
331
- @editors = SampleEditPanel.new(self, @sample)
332
-
333
341
  evt_idle(:on_idle)
334
342
 
335
343
  evt_update_editor_ui(:on_update_editor_ui)
@@ -382,15 +390,15 @@ module WxRuby
382
390
  def update_undo_redo(f_undo, f_redo)
383
391
  @m_undo.enable(f_undo)
384
392
  @m_redo.enable(f_redo)
385
- self.tool_bar.enable_tool(ID::UNDO, f_undo)
386
- self.tool_bar.enable_tool(ID::REDO, f_redo)
393
+ @tbar.enable_tool(ID::UNDO, f_undo)
394
+ @tbar.enable_tool(ID::REDO, f_redo)
387
395
  set_status_text('')
388
396
  end
389
397
  private :update_undo_redo
390
398
 
391
399
  def update_paste(f_paste)
392
400
  @m_paste.enable(f_paste)
393
- self.tool_bar.enable_tool(ID::PASTE, f_paste)
401
+ @tbar.enable_tool(ID::PASTE, f_paste)
394
402
  set_status_text('')
395
403
  end
396
404
 
@@ -293,7 +293,7 @@ module WxRuby
293
293
  category.modulize!
294
294
  Dir[File.join(entry, '*.rb')].each do |rb|
295
295
  # only if this is a file (paranoia check) and contains 'include WxRuby::Sample'
296
- if File.file?(rb) && (sample_lns = File.readlines(rb)).any? { |ln| /\s+include\s+WxRuby::Sample/ =~ ln }
296
+ if File.file?(rb) && (sample_lns = File.readlines(rb, encoding: 'utf-8')).any? { |ln| /\s+include\s+WxRuby::Sample/ =~ ln }
297
297
  # register currently required files
298
298
  cur_loaded = ::Set.new($LOADED_FEATURES)
299
299
  @loading_sample = rb
@@ -302,7 +302,7 @@ module WxRuby
302
302
  # in the class/module scope in which the dialog class is defined working from the dialog class name;
303
303
  # this will fail for anonymous modules as these cannot be identified by name)
304
304
  sample_mod = Sample.const_set("SampleLoader_#{File.basename(rb, '.*').modulize!}", Module.new)
305
- sample_mod.module_eval File.read(rb), rb, 1
305
+ sample_mod.module_eval File.read(rb, encoding: 'utf-8'), rb, 1
306
306
  # determine additionally required files
307
307
  new_loaded = ::Set.new($LOADED_FEATURES) - cur_loaded
308
308
  sample_captures.each do |mod|
@@ -114,8 +114,9 @@ module WxRuby
114
114
 
115
115
  def default_theme
116
116
  c_maroon = Wx::Colour.new('Maroon')
117
- style_set_foreground(Wx::STC::STC_STYLE_DEFAULT, Wx::BLACK);
118
- style_set_background(Wx::STC::STC_STYLE_DEFAULT, Wx::WHITE);
117
+ style_set_foreground(Wx::STC::STC_STYLE_DEFAULT, Wx::BLACK)
118
+ style_set_background(Wx::STC::STC_STYLE_DEFAULT, Wx::WHITE)
119
+ set_caret_foreground(Wx::BLACK)
119
120
  style_clear_all
120
121
  style_set_foreground(Wx::STC::STC_STYLE_LINENUMBER, Wx::Colour.new('Dark Grey'))
121
122
  style_set_background(Wx::STC::STC_STYLE_LINENUMBER, Wx::WHITE);
@@ -160,6 +161,7 @@ module WxRuby
160
161
  c_str = Wx::Colour.new('Lime Green')
161
162
  style_set_background(Wx::STC::STC_STYLE_DEFAULT, bg)
162
163
  style_set_foreground(Wx::STC::STC_STYLE_DEFAULT, Wx::WHITE)
164
+ set_caret_foreground(Wx::WHITE)
163
165
  style_clear_all
164
166
  style_set_background(Wx::STC::STC_STYLE_LINENUMBER, bg)
165
167
  style_set_foreground(Wx::STC::STC_STYLE_LINENUMBER, Wx::WHITE)
@@ -0,0 +1,82 @@
1
+
2
+ module ItemContainerTests
3
+
4
+ def test_ic_append
5
+ container.append("item 0")
6
+
7
+ assert_equal("item 0", container.get_string(0))
8
+
9
+ container.append(['item 1', 'item 2'])
10
+
11
+ assert_equal("item 1", container.get_string(1))
12
+ assert_equal("item 2", container.get_string(2))
13
+
14
+ container.append(['item 3', 'item 4'])
15
+
16
+ assert_equal("item 3", container.get_string(3))
17
+ assert_equal("item 4", container.get_string(4))
18
+ end
19
+
20
+ def test_ic_insert
21
+ assert_equal(0, container.insert("item 0", 0))
22
+ assert_equal("item 0", container.get_string(0))
23
+
24
+ assert_equal(1, container.insert(['item 1', 'item 2'], 0))
25
+
26
+ assert_equal("item 1", container.get_string(0))
27
+ assert_equal("item 2", container.get_string(1))
28
+
29
+ assert_equal(2, container.insert(['item 3', 'item 4'], 1))
30
+ assert_equal("item 3", container.get_string(1))
31
+ assert_equal("item 4", container.get_string(2))
32
+ end
33
+
34
+ def test_ic_count
35
+ assert(container.empty?)
36
+ assert_with_assertion_failure { container.get_string(0) }
37
+
38
+ container.append(['item 0', 'item 1', 'item 2', 'item 3'])
39
+
40
+ assert(!container.empty?)
41
+ assert_equal(4, container.count)
42
+
43
+ container.delete(0)
44
+
45
+ assert_equal(3, container.count)
46
+
47
+ container.delete(0)
48
+ container.delete(0)
49
+
50
+ assert_equal(1, container.count)
51
+
52
+ container.insert(['item 0', 'item 1', 'item 2', 'item 3'], 1)
53
+
54
+ assert_equal(5, container.count)
55
+ assert_with_assertion_failure { container.get_string(10) }
56
+ end
57
+
58
+ def test_ic_item_selection
59
+ container.append(['item 0', 'item 1', 'item 2', 'ITEM 2'])
60
+
61
+ container.set_selection(Wx::NOT_FOUND)
62
+ assert_equal(Wx::NOT_FOUND, container.get_selection)
63
+ assert_equal("", container.get_string_selection)
64
+
65
+ container.set_selection(1)
66
+ assert_equal(1, container.get_selection)
67
+ assert_equal("item 1", container.get_string_selection)
68
+
69
+ assert(container.set_string_selection("item 2"))
70
+ assert_equal(2, container.get_selection)
71
+ assert_equal("item 2", container.get_string_selection)
72
+
73
+ # Check that selecting a non-existent item fails.
74
+ assert(!container.set_string_selection("bloordyblop"))
75
+
76
+ # Check that SetStringSelection() is case-insensitive.
77
+ assert(container.set_string_selection("ITEM 2"))
78
+ assert_equal(2, container.get_selection)
79
+ assert_equal("item 2", container.get_string_selection)
80
+ end
81
+
82
+ end
@@ -0,0 +1,80 @@
1
+
2
+ module TextEntryTests
3
+
4
+ def test_te_set_value
5
+ text_entry.set_focus # removes the 'Hint' test which in GTK2 causes problems
6
+ assert(text_entry.empty?)
7
+
8
+ text_entry.value = 'foo'
9
+ assert_equal('foo', text_entry.value)
10
+
11
+ text_entry.value = ''
12
+ assert(text_entry.empty?)
13
+
14
+ text_entry.value = 'hi'
15
+ assert_equal('hi', text_entry.value)
16
+
17
+ text_entry.value = 'bye'
18
+ assert_equal('bye', text_entry.value)
19
+ end
20
+
21
+ def test_te_text_change_events
22
+ updates = count_events(text_entry, :evt_text) do |c_upd|
23
+
24
+ # WXQT only sends event when text changes
25
+ unless Wx::PLATFORM == 'WXQT'
26
+ text_entry.value = ''
27
+ assert_equal(1, c_upd.count)
28
+ c_upd.count = 0
29
+ end
30
+
31
+ text_entry.value = 'foo'
32
+ assert_equal(1, c_upd.count)
33
+ c_upd.count = 0
34
+
35
+ # WXQT only sends event when text changes
36
+ unless Wx::PLATFORM == 'WXQT'
37
+ text_entry.value = 'foo'
38
+ assert_equal(1, c_upd.count)
39
+ c_upd.count = 0
40
+ end
41
+
42
+ text_entry.value = ''
43
+ assert_equal(1, c_upd.count)
44
+ c_upd.count = 0
45
+
46
+ text_entry.change_value('bar')
47
+ assert_equal(0, c_upd.count)
48
+
49
+ text_entry.append_text('bar')
50
+ assert_equal(1, c_upd.count)
51
+ c_upd.count = 0
52
+
53
+ text_entry.replace(3, 6, 'baz')
54
+ assert_equal(1, c_upd.count)
55
+ c_upd.count = 0
56
+
57
+ text_entry.remove(0, 3)
58
+ assert_equal(1, c_upd.count)
59
+ c_upd.count = 0
60
+
61
+ text_entry.write_text('foo')
62
+ assert_equal(1, c_upd.count)
63
+ c_upd.count = 0
64
+
65
+ text_entry.clear
66
+ assert_equal(1, c_upd.count)
67
+ c_upd.count = 0
68
+
69
+ text_entry.change_value('')
70
+ assert_equal(0, c_upd.count)
71
+
72
+ text_entry.change_value('non-empty')
73
+ assert_equal(0, c_upd.count)
74
+
75
+ text_entry.change_value('')
76
+ assert_equal(0, c_upd.count)
77
+ end
78
+ end
79
+
80
+ end
@@ -60,5 +60,17 @@ module Test
60
60
  end
61
61
  end
62
62
  end
63
+
64
+ class TestCase
65
+
66
+ def self.is_ci_build?
67
+ !!ENV['GITHUB_ACTION']
68
+ end
69
+
70
+ def is_ci_build?
71
+ TestCase.is_ci_build?
72
+ end
73
+
74
+ end
63
75
  end
64
76
  end
@@ -6,7 +6,27 @@ module WxRuby
6
6
  module Test
7
7
 
8
8
  class App < Wx::App
9
+
10
+ Assert = Struct.new(:file, :line, :func, :condition, :message)
11
+
12
+ class AssertFailureSink
13
+ def initialize
14
+ @asserts = []
15
+ end
16
+
17
+ attr_reader :asserts
18
+
19
+ def asserts?
20
+ !@asserts.empty?
21
+ end
22
+
23
+ def <<(assert)
24
+ @asserts << assert
25
+ end
26
+ end
27
+
9
28
  def on_init
29
+ @assert_sink = nil
10
30
  @tests_have_run = false
11
31
  evt_idle :on_idle
12
32
  @frame = Wx::Frame.new(nil, size: [600,400])
@@ -21,6 +41,30 @@ module WxRuby
21
41
  end
22
42
 
23
43
  attr_reader :frame
44
+
45
+ def open_assert_sink
46
+ @assert_sink = AssertFailureSink.new
47
+ end
48
+
49
+ def close_assert_sink
50
+ @assert_sink = nil
51
+ end
52
+
53
+ def asserts
54
+ @assert_sink.asserts
55
+ end
56
+
57
+ def asserts?
58
+ @assert_sink.asserts?
59
+ end
60
+
61
+ def on_assert_failure(file, line, func, condition, message)
62
+ if @assert_sink
63
+ @assert_sink << Assert.new(file, line, func, condition, message)
64
+ else
65
+ super
66
+ end
67
+ end
24
68
  end
25
69
 
26
70
  class GUITests < ::Test::Unit::TestCase
@@ -38,20 +82,61 @@ module WxRuby
38
82
  def inc
39
83
  @count +=1
40
84
  end
85
+
86
+ def wait_event(msec)
87
+ start = Time.now
88
+ msec /= 1000.0
89
+ while (Time.now - start) < msec
90
+ Wx.get_app.yield
91
+ if @count > 0
92
+ raise StandardError.new("Too many events. Expected a single one.") unless @count == 1
93
+ @count = 0
94
+ return true
95
+ end
96
+ sleep(50.0/1000.0)
97
+ end
98
+ false
99
+ end
100
+ end
101
+
102
+ def self.has_ui_simulator?
103
+ Wx.has_feature?(:USE_UIACTIONSIMULATOR) && (Wx::PLATFORM != 'WXOSX' || Wx::WXWIDGETS_VERSION >= '3.3')
104
+ end
105
+
106
+ def has_ui_simulator?
107
+ GUITests.has_ui_simulator?
41
108
  end
42
109
 
43
110
  def count_events(win, evt, id1=Wx::ID_ANY, id2=nil)
44
111
  return 0 unless block_given?
45
112
  evt_count = EventCounter.new
46
- if id2.nil?
47
- win.event_handler.send(evt.to_sym, id1, ->(_evt){ evt_count.inc })
113
+ if Wx::EvtHandler.event_type_arity(evt) == 0
114
+ win.event_handler.send(evt.to_sym, ->(evt){ evt_count.inc; evt.skip if !evt.command_event? })
115
+ elsif id2.nil?
116
+ win.event_handler.send(evt.to_sym, id1, ->(evt){ evt_count.inc; evt.skip if !evt.command_event? })
48
117
  else
49
- win.event_handler.send(evt.to_sym, id1, id2, ->(_evt){ evt_count.inc })
118
+ win.event_handler.send(evt.to_sym, id1, id2, ->(evt){ evt_count.inc; evt.skip if !evt.command_event? })
119
+ end
120
+ begin
121
+ yield evt_count
122
+ ensure
123
+ win.event_handler.disconnect(id1, id2 || Wx::ID_ANY, evt.to_sym)
50
124
  end
51
- yield evt_count
52
125
  evt_count.count
53
126
  end
54
127
 
128
+ def assert_with_assertion_failure(max_asserts: nil, func: nil, &block)
129
+ Wx.get_app.open_assert_sink
130
+ begin
131
+ block.call
132
+ raise StandardError.new('No Wx assertion failure captured!') unless Wx.get_app.asserts?
133
+ raise StandardError.new("Too many assertion failures captures! Expected max #{max_asserts}, captured #{Wx.get_app.asserts.size}") if max_asserts && max_asserts < Wx.get_app.asserts.size
134
+ raise StandardError.new("Unexpected assertions failures. Expected assertion failure from #{func} but captured assertions from #{Wx.get_app.asserts.collect {|a| a.func } }") if func && !Wx.get_app.asserts.any? { |a| a.func == func }
135
+ ensure
136
+ Wx.get_app.close_assert_sink
137
+ end
138
+ end
139
+
55
140
  end
56
141
 
57
142
  end
data/tests/test_art.rb CHANGED
@@ -76,6 +76,15 @@ class TestArt < Test::Unit::TestCase
76
76
  end
77
77
  end
78
78
 
79
+ def test_image_histogram
80
+ img = Wx.Image(:wxruby, Wx::BitmapType::BITMAP_TYPE_JPEG)
81
+ img_hist = img.compute_histogram
82
+ assert(img_hist.is_a?(::Hash))
83
+ assert(img_hist.is_a?(Wx::Image::Histogram))
84
+ assert(img_hist.size > 0)
85
+ assert(img_hist.values.all? { |index, value| index>=0 && value>=1 })
86
+ end
87
+
79
88
  def test_art
80
89
  art = nil
81
90
  assert_nothing_raised do
@@ -0,0 +1,161 @@
1
+
2
+ require_relative './lib/wxframe_runner'
3
+
4
+ class BoxSizerTests < WxRuby::Test::GUITests
5
+
6
+ def setup
7
+ super
8
+ @win = Wx::Window.new(test_frame, Wx::ID_ANY)
9
+ @sizer = Wx::HBoxSizer.new
10
+ @win.set_client_size(127, 35)
11
+ @win.sizer = @sizer
12
+ end
13
+
14
+ def cleanup
15
+ test_frame.destroy_children
16
+ @win = nil
17
+ @sizer = nil
18
+ super
19
+ end
20
+
21
+ attr_reader :win, :sizer
22
+
23
+ def test_size
24
+ sizeTotal = win.get_client_size
25
+ sizeChild = sizeTotal / 2
26
+
27
+ child = Wx::Window.new(win, Wx::ID_ANY, Wx::DEFAULT_POSITION, sizeChild)
28
+ sizer.add(child)
29
+ win.layout
30
+ assert(child.size == sizeChild)
31
+
32
+ sizer.clear
33
+ sizer.add(child, Wx::SizerFlags.new(1))
34
+ win.layout
35
+ assert(child.size == [sizeTotal.x, sizeChild.y])
36
+
37
+ sizer.clear
38
+ sizer.add(child, Wx::SizerFlags.new(1).expand)
39
+ win.layout
40
+ assert(child.size == sizeTotal)
41
+
42
+ sizer.clear
43
+ sizer.add(child, Wx::SizerFlags.new)
44
+ sizer.set_item_min_size(child, sizeTotal*2)
45
+ win.layout
46
+ assert(child.size == sizeTotal)
47
+
48
+ sizer.clear
49
+ sizer.add(child, Wx::SizerFlags.new.expand)
50
+ sizer.set_item_min_size(child, sizeTotal*2)
51
+ win.layout
52
+ assert(child.size == sizeTotal)
53
+ end
54
+
55
+ class << self
56
+
57
+ def _ltd(*args)
58
+ @ltd_klass ||= Struct.new(:prop, :minsize, :x, :sizes, :dont_permute) do
59
+ def add_to_sizer(sizer, win, n)
60
+ sizer.add(win, Wx::SizerFlags.new(prop[n]))
61
+ sizer.set_item_min_size(win, Wx::Size.new(minsize[n], -1))
62
+ end
63
+ end
64
+ @ltd_klass.new(*args)
65
+ end
66
+
67
+ end
68
+
69
+ LayoutTestData = [
70
+ # some really simple cases (no need to permute those, they're
71
+ # symmetrical anyhow)
72
+ _ltd( [ 1, 1, 1, ], [ 50, 50, 50, ], 150, [ 50, 50, 50, ], true ),
73
+ _ltd( [ 2, 2, 2, ], [ 50, 50, 50, ], 600, [ 200, 200, 200, ], true ),
74
+
75
+ # items with different proportions and min sizes when there is enough
76
+ # space to lay them out
77
+ _ltd( [ 1, 2, 3, ], [ 0, 0, 0, ], 600, [ 100, 200, 300, ] ),
78
+ _ltd( [ 1, 2, 3, ], [ 100, 100, 100, ], 600, [ 100, 200, 300, ] ),
79
+ _ltd( [ 1, 2, 3, ], [ 100, 50, 50, ], 600, [ 100, 200, 300, ] ),
80
+ _ltd( [ 0, 1, 1, ], [ 200, 100, 100, ], 600, [ 200, 200, 200, ] ),
81
+ _ltd( [ 0, 1, 2, ], [ 300, 100, 100, ], 600, [ 300, 100, 200, ] ),
82
+ _ltd( [ 0, 1, 1, ], [ 100, 50, 50, ], 300, [ 100, 100, 100, ] ),
83
+ _ltd( [ 0, 1, 2, ], [ 100, 50, 50, ], 400, [ 100, 100, 200, ] ),
84
+
85
+ # cases when there is not enough space to lay out the items correctly
86
+ # while still respecting their min sizes
87
+ _ltd( [ 0, 1, 1, ], [ 100, 150, 50, ], 300, [ 100, 150, 50, ] ),
88
+ _ltd( [ 1, 2, 3, ], [ 100, 100, 100, ], 300, [ 100, 100, 100, ] ),
89
+ _ltd( [ 1, 2, 3, ], [ 100, 50, 50, ], 300, [ 100, 80, 120, ] ),
90
+ _ltd( [ 1, 2, 3, ], [ 100, 10, 10, ], 150, [ 100, 20, 30, ] ),
91
+
92
+ # cases when there is not enough space even for the min sizes (don't
93
+ # permute in these cases as the layout does depend on the item order
94
+ # because the first ones have priority)
95
+ _ltd( [ 1, 2, 3, ], [ 100, 50, 50, ], 150, [ 100, 50, 0, ], true ),
96
+ _ltd( [ 1, 2, 3, ], [ 100, 100, 100, ], 200, [ 100, 100, 0, ], true ),
97
+ _ltd( [ 1, 2, 3, ], [ 100, 100, 100, ], 150, [ 100, 50, 0, ], true ),
98
+ _ltd( [ 1, 2, 3, ], [ 100, 100, 100, ], 50, [ 50, 0, 0, ], true ),
99
+ _ltd( [ 1, 2, 3, ], [ 100, 100, 100, ], 0, [ 0, 0, 0, ], true ),
100
+ ]
101
+
102
+ def test_size_3
103
+ child = [Wx::Window.new(win, Wx::ID_ANY),
104
+ Wx::Window.new(win, Wx::ID_ANY),
105
+ Wx::Window.new(win, Wx::ID_ANY)]
106
+
107
+ LayoutTestData.each_with_index do |ltd, i|
108
+ # the results shouldn't depend on the order of items except in the
109
+ # case when there is not enough space for even the fixed width items
110
+ # (in which case the first ones might get enough of it but not the
111
+ # last ones) so test a couple of permutations of test data unless
112
+ # specifically disabled for this test case
113
+ 3.times do |p|
114
+ case p
115
+ when 0
116
+ # nothing, use original data
117
+ when 1
118
+ # exchange first and last elements
119
+ ltd.prop[0], ltd.prop[2] = ltd.prop[2], ltd.prop[0]
120
+ ltd.minsize[0], ltd.minsize[2] = ltd.minsize[2], ltd.minsize[0]
121
+ ltd.sizes[0], ltd.sizes[2] = ltd.sizes[2], ltd.sizes[0]
122
+ when 2
123
+ # exchange the original third and second elements
124
+ ltd.prop[0], ltd.prop[1] = ltd.prop[1], ltd.prop[0]
125
+ ltd.minsize[0], ltd.minsize[1] = ltd.minsize[1], ltd.minsize[0]
126
+ ltd.sizes[0], ltd.sizes[1] = ltd.sizes[1], ltd.sizes[0]
127
+ end
128
+
129
+ sizer.clear
130
+
131
+ child.each_with_index { |c, j| ltd.add_to_sizer(sizer, c, j) }
132
+
133
+ win.set_client_size(ltd.x, -1)
134
+ win.layout
135
+
136
+ child.each_with_index do |c, j|
137
+ assert_equal(ltd.sizes[j], c.size.x,
138
+ "test #{i}, permutation #{p}: wrong size for child #{j} for total size #{ltd.x}")
139
+ end
140
+
141
+ # don't try other permutations if explicitly disabled
142
+ break if ltd.dont_permute
143
+ end
144
+ end
145
+ end
146
+
147
+ def test_min_size
148
+ child = Wx::Window.new(win, Wx::ID_ANY)
149
+ child.set_initial_size([10, -1])
150
+ sizer.add(child)
151
+
152
+ # Setting minimal size explicitly must make get_min_size() return at least
153
+ # this size even if it needs a much smaller one.
154
+ sizer.set_min_size(100, 0)
155
+ assert(sizer.get_min_size.x == 100)
156
+
157
+ sizer.layout
158
+ assert(sizer.min_size.x == 100)
159
+ end
160
+
161
+ end
@@ -0,0 +1,28 @@
1
+
2
+ require_relative './lib/wxframe_runner'
3
+ require_relative './lib/text_entry_tests'
4
+
5
+ class SearchCtrlTests < WxRuby::Test::GUITests
6
+
7
+ include TextEntryTests
8
+
9
+ def setup
10
+ super
11
+ @search = Wx::SearchCtrl.new(test_frame, name: 'SearchCtrl')
12
+ Wx.get_app.yield
13
+ end
14
+
15
+ def cleanup
16
+ @search.destroy
17
+ Wx.get_app.yield
18
+ super
19
+ end
20
+
21
+ attr_reader :search
22
+ alias :text_entry :search
23
+
24
+ def test_search
25
+ assert_equal('', search.get_value)
26
+ end
27
+
28
+ end