~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_ui.py

  • Committer: Martin Pool
  • Date: 2010-02-23 07:43:11 UTC
  • mfrom: (4797.2.20 2.1)
  • mto: This revision was merged to the branch mainline in revision 5055.
  • Revision ID: mbp@sourcefrog.net-20100223074311-gnj55xdhrgz9l94e
Merge 2.1 back to trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""
19
19
 
20
20
import os
 
21
import re
21
22
import time
22
23
 
23
 
from StringIO import StringIO
24
 
 
25
 
from testtools.matchers import *
26
 
 
27
24
from bzrlib import (
28
 
    config,
29
25
    errors,
30
 
    remote,
31
 
    repository,
32
26
    tests,
33
27
    ui as _mod_ui,
34
28
    )
35
29
from bzrlib.symbol_versioning import (
36
30
    deprecated_in,
37
31
    )
38
 
from bzrlib.tests import (
39
 
    fixtures,
40
 
    test_progress,
41
 
    )
 
32
from bzrlib.tests import test_progress
42
33
from bzrlib.ui import text as _mod_ui_text
43
 
from bzrlib.tests.testui import (
44
 
    ProgressRecordingUIFactory,
45
 
    )
46
 
 
47
 
 
48
 
class TestUIConfiguration(tests.TestCaseWithTransport):
49
 
 
50
 
    def test_output_encoding_configuration(self):
51
 
        enc = fixtures.generate_unicode_encodings().next()
52
 
        config.GlobalConfig().set_user_option('output_encoding',
53
 
            enc)
54
 
        ui = tests.TestUIFactory(stdin=None,
55
 
            stdout=tests.StringIOWrapper(),
56
 
            stderr=tests.StringIOWrapper())
57
 
        output = ui.make_output_stream()
58
 
        self.assertEquals(output.encoding, enc)
59
34
 
60
35
 
61
36
class TestTextUIFactory(tests.TestCase):
62
37
 
63
 
    def make_test_ui_factory(self, stdin_contents):
64
 
        ui = tests.TestUIFactory(stdin=stdin_contents,
65
 
                                 stdout=tests.StringIOWrapper(),
66
 
                                 stderr=tests.StringIOWrapper())
67
 
        return ui
68
 
 
69
 
    def test_text_factory_confirm(self):
70
 
        # turns into reading a regular boolean
71
 
        ui = self.make_test_ui_factory('n\n')
72
 
        self.assertEquals(ui.confirm_action('Should %(thing)s pass?',
73
 
            'bzrlib.tests.test_ui.confirmation',
74
 
            {'thing': 'this'},),
75
 
            False)
76
 
 
77
38
    def test_text_factory_ascii_password(self):
78
 
        ui = self.make_test_ui_factory('secret\n')
 
39
        ui = tests.TestUIFactory(stdin='secret\n',
 
40
                                 stdout=tests.StringIOWrapper(),
 
41
                                 stderr=tests.StringIOWrapper())
79
42
        pb = ui.nested_progress_bar()
80
43
        try:
