/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_status.py

  • Committer: Robert Collins
  • Date: 2010-05-06 23:41:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506234135-yivbzczw1sejxnxc
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
expected to return an object which can be used to unlock them. This reduces
duplicate code when using cleanups. The previous 'tokens's returned by
``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
on the result of the lock_write. ``repository.RepositoryWriteLockResult``
and ``branch.BranchWriteLockResult`` document this. (Robert Collins)

``log._get_info_for_log_files`` now takes an add_cleanup callable.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2005-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
22
22
interface later, they will be non blackbox tests.
23
23
"""
24
24
 
 
25
from cStringIO import StringIO
25
26
import codecs
26
27
from os import mkdir, chdir, rmdir, unlink
27
28
import sys
 
29
from tempfile import TemporaryFile
28
30
 
29
 
from ... import (
 
31
from bzrlib import (
 
32
    bzrdir,
30
33
    conflicts,
31
34
    errors,
32
35
    osutils,
33
 
    status,
34
 
    )
35
 
from breezy.bzr import (
36
 
    bzrdir,
37
 
    )
38
 
import breezy.branch
39
 
from ...osutils import pathjoin
40
 
from ...revisionspec import RevisionSpec
41
 
from ...sixish import (
42
 
    BytesIO,
43
 
    StringIO,
44
 
    PY3,
45
 
    )
46
 
from ...status import show_tree_status
47
 
from .. import TestCaseWithTransport, TestSkipped
48
 
from ...workingtree import WorkingTree
 
36
    )
 
37
import bzrlib.branch
 
38
from bzrlib.osutils import pathjoin
 
39
from bzrlib.revisionspec import RevisionSpec
 
40
from bzrlib.status import show_tree_status
 
41
from bzrlib.tests import TestCaseWithTransport, TestSkipped
 
42
from bzrlib.workingtree import WorkingTree
49
43
 
50
44
 
51
45
class BranchStatus(TestCaseWithTransport):
52
46
 
53
 
    def setUp(self):
54
 
        super(BranchStatus, self).setUp()
55
 
        # As TestCase.setUp clears all hooks, we install this default
56
 
        # post_status hook handler for the test.
57
 
        status.hooks.install_named_hook('post_status',
58
 
                                        status._show_shelve_summary,
59
 
                                        'brz status')
60
 
 
61
 
    def assertStatus(self, expected_lines, working_tree, specific_files=None,
62
 
                     revision=None, short=False, pending=True, verbose=False):
 
47
    def assertStatus(self, expected_lines, working_tree,
 
48
        revision=None, short=False, pending=True, verbose=False):
63
49
        """Run status in working_tree and look for output.
64
50
 
65
51
        :param expected_lines: The lines to look for.
66
52
        :param working_tree: The tree to run status in.
