/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_ui.py

  • Committer: Jelmer Vernooij
  • Date: 2018-07-26 19:15:27 UTC
  • mto: This revision was merged to the branch mainline in revision 7055.
  • Revision ID: jelmer@jelmer.uk-20180726191527-wniq205k6tzfo1xx
Install fastimport from git.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Tests for the breezy ui."""
 
18
 
 
19
import time
 
20
 
 
21
from testtools.matchers import *
 
22
 
 
23
from .. import (
 
24
    config,
 
25
    tests,
 
26
    ui as _mod_ui,
 
27
    )
 
28
from ..bzr import (
 
29
    remote,
 
30
    )
 
31
from . import (
 
32
    fixtures,
 
33
    ui_testing,
 
34
    )
 
35
from ..ui import text as _mod_ui_text
 
36
from .testui import (
 
37
    ProgressRecordingUIFactory,
 
38
    )
 
39
 
 
40
 
 
41
class TestUIConfiguration(tests.TestCaseInTempDir):
 
42
 
 
43
    def test_output_encoding_configuration(self):
 
44
        enc = next(fixtures.generate_unicode_encodings())
 
45
        config.GlobalStack().set('output_encoding', enc)
 
46
        IO = ui_testing.BytesIOWithEncoding
 
47
        ui = _mod_ui.make_ui_for_terminal(IO(), IO(), IO())
 
48
        output = ui.make_output_stream()
 
49
        self.assertEqual(output.encoding, enc)
 
50
 
 
51
 
 
52
class TestTextUIFactory(tests.TestCase):
 
53
 
 
54
    def test_text_factory_confirm(self):
 
55
        # turns into reading a regular boolean
 
56
        with ui_testing.TestUIFactory('n\n') as ui:
 
57
            self.assertEqual(
 
58
                False,
 
59
                ui.confirm_action(
 
60
                    u'Should %(thing)s pass?',
 
61
                    'breezy.tests.test_ui.confirmation',
 
62
                    {'thing': 'this'}))
 
63
 
 
64
    def test_text_factory_ascii_password(self):
 
65
        ui = ui_testing.TestUIFactory('secret\n')
 
66
        with ui.nested_progress_bar() as pb:
 
67
            self.assertEqual('secret',
 
68
                             self.apply_redirected(ui.stdin, ui.stdout,
 
69
                                                   ui.stderr,
 
70
                                                   ui.get_password))
 
71
            # ': ' is appended to prompt
 
72
            self.assertEqual(': ', ui.stderr.getvalue())
 
73
            self.assertEqual('', ui.stdout.readline())
 
74
            # stdin should be empty
 
75
            self.assertEqual('', ui.stdin.readline())
 
76
 
 
77
    def test_text_factory_unicode_password(self):
 
78
        """Test a unicode password."""
 
79
        ui = ui_testing.TextUIFactory(u'baz\u1234')
 
80
        password = ui.get_password(u'Hello \u1234 %(user)s', user=u'some\u1234')
 
81
        self.assertEqual(u'baz\u1234', password)
 
82
        self.assertEqual(u'Hello \u1234 some\u1234: ', ui.stderr.getvalue())
 
83
        # stdin and stdout should be empty
 
84
        self.assertEqual('', ui.stdin.readline())
 
85
        self.assertEqual('', ui.stdout.getvalue())
 
86
 
 
87
    def test_text_ui_get_boolean(self):
 
88
        stdin_text = (
 
89
            "y\n" # True
 
90
            "n\n" # False
 
91
            " \n y \n" # True
 
92
            " no \n" # False
 
93
            "yes with garbage\nY\n" # True
 
94
            "not an answer\nno\n" # False
 
95
            "I'm sure!\nyes\n" # True
 
96
            "NO\n" # False
 
97
            "foo\n")
 
98
        with ui_testing.TextUIFactory(stdin_text) as factory:
 
99
            self.assertEqual(True, factory.get_boolean(u""))
 
100
            self.assertEqual(False, factory.get_boolean(u""))
 
101
            self.assertEqual(True, factory.get_boolean(u""))
 
102
            self.assertEqual(False, factory.get_boolean(u""))
 
103
            self.assertEqual(True, factory.get_boolean(u""))
 
104
            self.assertEqual(False, factory.get_boolean(u""))
 
105
            self.assertEqual(True, factory.get_boolean(u""))
 
106
            self.assertEqual(False, factory.get_boolean(u""))
 
107
            self.assertEqual("foo\n", factory.stdin.read())
 
108
            # stdin should be empty
 
109
            self.assertEqual('', factory.stdin.readline())
 
110
            # return false on EOF
 
111
            self.assertEqual(False, factory.get_boolean(u""))
 
112
 
 
113
    def test_text_ui_choose_bad_parameters(self):
 
114
        with ui_testing.TextUIFactory(u"") as factory:
 
115
            # invalid default index
 
116
            self.assertRaises(ValueError, factory.choose, u"", u"&Yes\n&No", 3)
 
117
            # duplicated choice
 
118
            self.assertRaises(
 
119
                ValueError, factory.choose, u"", u"&choice\n&ChOiCe")
 
120
            # duplicated shortcut
 
121
            self.assertRaises(
 
122
                ValueError, factory.choose, u"", u"&choice1\nchoi&ce2")
 
123
 
 
124
    def test_text_ui_choose_prompt_explicit(self):
 
125
        # choices with explicit shortcuts
 
126
        with ui_testing.TextUIFactory(u"") as factory:
 
127
            factory.choose(u"prompt", u"&yes\n&No\nmore &info")
 
128
            self.assertEqual(
 
129
                "prompt ([y]es, [N]o, more [i]nfo): \n",
 
130
                factory.stderr.getvalue())
 
131
 
 
132
    def test_text_ui_choose_prompt_automatic(self):
 
133
        # automatic shortcuts
 
134
        with ui_testing.TextUIFactory(u"") as factory:
 
135
            factory.choose(u"prompt", u"yes\nNo\nmore info")
 
136
            self.assertEqual(
 
137
                "prompt ([y]es, [N]o, [m]ore info): \n",
 
138
                factory.stderr.getvalue())
 
139
 
 
140
    def test_text_ui_choose_return_values(self):
 
141
        def choose():
 
142
            return factory.choose(u"", u"&Yes\n&No\nMaybe\nmore &info", 3)
 
143
        stdin_text = (
 
144
            "y\n" # 0
 
145
            "n\n" # 1
 
146
            " \n" # default: 3
 
147
            " no \n" # 1
 
148
            "b\na\nd \n" # bad shortcuts, all ignored
 
149
            "yes with garbage\nY\n" # 0
 
150
            "not an answer\nno\n" # 1
 
151
            "info\nmore info\n" # 3
 
152
            "Maybe\n" # 2
 
153
            "foo\n")
 
154
        with ui_testing.TextUIFactory(stdin_text) as factory:
 
155
            self.assertEqual(0, choose())
 
156
            self.assertEqual(1, choose())
 
157
            self.assertEqual(3, choose())
 
158
            self.assertEqual(1, choose())
 
159
            self.assertEqual(0, choose())
 
160
            self.assertEqual(1, choose())
 
161
            self.assertEqual(3, choose())
 
162
            self.assertEqual(2, choose())
 
163
            self.assertEqual("foo\n", factory.stdin.read())
 
164
            # stdin should be empty
 
165
            self.assertEqual('', factory.stdin.readline())
 
166
            # return None on EOF
 
167
            self.assertEqual(None, choose())
 
168
 
 
169
    def test_text_ui_choose_no_default(self):
 
170
        stdin_text = (
 
171
            " \n" # no default, invalid!
 
172
            " yes \n" # 0
 
173
            "foo\n")
 
174
        with ui_testing.TextUIFactory(stdin_text) as factory:
 
175
            self.assertEqual(0, factory.choose(u"", u"&Yes\n&No"))
 
176
            self.assertEqual("foo\n", factory.stdin.read())
 
177
 
 
178
    def test_text_ui_get_integer(self):
 
179
        stdin_text = (
 
180
            "1\n"
 
181
            "  -2  \n"
 
182
            "hmmm\nwhat else ?\nCome on\nok 42\n4.24\n42\n")
 
183
        with ui_testing.TextUIFactory(stdin_text) as factory:
 
184
            self.assertEqual(1, factory.get_integer(u""))
 
185
            self.assertEqual(-2, factory.get_integer(u""))
 
186
            self.assertEqual(42, factory.get_integer(u""))
 
187
 
 
188
    def test_text_factory_prompt(self):
 
189
        # see <https://launchpad.net/bugs/365891>
 
190
        with ui_testing.TextUIFactory() as factory:
 
191
            factory.prompt(u'foo %2e')
 
192
            self.assertEqual('', factory.stdout.getvalue())
 
193
            self.assertEqual('foo %2e', factory.stderr.getvalue())
 
194
 
 
195
    def test_text_factory_prompts_and_clears(self):
 
196
        # a get_boolean call should clear the pb before prompting
 
197
        out = ui_testing.StringIOAsTTY()
 
198
        self.overrideEnv('TERM', 'xterm')
 
199
        factory = ui_testing.TextUIFactory("yada\ny\n", stdout=out, stderr=out)
 
200
        with factory:
 
201
            pb = factory.nested_progress_bar()
 
202
            pb._avail_width = lambda: 79
 
203
            pb.show_bar = False
 
204
            pb.show_spinner = False
 
205
            pb.show_count = False
 
206
            pb.update("foo", 0, 1)
 
207
            self.assertEqual(
 
208
                True,
 
209
                self.apply_redirected(
 
210
                    None, factory.stdout, factory.stdout, factory.get_boolean,
 
211
                    u"what do you want"))
 
212
            output = out.getvalue()
 
213
            self.assertContainsRe(output,
 
214
                "| foo *\r\r  *\r*")
 
215
            self.assertContainsString(output,
 
216
                r"what do you want? ([y]es, [n]o): what do you want? ([y]es, [n]o): ")
 
217
            # stdin should have been totally consumed
 
218
            self.assertEqual('', factory.stdin.readline())
 
219
 
 
220
    def test_text_tick_after_update(self):
 
221
        ui_factory = ui_testing.TextUIFactory()
 
222
        with ui_factory.nested_progress_bar() as pb:
 
223
            pb.update('task', 0, 3)
 
224
            # Reset the clock, so that it actually tries to repaint itself
 
225
            ui_factory._progress_view._last_repaint = time.time() - 1.0
 
226
            pb.tick()
 
227
 
 
228
    def test_text_ui_getusername(self):
 
229
        ui = ui_testing.TextUIFactory('someuser\n\n')
 
230
        self.assertEqual('someuser',
 
231
                         ui.get_username(u'Hello %(host)s', host='some'))
 
232
        self.assertEqual('Hello some: ', ui.stderr.getvalue())
 
233
        self.assertEqual('', ui.stdout.getvalue())
 
234
        self.assertEqual('', ui.get_username(u"Gebruiker"))
 
235
        # stdin should be empty
 
236
        self.assertEqual('', ui.stdin.readline())
 
237
 
 
238
    def test_text_ui_getusername_unicode(self):
 
239
        ui = ui_testing.TextUIFactory(u'someuser\u1234')
 
240
        username = ui.get_username(u'Hello %(host)s', host=u'some\u1234')
 
241
        self.assertEqual(u"someuser\u1234", username)
 
242
        self.assertEqual(u"Hello some\u1234: ", ui.stderr.getvalue())
 
243
        self.assertEqual('', ui.stdout.getvalue())
 
244
 
 
245
    def test_quietness(self):
 
246
        self.overrideEnv('BRZ_PROGRESS_BAR', 'text')
 
247
        ui_factory = ui_testing.TextUIFactory(
 
248
            stderr=ui_testing.StringIOAsTTY())
 
249
        with ui_factory:
 
250
            self.assertIsInstance(ui_factory._progress_view,
 
251
                _mod_ui_text.TextProgressView)
 
252
            ui_factory.be_quiet(True)
 
253
            self.assertIsInstance(ui_factory._progress_view,
 
254
                _mod_ui_text.NullProgressView)
 
255
 
 
256
    def test_text_ui_show_user_warning(self):
 
257
        from ..bzr.groupcompress_repo import RepositoryFormat2a
 
258
        from ..bzr.knitpack_repo import RepositoryFormatKnitPack5
 
259
        ui = ui_testing.TextUIFactory()
 
260
        remote_fmt = remote.RemoteRepositoryFormat()
 
261
        remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
 
262
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
 
263
            to_format=remote_fmt)
 
264
        self.assertEqual('', ui.stdout.getvalue())
 
265
        self.assertContainsRe(
 
266
            ui.stderr.getvalue(),
 
267
            "^Doing on-the-fly conversion from RepositoryFormat2a\\(\\) to "
 
268
                "RemoteRepositoryFormat\\(_network_name="
 
269
                "b?'Bazaar RepositoryFormatKnitPack5 \\(bzr 1.6\\)\\\\n'\\)\\.\n"
 
270
            "This may take some time. Upgrade the repositories to "
 
271
                "the same format for better performance\\.\n$")
 
272
        # and now with it suppressed please
 
273
        ui = ui_testing.TextUIFactory()
 
274
        ui.suppressed_warnings.add('cross_format_fetch')
 
275
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
 
276
            to_format=remote_fmt)
 
277
        self.assertEqual('', ui.stdout.getvalue())
 
278
        self.assertEqual('', ui.stderr.getvalue())
 
279
 
 
280
 
 
281
class TestTextUIOutputStream(tests.TestCase):
 
282
    """Tests for output stream that synchronizes with progress bar."""
 
283
 
 
284
    def test_output_clears_terminal(self):
 
285
        clear_calls = []
 
286
 
 
287
        uif =  ui_testing.TextUIFactory()
 
288
        uif.clear_term = lambda: clear_calls.append('clear')
 
289
 
 
290
        stream = _mod_ui_text.TextUIOutputStream(uif, uif.stdout, 'utf-8', 'strict')
 
291
        stream.write(u"Hello world!\n")
 
292
        stream.write(u"there's more...\n")
 
293
        stream.writelines([u"1\n", u"2\n", u"3\n"])
 
294
 
 
295
        self.assertEqual(uif.stdout.getvalue(),
 
296
            u"Hello world!\n"
 
297
            u"there's more...\n"
 
298
            u"1\n2\n3\n")
 
299
        self.assertEqual(['clear', 'clear', 'clear'],
 
300
            clear_calls)
 
301
 
 
302
        stream.flush()
 
303
 
 
304
 
 
305
class UITests(tests.TestCase):
 
306
 
 
307
    def test_progress_construction(self):
 
308
        """TextUIFactory constructs the right progress view.
 
