36
from bzrlib.tests.test_progress import _TTYStringIO
39
from bzrlib.tests.test_progress import (
37
43
from bzrlib.ui import (
41
50
from bzrlib.ui.text import (
47
class UITests(TestCase):
49
def test_silent_factory(self):
50
ui = SilentUIFactory()
52
self.assertEqual(None,
53
self.apply_redirected(None, stdout, stdout,
55
self.assertEqual('', stdout.getvalue())
56
self.assertEqual(None,
57
self.apply_redirected(None, stdout, stdout,
59
u'Hello\u1234 %(user)s',
61
self.assertEqual('', stdout.getvalue())
57
class UITests(tests.TestCase):
63
59
def test_text_factory_ascii_password(self):
64
ui = TestUIFactory(stdin='secret\n', stdout=StringIOWrapper(),
65
stderr=StringIOWrapper())
60
ui = tests.TestUIFactory(stdin='secret\n',
61
stdout=tests.StringIOWrapper(),
62
stderr=tests.StringIOWrapper())
66
63
pb = ui.nested_progress_bar()
68
65
self.assertEqual('secret',
103
def test_progress_construction(self):
104
"""TextUIFactory constructs the right progress view.
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),
123
os.environ['TERM'] = term
125
if 'BZR_PROGRESS_BAR' in os.environ:
126
del os.environ['BZR_PROGRESS_BAR']
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(),
137
"TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
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']
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,))
106
153
def test_progress_note(self):
107
154
stderr = StringIO()
108
155
stdout = StringIO()
161
def assert_get_bool_acceptance_of_user_input(self, factory):
162
factory.stdin = StringIO("y\nyes with garbage\n"
163
"yes\nn\nnot an answer\n"
165
factory.stdout = StringIO()
166
factory.stderr = StringIO()
167
# there is no output from the base factory
168
self.assertEqual(True, factory.get_boolean(""))
169
self.assertEqual(True, factory.get_boolean(""))
170
self.assertEqual(False, factory.get_boolean(""))
209
def test_text_ui_get_boolean(self):
210
stdin = StringIO("y\n" # True
212
"yes with garbage\nY\n" # True
213
"not an answer\nno\n" # False
214
"I'm sure!\nyes\n" # True
219
factory = TextUIFactory(stdin, stdout, stderr)
220
self.assertEqual(True, factory.get_boolean(""))
221
self.assertEqual(False, factory.get_boolean(""))
222
self.assertEqual(True, factory.get_boolean(""))
223
self.assertEqual(False, factory.get_boolean(""))
224
self.assertEqual(True, factory.get_boolean(""))
171
225
self.assertEqual(False, factory.get_boolean(""))
172
226
self.assertEqual("foo\n", factory.stdin.read())
173
227
# stdin should be empty
174
228
self.assertEqual('', factory.stdin.readline())
176
def test_silent_ui_getbool(self):
177
factory = SilentUIFactory()
178
self.assert_get_bool_acceptance_of_user_input(factory)
180
def test_silent_factory_prompts_silently(self):
181
factory = SilentUIFactory()
183
factory.stdin = StringIO("y\n")
184
self.assertEqual(True,
185
self.apply_redirected(None, stdout, stdout,
186
factory.get_boolean, "foo"))
187
self.assertEqual("", stdout.getvalue())
188
# stdin should be empty
189
self.assertEqual('', factory.stdin.readline())
191
def test_text_ui_getbool(self):
192
factory = TextUIFactory(None, None, None)
193
self.assert_get_bool_acceptance_of_user_input(factory)
195
230
def test_text_factory_prompt(self):
196
231
# see <https://launchpad.net/bugs/365891>
197
factory = TextUIFactory(None, StringIO(), StringIO(), StringIO())
232
factory = TextUIFactory(StringIO(), StringIO(), StringIO())
198
233
factory.prompt('foo %2e')
199
234
self.assertEqual('', factory.stdout.getvalue())
200
235
self.assertEqual('foo %2e', factory.stderr.getvalue())
278
class TestTextProgressView(TestCase):
279
"""Tests for text display of progress bars.
281
# XXX: These might be a bit easier to write if the rendering and
282
# state-maintaining parts of TextProgressView were more separate, and if
283
# the progress task called back directly to its own view not to the ui
284
# factory. -- mbp 20090312
304
class CLIUITests(TestCase):
306
def test_cli_factory_deprecated(self):
307
uif = self.applyDeprecated(deprecated_in((1, 18, 0)),
309
StringIO(), StringIO(), StringIO())
310
self.assertIsInstance(uif, UIFactory)
313
class SilentUITests(TestCase):
315
def test_silent_factory_get_password(self):
316
# A silent factory that can't do user interaction can't get a
317
# password. Possibly it should raise a more specific error but it
319
ui = SilentUIFactory()
323
self.apply_redirected,
324
None, stdout, stdout, ui.get_password)
325
# and it didn't write anything out either
326
self.assertEqual('', stdout.getvalue())
328
def test_silent_ui_getbool(self):
329
factory = SilentUIFactory()
333
self.apply_redirected,
334
None, stdout, stdout, factory.get_boolean, "foo")
337
class CannedInputUIFactoryTests(TestCase):
286
def _make_factory(self):
288
uif = TextUIFactory(stderr=out)
289
uif._progress_view._width = 80
292
def test_render_progress_easy(self):
293
"""Just one task and one quarter done"""
294
out, uif = self._make_factory()
295
task = uif.nested_progress_bar()
296
task.update('reticulating splines', 5, 20)
298
'\r[####/ ] reticulating splines 5/20 \r'
301
def test_render_progress_nested(self):
302
"""Tasks proportionally contribute to overall progress"""
303
out, uif = self._make_factory()
304
task = uif.nested_progress_bar()
305
task.update('reticulating splines', 0, 2)
306
task2 = uif.nested_progress_bar()
307
task2.update('stage2', 1, 2)
308
# so we're in the first half of the main task, and half way through
311
r'[####\ ] reticulating splines:stage2 1/2'
312
, uif._progress_view._render_line())
313
# if the nested task is complete, then we're all the way through the
314
# first half of the overall work
315
task2.update('stage2', 2, 2)
317
r'[#########| ] reticulating splines:stage2 2/2'
318
, uif._progress_view._render_line())
320
def test_render_progress_sub_nested(self):
321
"""Intermediate tasks don't mess up calculation."""
322
out, uif = self._make_factory()
323
task_a = uif.nested_progress_bar()
324
task_a.update('a', 0, 2)
325
task_b = uif.nested_progress_bar()
327
task_c = uif.nested_progress_bar()
328
task_c.update('c', 1, 2)
329
# the top-level task is in its first half; the middle one has no
330
# progress indication, just a label; and the bottom one is half done,
331
# so the overall fraction is 1/4
333
r'[####| ] a:b:c 1/2'
334
, uif._progress_view._render_line())
339
def test_canned_input_get_input(self):
340
uif = CannedInputUIFactory([True, 'mbp', 'password'])
341
self.assertEqual(uif.get_boolean('Extra cheese?'), True)
342
self.assertEqual(uif.get_username('Enter your user name'), 'mbp')
343
self.assertEqual(uif.get_password('Password for %(host)s', host='example.com'),
347
class TestBoolFromString(tests.TestCase):
349
def assertIsTrue(self, s, accepted_values=None):
350
res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
351
self.assertEquals(True, res)
353
def assertIsFalse(self, s, accepted_values=None):
354
res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
355
self.assertEquals(False, res)
357
def assertIsNone(self, s, accepted_values=None):
358
res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
359
self.assertIs(None, res)
361
def test_know_valid_values(self):
362
self.assertIsTrue('true')
363
self.assertIsFalse('false')
364
self.assertIsTrue('1')
365
self.assertIsFalse('0')
366
self.assertIsTrue('on')
367
self.assertIsFalse('off')
368
self.assertIsTrue('yes')
369
self.assertIsFalse('no')
370
self.assertIsTrue('y')
371
self.assertIsFalse('n')
372
# Also try some case variations
373
self.assertIsTrue('True')
374
self.assertIsFalse('False')
375
self.assertIsTrue('On')
376
self.assertIsFalse('Off')
377
self.assertIsTrue('ON')
378
self.assertIsFalse('OFF')
379
self.assertIsTrue('oN')
380
self.assertIsFalse('oFf')
382
def test_invalid_values(self):
383
self.assertIsNone(None)
384
self.assertIsNone('doubt')
385
self.assertIsNone('frue')
386
self.assertIsNone('talse')
387
self.assertIsNone('42')
389
def test_provided_values(self):
390
av = dict(y=True, n=False, yes=True, no=False)
391
self.assertIsTrue('y', av)
392
self.assertIsTrue('Y', av)
393
self.assertIsTrue('Yes', av)
394
self.assertIsFalse('n', av)
395
self.assertIsFalse('N', av)
396
self.assertIsFalse('No', av)
397
self.assertIsNone('1', av)
398
self.assertIsNone('0', av)
399
self.assertIsNone('on', av)
400
self.assertIsNone('off', av)