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,))
153
82
def test_progress_note(self):
156
ui_factory = TextUIFactory(stdin=StringIO(''),
83
stderr = tests.StringIOWrapper()
84
stdout = tests.StringIOWrapper()
85
ui_factory = _mod_ui_text.TextUIFactory(stdin=tests.StringIOWrapper(''),
159
88
pb = ui_factory.nested_progress_bar()
161
result = pb.note('t')
90
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
162
93
self.assertEqual(None, result)
163
94
self.assertEqual("t\n", stdout.getvalue())
164
95
# Since there was no update() call, there should be no clear() call
171
102
def test_progress_note_clears(self):
172
stderr = _TTYStringIO()
173
stdout = _TTYStringIO()
103
stderr = test_progress._TTYStringIO()
104
stdout = test_progress._TTYStringIO()
174
105
# so that we get a TextProgressBar
175
106
os.environ['TERM'] = 'xterm'
176
ui_factory = TextUIFactory(
107
ui_factory = _mod_ui_text.TextUIFactory(
108
stdin=tests.StringIOWrapper(''),
178
109
stdout=stdout, stderr=stderr)
179
110
self.assertIsInstance(ui_factory._progress_view,
111
_mod_ui_text.TextProgressView)
181
112
pb = ui_factory.nested_progress_bar()
183
114
# Create a progress update that isn't throttled
184
115
pb.update('x', 1, 1)
185
result = pb.note('t')
116
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
186
118
self.assertEqual(None, result)
187
119
self.assertEqual("t\n", stdout.getvalue())
188
120
# the exact contents will depend on the terminal width and we don't
195
def test_progress_nested(self):
196
# test factory based nested and popping.
197
ui = TextUIFactory(None, None, None)
198
pb1 = ui.nested_progress_bar()
199
pb2 = ui.nested_progress_bar()
200
# You do get a warning if the outermost progress bar wasn't finished
201
# first - it's not clear if this is really useful or if it should just
202
# become orphaned -- mbp 20090120
203
warnings, _ = self.callCatchWarnings(pb1.finished)
204
if len(warnings) != 1:
205
self.fail("unexpected warnings: %r" % (warnings,))
209
127
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)
128
stdin = tests.StringIOWrapper("y\n" # True
130
"yes with garbage\nY\n" # True
131
"not an answer\nno\n" # False
132
"I'm sure!\nyes\n" # True
135
stdout = tests.StringIOWrapper()
136
stderr = tests.StringIOWrapper()
137
factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
220
138
self.assertEqual(True, factory.get_boolean(""))
221
139
self.assertEqual(False, factory.get_boolean(""))
222
140
self.assertEqual(True, factory.get_boolean(""))
227
145
# stdin should be empty
228
146
self.assertEqual('', factory.stdin.readline())
148
def test_text_ui_get_integer(self):
149
stdin = tests.StringIOWrapper(
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(""))
230
160
def test_text_factory_prompt(self):
231
161
# see <https://launchpad.net/bugs/365891>
232
factory = TextUIFactory(StringIO(), StringIO(), StringIO())
162
StringIO = tests.StringIOWrapper
163
factory = _mod_ui_text.TextUIFactory(StringIO(), StringIO(), StringIO())
233
164
factory.prompt('foo %2e')
234
165
self.assertEqual('', factory.stdout.getvalue())
235
166
self.assertEqual('foo %2e', factory.stderr.getvalue())
237
168
def test_text_factory_prompts_and_clears(self):
238
169
# a get_boolean call should clear the pb before prompting
170
out = test_progress._TTYStringIO()
240
171
os.environ['TERM'] = 'xterm'
241
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)
242
175
pb = factory.nested_progress_bar()
243
176
pb.show_bar = False
244
177
pb.show_spinner = False
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):
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)
249
class TestTextUIOutputStream(tests.TestCase):
250
"""Tests for output stream that synchronizes with progress bar."""
252
def test_output_clears_terminal(self):
253
stdout = tests.StringIOWrapper()
254
stderr = tests.StringIOWrapper()
257
uif = _mod_ui_text.TextUIFactory(None, stdout, stderr)
258
uif.clear_term = lambda: clear_calls.append('clear')
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"])
265
self.assertEqual(stdout.getvalue(),
269
self.assertEqual(['clear', 'clear', 'clear'],
275
class UITests(tests.TestCase):
277
def test_progress_construction(self):
278
"""TextUIFactory constructs the right progress view.
280
TTYStringIO = test_progress._TTYStringIO
281
FileStringIO = tests.StringIOWrapper
282
for (file_class, term, pb, expected_pb_class) in (
283
# on an xterm, either use them or not as the user requests,
284
# otherwise default on
285
(TTYStringIO, 'xterm', 'none', _mod_ui_text.NullProgressView),
286
(TTYStringIO, 'xterm', 'text', _mod_ui_text.TextProgressView),
287
(TTYStringIO, 'xterm', None, _mod_ui_text.TextProgressView),
288
# on a dumb terminal, again if there's explicit configuration do
289
# it, otherwise default off
290
(TTYStringIO, 'dumb', 'none', _mod_ui_text.NullProgressView),
291
(TTYStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
292
(TTYStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
293
# on a non-tty terminal, it's null regardless of $TERM
294
(FileStringIO, 'xterm', None, _mod_ui_text.NullProgressView),
295
(FileStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
296
# however, it can still be forced on
297
(FileStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
299
os.environ['TERM'] = term
301
if 'BZR_PROGRESS_BAR' in os.environ:
302
del os.environ['BZR_PROGRESS_BAR']
304
os.environ['BZR_PROGRESS_BAR'] = pb
305
stdin = file_class('')
306
stderr = file_class()
307
stdout = file_class()
308
uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
309
self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
310
"TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
311
self.assertIsInstance(uif.make_progress_view(),
313
"TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
315
def test_text_ui_non_terminal(self):
316
"""Even on non-ttys, make_ui_for_terminal gives a text ui."""
317
stdin = test_progress._NonTTYStringIO('')
318
stderr = test_progress._NonTTYStringIO()
319
stdout = test_progress._NonTTYStringIO()
320
for term_type in ['dumb', None, 'xterm']:
321
if term_type is None:
322
del os.environ['TERM']
324
os.environ['TERM'] = term_type
325
uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
326
self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
327
'TERM=%r' % (term_type,))
330
class SilentUITests(tests.TestCase):
315
332
def test_silent_factory_get_password(self):
316
333
# A silent factory that can't do user interaction can't get a
317
334
# password. Possibly it should raise a more specific error but it
319
ui = SilentUIFactory()
336
ui = _mod_ui.SilentUIFactory()
337
stdout = tests.StringIOWrapper()
321
338
self.assertRaises(
322
339
NotImplementedError,
323
340
self.apply_redirected,
326
343
self.assertEqual('', stdout.getvalue())
328
345
def test_silent_ui_getbool(self):
329
factory = SilentUIFactory()
346
factory = _mod_ui.SilentUIFactory()
347
stdout = tests.StringIOWrapper()
331
348
self.assertRaises(
332
349
NotImplementedError,
333
350
self.apply_redirected,
334
351
None, stdout, stdout, factory.get_boolean, "foo")
337
class TestUIFactoryTests(TestCase):
354
class TestUIFactoryTests(tests.TestCase):
339
356
def test_test_ui_factory_progress(self):
340
357
# there's no output; we just want to make sure this doesn't crash -
341
358
# see https://bugs.edge.launchpad.net/bzr/+bug/408201
359
ui = tests.TestUIFactory()
343
360
pb = ui.nested_progress_bar()
344
361
pb.update('hello')
349
class CannedInputUIFactoryTests(TestCase):
366
class CannedInputUIFactoryTests(tests.TestCase):
351
368
def test_canned_input_get_input(self):
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'),
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',
375
self.assertEqual(42, uif.get_integer('And all that jazz ?'))
359
378
class TestBoolFromString(tests.TestCase):