/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: 2010-02-12 04:33:05 UTC
  • mfrom: (5031 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5032.
  • Revision ID: andrew.bennetts@canonical.com-20100212043305-ujdbsdoviql2t7i3
MergeĀ lp:bzr

Show diffs side-by-side

added added

removed removed

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