67
53
        """
68
 
        output_string = self.status_string(working_tree, specific_files, revision, short,
69
 
                                           pending, verbose)
 
54
        output_string = self.status_string(working_tree, revision, short,
 
55
                pending, verbose)
70
56
        self.assertEqual(expected_lines, output_string.splitlines(True))
71
57
 
72
 
    def status_string(self, wt, specific_files=None, revision=None,
73
 
                      short=False, pending=True, verbose=False):
74
 
        uio = self.make_utf8_encoded_stringio()
75
 
        show_tree_status(wt, specific_files=specific_files, to_file=uio,
76
 
                         revision=revision, short=short, show_pending=pending,
77
 
                         verbose=verbose)
78
 
        return uio.getvalue().decode('utf-8')
 
58
    def status_string(self, wt, revision=None, short=False, pending=True,
 
59
        verbose=False):
 
60
        # use a real file rather than StringIO because it doesn't handle
 
61
        # Unicode very well.
 
62
        tof = codecs.getwriter('utf-8')(TemporaryFile())
 
63
        show_tree_status(wt, to_file=tof, revision=revision, short=short,
 
64
                show_pending=pending, verbose=verbose)
 
65
        tof.seek(0)
 
66
        return tof.read().decode('utf-8')
79
67
 
80
68
    def test_branch_status(self):
81
69
        """Test basic branch status"""
89
77
 
90
78
        self.build_tree(['hello.c', 'bye.c'])
91
79
        self.assertStatus([
92
 
            'unknown:\n',
93
 
            '  bye.c\n',
94
 
            '  hello.c\n',
 
80
                'unknown:\n',
 
81
                '  bye.c\n',
 
82
                '  hello.c\n',
95
83
            ],
96
84
            wt)
97
85
        self.assertStatus([
98
 
            '?   bye.c\n',
99
 
            '?   hello.c\n',
 
86
                '?   bye.c\n',
 
87
                '?   hello.c\n',
100
88
            ],
101
89
            wt, short=True)
102
90
 
103
91
        # add a commit to allow showing pending merges.
104
92
        wt.commit('create a parent to allow testing merge output')
105
93
 
106
 
        wt.add_parent_tree_id(b'pending@pending-0-0')
 
94
        wt.add_parent_tree_id('pending@pending-0-0')
107
95
        self.assertStatus([
108
 
            'unknown:\n',
109
 
            '  bye.c\n',
110
 
            '  hello.c\n',
111
 
            'pending merge tips: (use -v to see all merge revisions)\n',
112
 
            '  (ghost) pending@pending-0-0\n',
 
96
                'unknown:\n',
 
97
                '  bye.c\n',
 
98
                '  hello.c\n',
 
99
                'pending merge tips: (use -v to see all merge revisions)\n',
 
100
                '  (ghost) pending@pending-0-0\n',
113
101
            ],
114
102
            wt)
115
103
        self.assertStatus([
116
 
            'unknown:\n',
117
 
            '  bye.c\n',
118
 
            '  hello.c\n',
119
 
            'pending merges:\n',
120
 
            '  (ghost) pending@pending-0-0\n',
 
104
                'unknown:\n',
 
105
                '  bye.c\n',
 
106
                '  hello.c\n',
 
107
                'pending merges:\n',
 
108
                '  (ghost) pending@pending-0-0\n',
121
109
            ],
122
110
            wt, verbose=True)
123
111
        self.assertStatus([
124
 
            '?   bye.c\n',
125
 
            '?   hello.c\n',
126
 
            'P   (ghost) pending@pending-0-0\n',
 
112
                '?   bye.c\n',
 
113
                '?   hello.c\n',
 
114
                'P   (ghost) pending@pending-0-0\n',
127
115
            ],
128
116
            wt, short=True)
129
117
        self.assertStatus([
130
 
            'unknown:\n',
131
 
            '  bye.c\n',
132
 
            '  hello.c\n',
 
118
                'unknown:\n',
 
119
                '  bye.c\n',
 
120
                '  hello.c\n',
133
121
            ],
134
122
            wt, pending=False)
135
123
        self.assertStatus([
136
 
            '?   bye.c\n',
137
 
            '?   hello.c\n',
 
124
                '?   bye.c\n',
 
125
                '?   hello.c\n',
138
126
            ],
139
127
            wt, short=True, pending=False)
140
128
 
149
137
 
150
138
        revs = [RevisionSpec.from_string('0')]
151
139
        self.assertStatus([
152
 
            'added:\n',
153
 
            '  bye.c\n',
154
 
            '  hello.c\n'
 
140
                'added:\n',
 
141
                '  bye.c\n',
 
142
                '  hello.c\n'
155
143
            ],
156
144
            wt,
157
145
            revision=revs)
162
150
 
163
151
        revs.append(RevisionSpec.from_string('1'))
164
152
        self.assertStatus([
165
 
            'added:\n',
166
 
            '  bye.c\n',
167
 
            '  hello.c\n',
 
153
                'added:\n',
 
154
                '  bye.c\n',
 
155
                '  hello.c\n',
168
156
            ],
169
157
            wt,
170
158
            revision=revs)
175
163
        wt = self.make_branch_and_tree('branch')
176
164
        b = wt.branch
177
165
        wt.commit("Empty commit 1")
178
 
        b_2_dir = b.controldir.sprout('./copy')
 
166
        b_2_dir = b.bzrdir.sprout('./copy')
179
167
        b_2 = b_2_dir.open_branch()
180
168
        wt2 = b_2_dir.open_workingtree()
181
169
        wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
185
173
        self.assertEndsWith(message, "Empty commit 2\n")
186
174
        wt2.commit("merged")
187
175
        # must be long to make sure we see elipsis at the end
188
 
        wt.commit("Empty commit 3 "
189
 
                  + "blah blah blah blah " * 100)
 
176
        wt.commit("Empty commit 3 " +
 
177
                   "blah blah blah blah " * 100)
190
178
        wt2.merge_from_branch(wt.branch)
191
179
        message = self.status_string(wt2, verbose=True)
192
180
        self.assertStartsWith(message, "pending merges:\n")
193
 
        self.assertTrue("Empty commit 3" in message)
 
181
        self.assert_("Empty commit 3" in message)
194
182
        self.assertEndsWith(message, "...\n")
195
183
 
196
184
    def test_tree_status_ignores(self):
200
188
        wt.commit('commit .bzrignore')
201
189
        self.build_tree(['foo.c', 'foo.c~'])
202
190
        self.assertStatus([
203
 
            'unknown:\n',
204
 
            '  foo.c\n',
205
 
            ],
206
 
            wt)
 
191
                'unknown:\n',
 
192
                '  foo.c\n',
 
193
                ],
 
194
                wt)
207
195
        self.assertStatus([
208
 
            '?   foo.c\n',
209
 
            ],
210
 
            wt, short=True)
 
196
                '?   foo.c\n',
 
197
                ],
 
198
                wt, short=True)
211
199
 
212
200
    def test_tree_status_specific_files(self):
213
201
        """Tests branch status with given specific files"""
214
202
        wt = self.make_branch_and_tree('.')
215
203
        b = wt.branch
216
204
 
217
 
        self.build_tree(['directory/', 'directory/hello.c',
218
 
                         'bye.c', 'test.c', 'dir2/',
219
 
                         'missing.c'])
 
205
        self.build_tree(['directory/','directory/hello.c', 'bye.c','test.c','dir2/'])
220
206
        wt.add('directory')
221
207
        wt.add('test.c')
222
208
        wt.commit('testing')
223
 
        wt.add('missing.c')
224
 
        unlink('missing.c')
225
 
 
226
 
        self.assertStatus([
227
 
            'missing:\n',
228
 
            '  missing.c\n',
229
 
            'unknown:\n',
230
 
            '  bye.c\n',
231
 
            '  dir2/\n',
232
 
            '  directory/hello.c\n'
233
 
            ],
234
 
            wt)
235
 
 
236
 
        self.assertStatus([
237
 
            '?   bye.c\n',
238
 
            '?   dir2/\n',
239
 
            '?   directory/hello.c\n',
240
 
            '+!  missing.c\n',
241
 
            ],
242
 
            wt, short=True)
 
209
 
 
210
        self.assertStatus([
 
211
                'unknown:\n',
 
212
                '  bye.c\n',
 
213
                '  dir2/\n',
 
214
                '  directory/hello.c\n'
 
215
                ],
 
216
                wt)
 
217
 
 
218
        self.assertStatus([
 
219
                '?   bye.c\n',
 
220
                '?   dir2/\n',
 
221
                '?   directory/hello.c\n'
 
222
                ],
 
223
                wt, short=True)
243
224
 
244
225
        tof = StringIO()
245
226
        self.assertRaises(errors.PathsDoNotExist,
246
227
                          show_tree_status,
247
 
                          wt, specific_files=['bye.c', 'test.c', 'absent.c'],
 
228
                          wt, specific_files=['bye.c','test.c','absent.c'],
248
229
                          to_file=tof)
249
230
 
250
231
        tof = StringIO()
251
232
        show_tree_status(wt, specific_files=['directory'], to_file=tof)
252
233
        tof.seek(0)
253
 
        self.assertEqual(tof.readlines(),
254
 
                         ['unknown:\n',
255
 
                          '  directory/hello.c\n'
256
 
                          ])
 
234
        self.assertEquals(tof.readlines(),
 
235
                          ['unknown:\n',
 
236
                           '  directory/hello.c\n'
 
237
                           ])
257
238
        tof = StringIO()
258
239
        show_tree_status(wt, specific_files=['directory'], to_file=tof,
259
240
                         short=True)
260
241
        tof.seek(0)
261
 
        self.assertEqual(tof.readlines(), ['?   directory/hello.c\n'])
 
242
        self.assertEquals(tof.readlines(), ['?   directory/hello.c\n'])
262
243
 
263
244
        tof = StringIO()
264
245
        show_tree_status(wt, specific_files=['dir2'], to_file=tof)
265
246
        tof.seek(0)
266
 
        self.assertEqual(tof.readlines(),
267
 
                         ['unknown:\n',
268
 
                          '  dir2/\n'
269
 
                          ])
 
247
        self.assertEquals(tof.readlines(),
 
248
                          ['unknown:\n',
 
249
                           '  dir2/\n'
 
250
                           ])
270
251
        tof = StringIO()
271
252
        show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
272
253
        tof.seek(0)
273
 
        self.assertEqual(tof.readlines(), ['?   dir2/\n'])
 
254
        self.assertEquals(tof.readlines(), ['?   dir2/\n'])
274
255
 
275
256
        tof = StringIO()
276
257
        revs = [RevisionSpec.from_string('0'), RevisionSpec.from_string('1')]
277
258
        show_tree_status(wt, specific_files=['test.c'], to_file=tof,
278
259
                         short=True, revision=revs)
279
260
        tof.seek(0)
280
 
        self.assertEqual(tof.readlines(), ['+N  test.c\n'])
281
 
 
282
 
        tof = StringIO()
283
 
        show_tree_status(wt, specific_files=['missing.c'], to_file=tof)
284
 
        tof.seek(0)
285
 
        self.assertEqual(tof.readlines(),
286
 
                         ['missing:\n',
287
 
                          '  missing.c\n'])
288
 
 
289
 
        tof = StringIO()
290
 
        show_tree_status(wt, specific_files=['missing.c'], to_file=tof,
291
 
                         short=True)
292
 
        tof.seek(0)
293
 
        self.assertEqual(tof.readlines(),
294
 
                         ['+!  missing.c\n'])
 
261
        self.assertEquals(tof.readlines(), ['+N  test.c\n'])
295
262
 
296
263
    def test_specific_files_conflicts(self):
297
264
        tree = self.make_branch_and_tree('.')
300
267
        tree.commit('added dir2')
301
268
        tree.set_conflicts(conflicts.ConflictList(
302
269
            [conflicts.ContentsConflict('foo')]))
303
 
        tof = BytesIO()
 
270
        tof = StringIO()
304
271
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
305
 
        self.assertEqualDiff(b'', tof.getvalue())
 
272
        self.assertEqualDiff('', tof.getvalue())
306
273
        tree.set_conflicts(conflicts.ConflictList(
307
274
            [conflicts.ContentsConflict('dir2')]))
308
275
        tof = StringIO()
327
294
        wt.add('FILE_D')
328
295
        wt.add('FILE_E')
329
296
        wt.commit('Create five empty files.')
330
 
        with open('FILE_B', 'w') as f:
331
 
            f.write('Modification to file FILE_B.')
332
 
        with open('FILE_C', 'w') as f:
333
 
            f.write('Modification to file FILE_C.')
 
297
        open('FILE_B', 'w').write('Modification to file FILE_B.')
 
298
        open('FILE_C', 'w').write('Modification to file FILE_C.')
334
299
        unlink('FILE_E')  # FILE_E will be versioned but missing
335
 
        with open('FILE_Q', 'w') as f:
336
 
            f.write('FILE_Q is added but not committed.')
 
300
        open('FILE_Q', 'w').write('FILE_Q is added but not committed.')
337
301
        wt.add('FILE_Q')  # FILE_Q will be added but not committed
338
302
        open('UNVERSIONED_BUT_EXISTING', 'w')
339
303
        return wt
366
330
        # Okay, everything's looking good with the existent files.
367
331
        # Let's see what happens when we throw in non-existent files.
368
332
 
369
 
        # brz st [--short] NONEXISTENT '
 
333
        # bzr st [--short] NONEXISTENT '
370
334
        expected = [
371
 
            'nonexistent:\n',
372
 
            '  NONEXISTENT\n',
373
 
            ]
 
335
          'nonexistent:\n',
 
336
          '  NONEXISTENT\n',
 
337
          ]
374
338
        out, err = self.run_bzr('status NONEXISTENT', retcode=3)
375
339
        self.assertEqual(expected, out.splitlines(True))
376
340
        self.assertContainsRe(err,
377
341
                              r'.*ERROR: Path\(s\) do not exist: '
378
342
                              'NONEXISTENT.*')
379
343
        expected = [
380
 
            'X:   NONEXISTENT\n',
381
 
            ]
 
344
          'X:   NONEXISTENT\n',
 
345
          ]
382
346
        out, err = self.run_bzr('status --short NONEXISTENT', retcode=3)
383
347
        self.assertContainsRe(err,
384
348
                              r'.*ERROR: Path\(s\) do not exist: '
385
349
                              'NONEXISTENT.*')
386
350
 
387
351
    def test_status_nonexistent_file_with_others(self):
388
 
        # brz st [--short] NONEXISTENT ...others..
 
352
        # bzr st [--short] NONEXISTENT ...others..
389
353
        wt = self._prepare_nonexistent()
390
354
        expected = [
391
 
            'removed:\n',
392
 
            '  FILE_E\n',
393
 
            'modified:\n',
394
 
            '  FILE_B\n',
395
 
            '  FILE_C\n',
396
 
            'nonexistent:\n',
397
 
            '  NONEXISTENT\n',
398
 
            ]
 
355
          'removed:\n',
 
356
          '  FILE_E\n',
 
357
          'modified:\n',
 
358
          '  FILE_B\n',
 
359
          '  FILE_C\n',
 
360
          'nonexistent:\n',
 
361
          '  NONEXISTENT\n',
 
362
          ]
399
363
        out, err = self.run_bzr('status NONEXISTENT '
400
364
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
401
365
                                retcode=3)
404
368
                              r'.*ERROR: Path\(s\) do not exist: '
405
369
                              'NONEXISTENT.*')
406
370
        expected = [
407
 
            ' M  FILE_B\n',
408
 
            ' M  FILE_C\n',
409
 
            ' D  FILE_E\n',
410
 
            'X   NONEXISTENT\n',
411
 
            ]
 
371
          ' D  FILE_E\n',
 
372
          ' M  FILE_C\n',
 
373
          ' M  FILE_B\n',
 
374
          'X   NONEXISTENT\n',
 
375
          ]
412
376
        out, err = self.run_bzr('status --short NONEXISTENT '
413
377
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
414
378
                                retcode=3)
418
382
                              'NONEXISTENT.*')
419
383
 
420
384
    def test_status_multiple_nonexistent_files(self):
421
 
        # brz st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
 
385
        # bzr st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
422
386
        wt = self._prepare_nonexistent()
423
387
        expected = [
424
 
            'removed:\n',
425
 
            '  FILE_E\n',
426
 
            'modified:\n',
427
 
            '  FILE_B\n',
428
 
            '  FILE_C\n',
429
 
            'nonexistent:\n',
430
 
            '  ANOTHER_NONEXISTENT\n',
431
 
            '  NONEXISTENT\n',
432
 
            ]
 
388
          'removed:\n',
 
389
          '  FILE_E\n',
 
390
          'modified:\n',
 
391
          '  FILE_B\n',
 
392
          '  FILE_C\n',
 
393
          'nonexistent:\n',
 
394
          '  ANOTHER_NONEXISTENT\n',
 
395
          '  NONEXISTENT\n',
 
396
          ]
433
397
        out, err = self.run_bzr('status NONEXISTENT '
434
398
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
435
399
                                'FILE_C FILE_D FILE_E', retcode=3)
438
402
                              r'.*ERROR: Path\(s\) do not exist: '
439
403
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
440
404
        expected = [
441
 
            ' M  FILE_B\n',
442
 
            ' M  FILE_C\n',
443
 
            ' D  FILE_E\n',
444
 
            'X   ANOTHER_NONEXISTENT\n',
445
 
            'X   NONEXISTENT\n',
446
 
            ]
 
405
          ' D  FILE_E\n',
 
406
          ' M  FILE_C\n',
 
407
          ' M  FILE_B\n',
 
408
          'X   ANOTHER_NONEXISTENT\n',
 
409
          'X   NONEXISTENT\n',
 
410
          ]
447
411
        out, err = self.run_bzr('status --short NONEXISTENT '
448
412
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
449
413
                                'FILE_C FILE_D FILE_E', retcode=3)
453
417
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
454
418
 
455
419
    def test_status_nonexistent_file_with_unversioned(self):
456
 
        # brz st [--short] NONEXISTENT A B UNVERSIONED_BUT_EXISTING C D E Q
 
420
        # bzr st [--short] NONEXISTENT A B UNVERSIONED_BUT_EXISTING C D E Q
457
421
        wt = self._prepare_nonexistent()
458
422
        expected = [
459
 
            'removed:\n',
460
 
            '  FILE_E\n',
461
 
            'added:\n',
462
 
            '  FILE_Q\n',
463
 
            'modified:\n',
464
 
            '  FILE_B\n',
465
 
            '  FILE_C\n',
466
 
            'unknown:\n',
467
 
            '  UNVERSIONED_BUT_EXISTING\n',
468
 
            'nonexistent:\n',
469
 
            '  NONEXISTENT\n',
470
 
            ]
 
423
          'removed:\n',
 
424
          '  FILE_E\n',
 
425
          'added:\n',
 
426
          '  FILE_Q\n',
 
427
          'modified:\n',
 
428
          '  FILE_B\n',
 
429
          '  FILE_C\n',
 
430
          'unknown:\n',
 
431
          '  UNVERSIONED_BUT_EXISTING\n',
 
432
          'nonexistent:\n',
 
433
          '  NONEXISTENT\n',
 
434
          ]
471
435
        out, err = self.run_bzr('status NONEXISTENT '
472
436
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
473
437
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
475
439
        self.assertContainsRe(err,
476
440
                              r'.*ERROR: Path\(s\) do not exist: '
477
441
                              'NONEXISTENT.*')
478
 
        expected = sorted([
479
 
            '+N  FILE_Q\n',
480
 
            '?   UNVERSIONED_BUT_EXISTING\n',
481
 
            ' D  FILE_E\n',
482
 
            ' M  FILE_C\n',
483
 
            ' M  FILE_B\n',
484
 
            'X   NONEXISTENT\n',
485
 
            ])
 
442
        expected = [
 
443
          '+N  FILE_Q\n',
 
444
          '?   UNVERSIONED_BUT_EXISTING\n',
 
445
          ' D  FILE_E\n',
 
446
          ' M  FILE_C\n',
 
447
          ' M  FILE_B\n',
 
448
          'X   NONEXISTENT\n',
 
449
          ]
486
450
        out, err = self.run_bzr('status --short NONEXISTENT '
487
451
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
488
452
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
489
 
        actual = out.splitlines(True)
490
 
        actual.sort()
491
 
        self.assertEqual(expected, actual)
 
453
        self.assertEqual(expected, out.splitlines(True))
492
454
        self.assertContainsRe(err,
493
455
                              r'.*ERROR: Path\(s\) do not exist: '
494
456
                              'NONEXISTENT.*')
496
458
    def test_status_out_of_date(self):
497
459
        """Simulate status of out-of-date tree after remote push"""
498
460
        tree = self.make_branch_and_tree('.')
499
 
        self.build_tree_contents([('a', b'foo\n')])
500
 
        with tree.lock_write():
 
461
        self.build_tree_contents([('a', 'foo\n')])
 
462
        tree.lock_write()
 
463
        try:
501
464
            tree.add(['a'])
502
465
            tree.commit('add test file')
503
466
            # simulate what happens after a remote push
504
 
            tree.set_last_revision(b"0")
 
467
            tree.set_last_revision("0")
 
468
        finally:
 
469
            # before run another commands we should unlock tree
 
470
            tree.unlock()
505
471
        out, err = self.run_bzr('status')
506
 
        self.assertEqual("working tree is out of date, run 'brz update'\n",
 
472
        self.assertEqual("working tree is out of date, run 'bzr update'\n",
507
473
                         err)
508
474
 
509
475
    def test_status_on_ignored(self):
517
483
        result = self.run_bzr('status')[0]
518
484
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
519
485
        short_result = self.run_bzr('status --short')[0]
520
 
        self.assertContainsRe(short_result, "\\?   test1.c\n")
 
486
        self.assertContainsRe(short_result, "\?   test1.c\n")
521
487
 
522
488
        result = self.run_bzr('status test1.c')[0]
523
489
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
524
490
        short_result = self.run_bzr('status --short test1.c')[0]
525
 
        self.assertContainsRe(short_result, "\\?   test1.c\n")
 
491
        self.assertContainsRe(short_result, "\?   test1.c\n")
526
492
 
527
493
        result = self.run_bzr('status test1.c~')[0]
528
494
        self.assertContainsRe(result, "ignored:\n  test1.c~\n")
535
501
        self.assertContainsRe(short_result, "I   test1.c~\nI   test2.c~\n")
536
502
 
537
503
        result = self.run_bzr('status test1.c test1.c~ test2.c~')[0]
538
 
        self.assertContainsRe(
539
 
            result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
540
 
        short_result = self.run_bzr(
541
 
            'status --short test1.c test1.c~ test2.c~')[0]
542
 
        self.assertContainsRe(
543
 
            short_result, "\\?   test1.c\nI   test1.c~\nI   test2.c~\n")
 
504
        self.assertContainsRe(result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
 
505
        short_result = self.run_bzr('status --short test1.c test1.c~ test2.c~')[0]
 
506
        self.assertContainsRe(short_result, "\?   test1.c\nI   test1.c~\nI   test2.c~\n")
544
507
 
545
508
    def test_status_write_lock(self):
546
509
        """Test that status works without fetching history and
