/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: Robert Collins
  • Date: 2008-08-20 02:07:36 UTC
  • mfrom: (3640 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3682.
  • Revision ID: robertc@robertcollins.net-20080820020736-g2xe4921zzxtymle
Merge 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 -*-
 
1
# Copyright (C) 2006, 2007 Canonical Ltd
3
2
#
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
20
19
import sys
21
20
import os
22
21
 
 
22
from bzrlib import osutils, urlutils
23
23
import bzrlib
24
 
from bzrlib.tests import TestCaseInTempDir, TestSkipped
 
24
from bzrlib.tests import TestCaseWithTransport, TestSkipped
25
25
from bzrlib.trace import mutter, note
26
 
import bzrlib.urlutils as urlutils
27
 
 
28
 
 
29
 
class TestNonAscii(TestCaseInTempDir):
 
26
 
 
27
 
 
28
class TestNonAscii(TestCaseWithTransport):
30
29
    """Test that bzr handles files/committers/etc which are non-ascii."""
31
30
 
32
31
    def setUp(self):
33
32
        super(TestNonAscii, self).setUp()
34
 
        self._orig_email = os.environ.get('BZREMAIL', None)
 
33
        self._orig_email = os.environ.get('BZR_EMAIL', None)
35
34
        self._orig_encoding = bzrlib.user_encoding
36
35
 
37
36
        bzrlib.user_encoding = self.encoding
38
37
        email = self.info['committer'] + ' <joe@foo.com>'
39
 
        os.environ['BZREMAIL'] = email.encode(bzrlib.user_encoding)
 
38
        os.environ['BZR_EMAIL'] = email.encode(bzrlib.user_encoding)
40
39
        self.create_base()
41
40
 
42
41
    def tearDown(self):
43
42
        if self._orig_email is not None:
44
 
            os.environ['BZREMAIL'] = self._orig_email
 
43
            os.environ['BZR_EMAIL'] = self._orig_email
45
44
        else:
46
 
            if os.environ.get('BZREMAIL', None) is not None:
47
 
                del os.environ['BZREMAIL']
 
45
            if os.environ.get('BZR_EMAIL', None) is not None:
 
46
                del os.environ['BZR_EMAIL']
48
47
        bzrlib.user_encoding = self._orig_encoding
49
48
        super(TestNonAscii, self).tearDown()
50
49
 
 
50
    def run_bzr_decode(self, args, encoding=None, fail=False, retcode=None,
 
51
                        working_dir=None):
 
52
        """Run bzr and decode the output into a particular encoding.
 
53
 
 
54
        Returns a string containing the stdout output from bzr.
 
55
 
 
56
        :param fail: If true, the operation is expected to fail with 
 
57
            a UnicodeError.
 
58
        """
 
59
        if encoding is None:
 
60
            encoding = bzrlib.user_encoding
 
61
        try:
 
62
            out = self.run_bzr(args, output_encoding=encoding, encoding=encoding,
 
63
                retcode=retcode, working_dir=working_dir)[0]
 
64
            return out.decode(encoding)
 
65
        except UnicodeError, e:
 
66
            if not fail:
 
67
                raise
 
68
        else:
 
69
            # This command, run from the regular command line, will give a
 
70
            # traceback to the user.  That's not really good for a situation
 
71
            # that can be provoked just by the interaction of their input data
 
72
            # and locale, as some of these are.  What would be better?
 
73
            if fail:
 
74
                self.fail("Expected UnicodeError not raised")
 
75
 
51
76
    def create_base(self):
52
 
        bzr = self.run_bzr
53
 
 
54
77
        fs_enc = sys.getfilesystemencoding()
 
78
        terminal_enc = osutils.get_terminal_encoding()
55
79
        fname = self.info['filename']
56
80
        dir_name = self.info['directory']
57
81
        for thing in [fname, dir_name]:
59
83
                thing.encode(fs_enc)
60
84
            except UnicodeEncodeError:
61
85
                raise TestSkipped(('Unable to represent path %r'
62
 
                                   ' in filesystem encoding %s')
 
86
                                   ' in filesystem encoding "%s"')
63
87
                                    % (thing, fs_enc))
64
 
 
65
 
        bzr('init')
66
 
        open('a', 'wb').write('foo\n')
67
 
        bzr('add', 'a')
68
 
        bzr('commit', '-m', 'adding a')
69
 
 
70
 
        open('b', 'wb').write('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n')
