~bzr-pqm/bzr/bzr.dev

4597.9.5 by Vincent Ladeuil
Merge bzr.dev into cleanup
1
# Copyright (C) 2005-2010 Canonical Ltd
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
16
17
"""Tests for the bzrlib ui
18
"""
19
20
import os
4017.1.1 by John Arbash Meinel
Get a pb.tick() to work after calling pb.update()
21
import time
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
22
4797.40.2 by Martin Pool
Add missing import
23
from StringIO import StringIO
24
5416.1.11 by Martin Pool
Add ConfirmationUserInterfacePolicy that lets specific confirmations be configured off.
25
from testtools.matchers import *
26
4488.1.1 by Vincent Ladeuil
(vila) Cleanup imports in some test files
27
from bzrlib import (
5230.1.3 by Martin Pool
Use configured output encoding for make_output_stream
28
    config,
4488.1.1 by Vincent Ladeuil
(vila) Cleanup imports in some test files
29
    errors,
4634.144.5 by Martin Pool
Cleaner presentation and tests for warn_cross_format_fetch
30
    remote,
31
    repository,
4488.1.1 by Vincent Ladeuil
(vila) Cleanup imports in some test files
32
    tests,
33
    ui as _mod_ui,
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
34
    )
3948.2.6 by Martin Pool
ProgressBarStack is deprecated
35
from bzrlib.symbol_versioning import (
36
    deprecated_in,
37
    )
5230.1.3 by Martin Pool
Use configured output encoding for make_output_stream
38
from bzrlib.tests import (
39
    fixtures,
40
    test_progress,
41
    )
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
42
from bzrlib.ui import text as _mod_ui_text
5422.1.5 by Martin Pool
Move ProgressRecordingUIFactory to bzrlib.tests.testui
43
from bzrlib.tests.testui import (
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
44
    ProgressRecordingUIFactory,
5422.1.1 by Martin Pool
Move CapturingUIFactory out of per_workingtree tests into somewhere reusable
45
    )
1185.49.22 by John Arbash Meinel
Added get_password to the UIFactory, using it inside of sftp.py
46
1681.1.2 by Robert Collins
* bzrlib.ui.text.TextUIFactory now accepts a bar_type parameter which
47
5230.1.3 by Martin Pool
Use configured output encoding for make_output_stream
48
class TestUIConfiguration(tests.TestCaseWithTransport):
49
50
    def test_output_encoding_configuration(self):
5230.1.5 by Martin Pool
Merge updated test fixtures
51
        enc = fixtures.generate_unicode_encodings().next()
5230.1.3 by Martin Pool
Use configured output encoding for make_output_stream
52
        config.GlobalConfig().set_user_option('output_encoding',
53
            enc)
54
        ui = tests.TestUIFactory(stdin=None,
5230.1.5 by Martin Pool
Merge updated test fixtures
55
            stdout=tests.StringIOWrapper(),
56
            stderr=tests.StringIOWrapper())
5416.1.11 by Martin Pool
Add ConfirmationUserInterfacePolicy that lets specific confirmations be configured off.
57
        output = ui.make_output_stream()
58
        self.assertEquals(output.encoding, enc)
5230.1.3 by Martin Pool
Use configured output encoding for make_output_stream
59
60
4711.1.6 by Martin Pool
Separate TextUIFactory tests
61
class TestTextUIFactory(tests.TestCase):
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
62
5416.1.1 by Martin Pool
Use a structured ui_factory.confirm_action rather than just get_boolean
63
    def make_test_ui_factory(self, stdin_contents):
64
        ui = tests.TestUIFactory(stdin=stdin_contents,
65
                                 stdout=tests.StringIOWrapper(),
66
                                 stderr=tests.StringIOWrapper())
67
        return ui
68
69
    def test_text_factory_confirm(self):
70
        # turns into reading a regular boolean
71
        ui = self.make_test_ui_factory('n\n')
72
        self.assertEquals(ui.confirm_action('Should %(thing)s pass?',
73
            'bzrlib.tests.test_ui.confirmation',
74
            {'thing': 'this'},),
75
            False)
76
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
77
    def test_text_factory_ascii_password(self):
