1
 
# Copyright (C) 2012 Curtis Hovey <sinzui.is@verizon.net>
 
3
 
# This program is free software; you can redistribute it and/or modify
 
4
 
# it under the terms of the GNU General Public License as published by
 
5
 
# the Free Software Foundation; either version 2 of the License, or
 
6
 
# (at your option) any later version.
 
8
 
# This program is distributed in the hope that it will be useful,
 
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 
# GNU General Public License for more details.
 
13
 
# You should have received a copy of the GNU General Public License
 
14
 
# along with this program; if not, write to the Free Software
 
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
"""Test the ui functionality."""
 
19
 
from gi.repository import Gtk
 
25
 
from bzrlib.plugins.gtk import ui
 
26
 
from bzrlib.plugins.gtk.tests import (
 
30
 
from bzrlib.progress import ProgressTask
 
33
 
class MainIterationTestCase(tests.TestCase):
 
35
 
    def test_main_iteration(self):
 
36
 
        # The main_iteration decorator iterates over the pending Gtk events
 
37
 
        # after calling its function so that the UI is updated too.
 
38
 
        button = Gtk.ToggleButton(label='before')
 
40
 
        def event_listener(button):
 
41
 
            button.props.label = 'after'
 
43
 
        button.connect('clicked', event_listener)
 
46
 
            button.emit('clicked')
 
49
 
        decorated_func = ui.main_iteration(test_func)
 
50
 
        result = decorated_func(object())
 
51
 
        self.assertIs(True, result)
 
52
 
        self.assertIs(False, Gtk.events_pending())
 
53
 
        self.assertEqual('after', button.props.label)
 
56
 
class PromptDialogTestCase(tests.TestCase):
 
59
 
        # The text and buttons are created.
 
60
 
        dialog = ui.PromptDialog('test 123')
 
61
 
        self.assertEqual('test 123', dialog.props.text)
 
62
 
        self.assertEqual(Gtk.MessageType.QUESTION, dialog.props.message_type)
 
63
 
        buttons = dialog.get_action_area().get_children()
 
64
 
        self.assertEqual('gtk-yes', buttons[0].props.label)
 
65
 
        self.assertEqual('gtk-no', buttons[1].props.label)
 
68
 
class InfoDialogTestCase(tests.TestCase):
 
71
 
        # The text and buttons are created.
 
72
 
        dialog = ui.InfoDialog('test 123')
 
73
 
        self.assertEqual('test 123', dialog.props.text)
 
74
 
        self.assertEqual(Gtk.MessageType.INFO, dialog.props.message_type)
 
75
 
        buttons = dialog.get_action_area().get_children()
 
76
 
        self.assertEqual('gtk-close', buttons[0].props.label)
 
79
 
class WarningDialogTestCase(tests.TestCase):
 
82
 
        # The text and buttons are created.
 
83
 
        dialog = ui.WarningDialog('test 123')
 
84
 
        self.assertEqual('test 123', dialog.props.text)
 
85
 
        self.assertEqual(Gtk.MessageType.WARNING, dialog.props.message_type)
 
86
 
        buttons = dialog.get_action_area().get_children()
 
87
 
        self.assertEqual('gtk-close', buttons[0].props.label)
 
90
 
class ErrorDialogTestCase(tests.TestCase):
 
93
 
        # The text and buttons are created, then shown.
 
94
 
        dialog = ui.ErrorDialog('test 123')
 
95
 
        self.assertEqual('test 123', dialog.props.text)
 
96
 
        self.assertEqual(Gtk.MessageType.ERROR, dialog.props.message_type)
 
97
 
        buttons = dialog.get_action_area().get_children()
 
98
 
        self.assertEqual('gtk-close', buttons[0].props.label)
 
101
 
class PasswordDialogTestCase(tests.TestCase):
 
104
 
        # The label, password entry, and buttons are created, then shown.
 
105
 
        MockMethod.bind(self, Gtk.Box, 'show_all')
 
106
 
        dialog = ui.PasswordDialog('test password')
 
107
 
        content_area = dialog.get_content_area()
 
108
 
        self.assertIs(True, dialog.get_content_area().show_all.called)
 
109
 
        widgets = content_area.get_children()
 
110
 
        self.assertEqual('test password', widgets[0].props.label)
 
111
 
        self.assertEqual(False, widgets[1].props.visibility)
 
112
 
        buttons = dialog.get_action_area().get_children()
 
113
 
        self.assertEqual('gtk-cancel', buttons[0].props.label)
 
115
 
            Gtk.ResponseType.CANCEL,
 
116
 
            dialog.get_response_for_widget(buttons[0]))
 
