~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: 2009-09-19 00:32:14 UTC
  • mfrom: (4685.2.1 bzr.dev)
  • Revision ID: pqm@pqm.ubuntu.com-20090919003214-2dli9jc4y5xhjj3n
(mbp for garyvdm) Revert rename of
        test_merge_uncommitted_otherbasis_ancestor_of_thisbasis.

Show diffs side-by-side

added added

removed removed

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