/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 bzrlib/tests/blackbox/test_non_ascii.py

  • Committer: Martin von Gagern
  • Date: 2010-04-20 08:47:38 UTC
  • mfrom: (5167 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5195.
  • Revision ID: martin.vgagern@gmx.net-20100420084738-ygymnqmdllzrhpfn
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Black-box tests for bzr handling non-ascii characters."""
18
18
 
 
19
import os
19
20
import sys
20
 
import os
21
 
 
22
 
from bzrlib import osutils, urlutils
23
 
import bzrlib
24
 
from bzrlib.tests import TestCaseWithTransport, TestSkipped
25
 
from bzrlib.trace import mutter, note
26
 
 
27
 
 
28
 
class TestNonAscii(TestCaseWithTransport):
 
21
 
 
22
from bzrlib import (
 
23
    osutils,
 
24
    tests,
 
25
    urlutils,
 
26
    )
 
27
from bzrlib.tests import EncodingAdapter
 
28
 
 
29
 
 
30
def load_tests(standard_tests, module, loader):
 
31
    return tests.multiply_tests(standard_tests,
 
32
                                EncodingAdapter.encoding_scenarios,
 
33
                                loader.suiteClass())
 
34
 
 
35
 
 
36
class TestNonAscii(tests.TestCaseWithTransport):
29
37
    """Test that bzr handles files/committers/etc which are non-ascii."""
30
38
 
31
39
    def setUp(self):
32
40
        super(TestNonAscii, self).setUp()
33
 
        self._orig_email = os.environ.get('BZR_EMAIL', None)
34
 
        self._orig_encoding = bzrlib.user_encoding
 
41
        self._check_can_encode_paths()
35
42
 
36
 
        bzrlib.user_encoding = self.encoding
 
43
        self.overrideAttr(osutils, '_cached_user_encoding', self.encoding)
37
44
        email = self.info['committer'] + ' <joe@foo.com>'
38
 
        os.environ['BZR_EMAIL'] = email.encode(bzrlib.user_encoding)
 
45
        os.environ['BZR_EMAIL'] = email.encode(osutils.get_user_encoding())
39
46
        self.create_base()
40
47
 
41
 
    def tearDown(self):
42
 
        if self._orig_email is not None:
43
 
            os.environ['BZR_EMAIL'] = self._orig_email
44
 
        else:
45
 
            if os.environ.get('BZR_EMAIL', None) is not None:
46
 
                del os.environ['BZR_EMAIL']
47
 
        bzrlib.user_encoding = self._orig_encoding
48
 
        super(TestNonAscii, self).tearDown()
49
 
 
50
48
    def run_bzr_decode(self, args, encoding=None, fail=False, retcode=None,
51
 
                        working_dir=None):
 
49
                       working_dir=None):
52
50
        """Run bzr and decode the output into a particular encoding.
53
51
 
54
52
        Returns a string containing the stdout output from bzr.
55
53
 
56
 
        :param fail: If true, the operation is expected to fail with 
 
54
        :param fail: If true, the operation is expected to fail with
57
55
            a UnicodeError.
58
56
        """
59
57
        if encoding is None:
60
 
            encoding = bzrlib.user_encoding
 
58
            encoding = osutils.get_user_encoding()
61
59
        try:
62
 
            out = self.run_bzr(args, output_encoding=encoding, encoding=encoding,
63
 
                retcode=retcode, working_dir=working_dir)[0]
 
60
            out = self.run_bzr(args,
 
61
                               output_encoding=encoding, encoding=encoding,
 
62
                               retcode=retcode, working_dir=working_dir)[0]
64
63
            return out.decode(encoding)
65
64
        except UnicodeError, e:
66
65
            if not fail:
73
72
            if fail:
74
73
                self.fail("Expected UnicodeError not raised")
75
74
 
76
 
    def create_base(self):
77
 
        fs_enc = sys.getfilesystemencoding()
 
75
    def _check_OSX_can_roundtrip(self, path, fs_enc=None):
 
76
        """Stop the test if it's about to fail or errors out.
 
77
 
 
78
        Until we get proper support on OSX for accented paths (in fact, any
 
79
        path whose NFD decomposition is different than the NFC one), this is
 
80
        the best way to keep test active (as opposed to disabling them
 
81
        completely). This is a stop gap. The tests should at least be rewritten
 
82
        so that the failing ones are clearly separated from the passing ones.
 
83
        """
 
84
        if fs_enc is None:
 
85
            fs_enc = osutils._fs_enc
 
86
        if sys.platform == 'darwin':
 
87
            encoded = path.encode(fs_enc)
 
88
            import unicodedata
 
89
            normal_thing = unicodedata.normalize('NFD', path)
 
90
            mac_encoded = normal_thing.encode(fs_enc)
 
91
            if mac_encoded != encoded:
 
92
                raise tests.KnownFailure(
 
93
                    'Unable to roundtrip path %r on OSX filesystem'
 
94
                    ' using encoding "%s"'
 
95
                    % (path, fs_enc))
 
96
 
 
97
    def _check_can_encode_paths(self):
 
98
        fs_enc = osutils._fs_enc
78
99
        terminal_enc = osutils.get_terminal_encoding()
79
100
        fname = self.info['filename']
80
101
        dir_name = self.info['directory']
82
103
            try:
83
104
                thing.encode(fs_enc)
84
105
            except UnicodeEncodeError:
85
 
                raise TestSkipped(('Unable to represent path %r'
86
 
                                   ' in filesystem encoding "%s"')
87
 
                                    % (thing, fs_enc))
 
106
                raise tests.TestSkipped(
 
107
                    'Unable to represent path %r in filesystem encoding "%s"'
 
108
                    % (thing, fs_enc))
88
109
            try:
89
110
                thing.encode(terminal_enc)
90
111
            except UnicodeEncodeError:
91
 
                raise TestSkipped(('Unable to represent path %r'
92
 
                                   ' in terminal encoding "%s"'
93
 
                                   ' (even though it is valid in'
94
 
                                   ' filesystem encoding "%s")')
95
 
                                   % (thing, terminal_enc, fs_enc))
 
112
                raise tests.TestSkipped(
 
113
                    'Unable to represent path %r in terminal encoding "%s"'
 
114
                    ' (even though it is valid in filesystem encoding "%s")'
 
115
                    % (thing, terminal_enc, fs_enc))
96
116
 
 
117
    def create_base(self):
97
118
        wt = self.make_branch_and_tree('.')
98
119
        self.build_tree_contents([('a', 'foo\n')])
99
120
        wt.add('a')
104
125
        wt.add('b')
105
126
        wt.commit(self.info['message'])
106
127
 
 
128
        fname = self.info['filename']
107
129
        self.build_tree_contents([(fname, 'unicode filename\n')])
108
130
        wt.add(fname)
109
131
        wt.commit(u'And a unicode file\n')
110
132
        self.wt = wt
 
133
        # FIXME: We don't check that the add went well, in fact, it doesn't on
 
134
        # OSX (when LC_ALL is set correctly) because the added path doesn't
 
135
        # match the one used on OSX. But checking here will require more
 
136
        # invasive changes than adding the _check_OSX_can_roundtrip(), so I
 
137
        # punt for now -- vila 20090702
111
138
 
112
139
    def test_status(self):
113
140
        self.build_tree_contents(
114
141
            [(self.info['filename'], 'changed something\n')])
115
142
        txt = self.run_bzr_decode('status')
 
143
        self._check_OSX_can_roundtrip(self.info['filename'])
116
144
        self.assertEqual(u'modified:\n  %s\n' % (self.info['filename'],), txt)
117
145
 
118
146
        txt = self.run_bzr_decode('status', encoding='ascii')
126
154
        txt = self.run_bzr('cat b')[0]
127
155
        self.assertEqual('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n', txt)
128
156
 
 
157
        self._check_OSX_can_roundtrip(self.info['filename'])
129
158
        txt = self.run_bzr(['cat', self.info['filename']])[0]
130
159
        self.assertEqual('unicode filename\n', txt)
131
160
 
159
188
 
160
189
    def test_inventory(self):
161
190
        txt = self.run_bzr_decode('inventory')
 
191
        self._check_OSX_can_roundtrip(self.info['filename'])
162
192
        self.assertEqual(['a', 'b', self.info['filename']],
163
193
                         txt.splitlines())
164
194
 
202
232
        os.mkdir(dirname)
203
233
        self.wt.add(dirname)
204
234
        txt = self.run_bzr_decode(['mv', fname1, fname2, dirname])
 
235
        self._check_OSX_can_roundtrip(self.info['filename'])
205
236
        self.assertEqual([u'%s => %s/%s' % (fname1, dirname, fname1),
206
237
                          u'%s => %s/%s' % (fname2, dirname, fname2)]
207
238
                         , txt.splitlines())
252
283
        # TODO: jam 20060427 For drastically improving performance, we probably
253
284
        #       could create a local repository, so it wouldn't have to copy
254
285
        #       the files around as much.
 
286
        # Note that the tests don't actually fail, but if we don't set this
 
287
        # flag, we end up getting "Lock was not Unlocked" warnings
255
288
 
256
289
        dirname = self.info['directory']
257
290
        self.run_bzr_decode(['push', dirname])
299
332
        fname = self.info['filename']
300
333
        txt = self.run_bzr_decode(['file-id', fname])
301
334
 
302
 
        # TODO: jam 20060106 We don't support non-ascii file ids yet, 
 
335
        # TODO: jam 20060106 We don't support non-ascii file ids yet,
303
336
        #       so there is nothing which would fail in ascii encoding
304
337
        #       This *should* be retcode=3
305
338
        txt = self.run_bzr_decode(['file-id', fname], encoding='ascii')
314
347
        self.wt.add('base')
315
348
        self.wt.add('base/'+dirname)
316
349
        path = osutils.pathjoin('base', dirname, fname)
 
350
        self._check_OSX_can_roundtrip(self.info['filename'])
317
351
        self.wt.rename_one(fname, path)
318
352
        self.wt.commit('moving things around')
319
353
 
320
354
        txt = self.run_bzr_decode(['file-path', path])
321
355
 
322
 
        # TODO: jam 20060106 We don't support non-ascii file ids yet, 
 
356
        # TODO: jam 20060106 We don't support non-ascii file ids yet,
323
357
        #       so there is nothing which would fail in ascii encoding
324
358
        #       This *should* be retcode=3
325
359
        txt = self.run_bzr_decode(['file-path', path], encoding='ascii')
326
360
 
327
361
    def test_revision_history(self):
328
 
        # TODO: jam 20060106 We don't support non-ascii revision ids yet, 
 
362
        # TODO: jam 20060106 We don't support non-ascii revision ids yet,
329
363
        #       so there is nothing which would fail in ascii encoding
330
364
        txt = self.run_bzr_decode('revision-history')
331
365
 
332
366
    def test_ancestry(self):
333
 
        # TODO: jam 20060106 We don't support non-ascii revision ids yet, 
 
367
        # TODO: jam 20060106 We don't support non-ascii revision ids yet,
334
368
        #       so there is nothing which would fail in ascii encoding
335
369
        txt = self.run_bzr_decode('ancestry')
336
370
 
337
371
    def test_diff(self):
338
 
        # TODO: jam 20060106 diff is a difficult one to test, because it 
 
372
        self._check_OSX_can_roundtrip(self.info['filename'])
 
373
        # TODO: jam 20060106 diff is a difficult one to test, because it
339
374
        #       shouldn't encode the file contents, but it needs some sort
340
375
        #       of encoding for the paths, etc which are displayed.
341
376
        self.build_tree_contents([(self.info['filename'], 'newline\n')])
342
377
        txt = self.run_bzr('diff', retcode=1)[0]
343
378
 
344
379
    def test_deleted(self):
 
380
        self._check_OSX_can_roundtrip(self.info['filename'])
345
381
        fname = self.info['filename']
346
382
        os.remove(fname)
347
383
        self.wt.remove(fname)
362
398
        self.build_tree_contents([(fname, 'modified\n')])
363
399
 
364
400
        txt = self.run_bzr_decode('modified')
 
401
        self._check_OSX_can_roundtrip(self.info['filename'])
365
402
        self.assertEqual('"'+fname+'"'+'\n', txt)
366
403
 
367
404
        self.run_bzr_decode('modified', encoding='ascii', fail=True)
397
434
        self.assertNotEqual(-1, txt.find(self.info['message']))
398
435
 
399
436
        txt = self.run_bzr_decode('log --verbose')
 
437
        # FIXME: iso-8859-2 test shouldn't be skipped here --vila 20090702
 
438
        self._check_OSX_can_roundtrip(self.info['filename'])
400
439
        self.assertNotEqual(-1, txt.find(fname))
401
440
 
402
441
        # Make sure log doesn't fail even if we can't write out
407
446
    def test_touching_revisions(self):
408
447
        fname = self.info['filename']
409
448
        txt = self.run_bzr_decode(['touching-revisions', fname])
 
449
        self._check_OSX_can_roundtrip(self.info['filename'])
410
450
        self.assertEqual(u'     3 added %s\n' % (fname,), txt)
411
451
 
412
452
        fname2 = self.info['filename'] + '2'
414
454
        self.wt.commit(u'Renamed %s => %s' % (fname, fname2))
415
455
 
416
456
        txt = self.run_bzr_decode(['touching-revisions', fname2])
417
 
        expected_txt = (u'     3 added %s\n' 
 
457
        expected_txt = (u'     3 added %s\n'
418
458
                        u'     4 renamed %s => %s\n'
419
459
                        % (fname, fname, fname2))
420
460
        self.assertEqual(expected_txt, txt)
437
477
        fname = self.info['filename'] + '2'
438
478
        self.build_tree_contents([(fname, 'unknown\n')])
439
479
 
440
 
        # TODO: jam 20060112 bzr unknowns is the only one which 
 
480
        # TODO: jam 20060112 bzr unknowns is the only one which
441
481
        #       quotes paths do we really want it to?
442
482
        #       awilkins 20080521 added and modified do it now as well
443
483
        txt = self.run_bzr_decode('unknowns')
 
484
        self._check_OSX_can_roundtrip(self.info['filename'])
444
485
        self.assertEqual(u'"%s"\n' % (fname,), txt)
445
486
 
446
487
        self.run_bzr_decode('unknowns', encoding='ascii', fail=True)
452
493
        def check_unknowns(expected):
453
494
            self.assertEqual(expected, list(self.wt.unknowns()))
454
495
 
 
496
        self._check_OSX_can_roundtrip(self.info['filename'])
455
497
        check_unknowns([fname2])
456
498
 
457
499
        self.run_bzr_decode(['ignore', './' + fname2])