/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_ui.py

  • Committer: John Arbash Meinel
  • Date: 2006-04-25 15:05:42 UTC
  • mfrom: (1185.85.85 bzr-encoding)
  • mto: This revision was merged to the branch mainline in revision 1752.
  • Revision ID: john@arbash-meinel.com-20060425150542-c7b518dca9928691
[merge] the old bzr-encoding changes, reparenting them on bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
"""Tests for the breezy ui."""
18
 
 
19
 
import time
20
 
 
21
 
from testtools.matchers import *
22
 
 
23
 
from .. import (
24
 
    config,
25
 
    tests,
26
 
    ui as _mod_ui,
27
 
    )
28
 
from ..bzr import (
29
 
    remote,
30
 
    )
31
 
from . import (
32
 
    fixtures,
33
 
    ui_testing,
34
 
    )
35
 
from ..ui import text as _mod_ui_text
36
 
from .testui import (
37
 
    ProgressRecordingUIFactory,
38
 
    )
39
 
 
40
 
 
41
 
class TestUIConfiguration(tests.TestCaseInTempDir):
42
 
 
43
 
    def test_output_encoding_configuration(self):
44
 
        enc = next(fixtures.generate_unicode_encodings())
45
 
        config.GlobalStack().set('output_encoding', enc)
46
 
        IO = ui_testing.BytesIOWithEncoding
47
 
        ui = _mod_ui.make_ui_for_terminal(IO(), IO(), IO())
48
 
        output = ui.make_output_stream()
49
 
        self.assertEqual(output.encoding, enc)
50
 
 
51
 
 
52
 
class TestTextUIFactory(tests.TestCase):
53
 
 
54
 
    def test_text_factory_confirm(self):
55
 
        # turns into reading a regular boolean
56
 
        with ui_testing.TestUIFactory('n\n') as ui:
57
 
            self.assertEqual(
58
 
                False,
59
 
                ui.confirm_action(
60
 
                    u'Should %(thing)s pass?',
61
 
                    'breezy.tests.test_ui.confirmation',
62
 
                    {'thing': 'this'}))
63
 
 
64
 
    def test_text_factory_ascii_password(self):
65
 
        ui = ui_testing.TestUIFactory('secret\n')
66
 
        with ui.nested_progress_bar():
67
 
            self.assertEqual('secret',
68
 
                             self.apply_redirected(ui.stdin, ui.stdout,
69
 
                                                   ui.stderr,
70
 
                                                   ui.get_password))
71
 
            # ': ' is appended to prompt
72
 
            self.assertEqual(': ', ui.stderr.getvalue())
73
 
            self.assertEqual('', ui.stdout.readline())
74
 
            # stdin should be empty
75
 
            self.assertEqual('', ui.stdin.readline())
76
 
 
77
 
    def test_text_factory_unicode_password(self):
78
 
        """Test a unicode password."""
79
 
        ui = ui_testing.TextUIFactory(u'baz\u1234')
80
 
        password = ui.get_password(
81
 
            u'Hello \u1234 %(user)s', user=u'some\u1234')
82
 
        self.assertEqual(u'baz\u1234', password)
83
 
        self.assertEqual(u'Hello \u1234 some\u1234: ', ui.stderr.getvalue())
84
 
        # stdin and stdout should be empty
85
 
        self.assertEqual('', ui.stdin.readline())
86
 
        self.assertEqual('', ui.stdout.getvalue())
87
 
 
88
 
    def test_text_ui_get_boolean(self):
89
 
        stdin_text = (
90
 
            "y\n"  # True
91
 
            "n\n"  # False
92
 
            " \n y \n"  # True
93
 
            " no \n"  # False
94
 
            "yes with garbage\nY\n"  # True
95
 
            "not an answer\nno\n"  # False
96
 
            "I'm sure!\nyes\n"  # True
97
 
            "NO\n"  # False
98
 
            "foo\n")
99
 
        with ui_testing.TextUIFactory(stdin_text) as factory:
100
 
            self.assertEqual(True, factory.get_boolean(u""))
101
 
            self.assertEqual(False, factory.get_boolean(u""))
102
 
            self.assertEqual(True, factory.get_boolean(u""))