309
        """
 
310
        FileStringIO = ui_testing.StringIOWithEncoding
 
311
        TTYStringIO = ui_testing.StringIOAsTTY
 
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),
 
328
            ):
 
329
            self.overrideEnv('TERM', term)
 
330
            self.overrideEnv('BRZ_PROGRESS_BAR', pb)
 
331
            stdin = file_class(u'')
 
332
            stderr = file_class()
 
333
            stdout = file_class()
 
334
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
 
335
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
 
336
                "TERM=%s BRZ_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
 
337
            self.assertIsInstance(uif.make_progress_view(),
 
338
                expected_pb_class,
 
339
                "TERM=%s BRZ_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
 
340
 
 
341
    def test_text_ui_non_terminal(self):
 
342
        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
 
343
        stdin = stderr = stdout = ui_testing.StringIOWithEncoding()
 
344
        for term_type in ['dumb', None, 'xterm']:
 
345
            self.overrideEnv('TERM', term_type)
 
346
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
 
347
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
 
348
                'TERM=%r' % (term_type,))
 
349
 
 
350
 
 
351
class SilentUITests(tests.TestCase):
 
352
 
 
353
    def test_silent_factory_get_password(self):
 
354
        # A silent factory that can't do user interaction can't get a
 
355
        # password.  Possibly it should raise a more specific error but it
 
356
        # can't succeed.
 
357
        ui = _mod_ui.SilentUIFactory()
 
358
        stdout = ui_testing.StringIOWithEncoding()
 
359
        self.assertRaises(
 
360
            NotImplementedError,
 
361
            self.apply_redirected,
 
362
            None, stdout, stdout, ui.get_password)
 
363
        # and it didn't write anything out either
 
364
        self.assertEqual('', stdout.getvalue())
 
365
 
 
366
    def test_silent_ui_getbool(self):
 
367
        factory = _mod_ui.SilentUIFactory()
 
368
        stdout = ui_testing.StringIOWithEncoding()
 
369
        self.assertRaises(
 
370
            NotImplementedError,
 
371
            self.apply_redirected,
 
372
            None, stdout, stdout, factory.get_boolean, u"foo")
 
373
 
 
374
 
 
375
class TestUIFactoryTests(tests.TestCase):
 
376
 
 
377
    def test_test_ui_factory_progress(self):
 
378
        # there's no output; we just want to make sure this doesn't crash -
 
379
        # see https://bugs.launchpad.net/bzr/+bug/408201
 
380
        ui = ui_testing.TestUIFactory()
 
381
        with ui.nested_progress_bar() as pb:
 
382
            pb.update('hello')
 
383
            pb.tick()
 
384
 
 
385
 
 
386
class CannedInputUIFactoryTests(tests.TestCase):
 
387
 
 
388
    def test_canned_input_get_input(self):
 
389
        uif = _mod_ui.CannedInputUIFactory([True, 'mbp', 'password', 42])
 
390
        self.assertEqual(True, uif.get_boolean(u'Extra cheese?'))
 
391
        self.assertEqual('mbp', uif.get_username(u'Enter your user name'))
 
392
        self.assertEqual('password',
 
393
                         uif.get_password(u'Password for %(host)s',
 
394
                                          host='example.com'))
 
395
        self.assertEqual(42, uif.get_integer(u'And all that jazz ?'))
 
396
 
 
397
 
 
398
class TestBoolFromString(tests.TestCase):
 
399
 
 
400
    def assertIsTrue(self, s, accepted_values=None):
 
401
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
 
402
        self.assertEqual(True, res)
 
403
 
 
404
    def assertIsFalse(self, s, accepted_values=None):
 
405
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
 
406
        self.assertEqual(False, res)
 
407
 
 
408
    def assertIsNone(self, s, accepted_values=None):
 
409
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
 
410
        self.assertIs(None, res)
 
411
 
 
412
    def test_know_valid_values(self):
 
413
        self.assertIsTrue('true')
 
414
        self.assertIsFalse('false')
 
415
        self.assertIsTrue('1')
 
416
        self.assertIsFalse('0')
 
417
        self.assertIsTrue('on')
 
418
        self.assertIsFalse('off')
 
419
        self.assertIsTrue('yes')
 
420
        self.assertIsFalse('no')
 
421
        self.assertIsTrue('y')
 
422
        self.assertIsFalse('n')
 
423
        # Also try some case variations
 
424
        self.assertIsTrue('True')
 
425
        self.assertIsFalse('False')
 
426
        self.assertIsTrue('On')
 
427
        self.assertIsFalse('Off')
 
428
        self.assertIsTrue('ON')
 
429
        self.assertIsFalse('OFF')
 
430
        self.assertIsTrue('oN')
 
431
        self.assertIsFalse('oFf')
 
432
 
 
433
    def test_invalid_values(self):
 
434
        self.assertIsNone(None)
 
435
        self.assertIsNone('doubt')
 
436
        self.assertIsNone('frue')
 
437
        self.assertIsNone('talse')
 
438
        self.assertIsNone('42')
 
439
 
 
440
    def test_provided_values(self):
 
441
        av = dict(y=True, n=False, yes=True, no=False)
 
442
        self.assertIsTrue('y', av)
 
443
        self.assertIsTrue('Y', av)
 
444
        self.assertIsTrue('Yes', av)
 
445
        self.assertIsFalse('n', av)
 
446
        self.assertIsFalse('N', av)
 
447
        self.assertIsFalse('No', av)
 
448
        self.assertIsNone('1', av)
 
449
        self.assertIsNone('0', av)
 
450
        self.assertIsNone('on', av)
 
451
        self.assertIsNone('off', av)
 
452
 
 
453
 
 
454
class TestConfirmationUserInterfacePolicy(tests.TestCase):
 
455
 
 
456
    def test_confirm_action_default(self):
 
457
        base_ui = _mod_ui.NoninteractiveUIFactory()
 
458
        for answer in [True, False]:
 
459
            self.assertEqual(
 
460
                _mod_ui.ConfirmationUserInterfacePolicy(base_ui, answer, {})
 
461
                .confirm_action("Do something?",
 
462
                    "breezy.tests.do_something", {}),
 
463
                answer)
 
464
 
 
465
    def test_confirm_action_specific(self):
 
466
        base_ui = _mod_ui.NoninteractiveUIFactory()
 
467
        for default_answer in [True, False]:
 
468
            for specific_answer in [True, False]:
 
469
                for conf_id in ['given_id', 'other_id']:
 
470
                    wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
 
471
                        base_ui, default_answer, dict(given_id=specific_answer))
 
472
                    result = wrapper.confirm_action("Do something?", conf_id, {})
 
473
                    if conf_id == 'given_id':
 
474
                        self.assertEqual(result, specific_answer)
 
475
                    else:
 
476
                        self.assertEqual(result, default_answer)
 
477
 
 
478
    def test_repr(self):
 
479
        base_ui = _mod_ui.NoninteractiveUIFactory()
 
480
        wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
 
481
            base_ui, True, dict(a=2))
 
482
        self.assertThat(repr(wrapper),
 
483
            Equals("ConfirmationUserInterfacePolicy("
 
484
                "NoninteractiveUIFactory(), True, {'a': 2})"))
 
485
 
 
486
 
 
487
class TestProgressRecordingUI(tests.TestCase):
 
488
    """Test test-oriented UIFactory that records progress updates"""
 
489
 
 
490
    def test_nested_ignore_depth_beyond_one(self):
 
491
        # we only want to capture the first level out progress, not
 
492
        # want sub-components might do. So we have nested bars ignored.
 
493
        factory = ProgressRecordingUIFactory()
 
494
        pb1 = factory.nested_progress_bar()
 
495
        pb1.update('foo', 0, 1)
 
496
        pb2 = factory.nested_progress_bar()
 
497
        pb2.update('foo', 0, 1)
 
498
        pb2.finished()
 
499
        pb1.finished()
 
500
        self.assertEqual([("update", 0, 1, 'foo')], factory._calls)