~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_non_ascii.py

  • Committer: John Arbash Meinel
  • Date: 2006-04-25 15:05:42 UTC
  • mfrom: (1185.85.85 bzr-encoding)
  • mto: This revision was merged to the branch mainline in revision 1752.
  • Revision ID: john@arbash-meinel.com-20060425150542-c7b518dca9928691
[merge] the old bzr-encoding changes, reparenting them on bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 by Canonical Ltd
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
 
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
 
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
"""\
 
19
Black-box tests for bzr handling non-ascii characters.
 
20
"""
 
21
 
 
22
import sys
 
23
import os
 
24
import bzrlib
 
25
from bzrlib.tests import TestCaseInTempDir, TestSkipped
 
26
from bzrlib.trace import mutter, note
 
27
 
 
28
 
 
29
class TestNonAscii(TestCaseInTempDir):
 
30
    """Test that bzr handles files/committers/etc which are non-ascii."""
 
31
 
 
32
    def setUp(self):
 
33
        super(TestNonAscii, self).setUp()
 
34
        raise TestSkipped('We cannot handle unicode filenames (yet)')
 
35
        # TODO: jam 20060425 because of the confusion of URLs versus Unicode
 
36
        #       'bzr add f' will not add a unicode filename
 
37
        self._orig_email = os.environ.get('BZREMAIL', None)
 
38
        self._orig_encoding = bzrlib.user_encoding
 
39
 
 
40
        bzrlib.user_encoding = self.encoding
 
41
        email = self.info['committer'] + ' <joe@foo.com>'
 
42
        os.environ['BZREMAIL'] = email.encode(bzrlib.user_encoding)
 
43
        self.create_base()
 
44
 
 
45
    def tearDown(self):
 
46
        if self._orig_email is not None:
 
47
            os.environ['BZREMAIL'] = self._orig_email
 
48
        else:
 
49
            if os.environ.get('BZREMAIL', None) is not None:
 
50
                del os.environ['BZREMAIL']
 
51
        bzrlib.user_encoding = self._orig_encoding
 
52
        super(TestNonAscii, self).tearDown()
 
53
 
 
54
    def create_base(self):
 
55
        bzr = self.run_bzr
 
56
 
 
57
        bzr('init')
 
58
        open('a', 'wb').write('foo\n')
 
59
        bzr('add', 'a')
 
60
        bzr('commit', '-m', 'adding a')
 
61
 
 
62
        open('b', 'wb').write('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n')
 
63
        bzr('add', 'b')
 
64
        bzr('commit', '-m', self.info['message'])
 
65
 
 
66
        fname = self.info['filename']
 
67
        try:
 
68
            open(fname, 'wb').write('unicode filename\n')
 
69
        except UnicodeEncodeError:
 
70
            raise TestSkipped(('Unable to represent filename %r'
 
71
                               ' in filesystem encoding %s')
 
72
                                % (fname, sys.getfilesystemencoding()))
 
73
 
 
74
        bzr('add', fname)
 
75
        bzr('commit', '-m', u'And an unicode file\n')
 
76
 
 
77
    def test_status(self):
 
78
        bzr = self.run_bzr_decode
 
79
 
 
80
        open(self.info['filename'], 'ab').write('added something\n')
 
81
        txt = bzr('status')
 
82
        self.assertEqual(u'modified:\n  %s\n' % (self.info['filename'],), txt)
 
83
 
 
84
    def test_cat(self):
 
85
        # bzr cat shouldn't change the contents
 
86
        # using run_bzr since that doesn't decode
 
87
        txt = self.run_bzr('cat', 'b')[0]
 
88
        self.assertEqual('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n', txt)
 
89
 
 
90
        txt = self.run_bzr('cat', self.info['filename'])[0]
 
91
        self.assertEqual('unicode filename\n', txt)
 
92
 
 
93
    def test_cat_revision(self):
 
94
        bzr = self.run_bzr_decode
 
95
 
 
96
        # TODO: jam 20060112 should cat-revision always output utf-8?
 
97
        committer = self.info['committer']
 
98
        txt = bzr('cat-revision', '-r', '1')
 
99
        self.failUnless(committer in txt,
 
100
                        'failed to find %r in %r' % (committer, txt))
 
101
 
 
102
        msg = self.info['message']
 
103
        txt = bzr('cat-revision', '-r', '2')
 
104
        self.failUnless(msg in txt, 'failed to find %r in %r' % (msg, txt))
 