71
 
        bzr('add', 'b')
72
 
        bzr('commit', '-m', self.info['message'])
73
 
 
74
 
        open(fname, 'wb').write('unicode filename\n')
75
 
        bzr('add', fname)
76
 
        bzr('commit', '-m', u'And a unicode file\n')
 
88
            try:
 
89
                thing.encode(terminal_enc)
 
90
            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))
 
96
 
 
97
        wt = self.make_branch_and_tree('.')
 
98
        self.build_tree_contents([('a', 'foo\n')])
 
99
        wt.add('a')
 
100
        wt.commit('adding a')
 
101
 
 
102
        self.build_tree_contents(
 
103
            [('b', 'non-ascii \xFF\xFF\xFC\xFB\x00 in b\n')])
 
104
        wt.add('b')
 
105
        wt.commit(self.info['message'])
 
106
 
 
107
        self.build_tree_contents([(fname, 'unicode filename\n')])
 
108
        wt.add(fname)
 
109
        wt.commit(u'And a unicode file\n')
 
110
        self.wt = wt
77
111
 
78
112
    def test_status(self):
79
 
        bzr = self.run_bzr_decode
80
 
 
81
 
        open(self.info['filename'], 'ab').write('added something\n')
82
 
        txt = bzr('status')
 
113
        self.build_tree_contents(
 
114
            [(self.info['filename'], 'changed something\n')])
 
115
        txt = self.run_bzr_decode('status')
83
116
        self.assertEqual(u'modified:\n  %s\n' % (self.info['filename'],), txt)
84
117
 
85
 
        txt = bzr('status', encoding='ascii')
 
118
        txt = self.run_bzr_decode('status', encoding='ascii')
86
119
        expected = u'modified:\n  %s\n' % (
87
120
                    self.info['filename'].encode('ascii', 'replace'),)
88
121
        self.assertEqual(expected, txt)
90
123
    def test_cat(self):
91
124
        # bzr cat shouldn't change the contents
92
125
        # using run_bzr since that doesn't decode
93
 
        txt = self.run_bzr('cat', 'b')[0]
 
126
        txt = self.run_bzr('cat b')[0]
94
127
        self.assertEqual('non-ascii \xFF\xFF\xFC\xFB\x00 in b\n', txt)
95
128
 
96
 
        txt = self.run_bzr('cat', self.info['filename'])[0]
 
129
        txt = self.run_bzr(['cat', self.info['filename']])[0]
97
130
        self.assertEqual('unicode filename\n', txt)
98
131
 
99
132
    def test_cat_revision(self):
100
 
        bzr = self.run_bzr_decode
101
 
 
102
133
        committer = self.info['committer']
103
 
        txt = bzr('cat-revision', '-r', '1')
 
134
        txt = self.run_bzr_decode('cat-revision -r 1')
104
135
        self.failUnless(committer in txt,
105
136
                        'failed to find %r in %r' % (committer, txt))
106
137
 
107
138
        msg = self.info['message']
108
 
        txt = bzr('cat-revision', '-r', '2')
 
139
        txt = self.run_bzr_decode('cat-revision -r 2')
109
140
        self.failUnless(msg in txt, 'failed to find %r in %r' % (msg, txt))
110
141
 
111
142
    def test_mkdir(self):
112
 
        bzr = self.run_bzr_decode
113
 
 
114
 
        txt = bzr('mkdir', self.info['directory'])
 
143
        txt = self.run_bzr_decode(['mkdir', self.info['directory']])
115
144
        self.assertEqual(u'added %s\n' % self.info['directory'], txt)
116
145
 
117
146
        # The text should be garbled, but the command should succeed
118
 
        txt = bzr('mkdir', self.info['directory'] + '2', encoding='ascii')
 
147
        txt = self.run_bzr_decode(['mkdir', self.info['directory'] + '2'],
 
148
                                  encoding='ascii')
119
149
        expected = u'added %s2\n' % (self.info['directory'],)
120
150
        expected = expected.encode('ascii', 'replace')
121
151
        self.assertEqual(expected, txt)
122
152
 
123
153
    def test_relpath(self):
124
 
        bzr = self.run_bzr_decode
125
 
 
126
 
        txt = bzr('relpath', self.info['filename'])
 
154
        txt = self.run_bzr_decode(['relpath', self.info['filename']])
127
155
        self.assertEqual(self.info['filename'] + '\n', txt)
128
156
 
