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 platform
13import unittest
14
15from ..constant import CANCEL, NO, OK, YES
16from ..toolkit import toolkit_object
17from ..window import Window
18
19is_qt = toolkit_object.toolkit == "qt4"
20if is_qt:
21    from pyface.qt import qt_api
22
23GuiTestAssistant = toolkit_object("util.gui_test_assistant:GuiTestAssistant")
24no_gui_test_assistant = GuiTestAssistant.__name__ == "Unimplemented"
25
26ModalDialogTester = toolkit_object(
27    "util.modal_dialog_tester:ModalDialogTester"
28)
29no_modal_dialog_tester = ModalDialogTester.__name__ == "Unimplemented"
30
31is_pyqt5 = is_qt and qt_api == "pyqt5"
32is_pyqt4_linux = is_qt and qt_api == "pyqt" and platform.system() == "Linux"
33
34
35@unittest.skipIf(no_gui_test_assistant, "No GuiTestAssistant")
36class TestWindow(unittest.TestCase, GuiTestAssistant):
37    def setUp(self):
38        GuiTestAssistant.setUp(self)
39        self.window = Window()
40
41    def tearDown(self):
42        if self.window.control is not None:
43            with self.delete_widget(self.window.control):
44                self.window.destroy()
45        self.window = None
46        GuiTestAssistant.tearDown(self)
47
48    def test_destroy(self):
49        # test that destroy works even when no control
50        with self.event_loop():
51            self.window.destroy()
52
53    def test_open_close(self):
54        # test that opening and closing works as expected
55        with self.assertTraitChanges(self.window, "opening", count=1):
56            with self.assertTraitChanges(self.window, "opened", count=1):
57                with self.event_loop():
58                    self.window.open()
59
60        with self.assertTraitChanges(self.window, "closing", count=1):
61            with self.assertTraitChanges(self.window, "closed", count=1):
62                with self.event_loop():
63                    self.window.close()
64
65    def test_show(self):
66        # test that showing works as expected
67        with self.event_loop():
68            self.window._create()
69        with self.event_loop():
70            self.window.show(True)
71        with self.event_loop():
72            self.window.show(False)
73        with self.event_loop():
74            self.window.destroy()
75
76    def test_activate(self):
77        # test that activation works as expected
78        with self.event_loop():
79            self.window.open()
80        with self.event_loop():
81            self.window.activate()
82        with self.event_loop():
83            self.window.close()
84
85    def test_position(self):
86        # test that default position works as expected
87        self.window.position = (100, 100)
88        with self.event_loop():
89            self.window.open()
90        with self.event_loop():
91            self.window.close()
92
93    def test_reposition(self):
94        # test that changing position works as expected
95        with self.event_loop():
96            self.window.open()
97        with self.event_loop():
98            self.window.position = (100, 100)
99        with self.event_loop():
100            self.window.close()
101
102    def test_size(self):
103        # test that default size works as expected
104        self.window.size = (100, 100)
105        with self.event_loop():
106            self.window.open()
107        with self.event_loop():
108            self.window.close()
109
110    def test_resize(self):
111        # test that changing size works as expected
112        with self.event_loop():
113            self.window.open()
114        with self.event_loop():
115            self.window.size = (100, 100)
116        with self.event_loop():
117            self.window.close()
118
119    def test_title(self):
120        # test that default title works as expected
121        self.window.title = "Test Title"
122        with self.event_loop():
123            self.window.open()
124        with self.event_loop():
125            self.window.close()
126
127    def test_retitle(self):
128        # test that changing title works as expected
129        with self.event_loop():
130            self.window.open()
131        with self.event_loop():
132            self.window.title = "Test Title"
133        with self.event_loop():
134            self.window.close()
135
136    def test_show_event(self):
137        with self.event_loop():
138            self.window.open()
139        with self.event_loop():
140            self.window.visible = False
141
142        with self.assertTraitChanges(self.window, "visible", count=1):
143            with self.event_loop():
144                self.window.control.show()
145
146        self.assertTrue(self.window.visible)
147
148    def test_hide_event(self):
149        with self.event_loop():
150            self.window.open()
151
152        with self.assertTraitChanges(self.window, "visible", count=1):
153            with self.event_loop():
154                self.window.control.hide()
155
156        self.assertFalse(self.window.visible)
157
158    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
159    @unittest.skipIf(
160        is_pyqt5, "Confirmation dialog click tests don't work on pyqt5."
161    )
162    @unittest.skipIf(
163        is_pyqt4_linux,
164        "Confirmation dialog click tests don't work reliably on linux.  Issue #282.",
165    )
166    def test_confirm_reject(self):
167        # test that cancel works as expected
168        tester = ModalDialogTester(
169            lambda: self.window.confirm("message", cancel=True)
170        )
171        tester.open_and_run(when_opened=lambda x: x.close(accept=False))
172
173        self.assertEqual(tester.result, CANCEL)
174
175    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
176    @unittest.skipIf(
177        is_pyqt5, "Confirmation dialog click tests don't work on pyqt5."
178    )
179    @unittest.skipIf(
180        is_pyqt4_linux,
181        "Confirmation dialog click tests don't work reliably on linux.  Issue #282.",
182    )
183    def test_confirm_yes(self):
184        # test that yes works as expected
185        tester = ModalDialogTester(lambda: self.window.confirm("message"))
186        tester.open_and_wait(when_opened=lambda x: x.click_button(YES))
187
188        self.assertEqual(tester.result, YES)
189
190    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
191    @unittest.skipIf(
192        is_pyqt5, "Confirmation dialog click tests don't work on pyqt5."
193    )
194    @unittest.skipIf(
195        is_pyqt4_linux,
196        "Confirmation dialog click tests don't work reliably on linux.  Issue #282.",
197    )
198    def test_confirm_no(self):
199        # test that no works as expected
200        tester = ModalDialogTester(lambda: self.window.confirm("message"))
201        tester.open_and_wait(when_opened=lambda x: x.click_button(NO))
202
203        self.assertEqual(tester.result, NO)
204
205    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
206    @unittest.skipIf(
207        is_pyqt5, "Confirmation dialog click tests don't work on pyqt5."
208    )
209    @unittest.skipIf(
210        is_pyqt4_linux,
211        "Confirmation dialog click tests don't work reliably on linux.  Issue #282.",
212    )
213    def test_confirm_cancel(self):
214        # test that cncel works as expected
215        tester = ModalDialogTester(
216            lambda: self.window.confirm("message", cancel=True)
217        )
218        tester.open_and_wait(when_opened=lambda x: x.click_button(CANCEL))
219
220        self.assertEqual(tester.result, CANCEL)
221
222    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
223    def test_information_accept(self):
224        self._check_message_dialog_accept(self.window.information)
225
226    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
227    @unittest.skipIf(
228        is_pyqt5, "Message dialog click tests don't work on pyqt5."
229    )
230    @unittest.skipIf(
231        is_pyqt4_linux,
232        "Message dialog click tests don't work reliably on linux.  Issue #282.",
233    )
234    def test_information_ok(self):
235        self._check_message_dialog_ok(self.window.information)
236
237    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
238    def test_warning_accept(self):
239        self._check_message_dialog_accept(self.window.warning)
240
241    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
242    @unittest.skipIf(
243        is_pyqt5, "Message dialog click tests don't work on pyqt5."
244    )
245    @unittest.skipIf(
246        is_pyqt4_linux,
247        "Message dialog click tests don't work reliably on linux.  Issue #282.",
248    )
249    def test_warning_ok(self):
250        self._check_message_dialog_ok(self.window.warning)
251
252    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
253    def test_error_accept(self):
254        self._check_message_dialog_accept(self.window.error)
255
256    @unittest.skipIf(no_modal_dialog_tester, "ModalDialogTester unavailable")
257    @unittest.skipIf(
258        is_pyqt5, "Message dialog click tests don't work on pyqt5."
259    )
260    @unittest.skipIf(
261        is_pyqt4_linux,
262        "Message dialog click tests don't work reliably on linux.  Issue #282.",
263    )
264    def test_error_ok(self):
265        self._check_message_dialog_ok(self.window.error)
266
267    def _check_message_dialog_ok(self, method):
268        tester = self._setup_tester(method)
269        tester.open_and_wait(when_opened=lambda x: x.click_button(OK))
270
271        self.assertIsNone(tester.result)
272
273    def _check_message_dialog_accept(self, method):
274        tester = self._setup_tester(method)
275        tester.open_and_run(when_opened=lambda x: x.close(accept=True))
276
277        self.assertIsNone(tester.result)
278
279    def _setup_tester(self, method):
280        kwargs = {
281            "title": "Title",
282            "detail": "Detail",
283            "informative": "Informative",
284        }
285        tester = ModalDialogTester(lambda: method("message", **kwargs))
286        return tester
287