/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: Andrew Bennetts
  • Date: 2009-10-15 02:19:43 UTC
  • mfrom: (4634.85.12 cleanup-hof)
  • mto: This revision was merged to the branch mainline in revision 4775.
  • Revision ID: andrew.bennetts@canonical.com-20091015021943-l8tuonz6q30tc4t6
Merge do_with_cleanups from cleanup-hof, and drop (or at least make private) everything else from that branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2008, 2009 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
18
18
"""
19
19
 
20
20
import os
 
21
from StringIO import StringIO
21
22
import re
 
23
import sys
22
24
import time
23
25
 
24
 
from StringIO import StringIO
25
 
 
26
26
from bzrlib import (
27
27
    errors,
28
 
    remote,
29
 
    repository,
30
28
    tests,
31
29
    ui as _mod_ui,
32
30
    )
33
31
from bzrlib.symbol_versioning import (
34
32
    deprecated_in,
35
33
    )
36
 
from bzrlib.tests import test_progress
37
 
from bzrlib.ui import text as _mod_ui_text
38
 
 
39
 
 
40
 
class TestTextUIFactory(tests.TestCase):
 
34
from bzrlib.tests import (
 
35
    TestCase,
 
36
    TestUIFactory,
 
37
    StringIOWrapper,
 
38
    )
 
39
from bzrlib.tests.test_progress import (
 
40
    _NonTTYStringIO,
 
41
    _TTYStringIO,
 
42
    )
 
43
from bzrlib.ui import (
 
44
    CannedInputUIFactory,
 
45
    CLIUIFactory,
 
46
    SilentUIFactory,
 
47
    UIFactory,
 
48
    make_ui_for_terminal,
 
49
    )
 
50
from bzrlib.ui.text import (
 
51
    NullProgressView,
 
52
    TextProgressView,
 
53
    TextUIFactory,
 
54
    )
 
55
 
 
56
 
 
57
class UITests(tests.TestCase):
41
58
 
42
59
    def test_text_factory_ascii_password(self):
43
60
        ui = tests.TestUIFactory(stdin='secret\n',
83
100
        finally:
84
101
            pb.finished()
85
102
 
 
103
    def test_progress_construction(self):
 
104
        """TextUIFactory constructs the right progress view.
 