129
 
        bzr('relpath', self.info['filename'], encoding='ascii', retcode=3)
 
157
        self.run_bzr_decode(['relpath', self.info['filename']],
 
158
                            encoding='ascii', fail=True)
130
159
 
131
160
    def test_inventory(self):
132
 
        bzr = self.run_bzr_decode
133
 
 
134
 
        txt = bzr('inventory')
 
161
        txt = self.run_bzr_decode('inventory')
135
162
        self.assertEqual(['a', 'b', self.info['filename']],
136
163
                         txt.splitlines())
137
164
 
138
165
        # inventory should fail if unable to encode
139
 
        bzr('inventory', encoding='ascii', retcode=3)
 
166
        self.run_bzr_decode('inventory', encoding='ascii', fail=True)
140
167
 
141
168
        # We don't really care about the ids themselves,
142
169
        # but the command shouldn't fail
143
 
        txt = bzr('inventory', '--show-ids')
 
170
        txt = self.run_bzr_decode('inventory --show-ids')
144
171
 
145
172
    def test_revno(self):
146
173
        # There isn't a lot to test here, since revno should always
147
174
        # be an integer
148
 
        bzr = self.run_bzr_decode
149
 
 
150
 
        self.assertEqual('3\n', bzr('revno'))
151
 
        self.assertEqual('3\n', bzr('revno', encoding='ascii'))
 
175
        self.assertEqual('3\n', self.run_bzr_decode('revno'))
 
176
        self.assertEqual('3\n', self.run_bzr_decode('revno', encoding='ascii'))
152
177
 
153
178
    def test_revision_info(self):
154
 
        bzr = self.run_bzr_decode
155
 
 
156
 
        bzr('revision-info', '-r', '1')
 
179
        self.run_bzr_decode('revision-info -r 1')
157
180
 
158
181
        # TODO: jam 20060105 If we support revisions with non-ascii characters,
159
182
        # this should be strict and fail.
160
 
        bzr('revision-info', '-r', '1', encoding='ascii')
 
183
        self.run_bzr_decode('revision-info -r 1', encoding='ascii')
161
184
 
162
185
    def test_mv(self):
163
 
        bzr = self.run_bzr_decode
164
 
 
165
186
        fname1 = self.info['filename']
166
187
        fname2 = self.info['filename'] + '2'
167
188
        dirname = self.info['directory']
168
189
 
169
190
        # fname1 already exists
170
 
        bzr('mv', 'a', fname1, retcode=3)
 
191
        self.run_bzr_decode(['mv', 'a', fname1], fail=True)
171
192
 
172
 
        txt = bzr('mv', 'a', fname2)
 
193
        txt = self.run_bzr_decode(['mv', 'a', fname2])
173
194
        self.assertEqual(u'a => %s\n' % fname2, txt)
174
195
        self.failIfExists('a')
175
196
        self.failUnlessExists(fname2)
176
197
 
177
 
        bzr('commit', '-m', 'renamed to non-ascii')
 
198
        # After 'mv' we need to re-open the working tree
 
199
        self.wt = self.wt.bzrdir.open_workingtree()
 
200
        self.wt.commit('renamed to non-ascii')
178
201
 
179
 
        bzr('mkdir', dirname)
180
 
        txt = bzr('mv', fname1, fname2, dirname)
 
202
        os.mkdir(dirname)
 
203
        self.wt.add(dirname)
 
204
        txt = self.run_bzr_decode(['mv', fname1, fname2, dirname])
181
205
        self.assertEqual([u'%s => %s/%s' % (fname1, dirname, fname1),
182
206
                          u'%s => %s/%s' % (fname2, dirname, fname2)]
183
207
                         , txt.splitlines())
184
208
 
185
209
        # The rename should still succeed
186
210
        newpath = u'%s/%s' % (dirname, fname2)
187
 
        txt = bzr('mv', newpath, 'a', encoding='ascii')
 
211
        txt = self.run_bzr_decode(['mv', newpath, 'a'], encoding='ascii')
188
212
        self.failUnlessExists('a')
189
213
        self.assertEqual(newpath.encode('ascii', 'replace') + ' => a\n', txt)
190
214
 
191
215
    def test_branch(self):
192
216
        # We should be able to branch into a directory that
193
217
        # has a unicode name, even if we can't display the name
194
 
        bzr = self.run_bzr_decode
195
 
        bzr('branch', u'.', self.info['directory'])