105
 
 
106
    def test_mkdir(self):
 
107
        bzr = self.run_bzr_decode
 
108
 
 
109
        txt = bzr('mkdir', self.info['directory'])
 
110
        self.assertEqual(u'added %s\n' % self.info['directory'], txt)
 
111
 
 
112
        # The text should be garbled, but the command should succeed
 
113
        txt = bzr('mkdir', self.info['directory'] + '2', encoding='ascii')
 
114
        expected = u'added %s2\n' % (self.info['directory'],)
 
115
        expected = expected.encode('ascii', 'replace')
 
116
        self.assertEqual(expected, txt)
 
117
 
 
118
    def test_relpath(self):
 
119
        bzr = self.run_bzr_decode
 
120
 
 
121
        txt = bzr('relpath', self.info['filename'])
 
122
        self.assertEqual(self.info['filename'] + '\n', txt)
 
123
 
 
124
        # TODO: jam 20060106 if relpath can return a munged string
 
125
        #       this text needs to be fixed
 
126
        bzr('relpath', self.info['filename'], encoding='ascii', retcode=3)
 
127
 
 
128
    def test_inventory(self):
 
129
        bzr = self.run_bzr_decode
 
130
 
 
131
        txt = bzr('inventory')
 
132
        self.assertEqual(['a', 'b', self.info['filename']],
 
133
                         txt.splitlines())
 
134
 
 
135
        # inventory should fail if unable to encode
 
136
        bzr('inventory', encoding='ascii', retcode=3)
 
137
 
 
138
        # We don't really care about the ids themselves,
 
139
        # but the command shouldn't fail
 
140
        txt = bzr('inventory', '--show-ids')
 
141
 
 
142
    def test_revno(self):
 
143
        # There isn't a lot to test here, since revno should always
 
144
        # be an integer
 
145
        bzr = self.run_bzr_decode
 
146
 
 
147
        self.assertEqual('3\n', bzr('revno'))
 
148
        self.assertEqual('3\n', bzr('revno', encoding='ascii'))
 
149
 
 
150
    def test_revision_info(self):
 
151
        bzr = self.run_bzr_decode
 
152
 
 
153
        bzr('revision-info', '-r', '1')
 
154
 
 
155
        # TODO: jam 20060105 We have no revisions with non-ascii characters.
 
156
        bzr('revision-info', '-r', '1', encoding='ascii')
 
157
 
 
158
    def test_mv(self):
 
159
        bzr = self.run_bzr_decode
 
160
 
 
161
        fname1 = self.info['filename']
 
162
        fname2 = self.info['filename'] + '2'
 
163
        dirname = self.info['directory']
 
164
 
 
165
        bzr('mv', 'a', fname1, retcode=3)
 
166
 
 
167
        txt = bzr('mv', 'a', fname2)
 
168
        self.assertEqual(u'a => %s\n' % fname2, txt)
 
169
        self.failIfExists('a')
 
170
        self.failUnlessExists(fname2)
 
171
 
 
172
        bzr('commit', '-m', 'renamed to non-ascii')
 
173
 
 
174
        bzr('mkdir', dirname)
 
175
        txt = bzr('mv', fname1, fname2, dirname)
 
176
        self.assertEqual([u'%s => %s/%s' % (fname1, dirname, fname1),
 
177
                          u'%s => %s/%s' % (fname2, dirname, fname2)]
 
178
                         , txt.splitlines())
 
179
 
 
180
        # The rename should still succeed
 
181
        newpath = u'%s/%s' % (dirname, fname2)
 
182
        txt = bzr('mv', newpath, 'a', encoding='ascii')
 
183
        self.failUnlessExists('a')
 
184
        self.assertEqual(newpath.encode('ascii', 'replace'), txt)
 
185
 
 
186
    def test_branch(self):
 
187
        # We should be able to branch into a directory that
 
188
        # has a unicode name, even if we can't display the name
 
189
        bzr = self.run_bzr_decode
 
190
 
 
191
        bzr('branch', u'.', self.info['directory'])
 
192
 
 
193
        bzr('branch', u'.', self.info['directory'] + '2', encoding='ascii')
 
194
 
 
195
    def test_pull(self):
 
196
        # Make sure we can pull from paths that can't be encoded
 
197
        bzr = self.run_bzr_decode
 
198
 
 
199
        dirname1 = self.info['directory']
 