5416.1.1 by Martin Pool
Use a structured ui_factory.confirm_action rather than just get_boolean
78
        ui = self.make_test_ui_factory('secret\n')
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
79
        pb = ui.nested_progress_bar()
80
        try:
81
            self.assertEqual('secret',
82
                             self.apply_redirected(ui.stdin, ui.stdout,
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
83
                                                   ui.stderr,
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
84
                                                   ui.get_password))
85
            # ': ' is appended to prompt
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
86
            self.assertEqual(': ', ui.stderr.getvalue())
87
            self.assertEqual('', ui.stdout.readline())
2363.4.3 by Vincent Ladeuil
Tidy-up tests.
88
            # stdin should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
89
            self.assertEqual('', ui.stdin.readline())
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
90
        finally:
91
            pb.finished()
92
93
    def test_text_factory_utf8_password(self):
94
        """Test an utf8 password.
95
96
        We can't predict what encoding users will have for stdin, so we force
97
        it to utf8 to test that we transport the password correctly.
98
        """
5416.1.1 by Martin Pool
Use a structured ui_factory.confirm_action rather than just get_boolean
99
        ui = self.make_test_ui_factory(u'baz\u1234'.encode('utf8'))
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
100
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = 'utf8'
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
101
        pb = ui.nested_progress_bar()
102
        try:
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
103
            password = self.apply_redirected(ui.stdin, ui.stdout, ui.stderr,
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
104
                                             ui.get_password,
105
                                             u'Hello \u1234 %(user)s',
106
                                             user=u'some\u1234')
107
            # We use StringIO objects, we need to decode them
108
            self.assertEqual(u'baz\u1234', password.decode('utf8'))
109
            self.assertEqual(u'Hello \u1234 some\u1234: ',
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
110
                             ui.stderr.getvalue().decode('utf8'))
111
            # stdin and stdout should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
112
            self.assertEqual('', ui.stdin.readline())
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
113
            self.assertEqual('', ui.stdout.readline())
2294.4.1 by Vincent Ladeuil
Add a UIFactory.get_login method, fix tests.
114
        finally:
115
            pb.finished()
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
116
4449.3.38 by Martin Pool
Cleanup get_boolean tests
117
    def test_text_ui_get_boolean(self):
4773.1.2 by Vincent Ladeuil
Cleanup imports in test_ui
118
        stdin = tests.StringIOWrapper("y\n" # True
119
                                      "n\n" # False
120
                                      "yes with garbage\nY\n" # True
121
                                      "not an answer\nno\n" # False
122
                                      "I'm sure!\nyes\n" # True
123
                                      "NO\n" # False
124
                                      "foo\n")
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
125
        stdout = tests.StringIOWrapper()
126
        stderr = tests.StringIOWrapper()
127
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
128
        self.assertEqual(True, factory.get_boolean(""))
4503.2.5 by Vincent Ladeuil
ui.get_boolean can also use bool_from_string.
129
        self.assertEqual(False, factory.get_boolean(""))
130
        self.assertEqual(True, factory.get_boolean(""))
131
        self.assertEqual(False, factory.get_boolean(""))
132
        self.assertEqual(True, factory.get_boolean(""))
133
        self.assertEqual(False, factory.get_boolean(""))
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
134
        self.assertEqual("foo\n", factory.stdin.read())
2363.4.4 by Vincent Ladeuil
More tidying-up.
135
        # stdin should be empty
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
136
        self.assertEqual('', factory.stdin.readline())
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
137
4597.3.37 by Vincent Ladeuil
Allows ui factories to query users for an integer.
138
    def test_text_ui_get_integer(self):
139
        stdin = tests.StringIOWrapper(
140
            "1\n"
141
            "  -2  \n"
142
            "hmmm\nwhat else ?\nCome on\nok 42\n4.24\n42\n")
143
        stdout = tests.StringIOWrapper()
144
        stderr = tests.StringIOWrapper()
145
        factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
146
        self.assertEqual(1, factory.get_integer(""))
147
        self.assertEqual(-2, factory.get_integer(""))
148
        self.assertEqual(42, factory.get_integer(""))
149
4300.3.1 by Martin Pool
Fix string expansion in TextUIFactory.prompt
150
    def test_text_factory_prompt(self):