196
 
        bzr('branch', u'.', self.info['directory'] + '2', encoding='ascii')
 
218
        self.run_bzr_decode(['branch', u'.', self.info['directory']])
 
219
        self.run_bzr_decode(['branch', u'.', self.info['directory'] + '2'],
 
220
                            encoding='ascii')
197
221
 
198
222
    def test_pull(self):
199
223
        # Make sure we can pull from paths that can't be encoded
200
 
        bzr = self.run_bzr_decode
201
 
 
202
224
        dirname1 = self.info['directory']
203
225
        dirname2 = self.info['directory'] + '2'
204
 
        bzr('branch', '.', dirname1)
205
 
        bzr('branch', dirname1, dirname2)
206
 
 
207
 
        os.chdir(dirname1)
208
 
        open('a', 'ab').write('more text\n')
209
 
        bzr('commit', '-m', 'mod a')
210
 
 
211
 
        pwd = os.getcwdu()
212
 
 
213
 
        os.chdir(u'../' + dirname2)
214
 
        txt = bzr('pull')
215
 
 
216
 
        self.assertEqual(u'Using saved location: %s/\n' % (pwd,), txt)
217
 
 
218
 
        os.chdir('../' + dirname1)
219
 
        open('a', 'ab').write('and yet more\n')
220
 
        bzr('commit', '-m', 'modifying a by ' + self.info['committer'])
221
 
 
222
 
        os.chdir('../' + dirname2)
 
226
        url1 = urlutils.local_path_to_url(dirname1)
 
227
        url2 = urlutils.local_path_to_url(dirname2)
 
228
        out_bzrdir = self.wt.bzrdir.sprout(url1)
 
229
        out_bzrdir.sprout(url2)
 
230
 
 
231
        self.build_tree_contents(
 
232
            [(osutils.pathjoin(dirname1, "a"), 'different text\n')])
 
233
        self.wt.commit('mod a')
 
234
 
 
235
        txt = self.run_bzr_decode('pull', working_dir=dirname2)
 
236
 
 
237
        expected = osutils.pathjoin(osutils.getcwd(), dirname1)
 
238
        self.assertEqual(u'Using saved location: %s/\n'
 
239
                'No revisions to pull.\n' % (expected,), txt)
 
240
 
 
241
        self.build_tree_contents(
 
242
            [(osutils.pathjoin(dirname1, 'a'), 'and yet more\n')])
 
243
        self.wt.commit(u'modifying a by ' + self.info['committer'])
 
244
 
223
245
        # We should be able to pull, even if our encoding is bad
224
 
        bzr('pull', '--verbose', encoding='ascii')
 
246
        self.run_bzr_decode('pull --verbose', encoding='ascii',
 
247
                            working_dir=dirname2)
225
248
 
226
249
    def test_push(self):
227
250
        # TODO: Test push to an SFTP location
228
251
        # Make sure we can pull from paths that can't be encoded
229
 
        bzr = self.run_bzr_decode
230
 
 
231
252
        # TODO: jam 20060427 For drastically improving performance, we probably
232
253
        #       could create a local repository, so it wouldn't have to copy
233
254
        #       the files around as much.
234
255
 
235
256
        dirname = self.info['directory']
236
 
        bzr('push', dirname)
 
257
        self.run_bzr_decode(['push', dirname])
237
258
 
238
 
        open('a', 'ab').write('adding more text\n')
239
 
        bzr('commit', '-m', 'added some stuff')
 
259
        self.build_tree_contents([('a', 'adding more text\n')])
 
260
        self.wt.commit('added some stuff')
240
261
 
241
262
        # TODO: check the output text is properly encoded
242
 
        bzr('push')
243
 
 
244
 
        f = open('a', 'ab')
245
 
        f.write('and a bit more: ')
246
 
        f.write(dirname.encode('utf-8'))
247
 
        f.write('\n')
248
 
        f.close()
249
 
 
250
 
        bzr('commit', '-m', u'Added some ' + dirname)
251
 
        bzr('push', '--verbose', encoding='ascii')
252
 
 
253
 
        bzr('push', '--verbose', dirname + '2')
254
 
 
255
 
        bzr('push', '--verbose', dirname + '3', encoding='ascii')
256
 
 
257
 
        bzr('push', '--verbose', '--create-prefix', dirname + '4/' + dirname + '5')
258
 
        bzr('push', '--verbose', '--create-prefix', dirname + '6/' + dirname + '7', encoding='ascii')
 
