144
152
ui = TextUIFactory(None, None, None)
145
153
pb1 = ui.nested_progress_bar()
146
154
pb2 = ui.nested_progress_bar()
147
# We no longer warn about finishing unnested progress bars.
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
148
158
warnings, _ = self.callCatchWarnings(pb1.finished)
149
self.assertEqual(len(warnings), 0)
159
if len(warnings) != 1:
160
self.fail("unexpected warnings: %r" % (warnings,))
153
164
def test_progress_stack(self):
154
# test the progress bar stack which the default text factory
165
# test the progress bar stack which the default text factory
156
167
stderr = StringIO()
157
168
stdout = StringIO()
158
169
# make a stack, which accepts parameters like a pb.
159
stack = ProgressBarStack(to_file=stderr, to_messages_file=stdout)
170
stack = self.applyDeprecated(
171
deprecated_in((1, 12, 0)),
173
to_file=stderr, to_messages_file=stdout)
161
175
self.assertFalse(getattr(stack, 'note', False))
162
176
pb1 = stack.get_nested()
228
242
r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
229
243
# stdin should have been totally consumed
230
244
self.assertEqual('', factory.stdin.readline())
246
def test_text_tick_after_update(self):
247
ui_factory = TextUIFactory(stdout=StringIO(), stderr=StringIO())
248
pb = ui_factory.nested_progress_bar()
250
pb.update('task', 0, 3)
251
# Reset the clock, so that it actually tries to repaint itself
252
ui_factory._progress_view._last_repaint = time.time() - 1.0
258
class TestTextProgressView(TestCase):
259
"""Tests for text display of progress bars.
261
# XXX: These might be a bit easier to write if the rendering and
262
# state-maintaining parts of TextProgressView were more separate, and if
263
# the progress task called back directly to its own view not to the ui
264
# factory. -- mbp 20090312
266
def _make_factory(self):
268
uif = TextUIFactory(stderr=out)
269
uif._progress_view._width = 80
272
def test_render_progress_easy(self):
273
"""Just one task and one quarter done"""
274
out, uif = self._make_factory()
275
task = uif.nested_progress_bar()
276
task.update('reticulating splines', 5, 20)
278
'\r[####/ ] reticulating splines 5/20 \r'
281
def test_render_progress_nested(self):
282
"""Tasks proportionally contribute to overall progress"""
283
out, uif = self._make_factory()
284
task = uif.nested_progress_bar()
285
task.update('reticulating splines', 0, 2)
286
task2 = uif.nested_progress_bar()
287
task2.update('stage2', 1, 2)
288
# so we're in the first half of the main task, and half way through
291
r'[####\ ] reticulating splines:stage2 1/2'
292
, uif._progress_view._render_line())
293
# if the nested task is complete, then we're all the way through the
294
# first half of the overall work
295
task2.update('stage2', 2, 2)
297
r'[#########| ] reticulating splines:stage2 2/2'
298
, uif._progress_view._render_line())
300
def test_render_progress_sub_nested(self):
301
"""Intermediate tasks don't mess up calculation."""
302
out, uif = self._make_factory()
303
task_a = uif.nested_progress_bar()
304
task_a.update('a', 0, 2)
305
task_b = uif.nested_progress_bar()
307
task_c = uif.nested_progress_bar()
308
task_c.update('c', 1, 2)
309
# the top-level task is in its first half; the middle one has no
310
# progress indication, just a label; and the bottom one is half done,
311
# so the overall fraction is 1/4
313
r'[####| ] a:b:c 1/2'
314
, uif._progress_view._render_line())