81
44
            self.assertEqual('secret',
96
59
        We can't predict what encoding users will have for stdin, so we force
97
60
        it to utf8 to test that we transport the password correctly.
98
61
        """
99
 
        ui = self.make_test_ui_factory(u'baz\u1234'.encode('utf8'))
 
62
        ui = tests.TestUIFactory(stdin=u'baz\u1234'.encode('utf8'),
 
63
                                 stdout=tests.StringIOWrapper(),
 
64
                                 stderr=tests.StringIOWrapper())
100
65
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = 'utf8'
101
66
        pb = ui.nested_progress_bar()
102
67
        try:
114
79
        finally:
115
80
            pb.finished()
116
81
 
 
82
    def test_progress_note(self):
 
83
        stderr = tests.StringIOWrapper()
 
84
        stdout = tests.StringIOWrapper()
 
85
        ui_factory = _mod_ui_text.TextUIFactory(stdin=tests.StringIOWrapper(''),
 
86
                                                stderr=stderr,
 
87
                                                stdout=stdout)
 
88
        pb = ui_factory.nested_progress_bar()
 
89
        try:
 
90
            result = self.applyDeprecated(deprecated_in((2, 1, 0)),
 
91
                pb.note,
 
92
                't')
 
93
            self.assertEqual(None, result)
 
94
            self.assertEqual("t\n", stdout.getvalue())
 
95
            # Since there was no update() call, there should be no clear() call
 
96
            self.failIf(re.search(r'^\r {10,}\r$',
 
97
                                  stderr.getvalue()) is not None,
 
98
                        'We cleared the stderr without anything to put there')
 
99
        finally:
 
100
            pb.finished()
 
101
 
 
102
    def test_progress_note_clears(self):
 
103
        stderr = test_progress._TTYStringIO()
 
104
        stdout = test_progress._TTYStringIO()
 
105
        # so that we get a TextProgressBar
 
106
        os.environ['TERM'] = 'xterm'
 
107
        ui_factory = _mod_ui_text.TextUIFactory(
 
108
            stdin=tests.StringIOWrapper(''),
 
109
            stdout=stdout, stderr=stderr)
 
110
        self.assertIsInstance(ui_factory._progress_view,
 
111
                              _mod_ui_text.TextProgressView)
 
112
        pb = ui_factory.nested_progress_bar()
 
113
        try:
 
114
            # Create a progress update that isn't throttled
 
115
            pb.update('x', 1, 1)
 
116
            result = self.applyDeprecated(deprecated_in((2, 1, 0)),
 
117
                pb.note, 't')
 
118
            self.assertEqual(None, result)
 
119
            self.assertEqual("t\n", stdout.getvalue())
 
120
            # the exact contents will depend on the terminal width and we don't
 
121
            # care about that right now - but you're probably running it on at
 
122
            # least a 10-character wide terminal :)
 
123
            self.assertContainsRe(stderr.getvalue(), r'\r {10,}\r$')
 
124
        finally:
 
125
            pb.finished()
 
126
 
117
127
    def test_text_ui_get_boolean(self):
118
128
        stdin = tests.StringIOWrapper("y\n" # True
119
129
                                      "n\n" # False
162
172
        factory = _mod_ui_text.TextUIFactory(
163
173
            stdin=tests.StringIOWrapper("yada\ny\n"),
164
174
            stdout=out, stderr=out)
165
 
        factory._avail_width = lambda: 79
166
175
        pb = factory.nested_progress_bar()
167
176
        pb.show_bar = False
168
177
        pb.show_spinner = False
174
183
                                               factory.get_boolean,
175
184
                                               "what do you want"))
176
185
        output = out.getvalue()
177
 
        self.assertContainsRe(output,
178
 
            "| foo *\r\r  *\r*")
179
 
        self.assertContainsRe(output,
 
186
        self.assertContainsRe(factory.stdout.getvalue(),
 
187
            "foo *\r\r  *\r*")
 
188
        self.assertContainsRe(factory.stdout.getvalue(),
180
189
            r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
181
190
        # stdin should have been totally consumed
182
191
        self.assertEqual('', factory.stdin.readline())
236
245
        self.assertIsInstance(ui_factory._progress_view,
237
246
            _mod_ui_text.NullProgressView)
238
247
 
239
 
    def test_text_ui_show_user_warning(self):
240
 
        from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
241
 
        from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5
242
 
        err = StringIO()
243
 
        out = StringIO()
244
 
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
245
 
        remote_fmt = remote.RemoteRepositoryFormat()
246
 
        remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
247
 
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
248
 
            to_format=remote_fmt)
249
 
        self.assertEquals('', out.getvalue())
250
 
        self.assertEquals("Doing on-the-fly conversion from RepositoryFormat2a() to "
251
 
            "RemoteRepositoryFormat(_network_name='Bazaar RepositoryFormatKnitPack5 "
252
 
            "(bzr 1.6)\\n').\nThis may take some time. Upgrade the repositories to "
253
 
            "the same format for better performance.\n",
254
 
            err.getvalue())
255
 
        # and now with it suppressed please
256
 
        err = StringIO()
257
 
        out = StringIO()
258
 
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
259
 
        ui.suppressed_warnings.add('cross_format_fetch')
260
 
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
261
 
            to_format=remote_fmt)
262
 
        self.assertEquals('', out.getvalue())
263
 
        self.assertEquals('', err.getvalue())
264
 
 
265
248
 
266
249
class TestTextUIOutputStream(tests.TestCase):
267
250
    """Tests for output stream that synchronizes with progress bar."""
372
355
 
373
356
    def test_test_ui_factory_progress(self):
374
357
        # there's no output; we just want to make sure this doesn't crash -
375
 
        # see https://bugs.launchpad.net/bzr/+bug/408201
 
358
        # see https://bugs.edge.launchpad.net/bzr/+bug/408201
376
359
        ui = tests.TestUIFactory()
377
360
        pb = ui.nested_progress_bar()
378
361
        pb.update('hello')
446
429
        self.assertIsNone('0', av)
447
430
        self.assertIsNone('on', av)
448
431
        self.assertIsNone('off', av)
449
 
 
450
 
 
451
 
class TestConfirmationUserInterfacePolicy(tests.TestCase):
452
 
 
453
 
    def test_confirm_action_default(self):
454
 
        base_ui = _mod_ui.NoninteractiveUIFactory()
455
 
        for answer in [True, False]:
456
 
            self.assertEquals(
457
 
                _mod_ui.ConfirmationUserInterfacePolicy(base_ui, answer, {})
458
 
                .confirm_action("Do something?",
459
 
                    "bzrlib.tests.do_something", {}),
460
 
                answer)
461
 
 
462
 
    def test_confirm_action_specific(self):
463
 
        base_ui = _mod_ui.NoninteractiveUIFactory()
464
 
        for default_answer in [True, False]:
465
 
            for specific_answer in [True, False]:
466
 
                for conf_id in ['given_id', 'other_id']:
467
 
                    wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
468
 
                        base_ui, default_answer, dict(given_id=specific_answer))
469
 
                    result = wrapper.confirm_action("Do something?", conf_id, {})
470
 
                    if conf_id == 'given_id':
471
 
                        self.assertEquals(result, specific_answer)
472
 
                    else:
473
 
                        self.assertEquals(result, default_answer)
474
 
 
475
 
    def test_repr(self):
476
 
        base_ui = _mod_ui.NoninteractiveUIFactory()
477
 
        wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
478
 
            base_ui, True, dict(a=2))
479
 
        self.assertThat(repr(wrapper),
480
 
            Equals("ConfirmationUserInterfacePolicy("
481
 
                "NoninteractiveUIFactory(), True, {'a': 2})"))
482
 
 
483
 
 
484
 
class TestProgressRecordingUI(tests.TestCase):
485
 
    """Test test-oriented UIFactory that records progress updates"""
486
 
 
487
 
    def test_nested_ignore_depth_beyond_one(self):
488
 
        # we only want to capture the first level out progress, not
489
 
        # want sub-components might do. So we have nested bars ignored.
490
 
        factory = ProgressRecordingUIFactory()
491
 
        pb1 = factory.nested_progress_bar()
492
 
        pb1.update('foo', 0, 1)
493
 
        pb2 = factory.nested_progress_bar()
494
 
        pb2.update('foo', 0, 1)
495
 
        pb2.finished()
496
 
        pb1.finished()
497
 
        self.assertEqual([("update", 0, 1, 'foo')], factory._calls)