117
 
        self.assertEqual('gtk-ok', buttons[1].props.label)
 
120
 
            dialog.get_response_for_widget(buttons[1]))
 
123
 
class GtkProgressBarTestCase(tests.TestCase):
 
126
 
        progress_bar = ui.GtkProgressBar()
 
127
 
        self.assertEqual(0.0, progress_bar.props.fraction)
 
128
 
        self.assertIs(None, progress_bar.total)
 
129
 
        self.assertIs(None, progress_bar.current)
 
132
 
        # tick() shows the widget, does one pulse, then handles the pending
 
133
 
        # events in the main loop.
 
134
 
        MockMethod.bind(self, ui.GtkProgressBar, 'show')
 
135
 
        MockMethod.bind(self, ui.GtkProgressBar, 'pulse')
 
136
 
        progress_bar = ui.GtkProgressBar()
 
138
 
        self.assertIs(True, progress_bar.show.called)
 
139
 
        self.assertEqual('with_main_iteration', progress_bar.tick.__name__)
 
141
 
    def test_update_with_data(self):
 
142
 
        # update() shows the widget, sets the fraction, then handles the
 
143
 
        # pending events in the main loop.
 
144
 
        MockMethod.bind(self, ui.GtkProgressBar, 'show')
 
145
 
        progress_bar = ui.GtkProgressBar()
 
146
 
        progress_bar.update(msg='test', current_cnt=5, total_cnt=10)
 
147
 
        self.assertIs(True, progress_bar.show.called)
 
148
 
        self.assertEqual(0.5, progress_bar.props.fraction)
 
149
 
        self.assertEqual(10, progress_bar.total)
 
150
 
        self.assertEqual(5, progress_bar.current)
 
151
 
        self.assertEqual('with_main_iteration', progress_bar.update.__name__)
 
153
 
    def test_update_without_data(self):
 
154
 
        progress_bar = ui.GtkProgressBar()
 
155
 
        progress_bar.update(current_cnt=5, total_cnt=None)
 
156
 
        self.assertEqual(0.0, progress_bar.props.fraction)
 
157
 
        self.assertIs(None, progress_bar.total)
 
158
 
        self.assertEqual(5, progress_bar.current)
 
160
 
    def test_update_with_insane_data(self):
 
161
 
        # The fraction must be between 0.0 and 1.0.
 
162
 
        progress_bar = ui.GtkProgressBar()
 
164
 
            ValueError, progress_bar.update, None, 20, 2)
 
166
 
    def test_finished(self):
 
167
 
        # finished() hides the widget, resets the state, then handles the
 
168
 
        # pending events in the main loop.
 
169
 
        MockMethod.bind(self, ui.GtkProgressBar, 'hide')
 
170
 
        progress_bar = ui.GtkProgressBar()
 
171
 
        progress_bar.finished()
 
172
 
        self.assertIs(True, progress_bar.hide.called)
 
173
 
        self.assertEqual(0.0, progress_bar.props.fraction)
 
174
 
        self.assertIs(None, progress_bar.total)
 
175
 
        self.assertIs(None, progress_bar.current)
 
176
 
        self.assertEqual('with_main_iteration', progress_bar.finished.__name__)
 
178
 
    def test_clear(self):
 
179
 
        # clear() is synonymous with finished.
 
180
 
        MockMethod.bind(self, ui.GtkProgressBar, 'finished')
 
181
 
        progress_bar = ui.GtkProgressBar()
 
182
 
        progress_bar.finished()
 
183
 
        self.assertIs(True, progress_bar.finished.called)
 
186
 
class ProgressContainerMixin:
 
189
 
        progress_widget = self.progress_container()
 
190
 
        MockMethod.bind(self, progress_widget, 'show_all')
 
191
 
        MockMethod.bind(self, progress_widget.pb, 'tick')
 
192
 
        progress_widget.tick()
 
193
 
        self.assertIs(True, progress_widget.show_all.called)
 
194
 
        self.assertIs(True, progress_widget.pb.tick.called)
 
196
 
    def test_update(self):
 
197
 
        progress_widget = self.progress_container()
 
198
 
        MockMethod.bind(self, progress_widget, 'show_all')
 
199
 
        MockMethod.bind(self, progress_widget.pb, 'update')
 
200
 
        progress_widget.update('test', 5, 10)
 
201
 
        self.assertIs(True, progress_widget.show_all.called)
 
202
 
        self.assertIs(True, progress_widget.pb.update.called)
 
204
 
            ('test', 5, 10), progress_widget.pb.update.args)
 
206
 
    def test_finished(self):
 
