From c4c7535e012d6be5adb29d107dcab9c9b0701e52 Mon Sep 17 00:00:00 2001 From: Ieva C Date: Wed, 20 May 2020 20:16:56 +0100 Subject: [PATCH 1/6] Add more tests for Enum Editor --- traitsui/tests/editors/test_enum_editor.py | 412 +++++++++++++++++---- 1 file changed, 343 insertions(+), 69 deletions(-) diff --git a/traitsui/tests/editors/test_enum_editor.py b/traitsui/tests/editors/test_enum_editor.py index 85bf6c159..46a33abea 100644 --- a/traitsui/tests/editors/test_enum_editor.py +++ b/traitsui/tests/editors/test_enum_editor.py @@ -3,7 +3,7 @@ from pyface.gui import GUI -from traits.api import Enum, HasTraits +from traits.api import Enum, HasTraits, Int, List from traitsui.api import EnumEditor, UItem, View from traitsui.tests._tools import ( is_current_backend_qt4, @@ -21,31 +21,24 @@ class EnumModel(HasTraits): value = Enum("one", "two", "three", "four") -simple_view = View(UItem("value", style="simple"), resizable=True) +def get_view(style): + return View(UItem("value", style=style), resizable=True) -simple_evaluate_view = View( - UItem( - "value", - editor=EnumEditor( - evaluate=True, values=["one", "two", "three", "four"] +def get_evaluate_view(style, auto_set=True, mode="radio"): + return View( + UItem( + "value", + editor=EnumEditor( + evaluate=True, + values=["one", "two", "three", "four"], + auto_set=auto_set, + mode=mode, + ), + style=style, ), - style="simple", - ), - resizable=True, -) - - -simple_evaluate_view_popup = View( - UItem( - "value", - editor=EnumEditor( - evaluate=True, values=["one", "two", "three", "four"] - ), - style="simple", - ), - resizable=True, -) + resizable=True, + ) def get_combobox_text(combobox): @@ -101,18 +94,180 @@ def set_combobox_index(combobox, idx): combobox.setCurrentIndex(idx) -class TestEnumEditor(unittest.TestCase): - def check_enum_text_update(self, view): +def finish_combobox_text_entry(combobox): + """ Finish text entry given combobox. """ + if is_current_backend_wx(): + raise unittest.SkipTest("Test not implemented for wx") + + elif is_current_backend_qt4(): + combobox.lineEdit().editingFinished.emit() + + +def get_all_button_status(widget): + """ Gets status of all radio buttons in the layout of a given widget.""" + if is_current_backend_wx(): + raise unittest.SkipTest("Test not implemented for wx") + + elif is_current_backend_qt4(): + layout = widget.layout() + button_status = [] + for i in range(layout.count()): + button_status.append(layout.itemAt(i).widget().isChecked()) + return button_status + + +def click_radio_button(widget, button_idx): + """ Simulate a radio button click given widget and button number.""" + if is_current_backend_wx(): + raise unittest.SkipTest("Test not implemented for wx") + + elif is_current_backend_qt4(): + widget.layout().itemAt(button_idx).widget().click() + + +def get_list_widget_text(list_widget): + """ Return the text of currently selected item in given list widget. """ + if is_current_backend_wx(): + raise unittest.SkipTest("Test not implemented for wx") + + elif is_current_backend_qt4(): + return list_widget.currentItem().text() + + +def set_list_widget_selected_index(list_widget, idx): + """ Set the choice index given a list widget control and index number. """ + if is_current_backend_wx(): + raise unittest.SkipTest("Test not implemented for wx") + + elif is_current_backend_qt4(): + list_widget.setCurrentRow(idx) + + +class TestEnumEditorMapping(unittest.TestCase): + + def setup_ui(self, model, view): + ui = model.edit_traits(view=view) + self.addCleanup(ui.dispose) + return ui.get_editors("value")[0] + + def check_enum_mappings_value_change(self, style, mode): + class IntEnumModel(HasTraits): + value = Int() + + enum_editor_factory = EnumEditor( + values=[0, 1], + format_func=lambda v: str(bool(v)).upper(), + mode=mode + ) + formatted_view = View( + UItem( + "value", + editor=enum_editor_factory, + style=style, + ) + ) + + with store_exceptions_on_all_threads(): + editor = self.setup_ui(IntEnumModel(), formatted_view) + + with self.assertRaises(AssertionError): # FIXME issue #782 + self.assertEqual(editor.names, ["FALSE", "TRUE"]) + self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) + self.assertEqual( + editor.inverse_mapping, {0: "FALSE", 1: "TRUE"} + ) + self.assertEqual(editor.names, ["0", "1"]) + self.assertEqual(editor.mapping, {"0": 0, "1": 1}) + self.assertEqual( + editor.inverse_mapping, {0: "0", 1: "1"} + ) + + enum_editor_factory.values = [1, 0] + + self.assertEqual(editor.names, ["TRUE", "FALSE"]) + self.assertEqual(editor.mapping, {"TRUE": 1, "FALSE": 0}) + self.assertEqual( + editor.inverse_mapping, {1: "TRUE", 0: "FALSE"} + ) + + def check_enum_mappings_name_change(self, style, mode): + class IntEnumModel(HasTraits): + value = Int() + possible_values = List([0, 1]) + + formatted_view = View( + UItem( + 'value', + editor=EnumEditor( + name="object.possible_values", + format_func=lambda v: str(bool(v)).upper(), + mode=mode + ), + style=style, + ) + ) + model = IntEnumModel() + + with store_exceptions_on_all_threads(): + editor = self.setup_ui(model, formatted_view) + + self.assertEqual(editor.names, ["FALSE", "TRUE"]) + self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) + self.assertEqual( + editor.inverse_mapping, {0: "FALSE", 1: "TRUE"} + ) + + model.possible_values = [1, 0] + + self.assertEqual(editor.names, ["TRUE", "FALSE"]) + self.assertEqual(editor.mapping, {"TRUE": 1, "FALSE": 0}) + self.assertEqual( + editor.inverse_mapping, {1: "TRUE", 0: "FALSE"} + ) + + @skip_if_null + def test_simple_editor_mapping_values(self): + self.check_enum_mappings_value_change("simple", "radio") + + @skip_if_null + def test_simple_editor_mapping_name(self): + self.check_enum_mappings_name_change("simple", "radio") + + @skip_if_null + def test_radio_editor_mapping_values(self): + self.check_enum_mappings_value_change("custom", "radio") + + @skip_if_null + def test_radio_editor_mapping_name(self): + self.check_enum_mappings_name_change("custom", "radio") + + @skip_if_null + def test_list_editor_mapping_values(self): + self.check_enum_mappings_value_change("custom", "list") + + @skip_if_null + def test_list_editor_mapping_name(self): + self.check_enum_mappings_name_change("custom", "list") + + +class TestSimpleEnumEditor(unittest.TestCase): + + def setup_gui(self, model, view): gui = GUI() + ui = model.edit_traits(view=view) + self.addCleanup(ui.dispose) + + gui.process_events() + editor = ui.get_editors("value")[0] + combobox = editor.control + + return gui, combobox + + def check_enum_text_update(self, view): enum_edit = EnumModel() with store_exceptions_on_all_threads(): - ui = enum_edit.edit_traits(view=view) - self.addCleanup(ui.dispose) - - gui.process_events() - editor = ui.get_editors("value")[0] - combobox = editor.control + gui, combobox = self.setup_gui(enum_edit, view) self.assertEqual(get_combobox_text(combobox), "one") @@ -122,16 +277,10 @@ def check_enum_text_update(self, view): self.assertEqual(get_combobox_text(combobox), "two") def check_enum_object_update(self, view): - gui = GUI() enum_edit = EnumModel() with store_exceptions_on_all_threads(): - ui = enum_edit.edit_traits(view=view) - self.addCleanup(ui.dispose) - - gui.process_events() - editor = ui.get_editors("value")[0] - combobox = editor.control + gui, combobox = self.setup_gui(enum_edit, view) self.assertEqual(enum_edit.value, "one") @@ -141,16 +290,10 @@ def check_enum_object_update(self, view): self.assertEqual(enum_edit.value, "two") def check_enum_index_update(self, view): - gui = GUI() enum_edit = EnumModel() with store_exceptions_on_all_threads(): - ui = enum_edit.edit_traits(view=view) - self.addCleanup(ui.dispose) - - gui.process_events() - editor = ui.get_editors("value")[0] - combobox = editor.control + gui, combobox = self.setup_gui(enum_edit, view) self.assertEqual(enum_edit.value, "one") @@ -160,16 +303,10 @@ def check_enum_index_update(self, view): self.assertEqual(enum_edit.value, "two") def check_enum_text_bad_update(self, view): - gui = GUI() enum_edit = EnumModel() with store_exceptions_on_all_threads(): - ui = enum_edit.edit_traits(view=view) - self.addCleanup(ui.dispose) - - gui.process_events() - editor = ui.get_editors("value")[0] - combobox = editor.control + gui, combobox = self.setup_gui(enum_edit, view) self.assertEqual(enum_edit.value, "one") @@ -180,46 +317,183 @@ def check_enum_text_bad_update(self, view): @skip_if_null def test_simple_enum_editor_text(self): - self.check_enum_text_update(simple_view) + self.check_enum_text_update(get_view("simple")) @skip_if_null def test_simple_enum_editor_index(self): - self.check_enum_index_update(simple_view) + self.check_enum_index_update(get_view("simple")) @skip_if_null @unittest.skipIf(is_windows, "Test needs fixing on windows") def test_simple_evaluate_editor_text(self): - self.check_enum_text_update(simple_evaluate_view) + self.check_enum_text_update(get_evaluate_view("simple")) @skip_if_null @unittest.skipIf(is_windows, "Test needs fixing on windows") def test_simple_evaluate_editor_index(self): - self.check_enum_index_update(simple_evaluate_view) + self.check_enum_index_update(get_evaluate_view("simple")) @skip_if_null def test_simple_evaluate_editor_bad_text(self): - self.check_enum_text_bad_update(simple_evaluate_view) + self.check_enum_text_bad_update(get_evaluate_view("simple")) @skip_if_null @unittest.skipIf(is_windows, "Test needs fixing on windows") def test_simple_evaluate_editor_object(self): - self.check_enum_object_update(simple_evaluate_view) + self.check_enum_object_update(get_evaluate_view("simple")) @skip_if_null - @unittest.skipIf(is_windows, "Test needs fixing on windows") - def test_simple_evaluate_popup_editor_text(self): - self.check_enum_text_update(simple_evaluate_view_popup) + def test_simple_evaluate_editor_object_no_auto_set(self): + view = get_evaluate_view("simple", auto_set=False) + enum_edit = EnumModel() + + with store_exceptions_on_all_threads(): + gui, combobox = self.setup_gui(enum_edit, view) + + self.assertEqual(enum_edit.value, "one") + + set_combobox_text(combobox, "two") + gui.process_events() + + self.assertEqual(enum_edit.value, "one") + + finish_combobox_text_entry(combobox) + gui.process_events() + + self.assertEqual(enum_edit.value, "two") @skip_if_null - @unittest.skipIf(is_windows, "Test needs fixing on windows") - def test_simple_evaluate_popup_editor_index(self): - self.check_enum_index_update(simple_evaluate_view_popup) + def test_simple_editor_resizable(self): + # Smoke test for `qt4.enum_editor.SimpleEditor.set_size_policy` + enum_edit = EnumModel() + resizable_view = View(UItem("value", style="simple", resizable=True)) + + with store_exceptions_on_all_threads(): + ui = enum_edit.edit_traits(view=resizable_view) + self.addCleanup(ui.dispose) + + +class TestRadioEnumEditor(unittest.TestCase): + + def setup_gui(self, model, view): + gui = GUI() + ui = model.edit_traits(view=view) + self.addCleanup(ui.dispose) + + gui.process_events() + editor = ui.get_editors("value")[0] + widget = editor.control + + return gui, widget @skip_if_null - def test_simple_evaluate_popup_editor_bad_text(self): - self.check_enum_text_bad_update(simple_evaluate_view_popup) + def test_radio_enum_editor_button_update(self): + enum_edit = EnumModel() + + with store_exceptions_on_all_threads(): + gui, widget = self.setup_gui(enum_edit, get_view("custom")) + + # The layout is: one, three, four \n two + self.assertEqual( + get_all_button_status(widget), [True, False, False, False] + ) + + enum_edit.value = "two" + gui.process_events() + + self.assertEqual( + get_all_button_status(widget), [False, False, False, True] + ) @skip_if_null - @unittest.skipIf(is_windows, "Test needs fixing on windows") - def test_simple_evaluate_popup_editor_object(self): - self.check_enum_object_update(simple_evaluate_view_popup) + def test_radio_enum_editor_pick(self): + enum_edit = EnumModel() + + with store_exceptions_on_all_threads(): + gui, widget = self.setup_gui(enum_edit, get_view("custom")) + + self.assertEqual(enum_edit.value, "one") + + # The layout is: one, three, four \n two + click_radio_button(widget, 3) + gui.process_events() + + self.assertEqual(enum_edit.value, "two") + + +class TestListEnumEditor(unittest.TestCase): + + def setup_gui(self, model, view): + gui = GUI() + ui = model.edit_traits(view=view) + self.addCleanup(ui.dispose) + + gui.process_events() + editor = ui.get_editors("value")[0] + list_widget = editor.control + + return gui, list_widget + + def check_enum_text_update(self, view): + enum_edit = EnumModel() + + with store_exceptions_on_all_threads(): + gui, list_widget = self.setup_gui(enum_edit, view) + + self.assertEqual(get_list_widget_text(list_widget), "one") + + enum_edit.value = "two" + gui.process_events() + + self.assertEqual(get_list_widget_text(list_widget), "two") + + def check_enum_index_update(self, view): + enum_edit = EnumModel() + + with store_exceptions_on_all_threads(): + gui, list_widget = self.setup_gui(enum_edit, view) + + self.assertEqual(enum_edit.value, "one") + + set_list_widget_selected_index(list_widget, 1) + gui.process_events() + + self.assertEqual(enum_edit.value, "two") + + @skip_if_null + def test_list_enum_editor_text(self): + view = View( + UItem( + "value", + editor=EnumEditor( + values=["one", "two", "three", "four"], + mode="list", + ), + style="custom", + ), + resizable=True, + ) + self.check_enum_text_update(view) + + @skip_if_null + def test_list_enum_editor_index(self): + view = View( + UItem( + "value", + editor=EnumEditor( + values=["one", "two", "three", "four"], + mode="list", + ), + style="custom", + ), + resizable=True, + ) + self.check_enum_index_update(view) + + @skip_if_null + def test_list_evaluate_editor_text(self): + self.check_enum_text_update(get_evaluate_view("custom", mode="list")) + + @skip_if_null + def test_list_evaluate_editor_index(self): + self.check_enum_index_update(get_evaluate_view("custom", mode="list")) From 39e143a1e870af85c50544ccfb273d26beb8271f Mon Sep 17 00:00:00 2001 From: Ieva C Date: Fri, 22 May 2020 16:45:04 +0100 Subject: [PATCH 2/6] Add wx EnumEditor tests --- traitsui/tests/editors/test_enum_editor.py | 112 +++++++++++++++++---- 1 file changed, 92 insertions(+), 20 deletions(-) diff --git a/traitsui/tests/editors/test_enum_editor.py b/traitsui/tests/editors/test_enum_editor.py index 46a33abea..aa68cb537 100644 --- a/traitsui/tests/editors/test_enum_editor.py +++ b/traitsui/tests/editors/test_enum_editor.py @@ -97,7 +97,10 @@ def set_combobox_index(combobox, idx): def finish_combobox_text_entry(combobox): """ Finish text entry given combobox. """ if is_current_backend_wx(): - raise unittest.SkipTest("Test not implemented for wx") + import wx + + event = wx.CommandEvent(wx.EVT_TEXT_ENTER.typeId, combobox.GetId()) + wx.PostEvent(combobox, event) elif is_current_backend_qt4(): combobox.lineEdit().editingFinished.emit() @@ -106,7 +109,12 @@ def finish_combobox_text_entry(combobox): def get_all_button_status(widget): """ Gets status of all radio buttons in the layout of a given widget.""" if is_current_backend_wx(): - raise unittest.SkipTest("Test not implemented for wx") + button_status = [] + for item in widget.GetSizer().GetChildren(): + button = item.GetWindow() + if button.value != "": # There are empty invisible buttons + button_status.append(button.GetValue()) + return button_status elif is_current_backend_qt4(): layout = widget.layout() @@ -119,7 +127,13 @@ def get_all_button_status(widget): def click_radio_button(widget, button_idx): """ Simulate a radio button click given widget and button number.""" if is_current_backend_wx(): - raise unittest.SkipTest("Test not implemented for wx") + import wx + + sizer_items = widget.GetSizer().GetChildren() + button = sizer_items[button_idx].GetWindow() + event = wx.CommandEvent(wx.EVT_RADIOBUTTON.typeId, button.GetId()) + event.SetEventObject(button) + wx.PostEvent(widget, event) elif is_current_backend_qt4(): widget.layout().itemAt(button_idx).widget().click() @@ -128,7 +142,8 @@ def click_radio_button(widget, button_idx): def get_list_widget_text(list_widget): """ Return the text of currently selected item in given list widget. """ if is_current_backend_wx(): - raise unittest.SkipTest("Test not implemented for wx") + selected_item_idx = list_widget.GetSelection() + return list_widget.GetString(selected_item_idx) elif is_current_backend_qt4(): return list_widget.currentItem().text() @@ -137,7 +152,11 @@ def get_list_widget_text(list_widget): def set_list_widget_selected_index(list_widget, idx): """ Set the choice index given a list widget control and index number. """ if is_current_backend_wx(): - raise unittest.SkipTest("Test not implemented for wx") + import wx + + list_widget.SetSelection(idx) + event = wx.CommandEvent(wx.EVT_LISTBOX.typeId, list_widget.GetId()) + wx.PostEvent(list_widget, event) elif is_current_backend_qt4(): list_widget.setCurrentRow(idx) @@ -211,19 +230,45 @@ class IntEnumModel(HasTraits): with store_exceptions_on_all_threads(): editor = self.setup_ui(model, formatted_view) - self.assertEqual(editor.names, ["FALSE", "TRUE"]) - self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) - self.assertEqual( - editor.inverse_mapping, {0: "FALSE", 1: "TRUE"} - ) + if is_current_backend_wx(): # FIXME issue #835 + with self.assertRaises(AssertionError): + self.assertEqual(editor.names, ["FALSE", "TRUE"]) + self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) + self.assertEqual( + editor.inverse_mapping, {0: "FALSE", 1: "TRUE"} + ) + self.assertEqual(editor.names, ["0", "1"]) + self.assertEqual(editor.mapping, {"0": 0, "1": 1}) + self.assertEqual( + editor.inverse_mapping, {0: "0", 1: "1"} + ) + else: + self.assertEqual(editor.names, ["FALSE", "TRUE"]) + self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) + self.assertEqual( + editor.inverse_mapping, {0: "FALSE", 1: "TRUE"} + ) model.possible_values = [1, 0] - self.assertEqual(editor.names, ["TRUE", "FALSE"]) - self.assertEqual(editor.mapping, {"TRUE": 1, "FALSE": 0}) - self.assertEqual( - editor.inverse_mapping, {1: "TRUE", 0: "FALSE"} - ) + if is_current_backend_wx(): # FIXME issue #835 + with self.assertRaises(AssertionError): + self.assertEqual(editor.names, ["TRUE", "FALSE"]) + self.assertEqual(editor.mapping, {"TRUE": 1, "FALSE": 0}) + self.assertEqual( + editor.inverse_mapping, {1: "TRUE", 0: "FALSE"} + ) + self.assertEqual(editor.names, ["1", "0"]) + self.assertEqual(editor.mapping, {"1": 1, "0": 0}) + self.assertEqual( + editor.inverse_mapping, {1: "1", 0: "0"} + ) + else: + self.assertEqual(editor.names, ["TRUE", "FALSE"]) + self.assertEqual(editor.mapping, {"TRUE": 1, "FALSE": 0}) + self.assertEqual( + editor.inverse_mapping, {1: "TRUE", 0: "FALSE"} + ) @skip_if_null def test_simple_editor_mapping_values(self): @@ -235,11 +280,23 @@ def test_simple_editor_mapping_name(self): @skip_if_null def test_radio_editor_mapping_values(self): - self.check_enum_mappings_value_change("custom", "radio") + if is_current_backend_wx(): # FIXME + import wx + + with self.assertRaises(wx._core.wxAssertionError): + self.check_enum_mappings_value_change("custom", "radio") + else: + self.check_enum_mappings_value_change("custom", "radio") @skip_if_null def test_radio_editor_mapping_name(self): - self.check_enum_mappings_name_change("custom", "radio") + if is_current_backend_wx(): # FIXME + import wx + + with self.assertRaises(wx._core.wxAssertionError): + self.check_enum_mappings_name_change("custom", "radio") + else: + self.check_enum_mappings_name_change("custom", "radio") @skip_if_null def test_list_editor_mapping_values(self): @@ -355,10 +412,12 @@ def test_simple_evaluate_editor_object_no_auto_set(self): set_combobox_text(combobox, "two") gui.process_events() - self.assertEqual(enum_edit.value, "one") + # wx modifies the value without the need to finish entry + if is_current_backend_qt4(): + self.assertEqual(enum_edit.value, "one") - finish_combobox_text_entry(combobox) - gui.process_events() + finish_combobox_text_entry(combobox) + gui.process_events() self.assertEqual(enum_edit.value, "two") @@ -372,6 +431,19 @@ def test_simple_editor_resizable(self): ui = enum_edit.edit_traits(view=resizable_view) self.addCleanup(ui.dispose) + def test_simple_editor_rebuild_editor_evaluate(self): + # Smoke test for `wx.enum_editor.SimpleEditor.rebuild_editor` + enum_editor_factory = EnumEditor( + evaluate=True, + values=["one", "two", "three", "four"], + ) + view = View(UItem("value", editor=enum_editor_factory, style="simple")) + + with store_exceptions_on_all_threads(): + gui, combobox = self.setup_gui(EnumModel(), view) + + enum_editor_factory.values = ["one", "two", "three"] + class TestRadioEnumEditor(unittest.TestCase): From d24f6f9a989e3b2ad340266800621f2ce276caef Mon Sep 17 00:00:00 2001 From: Ieva C Date: Fri, 22 May 2020 16:55:30 +0100 Subject: [PATCH 3/6] Add missing skipif decorator --- traitsui/tests/editors/test_enum_editor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/traitsui/tests/editors/test_enum_editor.py b/traitsui/tests/editors/test_enum_editor.py index aa68cb537..91145de80 100644 --- a/traitsui/tests/editors/test_enum_editor.py +++ b/traitsui/tests/editors/test_enum_editor.py @@ -431,6 +431,7 @@ def test_simple_editor_resizable(self): ui = enum_edit.edit_traits(view=resizable_view) self.addCleanup(ui.dispose) + @skip_if_null def test_simple_editor_rebuild_editor_evaluate(self): # Smoke test for `wx.enum_editor.SimpleEditor.rebuild_editor` enum_editor_factory = EnumEditor( From af38f290004bb6d8699ce9f8807f6fd70ca4827b Mon Sep 17 00:00:00 2001 From: Ieva C Date: Mon, 25 May 2020 13:59:51 +0100 Subject: [PATCH 4/6] Add issue references to FIXMEs --- traitsui/tests/editors/test_enum_editor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/traitsui/tests/editors/test_enum_editor.py b/traitsui/tests/editors/test_enum_editor.py index 91145de80..eb673b52a 100644 --- a/traitsui/tests/editors/test_enum_editor.py +++ b/traitsui/tests/editors/test_enum_editor.py @@ -280,7 +280,7 @@ def test_simple_editor_mapping_name(self): @skip_if_null def test_radio_editor_mapping_values(self): - if is_current_backend_wx(): # FIXME + if is_current_backend_wx(): # FIXME issue #842 import wx with self.assertRaises(wx._core.wxAssertionError): @@ -290,7 +290,7 @@ def test_radio_editor_mapping_values(self): @skip_if_null def test_radio_editor_mapping_name(self): - if is_current_backend_wx(): # FIXME + if is_current_backend_wx(): # FIXME issue #842 import wx with self.assertRaises(wx._core.wxAssertionError): From 366d3647b348349df3bc424878eb078d01e82cef Mon Sep 17 00:00:00 2001 From: Ieva C Date: Wed, 27 May 2020 10:50:07 +0100 Subject: [PATCH 5/6] Address review comments --- traitsui/tests/_tools.py | 26 +++++++ traitsui/tests/editors/test_enum_editor.py | 82 ++++++++++------------ 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/traitsui/tests/_tools.py b/traitsui/tests/_tools.py index a46047e3b..faaab71d7 100644 --- a/traitsui/tests/_tools.py +++ b/traitsui/tests/_tools.py @@ -177,6 +177,32 @@ def get_dialog_size(ui_control): return ui_control.size().width(), ui_control.size().height() +def get_all_button_status(control): + """Get status of all 2-state (wx) or checkable (qt) buttons under given + control. + + Assumes all sizer children (wx) or layout items (qt) are buttons. + """ + button_status = [] + + if is_current_backend_wx(): + for item in control.GetSizer().GetChildren(): + button = item.GetWindow() + # Ignore empty buttons (assumption that they are invisible) + if button.value != "": + button_status.append(button.GetValue()) + + elif is_current_backend_qt4(): + layout = control.layout() + for i in range(layout.count()): + button = layout.itemAt(i).widget() + button_status.append(button.isChecked()) + + else: + raise NotImplementedError() + + return button_status + # ######### Debug tools diff --git a/traitsui/tests/editors/test_enum_editor.py b/traitsui/tests/editors/test_enum_editor.py index eb673b52a..01f856528 100644 --- a/traitsui/tests/editors/test_enum_editor.py +++ b/traitsui/tests/editors/test_enum_editor.py @@ -6,6 +6,7 @@ from traits.api import Enum, HasTraits, Int, List from traitsui.api import EnumEditor, UItem, View from traitsui.tests._tools import ( + get_all_button_status, is_current_backend_qt4, is_current_backend_wx, skip_if_null, @@ -50,9 +51,13 @@ def get_combobox_text(combobox): return combobox.GetString(combobox.GetSelection()) else: return combobox.GetValue() + elif is_current_backend_qt4(): return combobox.currentText() + else: + raise unittest.SkipTest("Test not implemented for this toolkit") + def set_combobox_text(combobox, text): """ Set the text given a combobox control """ @@ -74,6 +79,9 @@ def set_combobox_text(combobox, text): elif is_current_backend_qt4(): combobox.setEditText(text) + else: + raise unittest.SkipTest("Test not implemented for this toolkit") + def set_combobox_index(combobox, idx): """ Set the choice index given a combobox control and index number """ @@ -93,6 +101,9 @@ def set_combobox_index(combobox, idx): elif is_current_backend_qt4(): combobox.setCurrentIndex(idx) + else: + raise unittest.SkipTest("Test not implemented for this toolkit") + def finish_combobox_text_entry(combobox): """ Finish text entry given combobox. """ @@ -105,27 +116,13 @@ def finish_combobox_text_entry(combobox): elif is_current_backend_qt4(): combobox.lineEdit().editingFinished.emit() - -def get_all_button_status(widget): - """ Gets status of all radio buttons in the layout of a given widget.""" - if is_current_backend_wx(): - button_status = [] - for item in widget.GetSizer().GetChildren(): - button = item.GetWindow() - if button.value != "": # There are empty invisible buttons - button_status.append(button.GetValue()) - return button_status - - elif is_current_backend_qt4(): - layout = widget.layout() - button_status = [] - for i in range(layout.count()): - button_status.append(layout.itemAt(i).widget().isChecked()) - return button_status + else: + raise unittest.SkipTest("Test not implemented for this toolkit") def click_radio_button(widget, button_idx): - """ Simulate a radio button click given widget and button number.""" + """ Simulate a radio button click given widget and button number. Assumes + all sizer children (wx) or layout items (qt) are buttons.""" if is_current_backend_wx(): import wx @@ -138,6 +135,9 @@ def click_radio_button(widget, button_idx): elif is_current_backend_qt4(): widget.layout().itemAt(button_idx).widget().click() + else: + raise unittest.SkipTest("Test not implemented for this toolkit") + def get_list_widget_text(list_widget): """ Return the text of currently selected item in given list widget. """ @@ -148,6 +148,9 @@ def get_list_widget_text(list_widget): elif is_current_backend_qt4(): return list_widget.currentItem().text() + else: + raise unittest.SkipTest("Test not implemented for this toolkit") + def set_list_widget_selected_index(list_widget, idx): """ Set the choice index given a list widget control and index number. """ @@ -161,7 +164,11 @@ def set_list_widget_selected_index(list_widget, idx): elif is_current_backend_qt4(): list_widget.setCurrentRow(idx) + else: + raise unittest.SkipTest("Test not implemented for this toolkit") + +@skip_if_null class TestEnumEditorMapping(unittest.TestCase): def setup_ui(self, model, view): @@ -189,7 +196,8 @@ class IntEnumModel(HasTraits): with store_exceptions_on_all_threads(): editor = self.setup_ui(IntEnumModel(), formatted_view) - with self.assertRaises(AssertionError): # FIXME issue #782 + # FIXME issue enthought/traitsui#782 + with self.assertRaises(AssertionError): self.assertEqual(editor.names, ["FALSE", "TRUE"]) self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) self.assertEqual( @@ -230,7 +238,8 @@ class IntEnumModel(HasTraits): with store_exceptions_on_all_threads(): editor = self.setup_ui(model, formatted_view) - if is_current_backend_wx(): # FIXME issue #835 + # FIXME issue enthought/traitsui#835 + if is_current_backend_wx(): with self.assertRaises(AssertionError): self.assertEqual(editor.names, ["FALSE", "TRUE"]) self.assertEqual(editor.mapping, {"FALSE": 0, "TRUE": 1}) @@ -251,7 +260,8 @@ class IntEnumModel(HasTraits): model.possible_values = [1, 0] - if is_current_backend_wx(): # FIXME issue #835 + # FIXME issue enthought/traitsui#835 + if is_current_backend_wx(): with self.assertRaises(AssertionError): self.assertEqual(editor.names, ["TRUE", "FALSE"]) self.assertEqual(editor.mapping, {"TRUE": 1, "FALSE": 0}) @@ -270,17 +280,15 @@ class IntEnumModel(HasTraits): editor.inverse_mapping, {1: "TRUE", 0: "FALSE"} ) - @skip_if_null def test_simple_editor_mapping_values(self): self.check_enum_mappings_value_change("simple", "radio") - @skip_if_null def test_simple_editor_mapping_name(self): self.check_enum_mappings_name_change("simple", "radio") - @skip_if_null def test_radio_editor_mapping_values(self): - if is_current_backend_wx(): # FIXME issue #842 + # FIXME issue enthought/traitsui#842 + if is_current_backend_wx(): import wx with self.assertRaises(wx._core.wxAssertionError): @@ -288,9 +296,9 @@ def test_radio_editor_mapping_values(self): else: self.check_enum_mappings_value_change("custom", "radio") - @skip_if_null def test_radio_editor_mapping_name(self): - if is_current_backend_wx(): # FIXME issue #842 + # FIXME issue enthought/traitsui#842 + if is_current_backend_wx(): import wx with self.assertRaises(wx._core.wxAssertionError): @@ -298,15 +306,14 @@ def test_radio_editor_mapping_name(self): else: self.check_enum_mappings_name_change("custom", "radio") - @skip_if_null def test_list_editor_mapping_values(self): self.check_enum_mappings_value_change("custom", "list") - @skip_if_null def test_list_editor_mapping_name(self): self.check_enum_mappings_name_change("custom", "list") +@skip_if_null class TestSimpleEnumEditor(unittest.TestCase): def setup_gui(self, model, view): @@ -372,34 +379,27 @@ def check_enum_text_bad_update(self, view): self.assertEqual(enum_edit.value, "one") - @skip_if_null def test_simple_enum_editor_text(self): self.check_enum_text_update(get_view("simple")) - @skip_if_null def test_simple_enum_editor_index(self): self.check_enum_index_update(get_view("simple")) - @skip_if_null @unittest.skipIf(is_windows, "Test needs fixing on windows") def test_simple_evaluate_editor_text(self): self.check_enum_text_update(get_evaluate_view("simple")) - @skip_if_null @unittest.skipIf(is_windows, "Test needs fixing on windows") def test_simple_evaluate_editor_index(self): self.check_enum_index_update(get_evaluate_view("simple")) - @skip_if_null def test_simple_evaluate_editor_bad_text(self): self.check_enum_text_bad_update(get_evaluate_view("simple")) - @skip_if_null @unittest.skipIf(is_windows, "Test needs fixing on windows") def test_simple_evaluate_editor_object(self): self.check_enum_object_update(get_evaluate_view("simple")) - @skip_if_null def test_simple_evaluate_editor_object_no_auto_set(self): view = get_evaluate_view("simple", auto_set=False) enum_edit = EnumModel() @@ -421,7 +421,6 @@ def test_simple_evaluate_editor_object_no_auto_set(self): self.assertEqual(enum_edit.value, "two") - @skip_if_null def test_simple_editor_resizable(self): # Smoke test for `qt4.enum_editor.SimpleEditor.set_size_policy` enum_edit = EnumModel() @@ -431,7 +430,6 @@ def test_simple_editor_resizable(self): ui = enum_edit.edit_traits(view=resizable_view) self.addCleanup(ui.dispose) - @skip_if_null def test_simple_editor_rebuild_editor_evaluate(self): # Smoke test for `wx.enum_editor.SimpleEditor.rebuild_editor` enum_editor_factory = EnumEditor( @@ -446,6 +444,7 @@ def test_simple_editor_rebuild_editor_evaluate(self): enum_editor_factory.values = ["one", "two", "three"] +@skip_if_null class TestRadioEnumEditor(unittest.TestCase): def setup_gui(self, model, view): @@ -459,7 +458,6 @@ def setup_gui(self, model, view): return gui, widget - @skip_if_null def test_radio_enum_editor_button_update(self): enum_edit = EnumModel() @@ -478,7 +476,6 @@ def test_radio_enum_editor_button_update(self): get_all_button_status(widget), [False, False, False, True] ) - @skip_if_null def test_radio_enum_editor_pick(self): enum_edit = EnumModel() @@ -494,6 +491,7 @@ def test_radio_enum_editor_pick(self): self.assertEqual(enum_edit.value, "two") +@skip_if_null class TestListEnumEditor(unittest.TestCase): def setup_gui(self, model, view): @@ -533,7 +531,6 @@ def check_enum_index_update(self, view): self.assertEqual(enum_edit.value, "two") - @skip_if_null def test_list_enum_editor_text(self): view = View( UItem( @@ -548,7 +545,6 @@ def test_list_enum_editor_text(self): ) self.check_enum_text_update(view) - @skip_if_null def test_list_enum_editor_index(self): view = View( UItem( @@ -563,10 +559,8 @@ def test_list_enum_editor_index(self): ) self.check_enum_index_update(view) - @skip_if_null def test_list_evaluate_editor_text(self): self.check_enum_text_update(get_evaluate_view("custom", mode="list")) - @skip_if_null def test_list_evaluate_editor_index(self): self.check_enum_index_update(get_evaluate_view("custom", mode="list")) From e0aa3ed7fa785658b3bb6e8e1257e1a3d3119d44 Mon Sep 17 00:00:00 2001 From: Ieva C Date: Wed, 27 May 2020 14:26:54 +0100 Subject: [PATCH 6/6] TMP: Remove wx vertical flag --- traitsui/wx/ui_panel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traitsui/wx/ui_panel.py b/traitsui/wx/ui_panel.py index 6f98de123..5c73ea618 100644 --- a/traitsui/wx/ui_panel.py +++ b/traitsui/wx/ui_panel.py @@ -1011,7 +1011,7 @@ def add_items(self, content, panel, sizer): item_sizer.Add( control, growable, - flags | layout_style | wx.ALIGN_CENTER_VERTICAL, + flags | layout_style, max(0, border_size + padding + item.padding), )