/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: 2017-05-22 00:56:52 UTC
  • mfrom: (6621.2.26 py3_pokes)
  • Revision ID: jelmer@jelmer.uk-20170522005652-yjahcr9hwmjkno7n
Merge Python3 porting work ('py3 pokes')

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""Tests for the breezy ui
18
 
"""
 
17
"""Tests for the breezy ui."""
19
18
 
20
19
import time
21
20
 
22
 
from StringIO import StringIO
23
 
 
24
21
from testtools.matchers import *
25
22
 
26
 
from breezy import (
 
23
from .. import (
27
24
    config,
28
25
    remote,
29
26
    tests,
30
27
    ui as _mod_ui,
31
28
    )
32
 
from breezy.tests import (
 
29
from . import (
33
30
    fixtures,
 
31
    ui_testing,
34
32
    )
35
 
from breezy.ui import text as _mod_ui_text
36
 
from breezy.tests.testui import (
 
33
from ..ui import text as _mod_ui_text
 
34
from .testui import (
37
35
    ProgressRecordingUIFactory,
38
36
    )
39
37
 
40
38
 
41
 
class TTYStringIO(StringIO):
42
 
    """A helper class which makes a StringIO look like a terminal"""
43
 
 
44
 
    def isatty(self):
45
 
        return True
46
 
 
47
 
 
48
 
class NonTTYStringIO(StringIO):
49
 
    """Helper that implements isatty() but returns False"""
50
 
 
51
 
    def isatty(self):
52
 
        return False
53
 
 
54
 
 
55
 
class TestUIConfiguration(tests.TestCaseWithTransport):
 
39
class TestUIConfiguration(tests.TestCase):
56
40
 
57
41
    def test_output_encoding_configuration(self):
58
42
        enc = fixtures.generate_unicode_encodings().next()
59
43
        config.GlobalStack().set('output_encoding', enc)
60
 
        ui = tests.TestUIFactory(stdin=None,
61
 
            stdout=tests.StringIOWrapper(),
62
 
            stderr=tests.StringIOWrapper())
 
44
        IO = ui_testing.BytesIOWithEncoding
 
45
        ui = _mod_ui.make_ui_for_terminal(IO(), IO(), IO())
63
46
        output = ui.make_output_stream()
64
47
        self.assertEqual(output.encoding, enc)
65
48
 
66
49
 
67
50
class TestTextUIFactory(tests.TestCase):
68
51
 
69
 
    def make_test_ui_factory(self, stdin_contents):
70
 
        ui = tests.TestUIFactory(stdin=stdin_contents,
71
 
                                 stdout=tests.StringIOWrapper(),
72
 
                                 stderr=tests.StringIOWrapper())
73
 
        return ui
74
 
 
75
52
    def test_text_factory_confirm(self):
76
53
        # turns into reading a regular boolean
77
 
        ui = self.make_test_ui_factory('n\n')
 
54
        ui = ui_testing.TestUIFactory('n\n')
78
55
        self.assertEqual(ui.confirm_action(u'Should %(thing)s pass?',
79
56
            'breezy.tests.test_ui.confirmation',
80
57
            {'thing': 'this'},),
81
58
            False)
82
59
 
83
60
    def test_text_factory_ascii_password(self):
84
 
        ui = self.make_test_ui_factory('secret\n')
 
61
        ui = ui_testing.TestUIFactory('secret\n')
85
62
        pb = ui.nested_progress_bar()
86
63
        try:
87
64
            self.assertEqual('secret',
96
73
        finally:
97
74
            pb.finished()
98
75
 
99
 
    def test_text_factory_utf8_password(self):
100
 
        """Test an utf8 password."""
101
 
        ui = _mod_ui_text.TextUIFactory(None, None, None)
102
 
        ui.stdin = tests.StringIOWrapper(u'baz\u1234'.encode('utf8'))
103
 
        ui.stdout = tests.StringIOWrapper()
104
 
        ui.stderr = tests.StringIOWrapper()
105
 
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = 'utf8'
 
76
    def test_text_factory_unicode_password(self):
 
77
        """Test a unicode password."""
 
78
        ui = ui_testing.TextUIFactory(u'baz\u1234')
106
79
        password = ui.get_password(u'Hello \u1234 %(user)s', user=u'some\u1234')
107
80
        self.assertEqual(u'baz\u1234', password)
108
 
        self.assertEqual(u'Hello \u1234 some\u1234: ',
109
 
                         ui.stderr.getvalue().decode('utf8'))
 
81
        self.assertEqual(u'Hello \u1234 some\u1234: ', ui.stderr.getvalue())
110
82
        # stdin and stdout should be empty
111
83
        self.assertEqual('', ui.stdin.readline())
112
84
        self.assertEqual('', ui.stdout.getvalue())
113
85
 
114
86
    def test_text_ui_get_boolean(self):
115
 
        stdin = tests.StringIOWrapper("y\n" # True
116
 
                                      "n\n" # False
117
 
                                      " \n y \n" # True
118
 
                                      " no \n" # False
119
 
                                      "yes with garbage\nY\n" # True
120
 
                                      "not an answer\nno\n" # False
121
 
                                      "I'm sure!\nyes\n" # True
122
 
                                      "NO\n" # False
123
 
                                      "foo\n")
124
 
        stdout = tests.StringIOWrapper()
125
 
        stderr = tests.StringIOWrapper()
126
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
87
        stdin_text = (
 
88
            "y\n" # True
 
89
            "n\n" # False
 
90
            " \n y \n" # True
 
91
            " no \n" # False
 
92
            "yes with garbage\nY\n" # True
 
93
            "not an answer\nno\n" # False
 
94
            "I'm sure!\nyes\n" # True
 
95
            "NO\n" # False
 
96
            "foo\n")
 
97
        factory = ui_testing.TextUIFactory(stdin_text)
127
98
        self.assertEqual(True, factory.get_boolean(u""))
128
99
        self.assertEqual(False, factory.get_boolean(u""))
129
100
        self.assertEqual(True, factory.get_boolean(u""))
139
110
        self.assertEqual(False, factory.get_boolean(u""))
140
111
 
141
112
    def test_text_ui_choose_bad_parameters(self):
142
 
        stdin = tests.StringIOWrapper()
143
 
        stdout = tests.StringIOWrapper()
144
 
        stderr = tests.StringIOWrapper()
145
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
113
        factory = ui_testing.TextUIFactory(u"")
146
114
        # invalid default index
147
115
        self.assertRaises(ValueError, factory.choose, u"", u"&Yes\n&No", 3)
148
116
        # duplicated choice
150
118
        # duplicated shortcut
151
119
        self.assertRaises(ValueError, factory.choose, u"", u"&choice1\nchoi&ce2")
152
120
 
153
 
    def test_text_ui_choose_prompt(self):
154
 
        stdin = tests.StringIOWrapper()
155
 
        stdout = tests.StringIOWrapper()
156
 
        stderr = tests.StringIOWrapper()
157
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
121
    def test_text_ui_choose_prompt_explicit(self):
158
122
        # choices with explicit shortcuts
 
123
        factory = ui_testing.TextUIFactory(u"")
159
124
        factory.choose(u"prompt", u"&yes\n&No\nmore &info")
160
125
        self.assertEqual("prompt ([y]es, [N]o, more [i]nfo): \n", factory.stderr.getvalue())
 
126
 
 
127
    def test_text_ui_choose_prompt_automatic(self):
161
128
        # automatic shortcuts
162
 
        factory.stderr.truncate(0)
 
129
        factory = ui_testing.TextUIFactory(u"")
163
130
        factory.choose(u"prompt", u"yes\nNo\nmore info")
164
131
        self.assertEqual("prompt ([y]es, [N]o, [m]ore info): \n", factory.stderr.getvalue())
165
132
 
166
133
    def test_text_ui_choose_return_values(self):
167
134
        choose = lambda: factory.choose(u"", u"&Yes\n&No\nMaybe\nmore &info", 3)
168
 
        stdin = tests.StringIOWrapper("y\n" # 0
169
 
                                      "n\n" # 1
170
 
                                      " \n" # default: 3
171
 
                                      " no \n" # 1
172
 
                                      "b\na\nd \n" # bad shortcuts, all ignored
173
 
                                      "yes with garbage\nY\n" # 0
174
 
                                      "not an answer\nno\n" # 1
175
 
                                      "info\nmore info\n" # 3
176
 
                                      "Maybe\n" # 2
177
 
                                      "foo\n")
178
 
        stdout = tests.StringIOWrapper()
179
 
        stderr = tests.StringIOWrapper()
180
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
135
        stdin_text = (
 
136
            "y\n" # 0
 
137
            "n\n" # 1
 
138
            " \n" # default: 3
 
139
            " no \n" # 1
 
140
            "b\na\nd \n" # bad shortcuts, all ignored
 
141
            "yes with garbage\nY\n" # 0
 
142
            "not an answer\nno\n" # 1
 
143
            "info\nmore info\n" # 3
 
144
            "Maybe\n" # 2
 
145
            "foo\n")
 
146
        factory = ui_testing.TextUIFactory(stdin_text)
181
147
        self.assertEqual(0, choose())
182
148
        self.assertEqual(1, choose())
183
149
        self.assertEqual(3, choose())
193
159
        self.assertEqual(None, choose())
194
160
 
195
161
    def test_text_ui_choose_no_default(self):
196
 
        stdin = tests.StringIOWrapper(" \n" # no default, invalid!
197
 
                                      " yes \n" # 0
198
 
                                      "foo\n")
199
 
        stdout = tests.StringIOWrapper()
200
 
        stderr = tests.StringIOWrapper()
201
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
162
        stdin_text = (
 
163
            " \n" # no default, invalid!
 
164
            " yes \n" # 0
 
165
            "foo\n")
 
166
        factory = ui_testing.TextUIFactory(stdin_text)
202
167
        self.assertEqual(0, factory.choose(u"", u"&Yes\n&No"))
203
168
        self.assertEqual("foo\n", factory.stdin.read())
204
169
 
205
170
    def test_text_ui_get_integer(self):
206
 
        stdin = tests.StringIOWrapper(
 
171
        stdin_text = (
207
172
            "1\n"
208
173
            "  -2  \n"
209
174
            "hmmm\nwhat else ?\nCome on\nok 42\n4.24\n42\n")
210
 
        stdout = tests.StringIOWrapper()
211
 
        stderr = tests.StringIOWrapper()
212
 
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
 
175
        factory = ui_testing.TextUIFactory(stdin_text)
213
176
        self.assertEqual(1, factory.get_integer(u""))
214
177
        self.assertEqual(-2, factory.get_integer(u""))
215
178
        self.assertEqual(42, factory.get_integer(u""))
216
179
 
217
180
    def test_text_factory_prompt(self):
218
181
        # see <https://launchpad.net/bugs/365891>
219
 
        StringIO = tests.StringIOWrapper
220
 
        factory = _mod_ui_text.TextUIFactory(StringIO(), StringIO(), StringIO())
 
182
        factory = ui_testing.TextUIFactory()
221
183
        factory.prompt(u'foo %2e')
222
184
        self.assertEqual('', factory.stdout.getvalue())
223
185
        self.assertEqual('foo %2e', factory.stderr.getvalue())
224
186
 
225
187
    def test_text_factory_prompts_and_clears(self):
226
188
        # a get_boolean call should clear the pb before prompting
227
 
        out = TTYStringIO()
 
189
        out = ui_testing.StringIOAsTTY()
228
190
        self.overrideEnv('TERM', 'xterm')
229
 
        factory = _mod_ui_text.TextUIFactory(
230
 
            stdin=tests.StringIOWrapper("yada\ny\n"),
231
 
            stdout=out, stderr=out)
232
 
        factory._avail_width = lambda: 79
 
191
        factory = ui_testing.TextUIFactory("yada\ny\n", stdout=out, stderr=out)
233
192
        pb = factory.nested_progress_bar()
 
193
        pb._avail_width = lambda: 79
234
194
        pb.show_bar = False
235
195
        pb.show_spinner = False
236
196
        pb.show_count = False
249
209
        self.assertEqual('', factory.stdin.readline())
250
210
 
251
211
    def test_text_tick_after_update(self):
252
 
        ui_factory = _mod_ui_text.TextUIFactory(stdout=tests.StringIOWrapper(),
253
 
                                                stderr=tests.StringIOWrapper())
 
212
        ui_factory = ui_testing.TextUIFactory()
254
213
        pb = ui_factory.nested_progress_bar()
255
214
        try:
256
215
            pb.update('task', 0, 3)
261
220
            pb.finished()
262
221
 
263
222
    def test_text_ui_getusername(self):
264
 
        ui = _mod_ui_text.TextUIFactory(None, None, None)
265
 
        ui.stdin = tests.StringIOWrapper('someuser\n\n')
266
 
        ui.stdout = tests.StringIOWrapper()
267
 
        ui.stderr = tests.StringIOWrapper()
268
 
        ui.stdout.encoding = 'utf8'
 
223
        ui = ui_testing.TextUIFactory('someuser\n\n')
269
224
        self.assertEqual('someuser',
270
225
                         ui.get_username(u'Hello %(host)s', host='some'))
271
226
        self.assertEqual('Hello some: ', ui.stderr.getvalue())
274
229
        # stdin should be empty
275
230
        self.assertEqual('', ui.stdin.readline())
276
231
 
277
 
    def test_text_ui_getusername_utf8(self):
278
 
        ui = _mod_ui_text.TextUIFactory(None, None, None)
279
 
        ui.stdin = tests.StringIOWrapper(u'someuser\u1234'.encode('utf8'))
280
 
        ui.stdout = tests.StringIOWrapper()
281
 
        ui.stderr = tests.StringIOWrapper()
282
 
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = "utf8"
 
232
    def test_text_ui_getusername_unicode(self):
 
233
        ui = ui_testing.TextUIFactory(u'someuser\u1234')
283
234
        username = ui.get_username(u'Hello %(host)s', host=u'some\u1234')
284
235
        self.assertEqual(u"someuser\u1234", username)
285
 
        self.assertEqual(u"Hello some\u1234: ",
286
 
                          ui.stderr.getvalue().decode("utf8"))
 
236
        self.assertEqual(u"Hello some\u1234: ", ui.stderr.getvalue())
287
237
        self.assertEqual('', ui.stdout.getvalue())
288
238
 
289
239
    def test_quietness(self):
290
240
        self.overrideEnv('BRZ_PROGRESS_BAR', 'text')
291
 
        ui_factory = _mod_ui_text.TextUIFactory(None,
292
 
            TTYStringIO(),
293
 
            TTYStringIO())
 
241
        ui_factory = ui_testing.TextUIFactory(
 
242
            stderr=ui_testing.StringIOAsTTY())
294
243
        self.assertIsInstance(ui_factory._progress_view,
295
244
            _mod_ui_text.TextProgressView)
296
245
        ui_factory.be_quiet(True)
298
247
            _mod_ui_text.NullProgressView)
299
248
 
300
249
    def test_text_ui_show_user_warning(self):
301
 
        from breezy.repofmt.groupcompress_repo import RepositoryFormat2a
302
 
        from breezy.repofmt.knitpack_repo import RepositoryFormatKnitPack5
303
 
        err = StringIO()
304
 
        out = StringIO()
305
 
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
 
250
        from ..repofmt.groupcompress_repo import RepositoryFormat2a
 
251
        from ..repofmt.knitpack_repo import RepositoryFormatKnitPack5
 
252
        ui = ui_testing.TextUIFactory()
306
253
        remote_fmt = remote.RemoteRepositoryFormat()
307
254
        remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
308
255
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
309
256
            to_format=remote_fmt)
310
 
        self.assertEqual('', out.getvalue())
 
257
        self.assertEqual('', ui.stdout.getvalue())
311
258
        self.assertEqual("Doing on-the-fly conversion from RepositoryFormat2a() to "
312
259
            "RemoteRepositoryFormat(_network_name='Bazaar RepositoryFormatKnitPack5 "
313
260
            "(bzr 1.6)\\n').\nThis may take some time. Upgrade the repositories to "
314
261
            "the same format for better performance.\n",
315
 
            err.getvalue())
 
262
            ui.stderr.getvalue())
316
263
        # and now with it suppressed please
317
 
        err = StringIO()
318
 
        out = StringIO()
319
 
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
 
264
        ui = ui_testing.TextUIFactory()
320
265
        ui.suppressed_warnings.add('cross_format_fetch')
321
266
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
322
267
            to_format=remote_fmt)
323
 
        self.assertEqual('', out.getvalue())
324
 
        self.assertEqual('', err.getvalue())
 
268
        self.assertEqual('', ui.stdout.getvalue())
 
269
        self.assertEqual('', ui.stderr.getvalue())
325
270
 
326
271
 
327
272
class TestTextUIOutputStream(tests.TestCase):
328
273
    """Tests for output stream that synchronizes with progress bar."""
329
274
 
330
275
    def test_output_clears_terminal(self):
331
 
        stdout = tests.StringIOWrapper()
332
 
        stderr = tests.StringIOWrapper()
333
276
        clear_calls = []
334
277
 
335
 
        uif =  _mod_ui_text.TextUIFactory(None, stdout, stderr)
 
278
        uif =  ui_testing.TextUIFactory()
336
279
        uif.clear_term = lambda: clear_calls.append('clear')
337
280
 
338
 
        stream = _mod_ui_text.TextUIOutputStream(uif, uif.stdout)
339
 
        stream.write("Hello world!\n")
340
 
        stream.write("there's more...\n")
341
 
        stream.writelines(["1\n", "2\n", "3\n"])
 
281
        stream = _mod_ui_text.TextUIOutputStream(uif, uif.stdout, 'utf-8', 'strict')
 
282
        stream.write(u"Hello world!\n")
 
283
        stream.write(u"there's more...\n")
 
284
        stream.writelines([u"1\n", u"2\n", u"3\n"])
342
285
 
343
 
        self.assertEqual(stdout.getvalue(),
344
 
            "Hello world!\n"
345
 
            "there's more...\n"
346
 
            "1\n2\n3\n")
 
286
        self.assertEqual(uif.stdout.getvalue(),
 
287
            u"Hello world!\n"
 
288
            u"there's more...\n"
 
289
            u"1\n2\n3\n")
347
290
        self.assertEqual(['clear', 'clear', 'clear'],
348
291
            clear_calls)
349
292
 
355
298
    def test_progress_construction(self):
356
299
        """TextUIFactory constructs the right progress view.
