Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions traitsui/testing/tester/qt4/default_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from traitsui.testing.tester.qt4.implementation import (
button_editor,
check_list_editor,
instance_editor,
list_editor,
range_editor,
text_editor,
Expand Down Expand Up @@ -48,4 +49,7 @@ def get_default_registry():
# RangeEditor
range_editor.register(registry)

# InstanceEditor
instance_editor.register(registry)

return registry
59 changes: 59 additions & 0 deletions traitsui/testing/tester/qt4/implementation/instance_editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright (c) 2005-2020, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#

from traitsui.testing.tester import command
from traitsui.testing.tester.qt4.helpers import mouse_click_qwidget
from traitsui.testing.tester.registry_helper import register_nested_ui_solvers
from traitsui.qt4.instance_editor import (
CustomEditor,
SimpleEditor
)


def _get_nested_ui_simple(target):
""" Obtains a nested UI within a Simple Instance Editor.

Parameters
----------
target : instance of SimpleEditor
"""
return target._dialog_ui


def _get_nested_ui_custom(target):
""" Obtains a nested UI within a Custom Instance Editor.

Parameters
----------
target : instance of CustomEditor
"""
return target._ui


def register(registry):
""" Register interactions for the given registry.

If there are any conflicts, an error will occur.

Parameters
----------
registry : TargetRegistry
The registry being registered to.
"""
registry.register_handler(
target_class=SimpleEditor,
interaction_class=command.MouseClick,
handler=lambda wrapper, _: (
mouse_click_qwidget(wrapper.target._button, delay=wrapper.delay)
)
)
register_nested_ui_solvers(registry, SimpleEditor, _get_nested_ui_simple)
register_nested_ui_solvers(registry, CustomEditor, _get_nested_ui_custom)
4 changes: 4 additions & 0 deletions traitsui/testing/tester/wx/default_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from traitsui.testing.tester.wx.implementation import (
button_editor,
check_list_editor,
instance_editor,
list_editor,
range_editor,
text_editor,
Expand Down Expand Up @@ -48,4 +49,7 @@ def get_default_registry():
# RangeEditor
range_editor.register(registry)

# InstanceEditor
instance_editor.register(registry)

return registry
59 changes: 59 additions & 0 deletions traitsui/testing/tester/wx/implementation/instance_editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright (c) 2005-2020, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#

from traitsui.testing.tester import command
from traitsui.testing.tester.registry_helper import register_nested_ui_solvers
from traitsui.testing.tester.wx.helpers import mouse_click_button
from traitsui.wx.instance_editor import (
CustomEditor,
SimpleEditor
)


def _get_nested_ui_simple(target):
""" Obtains a nested UI within a Simple Instance Editor.

Parameters
----------
target : instance of SimpleEditor
"""
return target._dialog_ui


def _get_nested_ui_custom(target):
""" Obtains a nested UI within a Custom Instance Editor.

Parameters
----------
target : instance of CustomEditor
"""
return target._ui


def register(registry):
""" Register interactions for the given registry.

If there are any conflicts, an error will occur.

Parameters
----------
registry : TargetRegistry
The registry being registered to.
"""
registry.register_handler(
target_class=SimpleEditor,
interaction_class=command.MouseClick,
handler=lambda wrapper, _: mouse_click_button(
wrapper.target._button, delay=wrapper.delay,
)
)
register_nested_ui_solvers(registry, SimpleEditor, _get_nested_ui_simple)
register_nested_ui_solvers(registry, CustomEditor, _get_nested_ui_custom)
69 changes: 52 additions & 17 deletions traitsui/tests/editors/test_instance_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
from traitsui.item import Item
from traitsui.view import View
from traitsui.tests._tools import (
create_ui,
press_ok_button,
requires_toolkit,
reraise_exceptions,
ToolkitName,
)

from traitsui.testing.tester import command, query
from traitsui.testing.tester.ui_tester import UITester


class EditedInstance(HasTraits):
value = Str()
Expand All @@ -19,28 +19,63 @@ class EditedInstance(HasTraits):

class NonmodalInstanceEditor(HasTraits):
inst = Instance(EditedInstance, ())
traits_view = View(Item("inst", style="simple"), buttons=["OK"])


def get_view(style):
return View(Item("inst", style=style), buttons=["OK"])


@requires_toolkit([ToolkitName.qt, ToolkitName.wx])
class TestInstanceEditor(unittest.TestCase):

@requires_toolkit([ToolkitName.qt])
def test_simple_editor(self):
obj = NonmodalInstanceEditor()
with reraise_exceptions(), create_ui(obj) as ui:
editor = ui.get_editors("inst")[0]
tester = UITester()
with tester.create_ui(obj, dict(view=get_view("simple"))) as ui:
instance = tester.find_by_name(ui, "inst")
instance.perform(command.MouseClick())
value_txt = instance.find_by_name("value")
value_txt.perform(command.KeySequence("abc"))
self.assertEqual(obj.inst.value, "abc")

# make the dialog appear
editor._button.click()
def test_custom_editor(self):
obj = NonmodalInstanceEditor()
tester = UITester()
with tester.create_ui(obj, dict(view=get_view("custom"))) as ui:
value_txt = tester.find_by_name(ui, "inst").find_by_name("value")
value_txt.perform(command.KeySequence("abc"))
self.assertEqual(obj.inst.value, "abc")

# close the ui dialog
press_ok_button(editor._dialog_ui)
def test_custom_editor_resynch_editor(self):
edited_inst = EditedInstance(value='hello')
obj = NonmodalInstanceEditor(inst=edited_inst)
tester = UITester()
with tester.create_ui(obj, dict(view=get_view("custom"))) as ui:
value_txt = tester.find_by_name(ui, "inst").find_by_name("value")
displayed = value_txt.inspect(query.DisplayedText())
self.assertEqual(displayed, "hello")
edited_inst.value = "bye"
displayed = value_txt.inspect(query.DisplayedText())
self.assertEqual(displayed, "bye")

def test_simple_editor_resynch_editor(self):
edited_inst = EditedInstance(value='hello')
obj = NonmodalInstanceEditor(inst=edited_inst)
tester = UITester()
with tester.create_ui(obj, dict(view=get_view("simple"))) as ui:
instance = tester.find_by_name(ui, "inst")
instance.perform(command.MouseClick())

value_txt = instance.find_by_name("value")
displayed = value_txt.inspect(query.DisplayedText())
self.assertEqual(displayed, "hello")
edited_inst.value = "bye"
displayed = value_txt.inspect(query.DisplayedText())
self.assertEqual(displayed, "bye")

@requires_toolkit([ToolkitName.qt])
def test_simple_editor_parent_closed(self):
obj = NonmodalInstanceEditor()
with reraise_exceptions(), create_ui(obj) as ui:
editor = ui.get_editors("inst")[0]

# make the dialog appear
editor._button.click()
tester = UITester()
with tester.create_ui(obj, dict(view=get_view('simple'))) as ui:
instance = tester.find_by_name(ui, "inst")
instance.perform(command.MouseClick())
10 changes: 9 additions & 1 deletion traitsui/wx/instance_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import wx

from pyface.wx.drag_and_drop import PythonDropTarget
from traits.api import HasTraits, Property
from traits.api import HasTraits, Instance, Property

# FIXME: ToolkitEditorFactory is a proxy class defined here just for backward
# compatibility. The class has been moved to the
Expand Down Expand Up @@ -488,6 +488,9 @@ class SimpleEditor(CustomEditor):
orientation = wx.HORIZONTAL
extra = 2

#: The ui instance for the currently open editor dialog
_dialog_ui = Instance("traitsui.ui.UI")

def create_editor(self, parent, sizer):
""" Creates the editor control (a button).
"""
Expand All @@ -502,6 +505,10 @@ def dispose(self):
if button is not None:
button.Bind(wx.EVT_BUTTON, None, id=button.GetId())

if self._dialog_ui is not None:
self._dialog_ui.dispose()
self._dialog_ui = None

super(SimpleEditor, self).dispose()

def edit_instance(self, event):
Expand All @@ -527,6 +534,7 @@ def edit_instance(self, event):
# have its own:
if ui.history is None:
ui.history = self.ui.history
self._dialog_ui = ui

def resynch_editor(self):
""" Resynchronizes the contents of the editor when the object trait
Expand Down