200
        dirname2 = self.info['directory'] + '2'
 
201
        bzr('branch', '.', dirname1)
 
202
        bzr('branch', dirname1, dirname2)
 
203
 
 
204
        os.chdir(dirname1)
 
205
        open('a', 'ab').write('more text\n')
 
206
        bzr('commit', '-m', 'mod a')
 
207
 
 
208
        pwd = os.getcwdu()
 
209
 
 
210
        os.chdir(u'../' + dirname2)
 
211
        txt = bzr('pull')
 
212
 
 
213
        self.assertEqual(u'Using saved location: %s\n' % (pwd,), txt)
 
214
 
 
215
        os.chdir('../' + dirname1)
 
216
        open('a', 'ab').write('and yet more\n')
 
217
        bzr('commit', '-m', 'modifying a by ' + self.info['committer'])
 
218
 
 
219
        os.chdir('../' + dirname2)
 
220
        # We should be able to pull, even if our encoding is bad
 
221
        bzr('pull', '--verbose', encoding='ascii')
 
222
 
 
223
    def test_push(self):
 
224
        # TODO: Test push to an SFTP location
 
225
        # Make sure we can pull from paths that can't be encoded
 
226
        bzr = self.run_bzr_decode
 
227
 
 
228
        dirname = self.info['directory']
 
229
        bzr('push', dirname)
 
230
 
 
231
        open('a', 'ab').write('adding more text\n')
 
232
        bzr('commit', '-m', 'added some stuff')
 
233
 
 
234
        bzr('push')
 
235
 
 
236
        f = open('a', 'ab')
 
237
        f.write('and a bit more: ')
 
238
        f.write(dirname.encode('utf-8'))
 
239
        f.write('\n')
 
240
        f.close()
 
241
 
 
242
        bzr('commit', '-m', u'Added some ' + dirname)
 
243
        bzr('push', '--verbose', encoding='ascii')
 
244
 
 
245
        bzr('push', '--verbose', dirname + '2')
 
246
 
 
247
        bzr('push', '--verbose', dirname + '3', encoding='ascii')
 
248
 
 
249
    def test_renames(self):
 
250
        bzr = self.run_bzr_decode
 
251
 
 
252
        fname = self.info['filename'] + '2'
 
253
        bzr('mv', 'a', fname)
 
254
        txt = bzr('renames')
 
255
        self.assertEqual(u'a => %s\n' % fname, txt)
 
256
 
 
257
        bzr('renames', retcode=3, encoding='ascii')
 
258
 
 
259
    def test_remove(self):
 
260
        bzr = self.run_bzr_decode
 
261
 
 
262
        fname = self.info['filename']
 
263
        txt = bzr('remove', fname, encoding='ascii')
 
264
 
 
265
    def test_remove_verbose(self):
 
266
        bzr = self.run_bzr_decode
 
267
 
 
268
        raise TestSkipped('bzr remove --verbose uses tree.remove, which calls print directly.')
 
269
        fname = self.info['filename']
 
270
        txt = bzr('remove', '--verbose', fname, encoding='ascii')
 
271
 
 
272
    def test_file_id(self):
 
273
        bzr = self.run_bzr_decode
 
274
 
 
275
        fname = self.info['filename']
 
276
        txt = bzr('file-id', fname)
 
277
 
 
278
        # TODO: jam 20060106 We don't support non-ascii file ids yet, 
 
279
        #       so there is nothing which would fail in ascii encoding
 
280
        #       This *should* be retcode=3
 
281
        txt = bzr('file-id', fname, encoding='ascii')
 
282
 
 
283
    def test_file_path(self):
 
284
        bzr = self.run_bzr_decode
 
285
 
 
286
        # Create a directory structure
 
287
        fname = self.info['filename']
 
288
        dirname = self.info['directory']
 
289
        bzr('mkdir', 'base')
 
290
        bzr('mkdir', 'base/' + dirname)
 
291
        path = '/'.join(['base', dirname, fname])
 
292
        bzr('mv', fname, path)
 
293
        bzr('commit', '-m', 'moving things around')
 
294
 
 
295
        txt = bzr('file-path', path)
 
296
 
 
297
        # TODO: jam 20060106 We don't support non-ascii file ids yet, 
 
298
        #       so there is nothing which would fail in ascii encoding
 
299
        #       This *should* be retcode=3
 
300
        txt = bzr('file-path', path, encoding='ascii')
 