103
 
            self.assertEqual(False, factory.get_boolean(u""))
104
 
            self.assertEqual(True, factory.get_boolean(u""))
105
 
            self.assertEqual(False, factory.get_boolean(u""))
106
 
            self.assertEqual(True, factory.get_boolean(u""))
107
 
            self.assertEqual(False, factory.get_boolean(u""))
108
 
            self.assertEqual("foo\n", factory.stdin.read())
109
 
            # stdin should be empty
110
 
            self.assertEqual('', factory.stdin.readline())
111
 
            # return false on EOF
112
 
            self.assertEqual(False, factory.get_boolean(u""))
113
 
 
114
 
    def test_text_ui_choose_bad_parameters(self):
115
 
        with ui_testing.TextUIFactory(u"") as factory:
116
 
            # invalid default index
117
 
            self.assertRaises(ValueError, factory.choose, u"", u"&Yes\n&No", 3)
118
 
            # duplicated choice
119
 
            self.assertRaises(
120
 
                ValueError, factory.choose, u"", u"&choice\n&ChOiCe")
121
 
            # duplicated shortcut
122
 
            self.assertRaises(
123
 
                ValueError, factory.choose, u"", u"&choice1\nchoi&ce2")
124
 
 
125
 
    def test_text_ui_choose_prompt_explicit(self):
126
 
        # choices with explicit shortcuts
127
 
        with ui_testing.TextUIFactory(u"") as factory:
128
 
            factory.choose(u"prompt", u"&yes\n&No\nmore &info")
129
 
            self.assertEqual(
130
 
                "prompt ([y]es, [N]o, more [i]nfo): \n",
131
 
                factory.stderr.getvalue())
132
 
 
133
 
    def test_text_ui_choose_prompt_automatic(self):
134
 
        # automatic shortcuts
135
 
        with ui_testing.TextUIFactory(u"") as factory:
136
 
            factory.choose(u"prompt", u"yes\nNo\nmore info")
137
 
            self.assertEqual(
138
 
                "prompt ([y]es, [N]o, [m]ore info): \n",
139
 
                factory.stderr.getvalue())
140
 
 
141
 
    def test_text_ui_choose_return_values(self):
142
 
        def choose():
143
 
            return factory.choose(u"", u"&Yes\n&No\nMaybe\nmore &info", 3)
144
 
        stdin_text = (
145
 
            "y\n"  # 0
146
 
            "n\n"  # 1
147
 
            " \n"  # default: 3
148
 
            " no \n"  # 1
149
 
            "b\na\nd \n"  # bad shortcuts, all ignored
150
 
            "yes with garbage\nY\n"  # 0
151
 
            "not an answer\nno\n"  # 1
152
 
            "info\nmore info\n"  # 3
153
 
            "Maybe\n"  # 2
154
 
            "foo\n")
155
 
        with ui_testing.TextUIFactory(stdin_text) as factory:
156
 
            self.assertEqual(0, choose())
157
 
            self.assertEqual(1, choose())
158
 
            self.assertEqual(3, choose())
159
 
            self.assertEqual(1, choose())
160
 
            self.assertEqual(0, choose())
161
 
            self.assertEqual(1, choose())
162
 
            self.assertEqual(3, choose())
163
 
            self.assertEqual(2, choose())
164
 
            self.assertEqual("foo\n", factory.stdin.read())
165
 
            # stdin should be empty
166
 
            self.assertEqual('', factory.stdin.readline())
167
 
            # return None on EOF
168
 
            self.assertEqual(None, choose())
169
 
 
170
 
    def test_text_ui_choose_no_default(self):
171
 
        stdin_text = (
172
 
            " \n"  # no default, invalid!
173
 
            " yes \n"  # 0
174
 
            "foo\n")
175
 
        with ui_testing.TextUIFactory(stdin_text) as factory:
176
 
            self.assertEqual(0, factory.choose(u"", u"&Yes\n&No"))
177
 
            self.assertEqual("foo\n", factory.stdin.read())
178
 
 
179
 
    def test_text_ui_get_integer(self):
