1# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
2# All rights reserved.
3#
4# This software is provided without warranty under the terms of the BSD
5# license included in LICENSE.txt and may be redistributed only under
6# the conditions described in the aforementioned license. The license
7# is also available online at http://www.enthought.com/licenses/BSD.txt
8#
9# Thanks for using Enthought open source!
10
11
12import unittest
13
14from traits.api import Any, Bool, HasTraits
15from traits.testing.unittest_tools import UnittestTools
16
17from ..listening_action import ListeningAction
18from ..action_event import ActionEvent
19
20
21class WatchedObject(HasTraits):
22
23    #: Trait to watch for enabled state
24    is_enabled = Bool(True)
25
26    #: Other trait to watch for enabled state
27    is_also_enabled = Bool(True)
28
29    #: Trait to watch for visible state
30    is_visible = Bool(True)
31
32    #: Other trait to watch for visible state
33    is_also_visible = Bool(True)
34
35    #: Flag that is set when method called
36    was_called = Bool()
37
38    #: Child object to test dotted lookup
39    child = Any()
40
41    def callback(self):
42        self.was_called = True
43
44
45class TestListeningAction(unittest.TestCase, UnittestTools):
46    def setUp(self):
47        self.object = WatchedObject()
48
49    def perform_with_callback(self, action):
50        # test whether function is called by updating list
51        # XXX should really use mock
52        memo = []
53
54        def perform():
55            memo.append("called")
56
57        action.on_perform = perform
58        event = ActionEvent()
59
60        action.perform(event)
61
62        return memo
63
64    def test_defaults(self):
65        action = ListeningAction()
66        event = ActionEvent()
67
68        # does nothing, but shouldn't error
69        action.perform(event)
70
71        self.assertTrue(action.enabled)
72        self.assertTrue(action.visible)
73
74    def test_perform_no_object(self):
75        action = ListeningAction()
76
77        memo = self.perform_with_callback(action)
78
79        self.assertEqual(memo, ["called"])
80
81    def test_perform_no_method(self):
82        action = ListeningAction(object=self.object)
83
84        memo = self.perform_with_callback(action)
85
86        self.assertFalse(self.object.was_called)
87        self.assertEqual(memo, ["called"])
88
89    def test_perform_method(self):
90        action = ListeningAction(object=self.object, method="callback")
91
92        memo = self.perform_with_callback(action)
93
94        self.assertTrue(self.object.was_called)
95        self.assertEqual(memo, [])
96
97    def test_perform_method_missing(self):
98        action = ListeningAction(object=self.object, method="fallback")
99
100        # does nothing, but shouldn't error
101        memo = self.perform_with_callback(action)
102
103        self.assertFalse(self.object.was_called)
104        self.assertEqual(memo, [])
105
106    def test_perform_child_method(self):
107        self.object.child = WatchedObject()
108        action = ListeningAction(object=self.object, method="child.callback")
109
110        memo = self.perform_with_callback(action)
111
112        self.assertTrue(self.object.child.was_called)
113        self.assertFalse(self.object.was_called)
114        self.assertEqual(memo, [])
115
116    def test_perform_missing_child_method(self):
117        action = ListeningAction(object=self.object, method="child.callback")
118
119        # does nothing, but shouldn't error
120        memo = self.perform_with_callback(action)
121
122        self.assertFalse(self.object.was_called)
123        self.assertEqual(memo, [])
124
125    def test_enabled(self):
126        action = ListeningAction(object=self.object, enabled_name="is_enabled")
127
128        self.assertTrue(action.enabled)
129
130        with self.assertTraitChanges(action, "enabled", 1):
131            self.object.is_enabled = False
132
133        self.assertFalse(action.enabled)
134
135        with self.assertTraitChanges(action, "enabled", 1):
136            self.object.is_enabled = True
137
138        self.assertTrue(action.enabled)
139
140    def test_enabled_child(self):
141        self.object.child = WatchedObject()
142        action = ListeningAction(
143            object=self.object, enabled_name="child.is_enabled"
144        )
145
146        self.assertTrue(action.enabled)
147
148        with self.assertTraitChanges(action, "enabled", 1):
149            self.object.child.is_enabled = False
150
151        self.assertFalse(action.enabled)
152
153        with self.assertTraitChanges(action, "enabled", 1):
154            self.object.child.is_enabled = True
155
156        self.assertTrue(action.enabled)
157
158    def test_enabled_missing_child(self):
159        action = ListeningAction(
160            object=self.object, enabled_name="child.is_enabled"
161        )
162
163        self.assertFalse(action.enabled)
164
165        with self.assertTraitChanges(action, "enabled", 1):
166            self.object.child = WatchedObject()
167
168        self.assertTrue(action.enabled)
169
170        with self.assertTraitChanges(action, "enabled", 1):
171            self.object.child = None
172
173        self.assertFalse(action.enabled)
174
175    def test_enabled_name_change(self):
176        self.object.is_also_enabled = False
177        action = ListeningAction(object=self.object, enabled_name="is_enabled")
178
179        self.assertTrue(action.enabled)
180
181        with self.assertTraitChanges(action, "enabled", 1):
182            action.enabled_name = "is_also_enabled"
183
184        self.assertFalse(action.enabled)
185
186    def test_visible(self):
187        action = ListeningAction(object=self.object, visible_name="is_visible")
188
189        self.assertTrue(action.visible)
190
191        with self.assertTraitChanges(action, "visible", 1):
192            self.object.is_visible = False
193
194        self.assertFalse(action.visible)
195
196        with self.assertTraitChanges(action, "visible", 1):
197            self.object.is_visible = True
198
199        self.assertTrue(action.visible)
200
201    def test_visible_child(self):
202        self.object.child = WatchedObject()
203        action = ListeningAction(
204            object=self.object, visible_name="child.is_visible"
205        )
206
207        self.assertTrue(action.visible)
208
209        with self.assertTraitChanges(action, "visible", 1):
210            self.object.child.is_visible = False
211
212        self.assertFalse(action.visible)
213
214        with self.assertTraitChanges(action, "visible", 1):
215            self.object.child.is_visible = True
216
217        self.assertTrue(action.visible)
218
219    def test_visible_missing_child(self):
220        action = ListeningAction(
221            object=self.object, visible_name="child.is_visible"
222        )
223
224        self.assertFalse(action.visible)
225
226        with self.assertTraitChanges(action, "visible", 1):
227            self.object.child = WatchedObject()
228
229        self.assertTrue(action.visible)
230
231        with self.assertTraitChanges(action, "visible", 1):
232            self.object.child = None
233
234        self.assertFalse(action.visible)
235
236    def test_visible_name_change(self):
237        self.object.is_also_visible = False
238        action = ListeningAction(object=self.object, visible_name="is_visible")
239
240        self.assertTrue(action.visible)
241
242        with self.assertTraitChanges(action, "visible", 1):
243            action.visible_name = "is_also_visible"
244
245        self.assertFalse(action.visible)
246
247    def test_destroy(self):
248        action = ListeningAction(object=self.object)
249
250        action.destroy()
251