17
17
"""Tests for the bzrlib ui
24
22
from StringIO import StringIO
24
from testtools.matchers import *
26
26
from bzrlib import (
33
from bzrlib.symbol_versioning import (
32
from bzrlib.tests import (
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,
42
class TestUIConfiguration(tests.TestCaseWithTransport):
44
def test_output_encoding_configuration(self):
45
enc = fixtures.generate_unicode_encodings().next()
46
config.GlobalConfig().set_user_option('output_encoding',
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)
40
55
class TestTextUIFactory(tests.TestCase):
57
def make_test_ui_factory(self, stdin_contents):
58
ui = tests.TestUIFactory(stdin=stdin_contents,
59
stdout=tests.StringIOWrapper(),
60
stderr=tests.StringIOWrapper())
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',
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()
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.
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()
86
def test_progress_note(self):
87
stderr = tests.StringIOWrapper()
88
stdout = tests.StringIOWrapper()
89
ui_factory = _mod_ui_text.TextUIFactory(stdin=tests.StringIOWrapper(''),
92
pb = ui_factory.nested_progress_bar()
94
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
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')
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()
118
# Create a progress update that isn't throttled
120
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
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$')
131
111
def test_text_ui_get_boolean(self):
132
112
stdin = tests.StringIOWrapper("y\n" # True
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(),
192
self.assertContainsRe(factory.stdout.getvalue(),
171
self.assertContainsRe(output,
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())
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())
326
307
# however, it can still be forced on
327
308
(FileStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
329
os.environ['TERM'] = term
331
if 'BZR_PROGRESS_BAR' in os.environ:
332
del os.environ['BZR_PROGRESS_BAR']
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']
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,))
459
433
self.assertIsNone('0', av)
460
434
self.assertIsNone('on', av)
461
435
self.assertIsNone('off', av)
438
class TestConfirmationUserInterfacePolicy(tests.TestCase):
440
def test_confirm_action_default(self):
441
base_ui = _mod_ui.NoninteractiveUIFactory()
442
for answer in [True, False]:
444
_mod_ui.ConfirmationUserInterfacePolicy(base_ui, answer, {})
445
.confirm_action("Do something?",
446
"bzrlib.tests.do_something", {}),
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)
460
self.assertEquals(result, default_answer)
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})"))
471
class TestProgressRecordingUI(tests.TestCase):
472
"""Test test-oriented UIFactory that records progress updates"""
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)
484
self.assertEqual([("update", 0, 1, 'foo')], factory._calls)