151
        # see <https://launchpad.net/bugs/365891>
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
152
        StringIO = tests.StringIOWrapper
153
        factory = _mod_ui_text.TextUIFactory(StringIO(), StringIO(), StringIO())
4300.3.1 by Martin Pool
Fix string expansion in TextUIFactory.prompt
154
        factory.prompt('foo %2e')
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
155
        self.assertEqual('', factory.stdout.getvalue())
156
        self.assertEqual('foo %2e', factory.stderr.getvalue())
4300.3.1 by Martin Pool
Fix string expansion in TextUIFactory.prompt
157
1687.1.4 by Robert Collins
Add bzrlib.ui.ui_factory.get_boolean().
158
    def test_text_factory_prompts_and_clears(self):
159
        # a get_boolean call should clear the pb before prompting
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
160
        out = test_progress._TTYStringIO()
4449.3.4 by Martin Pool
ProgressTask now talks to ProgressView; easier to test
161
        os.environ['TERM'] = 'xterm'
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
162
        factory = _mod_ui_text.TextUIFactory(
163
            stdin=tests.StringIOWrapper("yada\ny\n"),
164
            stdout=out, stderr=out)
5339.2.6 by Martin Pool
One more UI test needs updates for spinner being at the front
165
        factory._avail_width = lambda: 79
3882.8.10 by Martin Pool
Fix up test_ui for new progress bars
166
        pb = factory.nested_progress_bar()
167
        pb.show_bar = False
168
        pb.show_spinner = False
169
        pb.show_count = False
170
        pb.update("foo", 0, 1)
2363.4.4 by Vincent Ladeuil
More tidying-up.
171
        self.assertEqual(True,
172
                         self.apply_redirected(None, factory.stdout,
173
                                               factory.stdout,
174
                                               factory.get_boolean,
175
                                               "what do you want"))
3882.8.10 by Martin Pool
Fix up test_ui for new progress bars
176
        output = out.getvalue()
5339.2.6 by Martin Pool
One more UI test needs updates for spinner being at the front
177
        self.assertContainsRe(output,
178
            "| foo *\r\r  *\r*")