263
        self.run_bzr_decode('push')
 
264
 
 
265
        self.build_tree_contents(
 
266
            [('a', 'and a bit more: \n%s\n' % (dirname.encode('utf-8'),))])
 
267
 
 
268
        self.wt.commit('Added some ' + dirname)
 
269
        self.run_bzr_decode('push --verbose', encoding='ascii')
 
270
 
 
271
        self.run_bzr_decode(['push', '--verbose', dirname + '2'])
 
272
 
 
273
        self.run_bzr_decode(['push', '--verbose', dirname + '3'],
 
274
                            encoding='ascii')
 
275
 
 
276
        self.run_bzr_decode(['push', '--verbose', '--create-prefix',
 
277
                            dirname + '4/' + dirname + '5'])
 
278
        self.run_bzr_decode(['push', '--verbose', '--create-prefix',
 
279
                            dirname + '6/' + dirname + '7'], encoding='ascii')
259
280
 
260
281
    def test_renames(self):
261
 
        bzr = self.run_bzr_decode
262
 
 
263
282
        fname = self.info['filename'] + '2'
264
 
        bzr('mv', 'a', fname)
265
 
        txt = bzr('renames')
 
283
        self.wt.rename_one('a', fname)
 
284
        txt = self.run_bzr_decode('renames')
266
285
        self.assertEqual(u'a => %s\n' % fname, txt)
267
286
 
268
 
        bzr('renames', retcode=3, encoding='ascii')
 
287
        self.run_bzr_decode('renames', fail=True, encoding='ascii')
269
288
 
270
289
    def test_remove(self):
271
 
        bzr = self.run_bzr_decode
272
 
 
273
290
        fname = self.info['filename']
274
 
        txt = bzr('remove', fname, encoding='ascii')
 
291
        txt = self.run_bzr_decode(['remove', fname], encoding='ascii')
275
292
 
276
293
    def test_remove_verbose(self):
277
 
        bzr = self.run_bzr_decode
278
 
 
279
294
        fname = self.info['filename']
280
 
        txt = bzr('remove', '--verbose', fname, encoding='ascii')
 
295
        txt = self.run_bzr_decode(['remove', '--verbose', fname],
 
296
                                  encoding='ascii')
281
297
 
282
298
    def test_file_id(self):
283
 
        bzr = self.run_bzr_decode
284
 
 
285
299
        fname = self.info['filename']
286
 
        txt = bzr('file-id', fname)
 
300
        txt = self.run_bzr_decode(['file-id', fname])
287
301
 
288
302
        # TODO: jam 20060106 We don't support non-ascii file ids yet, 
289
303
        #       so there is nothing which would fail in ascii encoding
290
304
        #       This *should* be retcode=3
291
 
        txt = bzr('file-id', fname, encoding='ascii')
 
305
        txt = self.run_bzr_decode(['file-id', fname], encoding='ascii')
292
306
 
293
307
    def test_file_path(self):
294
 
        bzr = self.run_bzr_decode
295
 
 
296
308
        # Create a directory structure
297
309
        fname = self.info['filename']
298
310
        dirname = self.info['directory']
299
 
        bzr('mkdir', 'base')
300
 
        bzr('mkdir', 'base/' + dirname)
301
 
        path = '/'.join(['base', dirname, fname])
302
 
        bzr('mv', fname, path)
303
 
        bzr('commit', '-m', 'moving things around')
 
311
        self.build_tree_contents([
 
312
            ('base/', ),
 
313
            (osutils.pathjoin('base', '%s/' % (dirname,)), )])
 
314
        self.wt.add('base')
 
315
        self.wt.add('base/'+dirname)
 
316
        path = osutils.pathjoin('base', dirname, fname)
 
317
        self.wt.rename_one(fname, path)
 
318
        self.wt.commit('moving things around')
304
319
 
305
 
        txt = bzr('file-path', path)
 
320
        txt = self.run_bzr_decode(['file-path', path])
306
321
 
307
322
        # TODO: jam 20060106 We don't support non-ascii file ids yet, 
308
323
        #       so there is nothing which would fail in ascii encoding
309
324
        #       This *should* be retcode=3
310
 
        txt = bzr('file-path', path, encoding='ascii')
 
325
        txt = self.run_bzr_decode(['file-path', path], encoding='ascii')
311
326
 
312
327
    def test_revision_history(self):