552
515
        wt = self.make_branch_and_tree('branch1')
553
516
        b = wt.branch
554
517
        wt.commit('Empty commit 1')
555
 
        wt2 = b.controldir.sprout('branch2').open_workingtree()
 
518
        wt2 = b.bzrdir.sprout('branch2').open_workingtree()
556
519
        wt2.commit('Empty commit 2')
557
520
        out, err = self.run_bzr('status branch1 -rbranch:branch2')
558
521
        self.assertEqual('', out)
559
522
 
560
 
    def test_status_with_shelves(self):
561
 
        """Ensure that _show_shelve_summary handler works.
562
 
        """
563
 
        wt = self.make_branch_and_tree('.')
564
 
        self.build_tree(['hello.c'])
565
 
        wt.add('hello.c')
566
 
        self.run_bzr(['shelve', '--all', '-m', 'foo'])
567
 
        self.build_tree(['bye.c'])
568
 
        wt.add('bye.c')
569
 
        self.assertStatus([
570
 
            'added:\n',
571
 
            '  bye.c\n',
572
 
            '1 shelf exists. See "brz shelve --list" for details.\n',
573
 
            ],
574
 
            wt)
575
 
        self.run_bzr(['shelve', '--all', '-m', 'bar'])
576
 
        self.build_tree(['eggs.c', 'spam.c'])
