105
def test_progress_construction(self):
106
"""TextUIFactory constructs the right progress view.
108
for (file_class, term, pb, expected_pb_class) in (
109
# on an xterm, either use them or not as the user requests,
110
# otherwise default on
111
(_TTYStringIO, 'xterm', 'none', NullProgressView),
112
(_TTYStringIO, 'xterm', 'text', TextProgressView),
113
(_TTYStringIO, 'xterm', None, TextProgressView),
114
# on a dumb terminal, again if there's explicit configuration do
115
# it, otherwise default off
116
(_TTYStringIO, 'dumb', 'none', NullProgressView),
117
(_TTYStringIO, 'dumb', 'text', TextProgressView),
118
(_TTYStringIO, 'dumb', None, NullProgressView),
119
# on a non-tty terminal, it's null regardless of $TERM
120
(StringIO, 'xterm', None, NullProgressView),
121
(StringIO, 'dumb', None, NullProgressView),
122
# however, it can still be forced on
123
(StringIO, 'dumb', 'text', TextProgressView),
125
os.environ['TERM'] = term
127
if 'BZR_PROGRESS_BAR' in os.environ:
128
del os.environ['BZR_PROGRESS_BAR']
130
os.environ['BZR_PROGRESS_BAR'] = pb
131
stdin = file_class('')
132
stderr = file_class()
133
stdout = file_class()
134
uif = make_ui_for_terminal(stdin, stdout, stderr)
135
self.assertIsInstance(uif, TextUIFactory,
136
"TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
137
self.assertIsInstance(uif.make_progress_view(),
139
"TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
141
def test_text_ui_non_terminal(self):
142
"""Even on non-ttys, make_ui_for_terminal gives a text ui."""
143
stdin = _NonTTYStringIO('')
144
stderr = _NonTTYStringIO()
145
stdout = _NonTTYStringIO()
146
for term_type in ['dumb', None, 'xterm']:
147
if term_type is None:
148
del os.environ['TERM']
150
os.environ['TERM'] = term_type
151
uif = make_ui_for_terminal(stdin, stdout, stderr)
152
self.assertIsInstance(uif, TextUIFactory,
153
'TERM=%r' % (term_type,))
86
155
def test_progress_note(self):
87
stderr = tests.StringIOWrapper()
88
stdout = tests.StringIOWrapper()
89
ui_factory = _mod_ui_text.TextUIFactory(stdin=tests.StringIOWrapper(''),
158
ui_factory = TextUIFactory(stdin=StringIO(''),
92
161
pb = ui_factory.nested_progress_bar()
94
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
163
result = pb.note('t')
97
164
self.assertEqual(None, result)
98
165
self.assertEqual("t\n", stdout.getvalue())
99
166
# Since there was no update() call, there should be no clear() call
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(
113
180
stdout=stdout, stderr=stderr)
114
181
self.assertIsInstance(ui_factory._progress_view,
115
_mod_ui_text.TextProgressView)
116
183
pb = ui_factory.nested_progress_bar()
118
185
# Create a progress update that isn't throttled
119
186
pb.update('x', 1, 1)
120
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
187
result = pb.note('t')
122
188
self.assertEqual(None, result)
123
189
self.assertEqual("t\n", stdout.getvalue())
124
190
# the exact contents will depend on the terminal width and we don't
197
def test_progress_nested(self):
198
# test factory based nested and popping.
199
ui = TextUIFactory(None, None, None)
200
pb1 = ui.nested_progress_bar()
201
pb2 = ui.nested_progress_bar()
202
# You do get a warning if the outermost progress bar wasn't finished
203
# first - it's not clear if this is really useful or if it should just
204
# become orphaned -- mbp 20090120
205
warnings, _ = self.callCatchWarnings(pb1.finished)
206
if len(warnings) != 1:
207
self.fail("unexpected warnings: %r" % (warnings,))
131
211
def test_text_ui_get_boolean(self):
132
stdin = tests.StringIOWrapper("y\n" # True
134
"yes with garbage\nY\n" # True
135
"not an answer\nno\n" # False
136
"I'm sure!\nyes\n" # True
139
stdout = tests.StringIOWrapper()
140
stderr = tests.StringIOWrapper()
141
factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
212
stdin = StringIO("y\n" # True
214
"yes with garbage\nY\n" # True
215
"not an answer\nno\n" # False
216
"I'm sure!\nyes\n" # True
221
factory = TextUIFactory(stdin, stdout, stderr)
142
222
self.assertEqual(True, factory.get_boolean(""))
143
223
self.assertEqual(False, factory.get_boolean(""))
144
224
self.assertEqual(True, factory.get_boolean(""))
149
229
# stdin should be empty
150
230
self.assertEqual('', factory.stdin.readline())
152
def test_text_ui_get_integer(self):
153
stdin = tests.StringIOWrapper(
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(""))
164
232
def test_text_factory_prompt(self):
165
233
# see <https://launchpad.net/bugs/365891>
166
StringIO = tests.StringIOWrapper
167
factory = _mod_ui_text.TextUIFactory(StringIO(), StringIO(), StringIO())
234
factory = TextUIFactory(StringIO(), StringIO(), StringIO())
168
235
factory.prompt('foo %2e')
169
236
self.assertEqual('', factory.stdout.getvalue())
170
237
self.assertEqual('foo %2e', factory.stderr.getvalue())
172
239
def test_text_factory_prompts_and_clears(self):
173
240
# a get_boolean call should clear the pb before prompting
174
out = test_progress._TTYStringIO()
175
242
os.environ['TERM'] = 'xterm'
176
factory = _mod_ui_text.TextUIFactory(
177
stdin=tests.StringIOWrapper("yada\ny\n"),
178
stdout=out, stderr=out)
243
factory = TextUIFactory(stdin=StringIO("yada\ny\n"), stdout=out, stderr=out)
179
244
pb = factory.nested_progress_bar()
180
245
pb.show_bar = False
181
246
pb.show_spinner = False
276
329
self.assertEquals('', err.getvalue())
279
class TestTextUIOutputStream(tests.TestCase):
280
"""Tests for output stream that synchronizes with progress bar."""
282
def test_output_clears_terminal(self):
283
stdout = tests.StringIOWrapper()
284
stderr = tests.StringIOWrapper()
287
uif = _mod_ui_text.TextUIFactory(None, stdout, stderr)
288
uif.clear_term = lambda: clear_calls.append('clear')
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"])
295
self.assertEqual(stdout.getvalue(),
299
self.assertEqual(['clear', 'clear', 'clear'],
305
class UITests(tests.TestCase):
307
def test_progress_construction(self):
308
"""TextUIFactory constructs the right progress view.
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),
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
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(),
343
"TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
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']
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,))
360
class SilentUITests(tests.TestCase):
332
class CLIUITests(TestCase):
334
def test_cli_factory_deprecated(self):
335
uif = self.applyDeprecated(deprecated_in((1, 18, 0)),
337
StringIO(), StringIO(), StringIO())
338
self.assertIsInstance(uif, UIFactory)
341
class SilentUITests(TestCase):
362
343
def test_silent_factory_get_password(self):
363
344
# A silent factory that can't do user interaction can't get a
364
345
# password. Possibly it should raise a more specific error but it
366
ui = _mod_ui.SilentUIFactory()
367
stdout = tests.StringIOWrapper()
347
ui = SilentUIFactory()
368
349
self.assertRaises(
369
350
NotImplementedError,
370
351
self.apply_redirected,
373
354
self.assertEqual('', stdout.getvalue())
375
356
def test_silent_ui_getbool(self):
376
factory = _mod_ui.SilentUIFactory()
377
stdout = tests.StringIOWrapper()
357
factory = SilentUIFactory()
378
359
self.assertRaises(
379
360
NotImplementedError,
380
361
self.apply_redirected,
381
362
None, stdout, stdout, factory.get_boolean, "foo")
384
class TestUIFactoryTests(tests.TestCase):
365
class TestUIFactoryTests(TestCase):
386
367
def test_test_ui_factory_progress(self):
387
368
# there's no output; we just want to make sure this doesn't crash -
388
369
# see https://bugs.edge.launchpad.net/bzr/+bug/408201
389
ui = tests.TestUIFactory()
390
371
pb = ui.nested_progress_bar()
391
372
pb.update('hello')
396
class CannedInputUIFactoryTests(tests.TestCase):
377
class CannedInputUIFactoryTests(TestCase):
398
379
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',
405
self.assertEqual(42, uif.get_integer('And all that jazz ?'))
380
uif = CannedInputUIFactory([True, 'mbp', 'password'])
381
self.assertEqual(uif.get_boolean('Extra cheese?'), True)
382
self.assertEqual(uif.get_username('Enter your user name'), 'mbp')
383
self.assertEqual(uif.get_password('Password for %(host)s', host='example.com'),
408
387
class TestBoolFromString(tests.TestCase):