313
 
        bzr = self.run_bzr_decode
314
 
 
315
328
        # TODO: jam 20060106 We don't support non-ascii revision ids yet, 
316
329
        #       so there is nothing which would fail in ascii encoding
317
 
        txt = bzr('revision-history')
 
330
        txt = self.run_bzr_decode('revision-history')
318
331
 
319
332
    def test_ancestry(self):
320
 
        bzr = self.run_bzr_decode
321
 
 
322
333
        # TODO: jam 20060106 We don't support non-ascii revision ids yet, 
323
334
        #       so there is nothing which would fail in ascii encoding
324
 
        txt = bzr('ancestry')
 
335
        txt = self.run_bzr_decode('ancestry')
325
336
 
326
337
    def test_diff(self):
327
338
        # TODO: jam 20060106 diff is a difficult one to test, because it 
328
339
        #       shouldn't encode the file contents, but it needs some sort
329
340
        #       of encoding for the paths, etc which are displayed.
330
 
        open(self.info['filename'], 'ab').write('newline\n')
 
341
        self.build_tree_contents([(self.info['filename'], 'newline\n')])
331
342
        txt = self.run_bzr('diff', retcode=1)[0]
332
343
 
333
344
    def test_deleted(self):
334
 
        bzr = self.run_bzr_decode
335
 
 
336
345
        fname = self.info['filename']
337
346
        os.remove(fname)
338
 
        bzr('rm', fname)
 
347
        self.wt.remove(fname)
339
348
 
340
 
        txt = bzr('deleted')
 
349
        txt = self.run_bzr_decode('deleted')
341
350
        self.assertEqual(fname+'\n', txt)
342
351
 
343
 
        txt = bzr('deleted', '--show-ids')
 
352
        txt = self.run_bzr_decode('deleted --show-ids')
344
353
        self.failUnless(txt.startswith(fname))
345
354
 
346
355
        # Deleted should fail if cannot decode
347
356
        # Because it is giving the exact paths
348
357
        # which might be used by a front end
349
 
        bzr('deleted', encoding='ascii', retcode=3)
 
358
        self.run_bzr_decode('deleted', encoding='ascii', fail=True)
350
359
 
351
360
    def test_modified(self):
352
 
        bzr = self.run_bzr_decode
353
 
 
354
361
        fname = self.info['filename']
355
 
        open(fname, 'ab').write('modified\n')
356
 
 
357
 
        txt = bzr('modified')
358
 
        self.assertEqual(fname+'\n', txt)
359
 
 
360
 
        bzr('modified', encoding='ascii', retcode=3)
 
362
        self.build_tree_contents([(fname, 'modified\n')])
 
363
 
 
364
        txt = self.run_bzr_decode('modified')
 
365
        self.assertEqual('"'+fname+'"'+'\n', txt)
 
366
 
 
367
        self.run_bzr_decode('modified', encoding='ascii', fail=True)
361
368
 
362
369
    def test_added(self):
363
 
        bzr = self.run_bzr_decode
364
 
 
365
370
        fname = self.info['filename'] + '2'
366
 
        open(fname, 'wb').write('added\n')
367
 
        bzr('add', fname)
368
 
 
369
 
        txt = bzr('added')
370
 
        self.assertEqual(fname+'\n', txt)
371
 
 
372
 
        bzr('added', encoding='ascii', retcode=3)
 
371
        self.build_tree_contents([(fname, 'added\n')])
 
372
        self.wt.add(fname)
 
373
 
 
374
        txt = self.run_bzr_decode('added')
 
375
        self.assertEqual('"'+fname+'"'+'\n', txt)
 
376
 
 
377
        self.run_bzr_decode('added', encoding='ascii', fail=True)
373
378
 
374
379
    def test_root(self):
375
 
        bzr = self.run_bzr_decode
376
 
 
377
380
        dirname = self.info['directory']
378
 
        bzr('root')
379
 
 
380
 
        bzr('branch', u'.', dirname)
381
 
 
382
 
        os.chdir(dirname)
383
 
 
384
 
        txt = bzr('root')
 
381
        url = urlutils.local_path_to_url(dirname)
 
382
        self.run_bzr_decode('root')
 
383
 
 
384
        self.wt.bzrdir.sprout(url)
 
385
 
 
386
        txt = self.run_bzr_decode('root', working_dir=dirname)
385
387
        self.failUnless(txt.endswith(dirname+'\n'))