577
 
        wt.add('eggs.c')
578
 
        wt.add('spam.c')
579
 
        self.assertStatus([
580
 
            'added:\n',
581
 
            '  eggs.c\n',
582
 
            '  spam.c\n',
583
 
            '2 shelves exist. See "brz shelve --list" for details.\n',
584
 
            ],
585
 
            wt)
586
 
        self.assertStatus([
587
 
            'added:\n',
588
 
            '  spam.c\n',
589
 
            ],
590
 
            wt,
591
 
            specific_files=['spam.c'])
592
 
 
593
523
 
594
524
class CheckoutStatus(BranchStatus):
595
525
 
601
531
    def make_branch_and_tree(self, relpath):
602
532
        source = self.make_branch(pathjoin('..', relpath))
603
533
        checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
604
 
        checkout.set_branch_reference(source)
 
534
        bzrlib.branch.BranchReferenceFormat().initialize(checkout,
 
535
            target_branch=source)
605
536
        return checkout.create_workingtree()
606
537
 
607
538
 
627
558
 
628
559
        self.build_tree(['world.txt'])
629
560
        result = self.run_bzr("status -r 0")[0]
630
 
        self.assertContainsRe(result, "added:\n  hello.txt\n"
 
561
        self.assertContainsRe(result, "added:\n  hello.txt\n" \
631
562
                                      "unknown:\n  world.txt\n")
632
563
        result2 = self.run_bzr("status -r 0..")[0]
633
 
        self.assertEqual(result2, result)
 
564
        self.assertEquals(result2, result)
634
565
 
635
566
    def test_status_short(self):
636
567
        tree = self.make_branch_and_tree('.')
648
579
        self.assertContainsRe(result, "[+]N  hello.txt\n")
649
580
 
650
581
        self.build_tree(['world.txt'])
651
 
        result = self.run_bzr("status -S -r 0")[0]
652
 
        self.assertContainsRe(result, "[+]N  hello.txt\n"
 
582
        result = self.run_bzr("status --short -r 0")[0]
 
583
        self.assertContainsRe(result, "[+]N  hello.txt\n" \
653
584
                                      "[?]   world.txt\n")
654
 
        result2 = self.run_bzr("status -S -r 0..")[0]
655
 
        self.assertEqual(result2, result)
 
585
        result2 = self.run_bzr("status --short -r 0..")[0]
 
586
        self.assertEquals(result2, result)
656
587
 
657
588
    def test_status_versioned(self):
658
589
        tree = self.make_branch_and_tree('.')
674
605
        self.assertContainsRe(result, "added:\n  hello.txt\n")
675
606
        self.assertNotContainsRe(result, "unknown:\n  world.txt\n")
676
607
        result2 = self.run_bzr("status --versioned -r 0..")[0]
677
 
        self.assertEqual(result2, result)
 
608
        self.assertEquals(result2, result)
678
609
 
679
610
    def test_status_SV(self):
680
611
        tree = self.make_branch_and_tree('.')
696
627
        self.assertContainsRe(result, "[+]N  hello.txt\n")
697
628
 
698
629
        result2 = self.run_bzr("status -SV -r 0..")[0]
699
 
        self.assertEqual(result2, result)
 
630
        self.assertEquals(result2, result)
700
631
 
701
632
    def assertStatusContains(self, pattern, short=False):
702
633
        """Run status, and assert it contains the given pattern"""
713
644
        tree.commit('added file')
714
645
        unlink('file')
715
646
        self.build_tree(['file/'])
716
 
        self.assertStatusContains(
717
 
            'kind changed:\n  file \\(file => directory\\)')
 
647
        self.assertStatusContains('kind changed:\n  file \(file => directory\)')
718
648
        tree.rename_one('file', 'directory')
719
 
        self.assertStatusContains('renamed:\n  file => directory/\n'
 
649
        self.assertStatusContains('renamed:\n  file/ => directory/\n' \
720
650
                                  'modified:\n  directory/\n')
721
651
        rmdir('directory')
722
652
        self.assertStatusContains('removed:\n  file\n')
729
659
        unlink('file')
730
660
        self.build_tree(['file/'])
731
661
        self.assertStatusContains('K  file => file/',
732
 
                                  short=True)
 
662
                                   short=True)
733
663
        tree.rename_one('file', 'directory')
734
664
        self.assertStatusContains('RK  file => directory/',
735
 
                                  short=True)
 
665
                                   short=True)
736
666
        rmdir('directory')
737
667
        self.assertStatusContains('RD  file => directory',
738
 
                                  short=True)
 
668
                                   short=True)