180
 
        stdin_text = (
181
 
            "1\n"
182
 
            "  -2  \n"
183
 
            "hmmm\nwhat else ?\nCome on\nok 42\n4.24\n42\n")
184
 
        with ui_testing.TextUIFactory(stdin_text) as factory:
185
 
            self.assertEqual(1, factory.get_integer(u""))
186
 
            self.assertEqual(-2, factory.get_integer(u""))
187
 
            self.assertEqual(42, factory.get_integer(u""))
188
 
 
189
 
    def test_text_factory_prompt(self):
190
 
        # see <https://launchpad.net/bugs/365891>
191
 
        with ui_testing.TextUIFactory() as factory:
192
 
            factory.prompt(u'foo %2e')
193
 
            self.assertEqual('', factory.stdout.getvalue())
194
 
            self.assertEqual('foo %2e', factory.stderr.getvalue())
195
 
 
196
 
    def test_text_factory_prompts_and_clears(self):
197
 
        # a get_boolean call should clear the pb before prompting
198
 
        out = ui_testing.StringIOAsTTY()
199
 
        self.overrideEnv('TERM', 'xterm')
200
 
        factory = ui_testing.TextUIFactory("yada\ny\n", stdout=out, stderr=out)
201
 
        with factory:
202
 
            pb = factory.nested_progress_bar()
203
 
            pb._avail_width = lambda: 79
204
 
            pb.show_bar = False
205
 
            pb.show_spinner = False
206
 
            pb.show_count = False
207
 
            pb.update("foo", 0, 1)
208
 
            self.assertEqual(
209
 
                True,
210
 
                self.apply_redirected(
211
 
                    None, factory.stdout, factory.stdout, factory.get_boolean,
212
 
                    u"what do you want"))
213
 
            output = out.getvalue()
214
 
            self.assertContainsRe(output,
215
 
                                  "| foo *\r\r  *\r*")
216
 
            self.assertContainsString(
217
 
                output,
218
 
                r"what do you want? ([y]es, [n]o): what do you want? "
219
 
                r"([y]es, [n]o): ")
220
 
            # stdin should have been totally consumed
221
 
            self.assertEqual('', factory.stdin.readline())
222
 
 
223
 
    def test_text_tick_after_update(self):
224
 
        ui_factory = ui_testing.TextUIFactory()
225
 
        with ui_factory.nested_progress_bar() as pb:
226
 
            pb.update('task', 0, 3)
227
 
            # Reset the clock, so that it actually tries to repaint itself
228
 
            ui_factory._progress_view._last_repaint = time.time() - 1.0
229
 
            pb.tick()
230
 
 
231
 
    def test_text_ui_getusername(self):
232
 
        ui = ui_testing.TextUIFactory('someuser\n\n')
233
 
        self.assertEqual('someuser',
234
 
                         ui.get_username(u'Hello %(host)s', host='some'))
235
 
        self.assertEqual('Hello some: ', ui.stderr.getvalue())
236
 
        self.assertEqual('', ui.stdout.getvalue())
237
 
        self.assertEqual('', ui.get_username(u"Gebruiker"))
238
 
        # stdin should be empty
239
 
        self.assertEqual('', ui.stdin.readline())
240
 
 
241
 
    def test_text_ui_getusername_unicode(self):
242
 
        ui = ui_testing.TextUIFactory(u'someuser\u1234')
243
 
        username = ui.get_username(u'Hello %(host)s', host=u'some\u1234')
244
 
        self.assertEqual(u"someuser\u1234", username)
245
 
        self.assertEqual(u"Hello some\u1234: ", ui.stderr.getvalue())
246
 
        self.assertEqual('', ui.stdout.getvalue())
247
 
 
248
 
    def test_quietness(self):
249
 
        self.overrideEnv('BRZ_PROGRESS_BAR', 'text')
250
 
        ui_factory = ui_testing.TextUIFactory(
251
 
            stderr=ui_testing.StringIOAsTTY())
252
 
        with ui_factory:
253
 
            self.assertIsInstance(ui_factory._progress_view,
254
 
                                  _mod_ui_text.TextProgressView)
255
 
            ui_factory.be_quiet(True)
256
 
            self.assertIsInstance(ui_factory._progress_view,
257
 
                                  _mod_ui_text.NullProgressView)
