~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_ui.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-05-26 15:20:03 UTC
  • mfrom: (5918.1.1 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20110526152003-azhnn5k01tjf1hrg
(vila) Release 2.4b3 (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 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
17
17
"""Tests for the bzrlib ui
18
18
"""
19
19
 
20
 
import os
21
 
import re
22
20
import time
23
21
 
24
22
from StringIO import StringIO
25
23
 
 
24
from testtools.matchers import *
 
25
 
26
26
from bzrlib import (
27
 
    errors,
 
27
    config,
28
28
    remote,
29
 
    repository,
30
29
    tests,
31
30
    ui as _mod_ui,
32
31
    )
33
 
from bzrlib.symbol_versioning import (
34
 
    deprecated_in,
 
32
from bzrlib.tests import (
 
33
    fixtures,
 
34
    test_progress,
35
35
    )
36
 
from bzrlib.tests import test_progress
37
36
from bzrlib.ui import text as _mod_ui_text
 
37
from bzrlib.tests.testui import (
 
38
    ProgressRecordingUIFactory,
 
39
    )
 
40
 
 
41
 
 
42
class TestUIConfiguration(tests.TestCaseWithTransport):
 
43
 
 
44
    def test_output_encoding_configuration(self):
 
45
        enc = fixtures.generate_unicode_encodings().next()
 
46
        config.GlobalConfig().set_user_option('output_encoding',
 
47
            enc)
 
48
        ui = tests.TestUIFactory(stdin=None,
 
49
            stdout=tests.StringIOWrapper(),
 
50
            stderr=tests.StringIOWrapper())
 
51
        output = ui.make_output_stream()
 
52
        self.assertEquals(output.encoding, enc)
38
53
 
39
54
 
40
55
class TestTextUIFactory(tests.TestCase):
41
56
 
 
57
    def make_test_ui_factory(self, stdin_contents):
 
58
        ui = tests.TestUIFactory(stdin=stdin_contents,
 
59
                                 stdout=tests.StringIOWrapper(),
 
60
                                 stderr=tests.StringIOWrapper())
 
61
        return ui
 
62
 
 
63
    def test_text_factory_confirm(self):
 
64
        # turns into reading a regular boolean
 
65
        ui = self.make_test_ui_factory('n\n')
 
66
        self.assertEquals(ui.confirm_action('Should %(thing)s pass?',
 
67
            'bzrlib.tests.test_ui.confirmation',
 
68
            {'thing': 'this'},),
 
69
            False)
 
70
 
42
71
    def test_text_factory_ascii_password(self):
43
 
        ui = tests.TestUIFactory(stdin='secret\n',
44
 
                                 stdout=tests.StringIOWrapper(),
45
 
                                 stderr=tests.StringIOWrapper())
 
72
        ui = self.make_test_ui_factory('secret\n')
46
73
        pb = ui.nested_progress_bar()
47
74
        try:
48
75
            self.assertEqual('secret',
63
90
        We can't predict what encoding users will have for stdin, so we force
64
91
        it to utf8 to test that we transport the password correctly.
65
92
        """
66
 
        ui = tests.TestUIFactory(stdin=u'baz\u1234'.encode('utf8'),
67
 
                                 stdout=tests.StringIOWrapper(),
68
 
                                 stderr=tests.StringIOWrapper())
 
93
        ui = self.make_test_ui_factory(u'baz\u1234'.encode('utf8'))
69
94
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = 'utf8'
70
95
        pb = ui.nested_progress_bar()
71
96
        try:
83
108
        finally:
84
109
            pb.finished()
85
110
 
86
 
    def test_progress_note(self):
87
 
        stderr = tests.StringIOWrapper()
88
 
        stdout = tests.StringIOWrapper()
89
 
        ui_factory = _mod_ui_text.TextUIFactory(stdin=tests.StringIOWrapper(''),
90
 
                                                stderr=stderr,
91
 
                                                stdout=stdout)
92
 
        pb = ui_factory.nested_progress_bar()
93
 
        try:
94
 
            result = self.applyDeprecated(deprecated_in((2, 1, 0)),
95
 
                pb.note,
96
 
                't')
97
 
            self.assertEqual(None, result)
98
 
            self.assertEqual("t\n", stdout.getvalue())
99
 
            # Since there was no update() call, there should be no clear() call
100
 
            self.failIf(re.search(r'^\r {10,}\r$',
101
 
                                  stderr.getvalue()) is not None,
102
 
                        'We cleared the stderr without anything to put there')
103
 
        finally:
104
 
            pb.finished()
105
 
 
106
 
    def test_progress_note_clears(self):
107
 
        stderr = test_progress._TTYStringIO()
108
 
        stdout = test_progress._TTYStringIO()
109
 
        # so that we get a TextProgressBar
110
 
        os.environ['TERM'] = 'xterm'
111
 
        ui_factory = _mod_ui_text.TextUIFactory(
112
 
            stdin=tests.StringIOWrapper(''),
113
 
            stdout=stdout, stderr=stderr)
114
 
        self.assertIsInstance(ui_factory._progress_view,
115
 
                              _mod_ui_text.TextProgressView)
116
 
        pb = ui_factory.nested_progress_bar()
117
 
        try:
118
 
            # Create a progress update that isn't throttled
119
 
            pb.update('x', 1, 1)
120
 
            result = self.applyDeprecated(deprecated_in((2, 1, 0)),
121
 
                pb.note, 't')
122
 
            self.assertEqual(None, result)
123
 
            self.assertEqual("t\n", stdout.getvalue())
124
 
            # the exact contents will depend on the terminal width and we don't
125
 
            # care about that right now - but you're probably running it on at
126
 
            # least a 10-character wide terminal :)
127
 
            self.assertContainsRe(stderr.getvalue(), r'\r {10,}\r$')
128
 
        finally:
129
 
            pb.finished()
130
 
 
131
111
    def test_text_ui_get_boolean(self):
132
112
        stdin = tests.StringIOWrapper("y\n" # True
133
113
                                      "n\n" # False
172
152
    def test_text_factory_prompts_and_clears(self):
173
153
        # a get_boolean call should clear the pb before prompting
174
154
        out = test_progress._TTYStringIO()
175
 
        os.environ['TERM'] = 'xterm'
 
155
        self.overrideEnv('TERM', 'xterm')
176
156
        factory = _mod_ui_text.TextUIFactory(
177
157
            stdin=tests.StringIOWrapper("yada\ny\n"),
178
158
            stdout=out, stderr=out)
 
159
        factory._avail_width = lambda: 79
179
160
        pb = factory.nested_progress_bar()
180
161
        pb.show_bar = False
181
162
        pb.show_spinner = False
187
168
                                               factory.get_boolean,
188
169
                                               "what do you want"))
189
170
        output = out.getvalue()
190
 
        self.assertContainsRe(factory.stdout.getvalue(),
191
 
            "foo *\r\r  *\r*")
192
 
        self.assertContainsRe(factory.stdout.getvalue(),
 
171
        self.assertContainsRe(output,
 
172
            "| foo *\r\r  *\r*")
 
173
        self.assertContainsRe(output,
193
174
            r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
194
175
        # stdin should have been totally consumed
195
176
        self.assertEqual('', factory.stdin.readline())
239
220
            pb.finished()
240
221
 
241
222
    def test_quietness(self):
242
 
        os.environ['BZR_PROGRESS_BAR'] = 'text'
 
223
        self.overrideEnv('BZR_PROGRESS_BAR', 'text')
243
224
        ui_factory = _mod_ui_text.TextUIFactory(None,
244
225
            test_progress._TTYStringIO(),
245
226
            test_progress._TTYStringIO())
251
232
 
252
233
    def test_text_ui_show_user_warning(self):
253
234
        from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
254
 
        from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5
 
235
        from bzrlib.repofmt.knitpack_repo import RepositoryFormatKnitPack5
255
236
        err = StringIO()
256
237
        out = StringIO()
257
238
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
326
307
            # however, it can still be forced on
327
308
            (FileStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
328
309
            ):
329
 
            os.environ['TERM'] = term
330
 
            if pb is None:
331
 
                if 'BZR_PROGRESS_BAR' in os.environ:
332
 
                    del os.environ['BZR_PROGRESS_BAR']
333
 
            else:
334
 
                os.environ['BZR_PROGRESS_BAR'] = pb
 
310
            self.overrideEnv('TERM', term)
 
311
            self.overrideEnv('BZR_PROGRESS_BAR', pb)
335
312
            stdin = file_class('')
336
313
            stderr = file_class()
337
314
            stdout = file_class()
348
325
        stderr = test_progress._NonTTYStringIO()
349
326
        stdout = test_progress._NonTTYStringIO()
350
327
        for term_type in ['dumb', None, 'xterm']:
351
 
            if term_type is None:
352
 
                del os.environ['TERM']
353
 
            else:
354
 
                os.environ['TERM'] = term_type
 
328
            self.overrideEnv('TERM', term_type)
355
329
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
356
330
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
357
331
                'TERM=%r' % (term_type,))
385
359
 
386
360
    def test_test_ui_factory_progress(self):
387
361
        # there's no output; we just want to make sure this doesn't crash -
388
 
        # see https://bugs.edge.launchpad.net/bzr/+bug/408201
 
362
        # see https://bugs.launchpad.net/bzr/+bug/408201
389
363
        ui = tests.TestUIFactory()
390
364
        pb = ui.nested_progress_bar()
391
365
        pb.update('hello')
459
433
        self.assertIsNone('0', av)
460
434
        self.assertIsNone('on', av)
461
435
        self.assertIsNone('off', av)
 
436
 
 
437
 
 
438
class TestConfirmationUserInterfacePolicy(tests.TestCase):
 
439
 
 
440
    def test_confirm_action_default(self):
 
441
        base_ui = _mod_ui.NoninteractiveUIFactory()
 
442
        for answer in [True, False]:
 
443
            self.assertEquals(
 
444
                _mod_ui.ConfirmationUserInterfacePolicy(base_ui, answer, {})
 
445
                .confirm_action("Do something?",
 
446
                    "bzrlib.tests.do_something", {}),
 
447
                answer)
 
448
 
 
449
    def test_confirm_action_specific(self):
 
450
        base_ui = _mod_ui.NoninteractiveUIFactory()
 
451
        for default_answer in [True, False]:
 
452
            for specific_answer in [True, False]:
 
453
                for conf_id in ['given_id', 'other_id']:
 
454
                    wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
 
455
                        base_ui, default_answer, dict(given_id=specific_answer))
 
456
                    result = wrapper.confirm_action("Do something?", conf_id, {})
 
457
                    if conf_id == 'given_id':
 
458
                        self.assertEquals(result, specific_answer)
 
459
                    else:
 
460
                        self.assertEquals(result, default_answer)
 
461
 
 
462
    def test_repr(self):
 
463
        base_ui = _mod_ui.NoninteractiveUIFactory()
 
464
        wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
 
465
            base_ui, True, dict(a=2))
 
466
        self.assertThat(repr(wrapper),
 
467
            Equals("ConfirmationUserInterfacePolicy("
 
468
                "NoninteractiveUIFactory(), True, {'a': 2})"))
 
469
 
 
470
 
 
471
class TestProgressRecordingUI(tests.TestCase):
 
472
    """Test test-oriented UIFactory that records progress updates"""
 
473
 
 
474
    def test_nested_ignore_depth_beyond_one(self):
 
475
        # we only want to capture the first level out progress, not
 
476
        # want sub-components might do. So we have nested bars ignored.
 
477
        factory = ProgressRecordingUIFactory()
 
478
        pb1 = factory.nested_progress_bar()
 
479
        pb1.update('foo', 0, 1)
 
480
        pb2 = factory.nested_progress_bar()
 
481
        pb2.update('foo', 0, 1)
 
482
        pb2.finished()
 
483
        pb1.finished()
 
484
        self.assertEqual([("update", 0, 1, 'foo')], factory._calls)