54
73
self.assertEqual('', ui.stdout.readline())
55
74
# stdin should be empty
56
75
self.assertEqual('', ui.stdin.readline())
60
def test_text_factory_utf8_password(self):
61
"""Test an utf8 password.
63
We can't predict what encoding users will have for stdin, so we force
64
it to utf8 to test that we transport the password correctly.
66
ui = tests.TestUIFactory(stdin=u'baz\u1234'.encode('utf8'),
67
stdout=tests.StringIOWrapper(),
68
stderr=tests.StringIOWrapper())
69
ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = 'utf8'
70
pb = ui.nested_progress_bar()
72
password = self.apply_redirected(ui.stdin, ui.stdout, ui.stderr,
74
u'Hello \u1234 %(user)s',
76
# We use StringIO objects, we need to decode them
77
self.assertEqual(u'baz\u1234', password.decode('utf8'))
78
self.assertEqual(u'Hello \u1234 some\u1234: ',
79
ui.stderr.getvalue().decode('utf8'))
80
# stdin and stdout should be empty
81
self.assertEqual('', ui.stdin.readline())
82
self.assertEqual('', ui.stdout.readline())
86
def test_progress_note(self):
87
stderr = tests.StringIOWrapper()
88
stdout = tests.StringIOWrapper()
89
ui_factory = _mod_ui_text.TextUIFactory(stdin=tests.StringIOWrapper(''),
92
pb = ui_factory.nested_progress_bar()
94
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
97
self.assertEqual(None, result)
98
self.assertEqual("t\n", stdout.getvalue())
99
# Since there was no update() call, there should be no clear() call
100
self.failIf(re.search(r'^\r {10,}\r$',
101
stderr.getvalue()) is not None,
102
'We cleared the stderr without anything to put there')
106
def test_progress_note_clears(self):
107
stderr = test_progress._TTYStringIO()
108
stdout = test_progress._TTYStringIO()
109
# so that we get a TextProgressBar
110
os.environ['TERM'] = 'xterm'
111
ui_factory = _mod_ui_text.TextUIFactory(
112
stdin=tests.StringIOWrapper(''),
113
stdout=stdout, stderr=stderr)
114
self.assertIsInstance(ui_factory._progress_view,
115
_mod_ui_text.TextProgressView)
116
pb = ui_factory.nested_progress_bar()
118
# Create a progress update that isn't throttled
120
result = self.applyDeprecated(deprecated_in((2, 1, 0)),
122
self.assertEqual(None, result)
123
self.assertEqual("t\n", stdout.getvalue())
124
# the exact contents will depend on the terminal width and we don't
125
# care about that right now - but you're probably running it on at
126
# least a 10-character wide terminal :)
127
self.assertContainsRe(stderr.getvalue(), r'\r {10,}\r$')
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())
131
87
def test_text_ui_get_boolean(self):
132
stdin = tests.StringIOWrapper("y\n" # True
134
"yes with garbage\nY\n" # True
135
"not an answer\nno\n" # False
136
"I'm sure!\nyes\n" # True
139
stdout = tests.StringIOWrapper()
140
stderr = tests.StringIOWrapper()
141
factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
142
self.assertEqual(True, factory.get_boolean(""))
143
self.assertEqual(False, factory.get_boolean(""))
144
self.assertEqual(True, factory.get_boolean(""))
145
self.assertEqual(False, factory.get_boolean(""))
146
self.assertEqual(True, factory.get_boolean(""))
147
self.assertEqual(False, factory.get_boolean(""))
148
self.assertEqual("foo\n", factory.stdin.read())
149
# stdin should be empty
150
self.assertEqual('', factory.stdin.readline())
93
"yes with garbage\nY\n" # True
94
"not an answer\nno\n" # False
95
"I'm sure!\nyes\n" # True
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""))
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)
119
ValueError, factory.choose, u"", u"&choice\n&ChOiCe")
120
# duplicated shortcut
122
ValueError, factory.choose, u"", u"&choice1\nchoi&ce2")
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")
129
"prompt ([y]es, [N]o, more [i]nfo): \n",
130
factory.stderr.getvalue())
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")
137
"prompt ([y]es, [N]o, [m]ore info): \n",
138
factory.stderr.getvalue())
140
def test_text_ui_choose_return_values(self):
142
return factory.choose(u"", u"&Yes\n&No\nMaybe\nmore &info", 3)
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
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())
167
self.assertEqual(None, choose())
169
def test_text_ui_choose_no_default(self):
171
" \n" # no default, invalid!
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())
152
178
def test_text_ui_get_integer(self):
153
stdin = tests.StringIOWrapper(
156
182
"hmmm\nwhat else ?\nCome on\nok 42\n4.24\n42\n")
157
stdout = tests.StringIOWrapper()
158
stderr = tests.StringIOWrapper()
159
factory = _mod_ui_text.TextUIFactory(stdin, stdout, stderr)
160
self.assertEqual(1, factory.get_integer(""))
161
self.assertEqual(-2, factory.get_integer(""))
162
self.assertEqual(42, factory.get_integer(""))
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""))
164
188
def test_text_factory_prompt(self):
165
189
# see <https://launchpad.net/bugs/365891>
166
StringIO = tests.StringIOWrapper
167
factory = _mod_ui_text.TextUIFactory(StringIO(), StringIO(), StringIO())
168
factory.prompt('foo %2e')
169
self.assertEqual('', factory.stdout.getvalue())
170
self.assertEqual('foo %2e', factory.stderr.getvalue())
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())
172
195
def test_text_factory_prompts_and_clears(self):
173
196
# a get_boolean call should clear the pb before prompting
174
out = test_progress._TTYStringIO()
175
os.environ['TERM'] = 'xterm'
176
factory = _mod_ui_text.TextUIFactory(
177
stdin=tests.StringIOWrapper("yada\ny\n"),
178
stdout=out, stderr=out)
179
pb = factory.nested_progress_bar()
181
pb.show_spinner = False
182
pb.show_count = False
183
pb.update("foo", 0, 1)
184
self.assertEqual(True,
185
self.apply_redirected(None, factory.stdout,
189
output = out.getvalue()
190
self.assertContainsRe(factory.stdout.getvalue(),
192
self.assertContainsRe(factory.stdout.getvalue(),
193
r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
194
# stdin should have been totally consumed
195
self.assertEqual('', factory.stdin.readline())
197
out = ui_testing.StringIOAsTTY()
198
self.overrideEnv('TERM', 'xterm')
199
factory = ui_testing.TextUIFactory("yada\ny\n", stdout=out, stderr=out)
201
pb = factory.nested_progress_bar()
202
pb._avail_width = lambda: 79
204
pb.show_spinner = False
205
pb.show_count = False
206
pb.update("foo", 0, 1)
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,
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())
197
220
def test_text_tick_after_update(self):
198
ui_factory = _mod_ui_text.TextUIFactory(stdout=tests.StringIOWrapper(),
199
stderr=tests.StringIOWrapper())
200
pb = ui_factory.nested_progress_bar()
221
ui_factory = ui_testing.TextUIFactory()
222
with ui_factory.nested_progress_bar() as pb:
202
223
pb.update('task', 0, 3)
203
224
# Reset the clock, so that it actually tries to repaint itself
204
225
ui_factory._progress_view._last_repaint = time.time() - 1.0
209
228
def test_text_ui_getusername(self):
210
factory = _mod_ui_text.TextUIFactory(None, None, None)
211
factory.stdin = tests.StringIOWrapper("someuser\n\n")
212
factory.stdout = tests.StringIOWrapper()
213
factory.stderr = tests.StringIOWrapper()
214
factory.stdout.encoding = "utf8"
215
# there is no output from the base factory
216
self.assertEqual("someuser",
217
factory.get_username('Hello %(host)s', host='some'))
218
self.assertEquals("Hello some: ", factory.stderr.getvalue())
219
self.assertEquals('', factory.stdout.getvalue())
220
self.assertEqual("", factory.get_username("Gebruiker"))
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"))
221
235
# stdin should be empty
222
self.assertEqual('', factory.stdin.readline())
236
self.assertEqual('', ui.stdin.readline())
224
def test_text_ui_getusername_utf8(self):
225
ui = tests.TestUIFactory(stdin=u'someuser\u1234'.encode('utf8'),
226
stdout=tests.StringIOWrapper(),
227
stderr=tests.StringIOWrapper())
228
ui.stderr.encoding = ui.stdout.encoding = ui.stdin.encoding = "utf8"
229
pb = ui.nested_progress_bar()
231
# there is no output from the base factory
232
username = self.apply_redirected(ui.stdin, ui.stdout, ui.stderr,
233
ui.get_username, u'Hello\u1234 %(host)s', host=u'some\u1234')
234
self.assertEquals(u"someuser\u1234", username.decode('utf8'))
235
self.assertEquals(u"Hello\u1234 some\u1234: ",
236
ui.stderr.getvalue().decode("utf8"))
237
self.assertEquals('', ui.stdout.getvalue())
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())
241
245
def test_quietness(self):
242
os.environ['BZR_PROGRESS_BAR'] = 'text'
243
ui_factory = _mod_ui_text.TextUIFactory(None,
244
test_progress._TTYStringIO(),
245
test_progress._TTYStringIO())
246
self.assertIsInstance(ui_factory._progress_view,
247
_mod_ui_text.TextProgressView)
248
ui_factory.be_quiet(True)
249
self.assertIsInstance(ui_factory._progress_view,
250
_mod_ui_text.NullProgressView)
246
self.overrideEnv('BRZ_PROGRESS_BAR', 'text')
247
ui_factory = ui_testing.TextUIFactory(
248
stderr=ui_testing.StringIOAsTTY())
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)
252
256
def test_text_ui_show_user_warning(self):
253
from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
254
from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack5
257
ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
257
from ..bzr.groupcompress_repo import RepositoryFormat2a
258
from ..bzr.knitpack_repo import RepositoryFormatKnitPack5
259
ui = ui_testing.TextUIFactory()
258
260
remote_fmt = remote.RemoteRepositoryFormat()
259
261
remote_fmt._network_name = RepositoryFormatKnitPack5().network_name()
260
262
ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
261
263
to_format=remote_fmt)
262
self.assertEquals('', out.getvalue())
263
self.assertEquals("Doing on-the-fly conversion from RepositoryFormat2a() to "
264
"RemoteRepositoryFormat(_network_name='Bazaar RepositoryFormatKnitPack5 "
265
"(bzr 1.6)\\n').\nThis may take some time. Upgrade the repositories to "
266
"the same format for better performance.\n",
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$")
268
272
# and now with it suppressed please
271
ui = tests.TextUIFactory(stdin=None, stdout=out, stderr=err)
273
ui = ui_testing.TextUIFactory()
272
274
ui.suppressed_warnings.add('cross_format_fetch')
273
275
ui.show_user_warning('cross_format_fetch', from_format=RepositoryFormat2a(),
274
276
to_format=remote_fmt)
275
self.assertEquals('', out.getvalue())
276
self.assertEquals('', err.getvalue())
277
self.assertEqual('', ui.stdout.getvalue())
278
self.assertEqual('', ui.stderr.getvalue())
279
281
class TestTextUIOutputStream(tests.TestCase):
280
282
"""Tests for output stream that synchronizes with progress bar."""
282
284
def test_output_clears_terminal(self):
283
stdout = tests.StringIOWrapper()
284
stderr = tests.StringIOWrapper()
287
uif = _mod_ui_text.TextUIFactory(None, stdout, stderr)
287
uif = ui_testing.TextUIFactory()
288
288
uif.clear_term = lambda: clear_calls.append('clear')
290
stream = _mod_ui_text.TextUIOutputStream(uif, uif.stdout)
291
stream.write("Hello world!\n")
292
stream.write("there's more...\n")
293
stream.writelines(["1\n", "2\n", "3\n"])
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"])
295
self.assertEqual(stdout.getvalue(),
295
self.assertEqual(uif.stdout.getvalue(),
299
299
self.assertEqual(['clear', 'clear', 'clear'],