386
388
 
387
 
        txt = bzr('root', encoding='ascii', retcode=3)
 
389
        txt = self.run_bzr_decode('root', encoding='ascii', fail=True,
 
390
                                  working_dir=dirname)
388
391
 
389
392
    def test_log(self):
390
 
        bzr = self.run_bzr_decode
391
 
 
392
393
        fname = self.info['filename']
393
394
 
394
 
        txt = bzr('log')
 
395
        txt = self.run_bzr_decode('log')
395
396
        self.assertNotEqual(-1, txt.find(self.info['committer']))
396
397
        self.assertNotEqual(-1, txt.find(self.info['message']))
397
398
 
398
 
        txt = bzr('log', '--verbose')
 
399
        txt = self.run_bzr_decode('log --verbose')
399
400
        self.assertNotEqual(-1, txt.find(fname))
400
401
 
401
402
        # Make sure log doesn't fail even if we can't write out
402
 
        txt = bzr('log', '--verbose', encoding='ascii')
 
403
        txt = self.run_bzr_decode('log --verbose', encoding='ascii')
403
404
        self.assertEqual(-1, txt.find(fname))
404
405
        self.assertNotEqual(-1, txt.find(fname.encode('ascii', 'replace')))
405
406
 
406
407
    def test_touching_revisions(self):
407
 
        bzr = self.run_bzr_decode
408
 
 
409
408
        fname = self.info['filename']
410
 
        txt = bzr('touching-revisions', fname)
 
409
        txt = self.run_bzr_decode(['touching-revisions', fname])
411
410
        self.assertEqual(u'     3 added %s\n' % (fname,), txt)
412
411
 
413
412
        fname2 = self.info['filename'] + '2'
414
 
        bzr('mv', fname, fname2)
415
 
        bzr('commit', '-m', u'Renamed %s => %s' % (fname, fname2))
 
413
        self.wt.rename_one(fname, fname2)
 
414
        self.wt.commit(u'Renamed %s => %s' % (fname, fname2))
416
415
 
417
 
        txt = bzr('touching-revisions', fname2)
 
416
        txt = self.run_bzr_decode(['touching-revisions', fname2])
418
417
        expected_txt = (u'     3 added %s\n' 
419
418
                        u'     4 renamed %s => %s\n'
420
419
                        % (fname, fname, fname2))
421
420
        self.assertEqual(expected_txt, txt)
422
421
 
423
 
        bzr('touching-revisions', fname2, encoding='ascii', retcode=3)
 
422
        self.run_bzr_decode(['touching-revisions', fname2], encoding='ascii',
 
423
                            fail=True)
424
424
 
425
425
    def test_ls(self):
426
 
        bzr = self.run_bzr_decode
427
 
 
428
 
        txt = bzr('ls')
429
 
        self.assertEqual(['a', 'b', self.info['filename']],
430
 
                         txt.splitlines())
431
 
        txt = bzr('ls', '--null')
432
 
        self.assertEqual(['a', 'b', self.info['filename'], ''],
433
 
                         txt.split('\0'))
434
 
 
435
 
        txt = bzr('ls', encoding='ascii', retcode=3)
436
 
        txt = bzr('ls', '--null', encoding='ascii', retcode=3)
 
426
        txt = self.run_bzr_decode('ls')
 
427
        self.assertEqual(sorted(['a', 'b', self.info['filename']]),
 
428
                         sorted(txt.splitlines()))
 
429
        txt = self.run_bzr_decode('ls --null')
 
430
        self.assertEqual(sorted(['', 'a', 'b', self.info['filename']]),
 
431
                         sorted(txt.split('\0')))
 
432
 
 
433
        txt = self.run_bzr_decode('ls', encoding='ascii', fail=True)
 
434
        txt = self.run_bzr_decode('ls --null', encoding='ascii', fail=True)
437
435
 
438
436
    def test_unknowns(self):
439
 
        bzr = self.run_bzr_decode
440
 
 
441
437
        fname = self.info['filename'] + '2'
442
 
        open(fname, 'wb').write('unknown\n')
 
438
        self.build_tree_contents([(fname, 'unknown\n')])
443
439
 
444
440
        # TODO: jam 20060112 bzr unknowns is the only one which 
445
441
        #       quotes paths do we really want it to?
446
 
        txt = bzr('unknowns')
 
442
        #       awilkins 20080521 added and modified do it now as well
 