739
669
 
740
670
    def test_status_illegal_revision_specifiers(self):
741
671
        out, err = self.run_bzr('status -r 1..23..123', retcode=3)
746
676
        self.build_tree(['a/a'])
747
677
        a_tree.add('a')
748
678
        a_tree.commit('a')
749
 
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
 
679
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
750
680
        self.build_tree(['b/b'])
751
681
        b_tree.add('b')
752
682
        b_tree.commit('b')
753
683
 
754
684
        self.run_bzr('merge ../b', working_dir='a')
755
685
        out, err = self.run_bzr('status --no-pending', working_dir='a')
756
 
        self.assertEqual(out, "added:\n  b\n")
 
686
        self.assertEquals(out, "added:\n  b\n")
757
687
 
758
688
    def test_pending_specific_files(self):
759
689
        """With a specific file list, pending merges are not shown."""
760
690
        tree = self.make_branch_and_tree('tree')
761
 
        self.build_tree_contents([('tree/a', b'content of a\n')])
 
691
        self.build_tree_contents([('tree/a', 'content of a\n')])
762
692
        tree.add('a')
763
693
        r1_id = tree.commit('one')
764
 
        alt = tree.controldir.sprout('alt').open_workingtree()
765
 
        self.build_tree_contents([('alt/a', b'content of a\nfrom alt\n')])
 