179
        self.assertContainsRe(output,
3882.8.10 by Martin Pool
Fix up test_ui for new progress bars
180
            r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
181
        # stdin should have been totally consumed
2363.4.6 by Vincent Ladeuil
Fix tests around stdin emptyness.
182
        self.assertEqual('', factory.stdin.readline())
4017.1.1 by John Arbash Meinel
Get a pb.tick() to work after calling pb.update()
183
184
    def test_text_tick_after_update(self):
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
185
        ui_factory = _mod_ui_text.TextUIFactory(stdout=tests.StringIOWrapper(),
186
                                                stderr=tests.StringIOWrapper())
4017.1.1 by John Arbash Meinel
Get a pb.tick() to work after calling pb.update()
187
        pb = ui_factory.nested_progress_bar()
188
        try:
189
            pb.update('task', 0, 3)
190
            # Reset the clock, so that it actually tries to repaint itself
191
            ui_factory._progress_view._last_repaint = time.time() - 1.0
192
            pb.tick()
193
        finally:
194
            pb.finished()
4110.2.15 by Martin Pool
Fix bug in showing task progress and add a test
195
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
196
    def test_text_ui_getusername(self):
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
197
        factory = _mod_ui_text.TextUIFactory(None, None, None)
198
        factory.stdin = tests.StringIOWrapper("someuser\n\n")
199
        factory.stdout = tests.StringIOWrapper()
200
        factory.stderr = tests.StringIOWrapper()
4222.2.6 by Jelmer Vernooij
Remove use of NotATerminal.
201
        factory.stdout.encoding = "utf8"
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
202
        # there is no output from the base factory
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
203
        self.assertEqual("someuser",
204
                         factory.get_username('Hello %(host)s', host='some'))
205
        self.assertEquals("Hello some: ", factory.stderr.getvalue())
206
        self.assertEquals('', factory.stdout.getvalue())
4222.2.1 by Jelmer Vernooij
Add get_username() call to the UIFactory.
207
        self.assertEqual("", factory.get_username("Gebruiker"))
208
        # stdin should be empty
209
        self.assertEqual('', factory.stdin.readline())
210
4222.2.2 by Jelmer Vernooij
Review from vila: Deal with UTF8 strings in prompts, fix typo.
211
    def test_text_ui_getusername_utf8(self):
4488.1.1 by Vincent Ladeuil
(vila) Cleanup imports in some test files
212
        ui = tests.TestUIFactory(stdin=u'someuser\u1234'.encode('utf8'),
213
                                 stdout=tests.StringIOWrapper(),
214
                                 stderr=tests.StringIOWrapper())
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
215
        ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = "utf8"
4222.2.3 by Jelmer Vernooij
Also check for unicode usernames.
216
        pb = ui.nested_progress_bar()
217
        try:
218
            # there is no output from the base factory
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
219
            username = self.apply_redirected(ui.stdin, ui.stdout, ui.stderr,
4222.2.12 by Jelmer Vernooij
Redirect to fix utf8 test with LC_ALL=C.
220
                ui.get_username, u'Hello\u1234 %(host)s', host=u'some\u1234')
4222.2.8 by Jelmer Vernooij
Fix copy-n-paste error.
221
            self.assertEquals(u"someuser\u1234", username.decode('utf8'))
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
222
            self.assertEquals(u"Hello\u1234 some\u1234: ",
223
                              ui.stderr.getvalue().decode("utf8"))
224
            self.assertEquals('', ui.stdout.getvalue())
4222.2.3 by Jelmer Vernooij
Also check for unicode usernames.
225
        finally:
226
            pb.finished()
4222.2.2 by Jelmer Vernooij
Review from vila: Deal with UTF8 strings in prompts, fix typo.
227
4961.1.3 by Martin Pool
trace quietness now controls whether the progress bar appears
228
    def test_quietness(self):
229
        os.environ['BZR_PROGRESS_BAR'] = 'text'
230
        ui_factory = _mod_ui_text.TextUIFactory(None,
231
            test_progress._TTYStringIO(),
232
            test_progress._TTYStringIO())
233
        self.assertIsInstance(ui_factory._progress_view,
234
            _mod_ui_text.TextProgressView)
235
        ui_factory.be_quiet(True)
236
        self.assertIsInstance(ui_factory._progress_view,
237
            _mod_ui_text.NullProgressView)
238
4634.144.10 by Martin Pool
Update test_ui for warning suppression
239
    def test_text_ui_show_user_warning(self):
4634.144.5 by Martin Pool
Cleaner presentation and tests for warn_cross_format_fetch
240
        from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
241
        from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5
242
        err = StringIO()
243
        out = StringIO()
244
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
245
        remote_fmt = remote.RemoteRepositoryFormat()
246
        remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
4634.144.10 by Martin Pool
Update test_ui for warning suppression
247
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
248
            to_format=remote_fmt)
4634.144.5 by Martin Pool
Cleaner presentation and tests for warn_cross_format_fetch
249
        self.assertEquals('', out.getvalue())
250
        self.assertEquals("Doing on-the-fly conversion from RepositoryFormat2a() to "
251
            "RemoteRepositoryFormat(_network_name='Bazaar RepositoryFormatKnitPack5 "
252
            "(bzr 1.6)\\n').\nThis may take some time. Upgrade the repositories to "
253
            "the same format for better performance.\n",
254
            err.getvalue())
4634.144.10 by Martin Pool
Update test_ui for warning suppression
255
        # and now with it suppressed please
256
        err = StringIO()
257
        out = StringIO()
258
        ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
4634.144.11 by Martin Pool
Rename squelched to suppressed
259
        ui.suppressed_warnings.add('cross_format_fetch')
4634.144.10 by Martin Pool
Update test_ui for warning suppression
260
        ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
261
            to_format=remote_fmt)
262
        self.assertEquals('', out.getvalue())
263
        self.assertEquals('', err.getvalue())
4634.144.5 by Martin Pool
Cleaner presentation and tests for warn_cross_format_fetch
264
4110.2.15 by Martin Pool
Fix bug in showing task progress and add a test
265
4884.1.1 by Vincent Ladeuil
Cleanup some test imports
266
class TestTextUIOutputStream(tests.TestCase):
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
267
    """Tests for output stream that synchronizes with progress bar."""