207
 
        progress_widget = self.progress_container()
 
208
 
        MockMethod.bind(self, progress_widget, 'hide')
 
209
 
        MockMethod.bind(self, progress_widget.pb, 'finished')
 
210
 
        progress_widget.finished()
 
211
 
        self.assertIs(True, progress_widget.hide.called)
 
212
 
        self.assertIs(True, progress_widget.pb.finished.called)
 
214
 
    def test_clear(self):
 
215
 
        progress_widget = self.progress_container()
 
216
 
        MockMethod.bind(self, progress_widget, 'hide')
 
217
 
        MockMethod.bind(self, progress_widget.pb, 'clear')
 
218
 
        progress_widget.clear()
 
219
 
        self.assertIs(True, progress_widget.hide.called)
 
220
 
        self.assertIs(True, progress_widget.pb.clear.called)
 
223
 
class ProgressBarWindowTestCase(ProgressContainerMixin, tests.TestCase):
 
225
 
    progress_container = ui.ProgressBarWindow
 
228
 
        pb_window = ui.ProgressBarWindow()
 
229
 
        self.assertEqual('Progress', pb_window.props.title)
 
231
 
            Gtk.WindowPosition.CENTER_ALWAYS, pb_window.props.window_position)
 
232
 
        self.assertIsInstance(pb_window.pb, ui.GtkProgressBar)
 
235
 
class ProgressPanelTestCase(ProgressContainerMixin, tests.TestCase):
 
237
 
    progress_container = ui.ProgressPanel
 
240
 
        pb_window = ui.ProgressPanel()
 
242
 
            Gtk.Orientation.HORIZONTAL, pb_window.props.orientation)
 
243
 
        self.assertEqual(5, pb_window.props.spacing)
 
244
 
        self.assertIsInstance(pb_window.pb, ui.GtkProgressBar)
 
245
 
        widgets = pb_window.get_children()
 
246
 
        # The image's stock and icon_name properties are always None?
 
247
 
        self.assertIsInstance(widgets[0], Gtk.Image)
 
250
 
class GtkUIFactoryTestCase(tests.TestCase):
 
252
 
    def test__init(self):
 
253
 
        ui_factory = ui.GtkUIFactory()
 
254
 
        self.assertIs(None, ui_factory._progress_bar_widget)
 
256
 
    def test_set_progress_bar_widget(self):
 
257
 
        ui_factory = ui.GtkUIFactory()
 
258
 
        progress_widget = ui.ProgressPanel()
 
259
 
        ui_factory.set_progress_bar_widget(progress_widget)
 
260
 
        self.assertIs(progress_widget, ui_factory._progress_bar_widget)
 
262
 
    def test_get_boolean_true(self):
 
263
 
        ui_factory = ui.GtkUIFactory()
 
264
 
        MockMethod.bind(self, ui.PromptDialog, 'run', Gtk.ResponseType.YES)
 
265
 
        boolean_value = ui_factory.get_boolean('test')
 
266
 
        self.assertIs(True, ui.PromptDialog.run.called)
 
267
 
        self.assertIs(True, boolean_value)
 
269
 
    def test_get_boolean_false(self):
 
270
 
        ui_factory = ui.GtkUIFactory()
 
271
 
        MockMethod.bind(self, ui.PromptDialog, 'run', Gtk.ResponseType.NO)
 
272
 
        boolean_value = ui_factory.get_boolean('test')
 
273
 
        self.assertIs(True, ui.PromptDialog.run.called)
 
274
 
        self.assertIs(False, boolean_value)
 
276
 
    def test_show_message(self):
 
277
 
        ui_factory = ui.GtkUIFactory()
 
278
 
        MockMethod.bind(self, ui.InfoDialog, 'run', Gtk.ResponseType.CLOSE)
 
279
 
        ui_factory.show_message('test')
 
280
 
        self.assertIs(True, ui.InfoDialog.run.called)
 
282
 
    def test_show_warning(self):
 
283
 
        ui_factory = ui.GtkUIFactory()
 
284
 
        MockMethod.bind(self, ui.WarningDialog, 'run', Gtk.ResponseType.CLOSE)
 
285
 
        ui_factory.show_warning('test')
 
286
 
        self.assertIs(True, ui.WarningDialog.run.called)
 
288
 
    def test_show_Error(self):
 
289
 
        ui_factory = ui.GtkUIFactory()
 
290
 
        MockMethod.bind(self, ui.ErrorDialog, 'run', Gtk.ResponseType.CLOSE)
 
291
 
        ui_factory.show_error('test')
 
292
 
        self.assertIs(True, ui.ErrorDialog.run.called)
 