301
 
 
302
    def test_revision_history(self):
 
303
        bzr = self.run_bzr_decode
 
304
 
 
305
        # TODO: jam 20060106 We don't support non-ascii revision ids yet, 
 
306
        #       so there is nothing which would fail in ascii encoding
 
307
        txt = bzr('revision-history')
 
308
 
 
309
    def test_ancestry(self):
 
310
        bzr = self.run_bzr_decode
 
311
 
 
312
        # TODO: jam 20060106 We don't support non-ascii revision ids yet, 
 
313
        #       so there is nothing which would fail in ascii encoding
 
314
        txt = bzr('ancestry')
 
315
 
 
316
    def test_diff(self):
 
317
        # TODO: jam 20060106 diff is a difficult one to test, because it 
 
318
        #       shouldn't encode the file contents, but it needs some sort
 
319
        #       of encoding for the paths, etc which are displayed.
 
320
        pass
 
321
 
 
322
    def test_deleted(self):
 
323
        bzr = self.run_bzr_decode
 
324
 
 
325
        fname = self.info['filename']
 
326
        os.remove(fname)
 
327
        bzr('rm', fname)
 
328
 
 
329
        txt = bzr('deleted')
 
330
        self.assertEqual(fname+'\n', txt)
 
331
 
 
332
        txt = bzr('deleted', '--show-ids')
 
333
        self.failUnless(txt.startswith(fname))
 
334
 
 
335
        # Deleted should fail if cannot decode
 
336
        # Because it is giving the exact paths
 
337
        # which might be used by a front end
 
338
        bzr('deleted', encoding='ascii', retcode=3)
 
339
 
 
340
    def test_modified(self):
 
341
        bzr = self.run_bzr_decode
 
342
 
 
343
        fname = self.info['filename']
 
344
        open(fname, 'ab').write('modified\n')
 
345
 
 
346
        txt = bzr('modified')
 
347
        self.assertEqual(fname+'\n', txt)
 
348
 
 
349
        bzr('modified', encoding='ascii', retcode=3)
 
350
 
 
351
    def test_added(self):
 
352
        bzr = self.run_bzr_decode
 
353
 
 
354
        fname = self.info['filename'] + '2'
 
355
        open(fname, 'wb').write('added\n')
 
356
        bzr('add', fname)
 
357
 
 
358
        txt = bzr('added')
 
359
        self.assertEqual(fname+'\n', txt)
 
360
 
 
361
        bzr('added', encoding='ascii', retcode=3)
 
362
 
 
363
    def test_root(self):
 
364
        bzr = self.run_bzr_decode
 
365
 
 
366
        dirname = self.info['directory']
 
367
        bzr('root')
 
368
 
 
369
        bzr('branch', u'.', dirname)
 
370
 
 
371
        os.chdir(dirname)
 
372
 
 
373
        txt = bzr('root')
 
374
        self.failUnless(txt.endswith(dirname+'\n'))
 
375
 
 
376
        txt = bzr('root', encoding='ascii', retcode=3)
 
377
 
 
378
    def test_log(self):
 
379
        bzr = self.run_bzr_decode
 
380
 
 
381
        fname = self.info['filename']
 
382
 
 
383
        txt = bzr('log')
 
384
        self.assertNotEqual(-1, txt.find(self.info['committer']))
 
385
        self.assertNotEqual(-1, txt.find(self.info['message']))
 
386
 
 
387
        txt = bzr('log', '--verbose')
 
388
        self.assertNotEqual(-1, txt.find(fname))
 
389
 
 
390
        # Make sure log doesn't fail even if we can't write out
 
391
        txt = bzr('log', '--verbose', encoding='ascii')
 
392
        self.assertEqual(-1, txt.find(fname))
 
393
        self.assertNotEqual(-1, txt.find(fname.encode('ascii', 'replace')))
 
394
 
 
395
    def test_touching_revisions(self):
 
396
        bzr = self.run_bzr_decode
 
397
 
 
398
        fname = self.info['filename']
 
399
        txt = bzr('touching-revisions', fname)
 
400
        self.assertEqual(u'     3 added %s\n' % (fname,), txt)
 
401
 
 
402
        fname2 = self.info['filename'] + '2'
 
403
        bzr('mv', fname, fname2)
 
404
        bzr('commit', '-m', u'Renamed %s => %s' % (fname, fname2))
 
405
 
 
406
        txt = bzr('touching-revisions', fname2)
 