258
 
 
259
 
    def test_text_ui_show_user_warning(self):
260
 
        from ..bzr.groupcompress_repo import RepositoryFormat2a
261
 
        from ..bzr.knitpack_repo import RepositoryFormatKnitPack5
262
 
        ui = ui_testing.TextUIFactory()
263
 
        remote_fmt = remote.RemoteRepositoryFormat()
264
 
        remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
265
 
        ui.show_user_warning(
266
 
            'cross_format_fetch', from_format=RepositoryFormat2a(),
267
 
            to_format=remote_fmt)
268
 
        self.assertEqual('', ui.stdout.getvalue())
269
 
        self.assertContainsRe(
270
 
            ui.stderr.getvalue(),
271
 
            "^Doing on-the-fly conversion from RepositoryFormat2a\\(\\) to "
272
 
            "RemoteRepositoryFormat\\(_network_name="
273
 
            "b?'Bazaar RepositoryFormatKnitPack5 \\(bzr 1.6\\)\\\\n'\\)\\.\n"
274
 
            "This may take some time. Upgrade the repositories to "
275
 
            "the same format for better performance\\.\n$")
276
 
        # and now with it suppressed please
277
 
        ui = ui_testing.TextUIFactory()
278
 
        ui.suppressed_warnings.add('cross_format_fetch')
279
 
        ui.show_user_warning(
280
 
            'cross_format_fetch', from_format=RepositoryFormat2a(),
281
 
            to_format=remote_fmt)
282
 
        self.assertEqual('', ui.stdout.getvalue())
283
 
        self.assertEqual('', ui.stderr.getvalue())
284
 
 
285
 
 
286
 
class TestTextUIOutputStream(tests.TestCase):
287
 
    """Tests for output stream that synchronizes with progress bar."""
288
 
 
289
 
    def test_output_clears_terminal(self):
290
 
        clear_calls = []
291
 
 
292
 
        uif = ui_testing.TextUIFactory()
293
 
        uif.clear_term = lambda: clear_calls.append('clear')
294
 
 
295
 
        stream = _mod_ui_text.TextUIOutputStream(
296
 
            uif, uif.stdout, 'utf-8', 'strict')
297
 
        stream.write(u"Hello world!\n")
298
 
        stream.write(u"there's more...\n")
299
 
        stream.writelines([u"1\n", u"2\n", u"3\n"])
300
 
 
301
 
        self.assertEqual(uif.stdout.getvalue(),
302
 
                         u"Hello world!\n"
303
 
                         u"there's more...\n"
304
 
                         u"1\n2\n3\n")
305
 
        self.assertEqual(['clear', 'clear', 'clear'],
306
 
                         clear_calls)
307
 
 
308
 
        stream.flush()
309
 
 
310
 
 
311
 
class UITests(tests.TestCase):
312
 
 
313
 
    def test_progress_construction(self):
314
 
        """TextUIFactory constructs the right progress view.
315
 
        """
316
 
        FileStringIO = ui_testing.StringIOWithEncoding
317
 
        TTYStringIO = ui_testing.StringIOAsTTY