294
 
    def test_show_user_warning(self):
 
295
 
        ui_factory = ui.GtkUIFactory()
 
296
 
        MockMethod.bind(self, ui.WarningDialog, 'run', Gtk.ResponseType.CLOSE)
 
297
 
        ui_factory.show_user_warning(
 
298
 
            'recommend_upgrade', current_format_name='1.0', basedir='./test')
 
299
 
        self.assertIs(True, ui.WarningDialog.run.called)
 
301
 
    def test_show_user_warning_supressed(self):
 
302
 
        ui_factory = ui.GtkUIFactory()
 
303
 
        ui_factory.suppressed_warnings.add('recommend_upgrade')
 
304
 
        MockMethod.bind(self, ui.WarningDialog, 'run', Gtk.ResponseType.CLOSE)
 
305
 
        ui_factory.show_user_warning(
 
306
 
            'recommend_upgrade', current_format_name='1.0', basedir='./test')
 
307
 
        self.assertIs(False, ui.WarningDialog.run.called)
 
309
 
    def test_get_password(self):
 
310
 
        ui_factory = ui.GtkUIFactory()
 
311
 
        MockMethod.bind(self, ui.PasswordDialog, 'run', Gtk.ResponseType.OK)
 
312
 
        mock_property = MockProperty.bind(
 
313
 
            self, ui.PasswordDialog, 'passwd', 'secret')
 
314
 
        password = ui_factory.get_password('test')
 
315
 
        self.assertIs(True, ui.PasswordDialog.run.called)
 
316
 
        self.assertIs(True, mock_property.called)
 
317
 
        self.assertEqual('secret', password)
 
319
 
    def test_progress_all_finished_with_widget(self):
 
320
 
        ui_factory = ui.GtkUIFactory()
 
321
 
        progress_widget = ui.ProgressPanel()
 
322
 
        MockMethod.bind(self, progress_widget, 'finished')
 
323
 
        ui_factory.set_progress_bar_widget(progress_widget)
 
324
 
        self.assertIs(None, ui_factory._progress_all_finished())
 
325
 
        self.assertIs(True, progress_widget.finished.called)
 
327
 
    def test_progress_all_finished_without_widget(self):
 
328
 
        ui_factory = ui.GtkUIFactory()
 
329
 
        self.assertIs(None, ui_factory._progress_all_finished())
 
331
 
    def test_progress_updated_with_widget(self):
 
332
 
        ui_factory = ui.GtkUIFactory()
 
333
 
        progress_widget = ui.ProgressPanel()
 
334
 
        MockMethod.bind(self, progress_widget, 'update')
 
335
 
        ui_factory.set_progress_bar_widget(progress_widget)
 
336
 
        task = ProgressTask()
 
340
 
        self.assertIs(None, ui_factory._progress_updated(task))
 
341
 
        self.assertIs(True, progress_widget.update.called)
 
343
 
            ('test', 1, 2), progress_widget.update.args)
 
345
 
    def test_progress_updated_without_widget(self):
 
346
 
        ui_factory = ui.GtkUIFactory()
 
347
 
        MockMethod.bind(self, ui.ProgressBarWindow, 'update')
 
348
 
        task = ProgressTask()
 
352
 
        self.assertIs(None, ui_factory._progress_updated(task))
 
353
 
        self.assertIsInstance(
 
354
 
            ui_factory._progress_bar_widget, ui.ProgressBarWindow)
 
355
 
        self.assertIs(True, ui_factory._progress_bar_widget.update.called)
 
357
 
            ('test', 1, 2), ui_factory._progress_bar_widget.update.args)
 
359
 
    def test_report_transport_activity_with_widget(self):
 
360
 
        ui_factory = ui.GtkUIFactory()
 
361
 
        progress_widget = ui.ProgressPanel()
 
362
 
        MockMethod.bind(self, progress_widget, 'tick')
 
363
 
        ui_factory.set_progress_bar_widget(progress_widget)
 
365
 
            None, ui_factory.report_transport_activity(None, None, None))
 
366
 
        self.assertIs(True, progress_widget.tick.called)
 
368
 
    def test_report_transport_activity_without_widget(self):
 
369
 
        ui_factory = ui.GtkUIFactory()
 
370
 
        MockMethod.bind(self, ui.ProgressBarWindow, 'tick')
 
372
 
            None, ui_factory.report_transport_activity(None, None, None))
 
373
 
        self.assertIsInstance(
 
374
 
            ui_factory._progress_bar_widget, ui.ProgressBarWindow)
 
375
 
        self.assertIs(True, ui.ProgressBarWindow.tick.called)