443
        txt = self.run_bzr_decode('unknowns')
447
444
        self.assertEqual(u'"%s"\n' % (fname,), txt)
448
445
 
449
 
        bzr('unknowns', encoding='ascii', retcode=3)
 
446
        self.run_bzr_decode('unknowns', encoding='ascii', fail=True)
450
447
 
451
448
    def test_ignore(self):
452
 
        bzr = self.run_bzr_decode
453
 
 
454
449
        fname2 = self.info['filename'] + '2.txt'
455
 
        open(fname2, 'wb').write('ignored\n')
456
 
 
457
 
        txt = bzr('unknowns')
458
 
        self.assertEqual(u'"%s"\n' % (fname2,), txt)
459
 
 
460
 
        bzr('ignore', './' + fname2)
461
 
        txt = bzr('unknowns')
462
 
        self.assertEqual(u'', txt)
 
450
        self.build_tree_contents([(fname2, 'ignored\n')])
 
451
 
 
452
        def check_unknowns(expected):
 
453
            self.assertEqual(expected, list(self.wt.unknowns()))
 
454
 
 
455
        check_unknowns([fname2])
 
456
 
 
457
        self.run_bzr_decode(['ignore', './' + fname2])
 
458
        check_unknowns([])
463
459
 
464
460
        fname3 = self.info['filename'] + '3.txt'
465
 
        open(fname3, 'wb').write('unknown 3\n')
466
 
        txt = bzr('unknowns')
467
 
        self.assertEqual(u'"%s"\n' % (fname3,), txt)
 
461
        self.build_tree_contents([(fname3, 'unknown 3\n')])
 
462
        check_unknowns([fname3])
468
463
 
469
464
        # Ignore should not care what the encoding is
470
465
        # (right now it doesn't print anything)
471
 
        bzr('ignore', fname3, encoding='ascii')
472
 
        txt = bzr('unknowns')
473
 
        self.assertEqual('', txt)
 
466
        self.run_bzr_decode(['ignore', fname3], encoding='ascii')
 
467
        check_unknowns([])
474
468
 
475
469
        # Now try a wildcard match
476
470
        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)
 
471
        self.build_tree_contents([(fname4, 'unknown 4\n')])
 
472
        self.run_bzr_decode('ignore *.txt')
 
473
        check_unknowns([])
481
474
 
 
475
        # and a different wildcard that matches everything
482
476
        os.remove('.bzrignore')
483
 
        bzr('ignore', self.info['filename'] + '*')
484
 
        txt = bzr('unknowns')
485
 
        self.assertEqual('', txt)
486
 
 
487
 
 
 
477
        self.run_bzr_decode(['ignore', self.info['filename'] + '*'])
 
478
        check_unknowns([])
 
479
 
 
480
    def test_missing(self):
 
481
        # create empty tree as reference for missing
 
482
        self.make_branch_and_tree('empty-tree')
 
483
 
 
484
        msg = self.info['message']
 
485
 
 
486
        txt = self.run_bzr_decode('missing empty-tree')
 
487
        self.assertNotEqual(-1, txt.find(self.info['committer']))
 
488
        self.assertNotEqual(-1, txt.find(msg))
 
489
 
 
490
        # Make sure missing doesn't fail even if we can't write out
 
491
        txt = self.run_bzr_decode('missing empty-tree', encoding='ascii')
 
492
        self.assertEqual(-1, txt.find(msg))
 
493
        self.assertNotEqual(-1, txt.find(msg.encode('ascii', 'replace')))
 
494
 
 
495
    def test_info(self):
 
496
        self.run_bzr_decode(['branch', u'.', self.info['directory']])
 
497
        self.run_bzr_decode(['info', self.info['directory']])
 
498
        self.run_bzr_decode(['info', self.info['directory']],
 
499
                            encoding='ascii')
 
500
 
 
501
    def test_ignored(self):
 
502
        fname = self.info['filename'] + '1.txt'
 
503
        self.build_tree_contents([(fname, 'ignored\n')])
 
504
        self.run_bzr(['ignore', fname])
 
505
        txt = self.run_bzr_decode(['ignored'])
 
506
        self.assertEqual(txt, '%-50s %s\n' % (fname, fname))
 
507
        txt = self.run_bzr_decode(['ignored'], encoding='ascii')
 
508
        fname = fname.encode('ascii', 'replace')
 
509
        self.assertEqual(txt, '%-50s %s\n' % (fname, fname))