105
        """
 
106
        for (file_class, term, pb, expected_pb_class) in (
 
107
            # on an xterm, either use them or not as the user requests,
 
108
            # otherwise default on
 
109
            (_TTYStringIO, 'xterm', 'none', NullProgressView),
 
110
            (_TTYStringIO, 'xterm', 'text', TextProgressView),
 
111
            (_TTYStringIO, 'xterm', None, TextProgressView),
 
112
            # on a dumb terminal, again if there's explicit configuration do
 
113
            # it, otherwise default off
 
114
            (_TTYStringIO, 'dumb', 'none', NullProgressView),
 
115
            (_TTYStringIO, 'dumb', 'text', TextProgressView),
 
116
            (_TTYStringIO, 'dumb', None, NullProgressView),
 
117
            # on a non-tty terminal, it's null regardless of $TERM
 
118
            (StringIO, 'xterm', None, NullProgressView),
 
119
            (StringIO, 'dumb', None, NullProgressView),
 
120
            # however, it can still be forced on
 
121
            (StringIO, 'dumb', 'text', TextProgressView),
 
122
            ):
 
123
            os.environ['TERM'] = term
 
124
            if pb is None:
 
125
                if 'BZR_PROGRESS_BAR' in os.environ:
 
126
                    del os.environ['BZR_PROGRESS_BAR']
 
127
            else:
 
128
                os.environ['BZR_PROGRESS_BAR'] = pb
 
129
            stdin = file_class('')
 
130
            stderr = file_class()
 
131
            stdout = file_class()
 
132
            uif = make_ui_for_terminal(stdin, stdout, stderr)
 
133
            self.assertIsInstance(uif, TextUIFactory,
 
134
                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
 
135
            self.assertIsInstance(uif.make_progress_view(),
 
136
                expected_pb_class,
 
137
                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
 
138
 
 
139
    def test_text_ui_non_terminal(self):
 
140
        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
 
141
        stdin = _NonTTYStringIO('')
 
142
        stderr = _NonTTYStringIO()
 
143
        stdout = _NonTTYStringIO()
 
144
        for term_type in ['dumb', None, 'xterm']:
 
145
            if term_type is None:
 
146
                del os.environ['TERM']
 
147
            else:
 
148
                os.environ['TERM'] = term_type
 
149
            uif = make_ui_for_terminal(stdin, stdout, stderr)
 
150
            self.assertIsInstance(uif, TextUIFactory,
 
151
                'TERM=%r' % (term_type,))
 
152
 
86
153
    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)
 
154
        stderr = StringIO()
 
155
        stdout = StringIO()
 
156
        ui_factory = TextUIFactory(stdin=StringIO(''),
 
157
            stderr=stderr,
 
158
            stdout=stdout)
92
159
        pb = ui_factory.nested_progress_bar()
93
160
        try:
94
161
            result = self.applyDeprecated(deprecated_in((2, 1, 0)),
104
171
            pb.finished()
105
172
 
106
173
    def test_progress_note_clears(self):
107
 
        stderr = test_progress._TTYStringIO()
108
 
        stdout = test_progress._TTYStringIO()
 
174
        stderr = _TTYStringIO()
 
175
        stdout = _TTYStringIO()
109
176
        # so that we get a TextProgressBar
110
177
        os.environ['TERM'] = 'xterm'
111
 
        ui_factory = _mod_ui_text.TextUIFactory(
112
 
            stdin=tests.StringIOWrapper(''),
 
178
        ui_factory = TextUIFactory(
 
179
            stdin=StringIO(''),
113
180
            stdout=stdout, stderr=stderr)
114
181
        self.assertIsInstance(ui_factory._progress_view,
115
 
                              _mod_ui_text.TextProgressView)
 
182
            TextProgressView)
116
183
        pb = ui_factory.nested_progress_bar()
117
184
        try:
118
185
            # Create a progress update that isn't throttled
128
195
        finally:
129
196
            pb.finished()
130
197
 
 
198
    def test_progress_nested(self):
 
199
        # test factory based nested and popping.
 
200
        ui = TextUIFactory(None, None, None)
 
201
        pb1 = ui.nested_progress_bar()
 
202
        pb2 = ui.nested_progress_bar()
 
203
        # You do get a warning if the outermost progress bar wasn't finished
 
204
        # first - it's not clear if this is really useful or if it should just
 
205
        # become orphaned -- mbp 20090120
 
206
        warnings, _ = self.callCatchWarnings(pb1.finished)
 
207
        if len(warnings) != 1:
 
208
            self.fail("unexpected warnings: %r" % (warnings,))
 
209
        pb2.finished()
 
210
        pb1.finished()
 
211
 
131
212
    def test_text_ui_get_boolean(self):
132
 
        stdin = tests.StringIOWrapper("y\n" # True
133
 
                                      "n\n" # False
134
 
                                      "yes with garbage\nY\n" # True
135
 
                                      "not an answer\nno\n" # False
136
 
                                      "I'm sure!\nyes\n" # True
137
 
                                      "NO\n" # False
138
 
                                      "foo\n")
139
 
        stdout = tests.StringIOWrapper()
140
 
        stderr = tests.StringIOWrapper()
141
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
213
        stdin = StringIO("y\n" # True
 
214
                         "n\n" # False
 
215
                         "yes with garbage\nY\n" # True
 
216
                         "not an answer\nno\n" # False
 
217
                         "I'm sure!\nyes\n" # True
 
218
                         "NO\n" # False
 
219
                         "foo\n")
 
220
        stdout = StringIO()
 
221
        stderr = StringIO()
 
222
        factory = TextUIFactory(stdin, stdout, stderr)
142
223
        self.assertEqual(True, factory.get_boolean(""))
143
224
        self.assertEqual(False, factory.get_boolean(""))
144
225
        self.assertEqual(True, factory.get_boolean(""))
149
230
        # stdin should be empty
150
231
        self.assertEqual('', factory.stdin.readline())
151
232
 
152
 
    def test_text_ui_get_integer(self):
153
 
        stdin = tests.StringIOWrapper(
154
 
            "1\n"
155
 
            "  -2  \n"
156
 
            "hmmm\nwhat else ?\nCome on\nok 42\n4.24\n42\n")
157
 
        stdout = tests.StringIOWrapper()
158
 
        stderr = tests.StringIOWrapper()
159
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
160
 
        self.assertEqual(1, factory.get_integer(""))
161
 
        self.assertEqual(-2, factory.get_integer(""))
162
 
        self.assertEqual(42, factory.get_integer(""))
163
 
 
164
233
    def test_text_factory_prompt(self):
165
234
        # see <https://launchpad.net/bugs/365891>
166
 
        StringIO = tests.StringIOWrapper
167
 
        factory = _mod_ui_text.TextUIFactory(StringIO(), StringIO(), StringIO())
 
235
        factory = TextUIFactory(StringIO(), StringIO(), StringIO())
168
236
        factory.prompt('foo %2e')
169
237
        self.assertEqual('', factory.stdout.getvalue())
170
238
        self.assertEqual('foo %2e', factory.stderr.getvalue())
171
239
 
172
240
    def test_text_factory_prompts_and_clears(self):
173
241
        # a get_boolean call should clear the pb before prompting
174
 
        out = test_progress._TTYStringIO()
 
242
        out = _TTYStringIO()
175
243
        os.environ['TERM'] = 'xterm'
176
 
        factory = _mod_ui_text.TextUIFactory(
177
 
            stdin=tests.StringIOWrapper("yada\ny\n"),
178
 
            stdout=out, stderr=out)
 
244
        factory = TextUIFactory(stdin=StringIO("yada\ny\n"), stdout=out, stderr=out)
179
245
        pb = factory.nested_progress_bar()
180
246
        pb.show_bar = False
181
247
        pb.show_spinner = False
195
261
        self.assertEqual('', factory.stdin.readline())
196
262
 
197
263
    def test_text_tick_after_update(self):
198
 
        ui_factory = _mod_ui_text.TextUIFactory(stdout=tests.StringIOWrapper(),
199
 
                                                stderr=tests.StringIOWrapper())
 
264
        ui_factory = TextUIFactory(stdout=StringIO(), stderr=StringIO())
200
265
        pb = ui_factory.nested_progress_bar()
201
266
        try:
202
267
            pb.update('task', 0, 3)
207
272
            pb.finished()
208
273
 
209
274
    def test_text_ui_getusername(self):
210
 
        factory = _mod_ui_text.TextUIFactory(None, None, None)
211
 
        factory.stdin = tests.StringIOWrapper("someuser\n\n")
212
 
        factory.stdout = tests.StringIOWrapper()
213
 
        factory.stderr = tests.StringIOWrapper()
 
275
        factory = TextUIFactory(None, None, None)
 
276
        factory.stdin = StringIO("someuser\n\n")
 
277
        factory.stdout = StringIO()
 
278
        factory.stderr = StringIO()
214
279
        factory.stdout.encoding = "utf8"
215
280
        # there is no output from the base factory
216
281
        self.assertEqual("someuser",
238
303
        finally:
239
304
            pb.finished()
240
305
 
241
 
    def test_quietness(self):
242
 
        os.environ['BZR_PROGRESS_BAR'] = 'text'
243
 
        ui_factory = _mod_ui_text.TextUIFactory(None,
244
 
            test_progress._TTYStringIO(),
245
 
            test_progress._TTYStringIO())
246
 
        self.assertIsInstance(ui_factory._progress_view,
247
 
            _mod_ui_text.TextProgressView)
248
 
        ui_factory.be_quiet(True)
249
 
        self.assertIsInstance(ui_factory._progress_view,
250
 
            _mod_ui_text.NullProgressView)
251
 
 
252
 
    def test_text_ui_show_user_warning(self):
253
 
        from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
254
 
        from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5
255
 
        err = StringIO()
256
 
        out = StringIO()
257
 
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
258
 
        remote_fmt = remote.RemoteRepositoryFormat()
259
 
        remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
260
 
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
261
 
            to_format=remote_fmt)
262
 
        self.assertEquals('', out.getvalue())
263
 
        self.assertEquals("Doing on-the-fly conversion from RepositoryFormat2a() to "
264
 
            "RemoteRepositoryFormat(_network_name='Bazaar RepositoryFormatKnitPack5 "
265
 
            "(bzr 1.6)\\n').\nThis may take some time. Upgrade the repositories to "
266
 
            "the same format for better performance.\n",
267
 
            err.getvalue())
268
 
        # and now with it suppressed please
269
 
        err = StringIO()
270
 
        out = StringIO()
271
 
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
272
 
        ui.suppressed_warnings.add('cross_format_fetch')
273
 
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
274
 
            to_format=remote_fmt)
275
 
        self.assertEquals('', out.getvalue())
276
 
        self.assertEquals('', err.getvalue())
277
 
 
278
 
 
279
 
class TestTextUIOutputStream(tests.TestCase):
280
 
    """Tests for output stream that synchronizes with progress bar."""
281
 
 
282
 
    def test_output_clears_terminal(self):
283
 
        stdout = tests.StringIOWrapper()
284
 
        stderr = tests.StringIOWrapper()
285
 
        clear_calls = []
286
 
 
287
 
        uif =  _mod_ui_text.TextUIFactory(None, stdout, stderr)
288
 
        uif.clear_term = lambda: clear_calls.append('clear')
289
 
 
290
 
        stream = _mod_ui_text.TextUIOutputStream(uif, uif.stdout)
291
 
        stream.write("Hello world!\n")
292
 
        stream.write("there's more...\n")
293
 
        stream.writelines(["1\n", "2\n", "3\n"])
294
 
 
295
 
        self.assertEqual(stdout.getvalue(),
296
 
            "Hello world!\n"
297
 
            "there's more...\n"
298
 
            "1\n2\n3\n")
299
 
        self.assertEqual(['clear', 'clear', 'clear'],
300
 
            clear_calls)
301
 
 
302
 
        stream.flush()
303
 
 
304
 
 
305
 
class UITests(tests.TestCase):
306
 
 
307
 
    def test_progress_construction(self):
308
 
        """TextUIFactory constructs the right progress view.