407
        expected_txt = (u'     3 added %s\n' 
 
408
                        u'     4 renamed %s => %s\n'
 
409
                        % (fname, fname, fname2))
 
410
        self.assertEqual(expected_txt, txt)
 
411
 
 
412
        txt = bzr('touching-revisions', fname2, encoding='ascii')
 
413
        expected_ascii = expected_txt.encode('ascii', 'replace')
 
414
        self.assertEqual(expected_ascii, txt)
 
415
 
 
416
    def test_ls(self):
 
417
        bzr = self.run_bzr_decode
 
418
 
 
419
        txt = bzr('ls')
 
420
        self.assertEqual(['a', 'b', self.info['filename']],
 
421
                         txt.splitlines())
 
422
        txt = bzr('ls', '--null')
 
423
        self.assertEqual(['a', 'b', self.info['filename'], ''],
 
424
                         txt.split('\0'))
 
425
 
 
426
        txt = bzr('ls', encoding='ascii', retcode=3)
 
427
        txt = bzr('ls', '--null', encoding='ascii', retcode=3)
 
428
 
 
429
    def test_unknowns(self):
 
430
        bzr = self.run_bzr_decode
 
431
 
 
432
        fname = self.info['filename'] + '2'
 
433
        open(fname, 'wb').write('unknown\n')
 
434
 
 
435
        # TODO: jam 20060112 bzr unknowns is the only one which 
 
436
        #       quotes paths do we really want it to?
 
437
        txt = bzr('unknowns')
 
438
        self.assertEqual(u'"%s"\n' % (fname,), txt)
 
439
 
 
440
        bzr('unknowns', encoding='ascii', retcode=3)
 
441
 
 
442
    def test_ignore(self):
 
443
        bzr = self.run_bzr_decode
 
444
 
 
445
        fname2 = self.info['filename'] + '2.txt'
 
446
        open(fname2, 'wb').write('ignored\n')
 
447
 
 
448
        txt = bzr('unknowns')
 
449
        self.assertEqual(u'"%s"\n' % (fname2,), txt)
 
450
 
 
451
        bzr('ignore', './' + fname2)
 
452
        txt = bzr('unknowns')
 
453
        # TODO: jam 20060107 This is the correct output
 
454
        # self.assertEqual('', txt)
 
455
        # This is the incorrect output
 
456
        self.assertEqual(u'"%s"\n' % (fname2,), txt)
 
457
 
 
458
        fname3 = self.info['filename'] + '3.txt'
 
459
        open(fname3, 'wb').write('unknown 3\n')
 
460
        txt = bzr('unknowns')
 
461
        # TODO: jam 20060107 This is the correct output
 
462
        # self.assertEqual(u'"%s"\n' % (fname3,), txt)
 
463
        # This is the incorrect output
 
464
        self.assertEqual(u'"%s"\n"%s"\n' % (fname2, fname3,), txt)
 
465
 
 
466
        # Ignore should not care what the encoding is
 
467
        # (right now it doesn't print anything)
 
468
        bzr('ignore', fname3, encoding='ascii')
 
469
        txt = bzr('unknowns')
 
470
        # TODO: jam 20060107 This is the correct output
 
471
        # self.assertEqual('', txt)
 
472
        # This is the incorrect output
 
473
        self.assertEqual(u'"%s"\n"%s"\n' % (fname2, fname3), txt)
 
474
 
 
475
        # Now try a wildcard match
 
476
        fname4 = self.info['filename'] + '4.txt'
 
477
        open(fname4, 'wb').write('unknown 4\n')
 
478
        bzr('ignore', '*.txt')
 
479
        txt = bzr('unknowns')
 
480
        self.assertEqual('', txt)
 
481
 
 
482
        os.remove('.bzrignore')
 
483
        bzr('ignore', self.info['filename'] + '*')
 
484
        txt = bzr('unknowns')
 
485
        # TODO: jam 20060107 This is the correct output
 
486
        # self.assertEqual('', txt)
 
487
        # This is the incorrect output
 
488
        self.assertEqual(u'"%s"\n"%s"\n"%s"\n' % (fname2, fname3, fname4), txt)
 
489
 
 
490
        # TODO: jam 20060107 The best error we have right now is TestSkipped
 
491
        #       to indicate that this test is known to fail
 
492
        raise TestSkipped("WorkingTree.is_ignored doesn't match unicode filenames (yet)")
 
493
 
 
494