694
        alt = tree.bzrdir.sprout('alt').open_workingtree()
 
695
        self.build_tree_contents([('alt/a', 'content of a\nfrom alt\n')])
766
696
        alt_id = alt.commit('alt')
767
697
        tree.merge_from_branch(alt.branch)
768
698
        output = self.make_utf8_encoded_stringio()
769
699
        show_tree_status(tree, to_file=output)
770
 
        self.assertContainsRe(output.getvalue(), b'pending merge')
 
700
        self.assertContainsRe(output.getvalue(), 'pending merge')
771
701
        out, err = self.run_bzr('status tree/a')
772
702
        self.assertNotContainsRe(out, 'pending merge')
773
703
 
774
704
 
775
705
class TestStatusEncodings(TestCaseWithTransport):
776
706
 
 
707
    def setUp(self):
 
708
        TestCaseWithTransport.setUp(self)
 
709
        self.user_encoding = osutils._cached_user_encoding
 
710
        self.stdout = sys.stdout
 
711
 
 
712
    def tearDown(self):
 
713
        osutils._cached_user_encoding = self.user_encoding
 
714
        sys.stdout = self.stdout
 
715
        TestCaseWithTransport.tearDown(self)
 
716
 
777
717
    def make_uncommitted_tree(self):
778
718
        """Build a branch with uncommitted unicode named changes in the cwd."""