318
 
        for (file_class, term, pb, expected_pb_class) in (
319
 
                # on an xterm, either use them or not as the user requests,
320
 
                # otherwise default on
321
 
                (TTYStringIO, 'xterm', 'none', _mod_ui_text.NullProgressView),
322
 
                (TTYStringIO, 'xterm', 'text', _mod_ui_text.TextProgressView),
323
 
                (TTYStringIO, 'xterm', None, _mod_ui_text.TextProgressView),
324
 
                # on a dumb terminal, again if there's explicit configuration
325
 
                # do it, otherwise default off
326
 
                (TTYStringIO, 'dumb', 'none', _mod_ui_text.NullProgressView),
327
 
                (TTYStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
328
 
                (TTYStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
329
 
                # on a non-tty terminal, it's null regardless of $TERM
330
 
                (FileStringIO, 'xterm', None, _mod_ui_text.NullProgressView),
331
 
                (FileStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
332
 
                # however, it can still be forced on
333
 
                (FileStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
334
 
                ):
335
 
            self.overrideEnv('TERM', term)
336
 
            self.overrideEnv('BRZ_PROGRESS_BAR', pb)
337
 
            stdin = file_class(u'')
338
 
            stderr = file_class()
339
 
            stdout = file_class()
340
 
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
341
 
            self.assertIsInstance(
342
 
                uif, _mod_ui_text.TextUIFactory,
343
 
                "TERM=%s BRZ_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
344
 
            self.assertIsInstance(
345
 
                uif.make_progress_view(),
346
 
                expected_pb_class,
347
 
                "TERM=%s BRZ_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
348
 
 
349
 
    def test_text_ui_non_terminal(self):
350
 
        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
351
 
        stdin = stderr = stdout = ui_testing.StringIOWithEncoding()
352
 
        for term_type in ['dumb', None, 'xterm']:
353
 
            self.overrideEnv('TERM', term_type)
354
 
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
355
 
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
356
 
                                  'TERM=%r' % (term_type,))
357
 
 
358
 
 
359
 
class SilentUITests(tests.TestCase):
360
 
 
361
 
    def test_silent_factory_get_password(self):
362
 
        # A silent factory that can't do user interaction can't get a
363
 
        # password.  Possibly it should raise a more specific error but it
364
 
        # can't succeed.
365
 
        ui = _mod_ui.SilentUIFactory()
366
 
        stdout = ui_testing.StringIOWithEncoding()
367
 
        self.assertRaises(
368
 
            NotImplementedError,
369
 
            self.apply_redirected,
370
 
            None, stdout, stdout, ui.get_password)
371
 
        # and it didn't write anything out either
372
 
        self.assertEqual('', stdout.getvalue())
373
 
 
374
 
    def test_silent_ui_getbool(self):
375
 
        factory = _mod_ui.SilentUIFactory()
376
 
        stdout = ui_testing.StringIOWithEncoding()
377
 
        self.assertRaises(
378
 
            NotImplementedError,
379
 
            self.apply_redirected,
380
 
            None, stdout, stdout, factory.get_boolean, u"foo")
381
 
 
382
 
 
383
 
class TestUIFactoryTests(tests.TestCase):
384
 
 
385
 
    def test_test_ui_factory_progress(self):
386
 
        # there's no output; we just want to make sure this doesn't crash -
387
 
        # see https://bugs.launchpad.net/bzr/+bug/408201
388
 
        ui = ui_testing.TestUIFactory()
389
 
        with ui.nested_progress_bar() as pb:
390
 
            pb.update('hello')
391
 
            pb.tick()
392
 
 
393
 
 
394
 
class CannedInputUIFactoryTests(tests.TestCase):
395
 
 
396
 
    def test_canned_input_get_input(self):
397
 
        uif = _mod_ui.CannedInputUIFactory([True, 'mbp', 'password', 42])
398
 
        self.assertEqual(True, uif.get_boolean(u'Extra cheese?'))
399
 
        self.assertEqual('mbp', uif.get_username(u'Enter your user name'))
400
 
        self.assertEqual('password',
401
 
                         uif.get_password(u'Password for %(host)s',
402
 
                                          host='example.com'))
403
 
        self.assertEqual(42, uif.get_integer(u'And all that jazz ?'))
404
 
 
405
 
 
406
 
class TestBoolFromString(tests.TestCase):
407
 
 
408
 
    def assertIsTrue(self, s, accepted_values=None):
409
 
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
410
 
        self.assertEqual(True, res)
411
 
 
412
 
    def assertIsFalse(self, s, accepted_values=None):
413
 
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
414
 
        self.assertEqual(False, res)
415
 
 
416
 
    def assertIsNone(self, s, accepted_values=None):
417
 
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
418
 
        self.assertIs(None, res)
419
 
 
420
 
    def test_know_valid_values(self):
421
 
        self.assertIsTrue('true')
422
 
        self.assertIsFalse('false')
423
 
        self.assertIsTrue('1')
424
 
        self.assertIsFalse('0')
425
 
        self.assertIsTrue('on')
426
 
        self.assertIsFalse('off')
427
 
        self.assertIsTrue('yes')
428
 
        self.assertIsFalse('no')
429
 
        self.assertIsTrue('y')
430
 
        self.assertIsFalse('n')
431
 
        # Also try some case variations
432
 
        self.assertIsTrue('True')
433
 
        self.assertIsFalse('False')
434
 
        self.assertIsTrue('On')
435
 
        self.assertIsFalse('Off')
436
 
        self.assertIsTrue('ON')
437
 
        self.assertIsFalse('OFF')
438
 
        self.assertIsTrue('oN')
439
 
        self.assertIsFalse('oFf')
440
 
 
441
 
    def test_invalid_values(self):
442
 
        self.assertIsNone(None)
443
 
        self.assertIsNone('doubt')
444
 
        self.assertIsNone('frue')
445
 
        self.assertIsNone('talse')
446
 
        self.assertIsNone('42')
447
 
 
448
 
    def test_provided_values(self):
449
 
        av = dict(y=True, n=False, yes=True, no=False)
450
 
        self.assertIsTrue('y', av)
451
 
        self.assertIsTrue('Y', av)
452
 
        self.assertIsTrue('Yes', av)
453
 
        self.assertIsFalse('n', av)
454
 
        self.assertIsFalse('N', av)
455
 
        self.assertIsFalse('No', av)
456
 
        self.assertIsNone('1', av)
457
 
        self.assertIsNone('0', av)
458
 
        self.assertIsNone('on', av)
459
 
        self.assertIsNone('off', av)
460
 
 
461
 
 
462
 
class TestConfirmationUserInterfacePolicy(tests.TestCase):
463
 
 
464
 
    def test_confirm_action_default(self):
465
 
        base_ui = _mod_ui.NoninteractiveUIFactory()
466
 
        for answer in [True, False]:
467
 
            self.assertEqual(
468
 
                _mod_ui.ConfirmationUserInterfacePolicy(base_ui, answer, {})
469
 
                .confirm_action("Do something?",
470
 
                                "breezy.tests.do_something", {}),
471
 
                answer)
472
 
 
473
 
    def test_confirm_action_specific(self):
474
 
        base_ui = _mod_ui.NoninteractiveUIFactory()
475
 
        for default_answer in [True, False]:
476
 
            for specific_answer in [True, False]:
477
 
                for conf_id in ['given_id', 'other_id']:
478
 
                    wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
479
 
                        base_ui, default_answer,
480
 
                        dict(given_id=specific_answer))
481
 
                    result = wrapper.confirm_action(
482
 
                        "Do something?", conf_id, {})
483
 
                    if conf_id == 'given_id':
484
 
                        self.assertEqual(result, specific_answer)
485
 
                    else:
486
 
                        self.assertEqual(result, default_answer)
487
 
 
488
 
    def test_repr(self):
489
 
        base_ui = _mod_ui.NoninteractiveUIFactory()
490
 
        wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
491
 
            base_ui, True, dict(a=2))
492
 
        self.assertThat(repr(wrapper),
493
 
                        Equals("ConfirmationUserInterfacePolicy("
494
 
                               "NoninteractiveUIFactory(), True, {'a': 2})"))
495
 
 
496
 
 
497
 
class TestProgressRecordingUI(tests.TestCase):
498
 
    """Test test-oriented UIFactory that records progress updates"""
499
 
 
500
 
    def test_nested_ignore_depth_beyond_one(self):
501
 
        # we only want to capture the first level out progress, not
502
 
        # want sub-components might do. So we have nested bars ignored.
503
 
        factory = ProgressRecordingUIFactory()
504
 
        pb1 = factory.nested_progress_bar()
505
 
        pb1.update('foo', 0, 1)
506
 
        pb2 = factory.nested_progress_bar()
507
 
        pb2.update('foo', 0, 1)
508
 
        pb2.finished()
509
 
        pb1.finished()
510
 
        self.assertEqual([("update", 0, 1, 'foo')], factory._calls)
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the bzrlib ui
 
18
"""
 
19
 
 
20
import os
 
21
from StringIO import StringIO
 
22
import sys
 
23
 
 
24
import bzrlib
 
25
import bzrlib.errors as errors
 
26
from bzrlib.progress import TTYProgressBar, ProgressBarStack
 
27
from bzrlib.tests import TestCase
 
28
from bzrlib.ui import SilentUIFactory
 
29
from bzrlib.ui.text import TextUIFactory
 
30
 
 
31
 
 
32
class UITests(TestCase):
 
33
 
 
34
    def test_silent_factory(self):
 
35
 
 
36
        ui = SilentUIFactory()
 
37
        pb = ui.nested_progress_bar()
 
38
        try:
 
39
            # TODO: Test that there is no output from SilentUIFactory
 
40
    
 
41
            self.assertEquals(ui.get_password(), None)
 
42
            self.assertEquals(ui.get_password(u'Hello There \u1234 %(user)s',
 
43
                                              user=u'some\u1234')
 
44
                             , None)
 
45
        finally:
 
46
            pb.finished()
 
47
 
 
48
    def test_text_factory(self):
 
49
        ui = TextUIFactory()
 
50
        pb = ui.nested_progress_bar()
 
51
        pb.finished()
 
52
        # TODO: Test the output from TextUIFactory, perhaps by overriding sys.stdout
 
53
 
 
54
        # Unfortunately we can't actually test the ui.get_password() because 
 
55
        # that would actually prompt the user for a password during the test suite
 
56
        # This has been tested manually with both LANG=en_US.utf-8 and LANG=C
 
57
        # print
 
58
        # self.assertEquals(ui.get_password(u"%(user)s please type 'bogus'",
 
59
        #                                   user=u'some\u1234')
 
60
        #                  , 'bogus')
 
61
 
 
62
 
 
63
    def test_progress_note(self):
 
64
        stderr = StringIO()
 
65
        stdout = StringIO()
 
66
        ui_factory = TextUIFactory()
 
67
        pb = ui_factory.nested_progress_bar()
 
68
        try:
 
69
            pb.to_messages_file = stdout
 
70
            ui_factory._progress_bar_stack.bottom().to_file = stderr
 
71
            result = pb.note('t')
 
72
            self.assertEqual(None, result)
 
73
            self.assertEqual("t\n", stdout.getvalue())
 
74
            # the exact contents will depend on the terminal width and we don't
 
75
            # care about that right now - but you're probably running it on at
 
76
            # least a 10-character wide terminal :)
 
77
            self.assertContainsRe(stderr.getvalue(), r'^\r {10,}\r$')
 
78
        finally:
 
79
            pb.finished()
 
80
 
 
81
    def test_progress_nested(self):
 
82
        # test factory based nested and popping.
 
83
        ui = TextUIFactory()
 
84
        pb1 = ui.nested_progress_bar()
 
85
        pb2 = ui.nested_progress_bar()
 
86
        self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
 
87
        pb2.finished()
 
88
        pb1.finished()
 
89
 
 
90
    def test_progress_stack(self):
 
91
        # test the progress bar stack which the default text factory 
 
92
        # uses.
 
93
        stderr = StringIO()
 
94
        stdout = StringIO()
 
95
        # make a stack, which accepts parameters like a pb.
 
96
        stack = ProgressBarStack(to_file=stderr, to_messages_file=stdout)
 
97
        # but is not one
 
98
        self.assertFalse(getattr(stack, 'note', False))
 
99
        pb1 = stack.get_nested()
 
100
        pb2 = stack.get_nested()
 
101
        self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
 
102
        pb2.finished()
 
103
        pb1.finished()
 
104
        # the text ui factory never actually removes the stack once its setup.
 
105
        # we need to be able to nest again correctly from here.
 
106
        pb1 = stack.get_nested()
 
107
        pb2 = stack.get_nested()
 
108
        self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
 
109
        pb2.finished()
 
110
        pb1.finished()
 
111
 
 
112
    def test_text_factory_setting_progress_bar(self):
 
113
        # we should be able to choose the progress bar type used.
 
114
        factory = bzrlib.ui.text.TextUIFactory(
 
115
            bar_type=bzrlib.progress.DotsProgressBar)
 
116
        bar = factory.nested_progress_bar()
 
117
        bar.finished()
 
118
        self.assertIsInstance(bar, bzrlib.progress.DotsProgressBar)