25
25
from bzrlib.tests import TestCaseInTempDir, TestSkipped
26
26
from bzrlib.trace import mutter, note
28
29
class TestNonAscii(TestCaseInTempDir):
29
30
"""Test that bzr handles files/committers/etc which are non-ascii."""
31
# This will be the tested encoding
35
33
super(TestNonAscii, self).setUp()
36
34
self._orig_email = os.environ.get('BZREMAIL', None)
37
email = _erik + u' <joe@foo.com>'
39
os.environ['BZREMAIL'] = email.encode(bzrlib.user_encoding)
40
except UnicodeEncodeError:
41
note('Unable to test unicode in BZREMAIL')
42
# Do the rest of the tests, just don't expect
43
# _erik to exist in the email
44
os.environ['BZREMAIL'] = 'Erik Bagfors <joe@foo.com>'
45
self.email_name = 'Erik Bagfors'
35
self._orig_encoding = bzrlib.user_encoding
37
bzrlib.user_encoding = self.encoding
38
email = self.info['committer'] + ' <joe@foo.com>'
39
os.environ['BZREMAIL'] = email.encode(bzrlib.user_encoding)
43
if self._orig_email is not None:
44
os.environ['BZREMAIL'] = self._orig_email
47
self.email_name = _erik
46
if os.environ.get('BZREMAIL', None) is not None:
47
del os.environ['BZREMAIL']
48
bzrlib.user_encoding = self._orig_encoding
49
super(TestNonAscii, self).tearDown()
51
def create_base(self):
51
55
open('a', 'wb').write('foo\n')
53
57
bzr('commit', '-m', 'adding a')
54
open('b', 'wb').write(_shrimp_sandwich.encode('utf-8') + '\n')
59
open('b', 'wb').write('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n')
56
bzr('commit', '-m', u'Creating a ' + _shrimp_sandwich)
57
fname = _juju + '.txt'
61
bzr('commit', '-m', self.info['message'])
63
fname = self.info['filename']
59
65
open(fname, 'wb').write('unicode filename\n')
60
66
except UnicodeEncodeError:
61
note('Unable to create an arabic filename')
62
fname = _juju_alt + '.txt'
64
open(fname, 'wb').write('unicode filename\n')
65
except UnicodeEncodeError:
66
raise TestSkipped("can't create an arabic or european filename"
67
" in filesystem encoding %s" % sys.getfilesystemencoding())
67
raise TestSkipped(('Unable to represent filename %r'
68
' in filesystem encoding %s')
69
% (fname, sys.getfilesystemencoding()))
74
72
bzr('commit', '-m', u'And an unicode file\n')
77
if self._orig_email is not None:
78
os.environ['BZREMAIL'] = self._orig_email
80
if os.environ.get('BZREMAIL', None) is not None:
81
del os.environ['BZREMAIL']
82
super(TestNonAscii, self).tearDown()
84
def try_character_set(self, charset, filename):
85
"""Try to create a file in a given character set."""
87
open(filename, 'wb').write('adding %s\n' % (charset,))
88
except UnicodeEncodeError:
89
raise TestSkipped('Cannot create %s filename.' % (charset,))
91
bzr = self.run_bzr_decode
95
self.assertEqual(filename+'\n', txt)
97
bzr('commit', '-m', u'adding ' + filename)
100
self.assertNotEqual(-1, txt.find(filename))
102
def test_russian(self):
103
self.try_character_set('russian', _alexander)
105
def test_kanji(self):
106
self.try_character_set('kanji', _nihonjin)
108
def test_swedish(self):
109
self.try_character_set('swedish', _shrimp_sandwich)
111
74
def test_status(self):
112
75
bzr = self.run_bzr_decode
114
open(self.juju + '.txt', 'ab').write('added something\n')
77
open(self.info['filename'], 'ab').write('added something\n')
115
78
txt = bzr('status')
116
self.assertEqual(u'modified:\n \u062c\u0648\u062c\u0648.txt\n' , txt)
79
self.assertEqual(u'modified:\n %s\n' % (self.info['filename'],), txt)
118
81
def test_cat(self):
119
82
# bzr cat shouldn't change the contents
120
83
# using run_bzr since that doesn't decode
121
84
txt = self.run_bzr('cat', 'b')[0]
122
self.assertEqual(_shrimp_sandwich.encode('utf-8') + '\n', txt)
85
self.assertEqual('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n', txt)
124
txt = self.run_bzr('cat', self.juju + '.txt')[0]
87
txt = self.run_bzr('cat', self.info['filename'])[0]
125
88
self.assertEqual('unicode filename\n', txt)
127
90
def test_cat_revision(self):
128
91
bzr = self.run_bzr_decode
130
93
txt = bzr('cat-revision', '-r', '1')
131
self.assertNotEqual(-1, txt.find(self.email_name))
94
self.assertNotEqual(-1, txt.find(self.info['committer']))
133
96
txt = bzr('cat-revision', '-r', '2')
134
self.assertNotEqual(-1, txt.find(_shrimp_sandwich))
97
self.assertNotEqual(-1, txt.find(self.info['message']))
136
99
def test_mkdir(self):
137
100
bzr = self.run_bzr_decode
139
txt = bzr('mkdir', _shrimp_sandwich)
140
self.assertEqual('added ' + _shrimp_sandwich + '\n', txt)
102
txt = bzr('mkdir', self.info['directory'])
103
self.assertEqual(u'added %s\n' % self.info['directory'], txt)
105
# The text should be garbled, but the command should succeed
106
txt = bzr('mkdir', self.info['directory'] + '2', encoding='ascii')
107
expected = u'added %s2\n' % (self.info['directory'],)
108
expected = expected.encode('ascii', 'replace')
109
self.assertEqual(expected, txt)
142
111
def test_relpath(self):
143
112
bzr = self.run_bzr_decode
145
txt = bzr('relpath', _shrimp_sandwich)
146
self.assertEqual(_shrimp_sandwich + '\n', txt)
114
txt = bzr('relpath', self.info['filename'])
115
self.assertEqual(self.info['filename'] + '\n', txt)
148
117
# TODO: jam 20060106 if relpath can return a munged string
149
118
# this text needs to be fixed
150
bzr('relpath', _shrimp_sandwich, encoding='ascii',
119
bzr('relpath', self.info['filename'], encoding='ascii', retcode=3)
153
121
def test_inventory(self):
154
122
bzr = self.run_bzr_decode
156
124
txt = bzr('inventory')
157
self.assertEqual(['a', 'b', u'\u062c\u0648\u062c\u0648.txt'],
125
self.assertEqual(['a', 'b', self.info['filename']],
158
126
txt.splitlines())
160
128
# inventory should fail if unable to encode
182
151
def test_mv(self):
183
152
bzr = self.run_bzr_decode
185
fname1 = self.juju + '.txt'
186
fname2 = self.juju + '2.txt'
154
fname1 = self.info['filename']
155
fname2 = self.info['filename'] + '2'
156
dirname = self.info['directory']
188
158
bzr('mv', 'a', fname1, retcode=3)
190
160
txt = bzr('mv', 'a', fname2)
191
self.assertEqual(u'a => ' + fname2 + '\n', txt)
161
self.assertEqual(u'a => %s\n' % fname2, txt)
192
162
self.failIfExists('a')
193
163
self.failUnlessExists(fname2)
195
165
bzr('commit', '-m', 'renamed to non-ascii')
197
bzr('mkdir', _shrimp_sandwich)
198
txt = bzr('mv', fname1, fname2, _shrimp_sandwich)
199
self.assertEqual([fname1 + ' => ' + _shrimp_sandwich + '/' + fname1,
200
fname2 + ' => ' + _shrimp_sandwich + '/' + fname2]
167
bzr('mkdir', dirname)
168
txt = bzr('mv', fname1, fname2, dirname)
169
self.assertEqual([u'%s => %s/%s' % (fname1, dirname, fname1),
170
u'%s => %s/%s' % (fname2, dirname, fname2)]
201
171
, txt.splitlines())
203
173
# The rename should still succeed
204
txt = bzr('mv', _shrimp_sandwich + '/' + fname2, 'a',
174
newpath = u'%s/%s' % (dirname, fname2)
175
txt = bzr('mv', newpath, 'a', encoding='ascii')
206
176
self.failUnlessExists('a')
207
self.assertEqual('r?ksm?rg?s/????2.txt => a\n', txt)
177
self.assertEqual(newpath.encode('ascii', 'replace'), txt)
209
179
def test_branch(self):
210
180
# We should be able to branch into a directory that
211
181
# has a unicode name, even if we can't display the name
212
182
bzr = self.run_bzr_decode
214
bzr('branch', u'.', _shrimp_sandwich)
184
bzr('branch', u'.', self.info['directory'])
216
bzr('branch', u'.', _shrimp_sandwich + '2', encoding='ascii')
186
bzr('branch', u'.', self.info['directory'] + '2', encoding='ascii')
218
188
def test_pull(self):
219
189
# Make sure we can pull from paths that can't be encoded
220
190
bzr = self.run_bzr_decode
222
bzr('branch', '.', _shrimp_sandwich)
223
bzr('branch', _shrimp_sandwich, _shrimp_sandwich + '2')
192
dirname1 = self.info['directory']
193
dirname2 = self.info['directory'] + '2'
194
bzr('branch', '.', dirname1)
195
bzr('branch', dirname1, dirname2)
225
os.chdir(_shrimp_sandwich)
226
198
open('a', 'ab').write('more text\n')
227
199
bzr('commit', '-m', 'mod a')
229
201
pwd = os.getcwdu()
231
os.chdir('../' + _shrimp_sandwich + '2')
203
os.chdir(u'../' + dirname2)
232
204
txt = bzr('pull')
234
206
self.assertEqual(u'Using saved location: %s\n' % (pwd,), txt)
236
os.chdir('../' + _shrimp_sandwich)
208
os.chdir('../' + dirname1)
237
209
open('a', 'ab').write('and yet more\n')
238
# here we cheat. If self.erik is not _erik, then technically
239
# we would not be able to supply the argument, since sys.argv
240
# could not be decoded to those characters.
241
# but self.run_bzr takes the decoded string directly
242
bzr('commit', '-m', 'modifying a by ' + _erik)
210
bzr('commit', '-m', 'modifying a by ' + self.info['committer'])
244
os.chdir('../' + _shrimp_sandwich + '2')
212
os.chdir('../' + dirname2)
245
213
# We should be able to pull, even if our encoding is bad
246
214
bzr('pull', '--verbose', encoding='ascii')
263
229
f = open('a', 'ab')
264
230
f.write('and a bit more: ')
265
f.write(_shrimp_sandwich.encode('utf-8'))
231
f.write(dirname.encode('utf-8'))
268
bzr('commit', '-m', u'Added some ' + _shrimp_sandwich)
235
bzr('commit', '-m', u'Added some ' + dirname)
269
236
bzr('push', '--verbose', encoding='ascii')
271
bzr('push', '--verbose', _shrimp_sandwich + '2')
238
bzr('push', '--verbose', dirname + '2')
273
bzr('push', '--verbose', _shrimp_sandwich + '3',
240
bzr('push', '--verbose', dirname + '3', encoding='ascii')
276
242
def test_renames(self):
277
243
bzr = self.run_bzr_decode
279
fname = self.juju + '2.txt'
245
fname = self.info['filename'] + '2'
280
246
bzr('mv', 'a', fname)
281
247
txt = bzr('renames')
282
self.assertEqual('a => ' + fname + '\n', txt)
248
self.assertEqual(u'a => %s\n' % fname, txt)
284
250
bzr('renames', retcode=3, encoding='ascii')
286
252
def test_remove(self):
287
253
bzr = self.run_bzr_decode
289
fname = self.juju + '.txt'
255
fname = self.info['filename']
290
256
txt = bzr('remove', fname, encoding='ascii')
292
258
def test_remove_verbose(self):
293
259
bzr = self.run_bzr_decode
295
261
raise TestSkipped('bzr remove --verbose uses tree.remove, which calls print directly.')
296
fname = self.juju + '.txt'
262
fname = self.info['filename']
297
263
txt = bzr('remove', '--verbose', fname, encoding='ascii')
299
265
def test_file_id(self):
300
266
bzr = self.run_bzr_decode
302
fname = self.juju + '.txt'
268
fname = self.info['filename']
303
269
txt = bzr('file-id', fname)
305
271
# TODO: jam 20060106 We don't support non-ascii file ids yet,
389
355
def test_root(self):
390
356
bzr = self.run_bzr_decode
358
dirname = self.info['directory']
394
bzr('branch', u'.', _shrimp_sandwich)
361
bzr('branch', u'.', dirname)
396
os.chdir(_shrimp_sandwich)
398
365
txt = bzr('root')
399
self.failUnless(txt.endswith(_shrimp_sandwich+'\n'))
366
self.failUnless(txt.endswith(dirname+'\n'))
401
368
txt = bzr('root', encoding='ascii', retcode=3)
403
370
def test_log(self):
404
371
bzr = self.run_bzr_decode
373
fname = self.info['filename']
407
self.assertNotEqual(-1, txt.find(self.email_name))
408
self.assertNotEqual(-1, txt.find(_shrimp_sandwich))
376
self.assertNotEqual(-1, txt.find(self.info['committer']))
377
self.assertNotEqual(-1, txt.find(self.info['message']))
410
379
txt = bzr('log', '--verbose')
411
self.assertNotEqual(-1, txt.find(self.juju))
380
self.assertNotEqual(-1, txt.find(fname))
413
382
# Make sure log doesn't fail even if we can't write out
414
383
txt = bzr('log', '--verbose', encoding='ascii')
415
self.assertEqual(-1, txt.find(self.juju))
416
self.assertNotEqual(-1, txt.find(self.juju.encode('ascii', 'replace')))
384
self.assertEqual(-1, txt.find(fname))
385
self.assertNotEqual(-1, txt.find(fname.encode('ascii', 'replace')))
418
387
def test_touching_revisions(self):
419
388
bzr = self.run_bzr_decode
421
fname = self.juju + '.txt'
390
fname = self.info['filename']
422
391
txt = bzr('touching-revisions', fname)
423
392
self.assertEqual(u' 3 added %s\n' % (fname,), txt)
425
fname_new = _shrimp_sandwich + '.txt'
426
bzr('mv', fname, fname_new)
427
bzr('commit', '-m', u'Renamed %s => %s' % (fname, fname_new))
394
fname2 = self.info['filename'] + '2'
395
bzr('mv', fname, fname2)
396
bzr('commit', '-m', u'Renamed %s => %s' % (fname, fname2))
429
txt = bzr('touching-revisions', fname_new)
398
txt = bzr('touching-revisions', fname2)
430
399
expected_txt = (u' 3 added %s\n'
431
400
u' 4 renamed %s => %s\n'
432
% (fname, fname, fname_new))
401
% (fname, fname, fname2))
433
402
self.assertEqual(expected_txt, txt)
435
txt = bzr('touching-revisions', fname_new, encoding='ascii')
404
txt = bzr('touching-revisions', fname2, encoding='ascii')
436
405
expected_ascii = expected_txt.encode('ascii', 'replace')
437
406
self.assertEqual(expected_ascii, txt)