309
 
        """
310
 
        TTYStringIO = test_progress._TTYStringIO
311
 
        FileStringIO = tests.StringIOWrapper
312
 
        for (file_class, term, pb, expected_pb_class) in (
313
 
            # on an xterm, either use them or not as the user requests,
314
 
            # otherwise default on
315
 
            (TTYStringIO, 'xterm', 'none', _mod_ui_text.NullProgressView),
316
 
            (TTYStringIO, 'xterm', 'text', _mod_ui_text.TextProgressView),
317
 
            (TTYStringIO, 'xterm', None, _mod_ui_text.TextProgressView),
318
 
            # on a dumb terminal, again if there's explicit configuration do
319
 
            # it, otherwise default off
320
 
            (TTYStringIO, 'dumb', 'none', _mod_ui_text.NullProgressView),
321
 
            (TTYStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
322
 
            (TTYStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
323
 
            # on a non-tty terminal, it's null regardless of $TERM
324
 
            (FileStringIO, 'xterm', None, _mod_ui_text.NullProgressView),
325
 
            (FileStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
326
 
            # however, it can still be forced on
327
 
            (FileStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
328
 
            ):
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
335
 
            stdin = file_class('')
336
 
            stderr = file_class()
337
 
            stdout = file_class()
338
 
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
339
 
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
340
 
                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
341
 
            self.assertIsInstance(uif.make_progress_view(),
342
 
                expected_pb_class,
343
 
                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
344
 
 
345
 
    def test_text_ui_non_terminal(self):
346
 
        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
347
 
        stdin = test_progress._NonTTYStringIO('')
348
 
        stderr = test_progress._NonTTYStringIO()
349
 
        stdout = test_progress._NonTTYStringIO()
350
 
        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
355
 
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
356
 
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
357
 
                'TERM=%r' % (term_type,))
358
 
 
359
 
 
360
 
class SilentUITests(tests.TestCase):
 
306
 
 
307
class CLIUITests(TestCase):
 
308
 
 
309
    def test_cli_factory_deprecated(self):
 
310
        uif = self.applyDeprecated(deprecated_in((1, 18, 0)),
 
311
            CLIUIFactory,
 
312
            StringIO(), StringIO(), StringIO())
 
313
        self.assertIsInstance(uif, UIFactory)
 
314
 
 
315
 
 
316
class SilentUITests(TestCase):
361
317
 
362
318
    def test_silent_factory_get_password(self):
363
319
        # A silent factory that can't do user interaction can't get a
364
320
        # password.  Possibly it should raise a more specific error but it
365
321
        # can't succeed.
366
 
        ui = _mod_ui.SilentUIFactory()
367
 
        stdout = tests.StringIOWrapper()
 
322
        ui = SilentUIFactory()
 
323
        stdout = StringIO()
368
324
        self.assertRaises(
369
325
            NotImplementedError,
370
326
            self.apply_redirected,
373
329
        self.assertEqual('', stdout.getvalue())
374
330
 
375
331
    def test_silent_ui_getbool(self):
376
 
        factory = _mod_ui.SilentUIFactory()
377
 
        stdout = tests.StringIOWrapper()
 
332
        factory = SilentUIFactory()
 
333
        stdout = StringIO()
378
334
        self.assertRaises(
379
335
            NotImplementedError,
380
336
            self.apply_redirected,
381
337
            None, stdout, stdout, factory.get_boolean, "foo")
382
338
 
383
339
 
384
 
class TestUIFactoryTests(tests.TestCase):
 
340
class TestUIFactoryTests(TestCase):
385
341
 
386
342
    def test_test_ui_factory_progress(self):
387
343
        # there's no output; we just want to make sure this doesn't crash -
388
344
        # see https://bugs.edge.launchpad.net/bzr/+bug/408201
389
 
        ui = tests.TestUIFactory()
 
345
        ui = TestUIFactory()
390
346
        pb = ui.nested_progress_bar()
391
347
        pb.update('hello')
392
348
        pb.tick()
393
349
        pb.finished()
394
350
 
395
351
 
396
 
class CannedInputUIFactoryTests(tests.TestCase):
397
 
 
 
352
class CannedInputUIFactoryTests(TestCase):
 
353
    
398
354
    def test_canned_input_get_input(self):
399
 
        uif = _mod_ui.CannedInputUIFactory([True, 'mbp', 'password', 42])
400
 
        self.assertEqual(True, uif.get_boolean('Extra cheese?'))
401
 
        self.assertEqual('mbp', uif.get_username('Enter your user name'))
402
 
        self.assertEqual('password',
403
 
                         uif.get_password('Password for %(host)s',
404
 
                                          host='example.com'))
405
 
        self.assertEqual(42, uif.get_integer('And all that jazz ?'))
 
355
        uif = CannedInputUIFactory([True, 'mbp', 'password'])
 
356
        self.assertEqual(uif.get_boolean('Extra cheese?'), True)
 
357
        self.assertEqual(uif.get_username('Enter your user name'), 'mbp')
 
358
        self.assertEqual(uif.get_password('Password for %(host)s', host='example.com'),
 
359
            'password')
406
360
 
407
361
 
408
362
class TestBoolFromString(tests.TestCase):