268
269
    def test_output_clears_terminal(self):
4884.1.1 by Vincent Ladeuil
Cleanup some test imports
270
        stdout = tests.StringIOWrapper()
271
        stderr = tests.StringIOWrapper()
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
272
        clear_calls = []
273
4884.1.1 by Vincent Ladeuil
Cleanup some test imports
274
        uif =  _mod_ui_text.TextUIFactory(None, stdout, stderr)
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
275
        uif.clear_term = lambda: clear_calls.append('clear')
276
4884.1.1 by Vincent Ladeuil
Cleanup some test imports
277
        stream = _mod_ui_text.TextUIOutputStream(uif, uif.stdout)
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
278
        stream.write("Hello world!\n")
279
        stream.write("there's more...\n")
4792.8.3 by Martin Pool
Add TextUIOutputStream.writelines
280
        stream.writelines(["1\n", "2\n", "3\n"])
4884.1.1 by Vincent Ladeuil
Cleanup some test imports
281
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
282
        self.assertEqual(stdout.getvalue(),
283
            "Hello world!\n"
4792.8.3 by Martin Pool
Add TextUIOutputStream.writelines
284
            "there's more...\n"
285
            "1\n2\n3\n")
286
        self.assertEqual(['clear', 'clear', 'clear'],
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
287
            clear_calls)
288
4792.8.8 by Martin Pool
Add TextUIOutputStream.flush
289
        stream.flush()
4792.8.1 by Martin Pool
Add TextUIOutputStream coordinated with progress view
290
291
4711.1.6 by Martin Pool
Separate TextUIFactory tests
292
class UITests(tests.TestCase):
293
294
    def test_progress_construction(self):
295
        """TextUIFactory constructs the right progress view.
296
        """
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
297
        TTYStringIO = test_progress._TTYStringIO
298
        FileStringIO = tests.StringIOWrapper