357
300
        """
358
 
        FileStringIO = tests.StringIOWrapper
 
301
        FileStringIO = ui_testing.StringIOWithEncoding
 
302
        TTYStringIO = ui_testing.StringIOAsTTY
359
303
        for (file_class, term, pb, expected_pb_class) in (
360
304
            # on an xterm, either use them or not as the user requests,
361
305
            # otherwise default on
375
319
            ):
376
320
            self.overrideEnv('TERM', term)
377
321
            self.overrideEnv('BRZ_PROGRESS_BAR', pb)
378
 
            stdin = file_class('')
 
322
            stdin = file_class(u'')
379
323
            stderr = file_class()
380
324
            stdout = file_class()
381
325
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
387
331
 
388
332
    def test_text_ui_non_terminal(self):
389
333
        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
390
 
        stdin = NonTTYStringIO('')
391
 
        stderr = NonTTYStringIO()
392
 
        stdout = NonTTYStringIO()
 
334
        stdin = stderr = stdout = ui_testing.StringIOWithEncoding()
393
335
        for term_type in ['dumb', None, 'xterm']:
394
336
            self.overrideEnv('TERM', term_type)
395
337
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
404
346
        # password.  Possibly it should raise a more specific error but it
405
347
        # can't succeed.
406
348
        ui = _mod_ui.SilentUIFactory()
407
 
        stdout = tests.StringIOWrapper()
 
349
        stdout = ui_testing.StringIOWithEncoding()
408
350
        self.assertRaises(
409
351
            NotImplementedError,
410
352
            self.apply_redirected,
414
356
 
415
357
    def test_silent_ui_getbool(self):
416
358
        factory = _mod_ui.SilentUIFactory()
417
 
        stdout = tests.StringIOWrapper()
 
359
        stdout = ui_testing.StringIOWithEncoding()
418
360
        self.assertRaises(
419
361
            NotImplementedError,
420
362
            self.apply_redirected,
426
368
    def test_test_ui_factory_progress(self):
427
369
        # there's no output; we just want to make sure this doesn't crash -
428
370
        # see https://bugs.launchpad.net/bzr/+bug/408201
429
 
        ui = tests.TestUIFactory()
 
371
        ui = ui_testing.TestUIFactory()
430
372
        pb = ui.nested_progress_bar()
431
373
        pb.update('hello')
432
374
        pb.tick()