779
719
        working_tree = self.make_branch_and_tree(u'.')
780
720
        filename = u'hell\u00d8'
781
721
        try:
782
 
            self.build_tree_contents([(filename, b'contents of hello')])
 
722
            self.build_tree_contents([(filename, 'contents of hello')])
783
723
        except UnicodeEncodeError:
784
724
            raise TestSkipped("can't build unicode working tree in "
785
 
                              "filesystem encoding %s" % sys.getfilesystemencoding())
 
725
                "filesystem encoding %s" % sys.getfilesystemencoding())
786
726
        working_tree.add(filename)
787
727
        return working_tree
788
728
 
789
729
    def test_stdout_ascii(self):
790
 
        self.overrideAttr(osutils, '_cached_user_encoding', 'ascii')
 
730
        sys.stdout = StringIO()
 
731
        osutils._cached_user_encoding = 'ascii'
791
732
        working_tree = self.make_uncommitted_tree()
792
733
        stdout, stderr = self.run_bzr("status")
793
734
 
794
 
        self.assertEqual(stdout, """\
 
735
        self.assertEquals(stdout, """\
795
736
added:
796
737
  hell?
797
738
""")
798
739
 
799
740
    def test_stdout_latin1(self):
800
 
        self.overrideAttr(osutils, '_cached_user_encoding', 'latin-1')
 
741
        sys.stdout = StringIO()
 
742
        osutils._cached_user_encoding = 'latin-1'
801
743
        working_tree = self.make_uncommitted_tree()
802
744
        stdout, stderr = self.run_bzr('status')
803
745
 
804
 
        expected = u"""\
 
746
        self.assertEquals(stdout, u"""\
805
747
added:
806
748
  hell\u00d8
807
 
"""
808
 
        if not PY3:
809
 
            expected = expected.encode('latin-1')
810
 
        self.assertEqual(stdout, expected)
 
749
""".encode('latin-1'))
 
750