150
131
def test_progress_nested(self):
151
132
# test factory based nested and popping.
152
ui = TextUIFactory(None, None, None)
153
134
pb1 = ui.nested_progress_bar()
154
135
pb2 = ui.nested_progress_bar()
155
# You do get a warning if the outermost progress bar wasn't finished
156
# first - it's not clear if this is really useful or if it should just
157
# become orphaned -- mbp 20090120
158
warnings, _ = self.callCatchWarnings(pb1.finished)
159
if len(warnings) != 1:
160
self.fail("unexpected warnings: %r" % (warnings,))
136
self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
164
140
def test_progress_stack(self):
165
# test the progress bar stack which the default text factory
141
# test the progress bar stack which the default text factory
167
143
stderr = StringIO()
168
144
stdout = StringIO()
169
145
# make a stack, which accepts parameters like a pb.
170
stack = self.applyDeprecated(
171
deprecated_in((1, 12, 0)),
173
to_file=stderr, to_messages_file=stdout)
146
stack = ProgressBarStack(to_file=stderr, to_messages_file=stdout)
175
148
self.assertFalse(getattr(stack, 'note', False))
176
149
pb1 = stack.get_nested()
177
150
pb2 = stack.get_nested()
178
warnings, _ = self.callCatchWarnings(pb1.finished)
179
self.assertEqual(len(warnings), 1)
151
self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
182
154
# the text ui factory never actually removes the stack once its setup.
183
155
# we need to be able to nest again correctly from here.
184
156
pb1 = stack.get_nested()
185
157
pb2 = stack.get_nested()
186
warnings, _ = self.callCatchWarnings(pb1.finished)
187
self.assertEqual(len(warnings), 1)
158
self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
162
def test_text_factory_setting_progress_bar(self):
163
# we should be able to choose the progress bar type used.
164
factory = bzrlib.ui.text.TextUIFactory(
165
bar_type=DotsProgressBar)
166
bar = factory.nested_progress_bar()
168
self.assertIsInstance(bar, DotsProgressBar)
170
def test_cli_stdin_is_default_stdin(self):
171
factory = bzrlib.ui.CLIUIFactory()
172
self.assertEqual(sys.stdin, factory.stdin)
191
174
def assert_get_bool_acceptance_of_user_input(self, factory):
192
factory.stdin = StringIO("y\nyes with garbage\n"
193
"yes\nn\nnot an answer\n"
175
factory.stdin = StringIO("y\nyes with garbage\nyes\nn\nnot an answer\nno\nfoo\n")
195
176
factory.stdout = StringIO()
196
177
# there is no output from the base factory
197
178
self.assertEqual(True, factory.get_boolean(""))
199
180
self.assertEqual(False, factory.get_boolean(""))
200
181
self.assertEqual(False, factory.get_boolean(""))
201
182
self.assertEqual("foo\n", factory.stdin.read())
202
# stdin should be empty
203
self.assertEqual('', factory.stdin.readline())
205
184
def test_silent_ui_getbool(self):
206
factory = SilentUIFactory()
185
factory = bzrlib.ui.SilentUIFactory()
207
186
self.assert_get_bool_acceptance_of_user_input(factory)
209
188
def test_silent_factory_prompts_silently(self):
210
factory = SilentUIFactory()
189
factory = bzrlib.ui.SilentUIFactory()
211
190
stdout = StringIO()
212
191
factory.stdin = StringIO("y\n")
213
self.assertEqual(True,
214
self.apply_redirected(None, stdout, stdout,
215
factory.get_boolean, "foo"))
194
self.apply_redirected(
195
None, stdout, stdout, factory.get_boolean, "foo")
216
197
self.assertEqual("", stdout.getvalue())
217
# stdin should be empty
218
self.assertEqual('', factory.stdin.readline())
220
199
def test_text_ui_getbool(self):
221
factory = TextUIFactory(None, None, None)
200
factory = bzrlib.ui.text.TextUIFactory()
222
201
self.assert_get_bool_acceptance_of_user_input(factory)
224
def test_text_factory_prompt(self):
225
# see <https://launchpad.net/bugs/365891>
226
factory = TextUIFactory(None, StringIO(), StringIO())
227
factory.prompt('foo %2e')
229
203
def test_text_factory_prompts_and_clears(self):
230
204
# a get_boolean call should clear the pb before prompting
232
factory = TextUIFactory(stdin=StringIO("yada\ny\n"), stdout=out, stderr=out)
233
pb = factory.nested_progress_bar()
235
pb.show_spinner = False
236
pb.show_count = False
237
pb.update("foo", 0, 1)
238
self.assertEqual(True,
239
self.apply_redirected(None, factory.stdout,
243
output = out.getvalue()
244
self.assertContainsRe(factory.stdout.getvalue(),
246
self.assertContainsRe(factory.stdout.getvalue(),
247
r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
248
# stdin should have been totally consumed
249
self.assertEqual('', factory.stdin.readline())
251
def test_text_tick_after_update(self):
252
ui_factory = TextUIFactory(stdout=StringIO(), stderr=StringIO())
253
pb = ui_factory.nested_progress_bar()
255
pb.update('task', 0, 3)
256
# Reset the clock, so that it actually tries to repaint itself
257
ui_factory._progress_view._last_repaint = time.time() - 1.0
262
def test_silent_ui_getusername(self):
263
factory = SilentUIFactory()
264
factory.stdin = StringIO("someuser\n\n")
265
factory.stdout = StringIO()
266
self.assertEquals(None,
267
factory.get_username(u'Hello\u1234 %(host)s', host=u'some\u1234'))
268
self.assertEquals("", factory.stdout.getvalue())
269
self.assertEquals("someuser\n\n", factory.stdin.getvalue())
271
def test_text_ui_getusername(self):
272
factory = TextUIFactory(None, None, None)
273
factory.stdin = StringIO("someuser\n\n")
274
factory.stdout = StringIO()
275
factory.stdout.encoding = "utf8"
276
# there is no output from the base factory
277
self.assertEqual("someuser",
278
factory.get_username('Hello %(host)s', host='some'))
279
self.assertEquals("Hello some: ", factory.stdout.getvalue())
280
self.assertEqual("", factory.get_username("Gebruiker"))
281
# stdin should be empty
282
self.assertEqual('', factory.stdin.readline())
284
def test_text_ui_getusername_utf8(self):
285
ui = TestUIFactory(stdin=u'someuser\u1234'.encode('utf8'),
286
stdout=StringIOWrapper())
287
ui.stdin.encoding = "utf8"
288
ui.stdout.encoding = ui.stdin.encoding
289
pb = ui.nested_progress_bar()
291
# there is no output from the base factory
292
username = self.apply_redirected(ui.stdin, ui.stdout, ui.stdout,
293
ui.get_username, u'Hello\u1234 %(host)s', host=u'some\u1234')
294
self.assertEquals(u"someuser\u1234", username.decode('utf8'))
295
self.assertEquals(u"Hello\u1234 some\u1234: ",
296
ui.stdout.getvalue().decode("utf8"))
301
class TestTextProgressView(TestCase):
302
"""Tests for text display of progress bars.
304
# XXX: These might be a bit easier to write if the rendering and
305
# state-maintaining parts of TextProgressView were more separate, and if
306
# the progress task called back directly to its own view not to the ui
307
# factory. -- mbp 20090312
309
def _make_factory(self):
311
uif = TextUIFactory(stderr=out)
312
uif._progress_view._width = 80
315
def test_render_progress_easy(self):
316
"""Just one task and one quarter done"""
317
out, uif = self._make_factory()
318
task = uif.nested_progress_bar()
319
task.update('reticulating splines', 5, 20)
321
'\r[####/ ] reticulating splines 5/20 \r'
324
def test_render_progress_nested(self):
325
"""Tasks proportionally contribute to overall progress"""
326
out, uif = self._make_factory()
327
task = uif.nested_progress_bar()
328
task.update('reticulating splines', 0, 2)
329
task2 = uif.nested_progress_bar()
330
task2.update('stage2', 1, 2)
331
# so we're in the first half of the main task, and half way through
334
r'[####\ ] reticulating splines:stage2 1/2'
335
, uif._progress_view._render_line())
336
# if the nested task is complete, then we're all the way through the
337
# first half of the overall work
338
task2.update('stage2', 2, 2)
340
r'[#########| ] reticulating splines:stage2 2/2'
341
, uif._progress_view._render_line())
343
def test_render_progress_sub_nested(self):
344
"""Intermediate tasks don't mess up calculation."""
345
out, uif = self._make_factory()
346
task_a = uif.nested_progress_bar()
347
task_a.update('a', 0, 2)
348
task_b = uif.nested_progress_bar()
350
task_c = uif.nested_progress_bar()
351
task_c.update('c', 1, 2)
352
# the top-level task is in its first half; the middle one has no
353
# progress indication, just a label; and the bottom one is half done,
354
# so the overall fraction is 1/4
356
r'[####| ] a:b:c 1/2'
357
, uif._progress_view._render_line())
205
factory = bzrlib.ui.text.TextUIFactory(bar_type=DotsProgressBar)
206
factory.stdout = _TTYStringIO()
207
factory.stdin = StringIO("yada\ny\n")
208
pb = self.apply_redirected(
209
factory.stdin, factory.stdout, factory.stdout, factory.nested_progress_bar)
211
self.apply_redirected(
212
factory.stdin, factory.stdout, factory.stdout, pb.update, "foo", 0, 1)
215
self.apply_redirected(
216
None, factory.stdout, factory.stdout, factory.get_boolean, "what do you want")
218
output = factory.stdout.getvalue()
219
self.assertEqual("foo: .\n"
220
"what do you want? [y/n]: what do you want? [y/n]: ",
221
factory.stdout.getvalue())