4711.1.6 by Martin Pool
Separate TextUIFactory tests
299
        for (file_class, term, pb, expected_pb_class) in (
300
            # on an xterm, either use them or not as the user requests,
301
            # otherwise default on
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
302
            (TTYStringIO, 'xterm', 'none', _mod_ui_text.NullProgressView),
303
            (TTYStringIO, 'xterm', 'text', _mod_ui_text.TextProgressView),
304
            (TTYStringIO, 'xterm', None, _mod_ui_text.TextProgressView),
4711.1.6 by Martin Pool
Separate TextUIFactory tests
305
            # on a dumb terminal, again if there's explicit configuration do
306
            # it, otherwise default off
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
307
            (TTYStringIO, 'dumb', 'none', _mod_ui_text.NullProgressView),
308
            (TTYStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
309
            (TTYStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
4711.1.6 by Martin Pool
Separate TextUIFactory tests
310
            # on a non-tty terminal, it's null regardless of $TERM
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
311
            (FileStringIO, 'xterm', None, _mod_ui_text.NullProgressView),
312
            (FileStringIO, 'dumb', None, _mod_ui_text.NullProgressView),
4711.1.6 by Martin Pool
Separate TextUIFactory tests
313
            # however, it can still be forced on
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
314
            (FileStringIO, 'dumb', 'text', _mod_ui_text.TextProgressView),
4711.1.6 by Martin Pool
Separate TextUIFactory tests
315
            ):
316
            os.environ['TERM'] = term
317
            if pb is None:
318
                if 'BZR_PROGRESS_BAR' in os.environ:
319
                    del os.environ['BZR_PROGRESS_BAR']
320
            else:
321
                os.environ['BZR_PROGRESS_BAR'] = pb
322
            stdin = file_class('')
323
            stderr = file_class()
324
            stdout = file_class()
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
325
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
326
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
4711.1.6 by Martin Pool
Separate TextUIFactory tests
327
                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
328
            self.assertIsInstance(uif.make_progress_view(),
329
                expected_pb_class,
330
                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
331
332
    def test_text_ui_non_terminal(self):
333
        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
334
        stdin = test_progress._NonTTYStringIO('')
335
        stderr = test_progress._NonTTYStringIO()
336
        stdout = test_progress._NonTTYStringIO()
4711.1.6 by Martin Pool
Separate TextUIFactory tests
337
        for term_type in ['dumb', None, 'xterm']:
338
            if term_type is None:
339
                del os.environ['TERM']
340
            else:
341
                os.environ['TERM'] = term_type
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
342
            uif = _mod_ui.make_ui_for_terminal(stdin, stdout, stderr)
343
            self.assertIsInstance(uif, _mod_ui_text.TextUIFactory,
4711.1.6 by Martin Pool
Separate TextUIFactory tests
344
                'TERM=%r' % (term_type,))
345
346
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
347
class SilentUITests(tests.TestCase):
4449.3.19 by Martin Pool
SilentUIFactory now always errors when asked for input
348
4449.3.36 by Martin Pool
Update tests: SilentUIFactory no longer does get_boolean or get_password
349
    def test_silent_factory_get_password(self):
350
        # A silent factory that can't do user interaction can't get a
351
        # password.  Possibly it should raise a more specific error but it
352
        # can't succeed.
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
353
        ui = _mod_ui.SilentUIFactory()
354
        stdout = tests.StringIOWrapper()
4449.3.19 by Martin Pool
SilentUIFactory now always errors when asked for input
355
        self.assertRaises(
356
            NotImplementedError,
357
            self.apply_redirected,
358
            None, stdout, stdout, ui.get_password)
359
        # and it didn't write anything out either
360
        self.assertEqual('', stdout.getvalue())
361
362
    def test_silent_ui_getbool(self):
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
363
        factory = _mod_ui.SilentUIFactory()
364
        stdout = tests.StringIOWrapper()
4449.3.19 by Martin Pool
SilentUIFactory now always errors when asked for input
365
        self.assertRaises(
366
            NotImplementedError,
367
            self.apply_redirected,
368
            None, stdout, stdout, factory.get_boolean, "foo")
4449.3.42 by Martin Pool
Add basic test for CannedInputUIFactory
369
370
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
371
class TestUIFactoryTests(tests.TestCase):
4580.2.2 by Martin Pool
Add test for bug 408201
372
373
    def test_test_ui_factory_progress(self):
374
        # there's no output; we just want to make sure this doesn't crash -
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
375
        # see https://bugs.launchpad.net/bzr/+bug/408201
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
376
        ui = tests.TestUIFactory()
4580.2.2 by Martin Pool
Add test for bug 408201
377
        pb = ui.nested_progress_bar()
378
        pb.update('hello')
379
        pb.tick()
380
        pb.finished()
381
382
4597.3.36 by Vincent Ladeuil
Fix imports and various cleanups in test_ui.
383
class CannedInputUIFactoryTests(tests.TestCase):
384
4449.3.42 by Martin Pool
Add basic test for CannedInputUIFactory
385
    def test_canned_input_get_input(self):
4597.3.37 by Vincent Ladeuil
Allows ui factories to query users for an integer.
386
        uif = _mod_ui.CannedInputUIFactory([True, 'mbp', 'password', 42])
387
        self.assertEqual(True, uif.get_boolean('Extra cheese?'))
388
        self.assertEqual('mbp', uif.get_username('Enter your user name'))
389
        self.assertEqual('password',
390
                         uif.get_password('Password for %(host)s',
391
                                          host='example.com'))
4886.1.1 by Vincent Ladeuil
Allows ui factories to query users for an integer.
392
        self.assertEqual(42, uif.get_integer('And all that jazz ?'))
4110.2.17 by Martin Pool
If one ProgressTask has no count, it passes through that of its child
393
4503.2.1 by Vincent Ladeuil
Get a bool from a string.
394
395
class TestBoolFromString(tests.TestCase):
396
397
    def assertIsTrue(self, s, accepted_values=None):
398
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
399
        self.assertEquals(True, res)
400
401
    def assertIsFalse(self, s, accepted_values=None):
402
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
403
        self.assertEquals(False, res)
404
405
    def assertIsNone(self, s, accepted_values=None):
406
        res = _mod_ui.bool_from_string(s, accepted_values=accepted_values)
407
        self.assertIs(None, res)
408
409
    def test_know_valid_values(self):
410
        self.assertIsTrue('true')
411
        self.assertIsFalse('false')
412
        self.assertIsTrue('1')
413
        self.assertIsFalse('0')
414
        self.assertIsTrue('on')
415
        self.assertIsFalse('off')
416
        self.assertIsTrue('yes')
417
        self.assertIsFalse('no')
418
        self.assertIsTrue('y')
419
        self.assertIsFalse('n')
420
        # Also try some case variations
421
        self.assertIsTrue('True')
422
        self.assertIsFalse('False')
423
        self.assertIsTrue('On')
424
        self.assertIsFalse('Off')
425
        self.assertIsTrue('ON')
426
        self.assertIsFalse('OFF')
427
        self.assertIsTrue('oN')
428
        self.assertIsFalse('oFf')
429
430
    def test_invalid_values(self):
431
        self.assertIsNone(None)
432
        self.assertIsNone('doubt')
433
        self.assertIsNone('frue')
434
        self.assertIsNone('talse')
435
        self.assertIsNone('42')
436
437
    def test_provided_values(self):
438
        av = dict(y=True, n=False, yes=True, no=False)
439
        self.assertIsTrue('y', av)
440
        self.assertIsTrue('Y', av)
441
        self.assertIsTrue('Yes', av)
442
        self.assertIsFalse('n', av)
443
        self.assertIsFalse('N', av)
444
        self.assertIsFalse('No', av)
445
        self.assertIsNone('1', av)
446
        self.assertIsNone('0', av)
447
        self.assertIsNone('on', av)
448
        self.assertIsNone('off', av)
5422.1.1 by Martin Pool
Move CapturingUIFactory out of per_workingtree tests into somewhere reusable
449
450
5416.1.11 by Martin Pool
Add ConfirmationUserInterfacePolicy that lets specific confirmations be configured off.
451
class TestConfirmationUserInterfacePolicy(tests.TestCase):
452
453
    def test_confirm_action_default(self):
454
        base_ui = _mod_ui.NoninteractiveUIFactory()
455
        for answer in [True, False]:
456
            self.assertEquals(
457
                _mod_ui.ConfirmationUserInterfacePolicy(base_ui, answer, {})
458
                .confirm_action("Do something?",
459
                    "bzrlib.tests.do_something", {}),
460
                answer)
461
462
    def test_confirm_action_specific(self):
463
        base_ui = _mod_ui.NoninteractiveUIFactory()
464
        for default_answer in [True, False]:
465
            for specific_answer in [True, False]:
466
                for conf_id in ['given_id', 'other_id']:
467
                    wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
468
                        base_ui, default_answer, dict(given_id=specific_answer))
469
                    result = wrapper.confirm_action("Do something?", conf_id, {})
470
                    if conf_id == 'given_id':
471
                        self.assertEquals(result, specific_answer)
472
                    else:
473
                        self.assertEquals(result, default_answer)
474
475
    def test_repr(self):
476
        base_ui = _mod_ui.NoninteractiveUIFactory()
477
        wrapper = _mod_ui.ConfirmationUserInterfacePolicy(
478
            base_ui, True, dict(a=2))
479
        self.assertThat(repr(wrapper),
480
            Equals("ConfirmationUserInterfacePolicy("
481
                "NoninteractiveUIFactory(), True, {'a': 2})"))
5416.1.13 by Martin Pool
merge trunk
482
483
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
484
class TestProgressRecordingUI(tests.TestCase):
5422.1.1 by Martin Pool
Move CapturingUIFactory out of per_workingtree tests into somewhere reusable
485
    """Test test-oriented UIFactory that records progress updates"""
486
487
    def test_nested_ignore_depth_beyond_one(self):
488
        # we only want to capture the first level out progress, not
489
        # want sub-components might do. So we have nested bars ignored.
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
490
        factory = ProgressRecordingUIFactory()
5422.1.1 by Martin Pool
Move CapturingUIFactory out of per_workingtree tests into somewhere reusable
491
        pb1 = factory.nested_progress_bar()
492
        pb1.update('foo', 0, 1)
493
        pb2 = factory.nested_progress_bar()
494
        pb2.update('foo', 0, 1)
495
        pb2.finished()
496
        pb1.finished()
497
        self.assertEqual([("update", 0, 1, 'foo')], factory._calls)