diff --git a/pyface/tasks/action/listening_action.py b/pyface/tasks/action/listening_action.py index 04ff76678..53d23b077 100644 --- a/pyface/tasks/action/listening_action.py +++ b/pyface/tasks/action/listening_action.py @@ -3,7 +3,7 @@ # Enthought library imports. from pyface.action.api import Action -from traits.api import Any, Str +from traits.api import Any, Str, List, Dict # Logging. logger = logging.getLogger(__name__) @@ -19,6 +19,12 @@ class ListeningAction(Action): # function will be called with the event. method = Str + # Extra arguments to method + args = List() + + # Extra keyword arguments to method + kwargs = Dict() + # The (extended) name of the attribute that determines whether the action is # enabled. By default, the action is always enabled when an object is set. enabled_name = Str @@ -40,7 +46,7 @@ def perform(self, event=None): if self.method != '': method = self._get_attr(self.object, self.method) if method: - method() + method(*self.args, **self.kwargs) else: super(ListeningAction, self).perform(event) diff --git a/pyface/tasks/action/test_listening_action.py b/pyface/tasks/action/test_listening_action.py new file mode 100644 index 000000000..25e6b2f0a --- /dev/null +++ b/pyface/tasks/action/test_listening_action.py @@ -0,0 +1,90 @@ +import unittest +from listening_action import ListeningAction +from traits.api import HasTraits + + +class TestListeningAction(unittest.TestCase): + + def setUp(self): + """ Creates a dummy class to apply listening action to + """ + class _DummyClass(HasTraits): + """ Dummy class to apply ListeningAction to + """ + def __init__(self, enabled=False, visible=False): + self.args = [] + self.kwargs = {} + self.enabled = enabled + self.visible = visible + + def dummy_method(self, *args, **kwargs): + self.args.extend(args) + self.kwargs.update(kwargs) + self._class = _DummyClass + + def test_method(self): + """ Tests whether the method attribute supports extra positional + and keyword arguments. + """ + # works with additional arguments? + dummy_obj = self._class() + action = ListeningAction(object=dummy_obj, method='dummy_method', + args=['arg1', 'arg2'], + kwargs={'arg1_pos': 0, 'arg2_pos': 1}) + action.perform() + self.assertEquals(dummy_obj.args, ['arg1', 'arg2']) + self.assertEquals(dummy_obj.kwargs, {'arg1_pos': 0, 'arg2_pos': 1}) + + # works without any argument? + dummy_obj = self._class() + action = ListeningAction(object=dummy_obj, method='dummy_method') + action.perform() + self.assertEquals(dummy_obj.args, []) + self.assertEquals(dummy_obj.kwargs, {}) + + # nothing happens if the specified method doesn't exist? + dummy_obj = self._class() + action = ListeningAction(object=dummy_obj, method='other_dummy_method') + action.perform() + self.assertEquals(dummy_obj.args, []) + self.assertEquals(dummy_obj.kwargs, {}) + + def test_enabled_name(self): + """ Whether the action follows enabled_name attribute of object to + enable/disable the action + """ + # enabled by default since enabled_name is not specified + dummy_obj = self._class() + action = ListeningAction(object=dummy_obj) + self.assertEquals(action.enabled, True) + + # disabled since the specified enabled_name attribute is set to False + dummy_obj = self._class(enabled=False) + action = ListeningAction(object=dummy_obj, enabled_name='enabled') + self.assertEquals(action.enabled, False) + + # what if enabled_name attribute of object is changed + dummy_obj.enabled = True + self.assertEquals(action.enabled, True) + + def test_visible_name(self): + """ Whether the action follows visible_name attribute of object to + make the action visible/invisible + """ + # enabled by default since enabled_name is not specified + dummy_obj = self._class() + action = ListeningAction(object=dummy_obj) + self.assertEquals(action.visible, True) + + # disabled since the specified enabled_name attribute is set to False + dummy_obj = self._class(visible=False) + action = ListeningAction(object=dummy_obj, visible_name='visible') + self.assertEquals(action.visible, False) + + # what if visible_name attribute of the object is changed + dummy_obj.visible = True + self.assertEquals(action.visible, True) + + +if __name__=="__main__": + unittest.main()