/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-11 08:36:16 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100511083616-b8fjb19zomwupid0
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.

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,
 
33
    conflicts,
30
34
    errors,
31
35
    osutils,
32
 
    status,
33
 
    )
34
 
from breezy.bzr import (
35
 
    bzrdir,
36
 
    conflicts,
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('.')
298
265
        self.build_tree(['dir2/'])
299
266
        tree.add('dir2')
300
267
        tree.commit('added dir2')
301
 
        tree.set_conflicts([conflicts.ContentsConflict('foo')])
302
 
        tof = BytesIO()
 
268
        tree.set_conflicts(conflicts.ConflictList(
 
269
            [conflicts.ContentsConflict('foo')]))
 
270
        tof = StringIO()
303
271
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
304
 
        self.assertEqualDiff(b'', tof.getvalue())
305
 
        tree.set_conflicts([conflicts.ContentsConflict('dir2')])
 
272
        self.assertEqualDiff('', tof.getvalue())
 
273
        tree.set_conflicts(conflicts.ConflictList(
 
274
            [conflicts.ContentsConflict('dir2')]))
306
275
        tof = StringIO()
307
276
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
308
277
        self.assertEqualDiff('conflicts:\n  Contents conflict in dir2\n',
309
278
                             tof.getvalue())
310
279
 
311
 
        tree.set_conflicts([conflicts.ContentsConflict('dir2/file1')])
 
280
        tree.set_conflicts(conflicts.ConflictList(
 
281
            [conflicts.ContentsConflict('dir2/file1')]))
312
282
        tof = StringIO()
313
283
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
314
284
        self.assertEqualDiff('conflicts:\n  Contents conflict in dir2/file1\n',
324
294
        wt.add('FILE_D')
325
295
        wt.add('FILE_E')
326
296
        wt.commit('Create five empty files.')
327
 
        with open('FILE_B', 'w') as f:
328
 
            f.write('Modification to file FILE_B.')
329
 
        with open('FILE_C', 'w') as f:
330
 
            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.')
331
299
        unlink('FILE_E')  # FILE_E will be versioned but missing
332
 
        with open('FILE_Q', 'w') as f:
333
 
            f.write('FILE_Q is added but not committed.')
 
300
        open('FILE_Q', 'w').write('FILE_Q is added but not committed.')
334
301
        wt.add('FILE_Q')  # FILE_Q will be added but not committed
335
302
        open('UNVERSIONED_BUT_EXISTING', 'w')
336
303
        return wt
363
330
        # Okay, everything's looking good with the existent files.
364
331
        # Let's see what happens when we throw in non-existent files.
365
332
 
366
 
        # brz st [--short] NONEXISTENT '
 
333
        # bzr st [--short] NONEXISTENT '
367
334
        expected = [
368
 
            'nonexistent:\n',
369
 
            '  NONEXISTENT\n',
370
 
            ]
 
335
          'nonexistent:\n',
 
336
          '  NONEXISTENT\n',
 
337
          ]
371
338
        out, err = self.run_bzr('status NONEXISTENT', retcode=3)
372
339
        self.assertEqual(expected, out.splitlines(True))
373
340
        self.assertContainsRe(err,
374
341
                              r'.*ERROR: Path\(s\) do not exist: '
375
342
                              'NONEXISTENT.*')
376
343
        expected = [
377
 
            'X:   NONEXISTENT\n',
378
 
            ]
 
344
          'X:   NONEXISTENT\n',
 
345
          ]
379
346
        out, err = self.run_bzr('status --short NONEXISTENT', retcode=3)
380
347
        self.assertContainsRe(err,
381
348
                              r'.*ERROR: Path\(s\) do not exist: '
382
349
                              'NONEXISTENT.*')
383
350
 
384
351
    def test_status_nonexistent_file_with_others(self):
385
 
        # brz st [--short] NONEXISTENT ...others..
 
352
        # bzr st [--short] NONEXISTENT ...others..
386
353
        wt = self._prepare_nonexistent()
387
354
        expected = [
388
 
            'removed:\n',
389
 
            '  FILE_E\n',
390
 
            'modified:\n',
391
 
            '  FILE_B\n',
392
 
            '  FILE_C\n',
393
 
            'nonexistent:\n',
394
 
            '  NONEXISTENT\n',
395
 
            ]
 
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
          ]
396
363
        out, err = self.run_bzr('status NONEXISTENT '
397
364
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
398
365
                                retcode=3)
401
368
                              r'.*ERROR: Path\(s\) do not exist: '
402
369
                              'NONEXISTENT.*')
403
370
        expected = [
404
 
            ' M  FILE_B\n',
405
 
            ' M  FILE_C\n',
406
 
            ' D  FILE_E\n',
407
 
            'X   NONEXISTENT\n',
408
 
            ]
 
371
          ' D  FILE_E\n',
 
372
          ' M  FILE_C\n',
 
373
          ' M  FILE_B\n',
 
374
          'X   NONEXISTENT\n',
 
375
          ]
409
376
        out, err = self.run_bzr('status --short NONEXISTENT '
410
377
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
411
378
                                retcode=3)
415
382
                              'NONEXISTENT.*')
416
383
 
417
384
    def test_status_multiple_nonexistent_files(self):
418
 
        # brz st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
 
385
        # bzr st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
419
386
        wt = self._prepare_nonexistent()
420
387
        expected = [
421
 
            'removed:\n',
422
 
            '  FILE_E\n',
423
 
            'modified:\n',
424
 
            '  FILE_B\n',
425
 
            '  FILE_C\n',
426
 
            'nonexistent:\n',
427
 
            '  ANOTHER_NONEXISTENT\n',
428
 
            '  NONEXISTENT\n',
429
 
            ]
 
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
          ]
430
397
        out, err = self.run_bzr('status NONEXISTENT '
431
398
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
432
399
                                'FILE_C FILE_D FILE_E', retcode=3)
435
402
                              r'.*ERROR: Path\(s\) do not exist: '
436
403
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
437
404
        expected = [
438
 
            ' M  FILE_B\n',
439
 
            ' M  FILE_C\n',
440
 
            ' D  FILE_E\n',
441
 
            'X   ANOTHER_NONEXISTENT\n',
442
 
            'X   NONEXISTENT\n',
443
 
            ]
 
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
          ]
444
411
        out, err = self.run_bzr('status --short NONEXISTENT '
445
412
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
446
413
                                'FILE_C FILE_D FILE_E', retcode=3)
450
417
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
451
418
 
452
419
    def test_status_nonexistent_file_with_unversioned(self):
453
 
        # 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
454
421
        wt = self._prepare_nonexistent()
455
422
        expected = [
456
 
            'removed:\n',
457
 
            '  FILE_E\n',
458
 
            'added:\n',
459
 
            '  FILE_Q\n',
460
 
            'modified:\n',
461
 
            '  FILE_B\n',
462
 
            '  FILE_C\n',
463
 
            'unknown:\n',
464
 
            '  UNVERSIONED_BUT_EXISTING\n',
465
 
            'nonexistent:\n',
466
 
            '  NONEXISTENT\n',
467
 
            ]
 
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
          ]
468
435
        out, err = self.run_bzr('status NONEXISTENT '
469
436
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
470
437
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
472
439
        self.assertContainsRe(err,
473
440
                              r'.*ERROR: Path\(s\) do not exist: '
474
441
                              'NONEXISTENT.*')
475
 
        expected = sorted([
476
 
            '+N  FILE_Q\n',
477
 
            '?   UNVERSIONED_BUT_EXISTING\n',
478
 
            ' D  FILE_E\n',
479
 
            ' M  FILE_C\n',
480
 
            ' M  FILE_B\n',
481
 
            'X   NONEXISTENT\n',
482
 
            ])
 
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
          ]
483
450
        out, err = self.run_bzr('status --short NONEXISTENT '
484
451
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
485
452
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
486
 
        actual = out.splitlines(True)
487
 
        actual.sort()
488
 
        self.assertEqual(expected, actual)
 
453
        self.assertEqual(expected, out.splitlines(True))
489
454
        self.assertContainsRe(err,
490
455
                              r'.*ERROR: Path\(s\) do not exist: '
491
456
                              'NONEXISTENT.*')
493
458
    def test_status_out_of_date(self):
494
459
        """Simulate status of out-of-date tree after remote push"""
495
460
        tree = self.make_branch_and_tree('.')
496
 
        self.build_tree_contents([('a', b'foo\n')])
497
 
        with tree.lock_write():
 
461
        self.build_tree_contents([('a', 'foo\n')])
 
462
        tree.lock_write()
 
463
        try:
498
464
            tree.add(['a'])
499
465
            tree.commit('add test file')
500
466
            # simulate what happens after a remote push
501
 
            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()
502
471
        out, err = self.run_bzr('status')
503
 
        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",
504
473
                         err)
505
474
 
506
475
    def test_status_on_ignored(self):
514
483
        result = self.run_bzr('status')[0]
515
484
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
516
485
        short_result = self.run_bzr('status --short')[0]
517
 
        self.assertContainsRe(short_result, "\\?   test1.c\n")
 
486
        self.assertContainsRe(short_result, "\?   test1.c\n")
518
487
 
519
488
        result = self.run_bzr('status test1.c')[0]
520
489
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
521
490
        short_result = self.run_bzr('status --short test1.c')[0]
522
 
        self.assertContainsRe(short_result, "\\?   test1.c\n")
 
491
        self.assertContainsRe(short_result, "\?   test1.c\n")
523
492
 
524
493
        result = self.run_bzr('status test1.c~')[0]
525
494
        self.assertContainsRe(result, "ignored:\n  test1.c~\n")
532
501
        self.assertContainsRe(short_result, "I   test1.c~\nI   test2.c~\n")
533
502
 
534
503
        result = self.run_bzr('status test1.c test1.c~ test2.c~')[0]
535
 
        self.assertContainsRe(
536
 
            result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
537
 
        short_result = self.run_bzr(
538
 
            'status --short test1.c test1.c~ test2.c~')[0]
539
 
        self.assertContainsRe(
540
 
            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")
541
507
 
542
508
    def test_status_write_lock(self):
543
509
        """Test that status works without fetching history and
549
515
        wt = self.make_branch_and_tree('branch1')
550
516
        b = wt.branch
551
517
        wt.commit('Empty commit 1')
552
 
        wt2 = b.controldir.sprout('branch2').open_workingtree()
 
518
        wt2 = b.bzrdir.sprout('branch2').open_workingtree()
553
519
        wt2.commit('Empty commit 2')
554
520
        out, err = self.run_bzr('status branch1 -rbranch:branch2')
555
521
        self.assertEqual('', out)
556
522
 
557
 
    def test_status_with_shelves(self):
558
 
        """Ensure that _show_shelve_summary handler works.
559
 
        """
560
 
        wt = self.make_branch_and_tree('.')
561
 
        self.build_tree(['hello.c'])
562
 
        wt.add('hello.c')
563
 
        self.run_bzr(['shelve', '--all', '-m', 'foo'])
564
 
        self.build_tree(['bye.c'])
565
 
        wt.add('bye.c')
566
 
        self.assertStatus([
567
 
            'added:\n',
568
 
            '  bye.c\n',
569
 
            '1 shelf exists. See "brz shelve --list" for details.\n',
570
 
            ],
571
 
            wt)
572
 
        self.run_bzr(['shelve', '--all', '-m', 'bar'])
573
 
        self.build_tree(['eggs.c', 'spam.c'])
574
 
        wt.add('eggs.c')
575
 
        wt.add('spam.c')
576
 
        self.assertStatus([
577
 
            'added:\n',
578
 
            '  eggs.c\n',
579
 
            '  spam.c\n',
580
 
            '2 shelves exist. See "brz shelve --list" for details.\n',
581
 
            ],
582
 
            wt)
583
 
        self.assertStatus([
584
 
            'added:\n',
585
 
            '  spam.c\n',
586
 
            ],
587
 
            wt,
588
 
            specific_files=['spam.c'])
589
 
 
590
523
 
591
524
class CheckoutStatus(BranchStatus):
592
525
 
598
531
    def make_branch_and_tree(self, relpath):
599
532
        source = self.make_branch(pathjoin('..', relpath))
600
533
        checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
601
 
        checkout.set_branch_reference(source)
 
534
        bzrlib.branch.BranchReferenceFormat().initialize(checkout,
 
535
            target_branch=source)
602
536
        return checkout.create_workingtree()
603
537
 
604
538
 
624
558
 
625
559
        self.build_tree(['world.txt'])
626
560
        result = self.run_bzr("status -r 0")[0]
627
 
        self.assertContainsRe(result, "added:\n  hello.txt\n"
 
561
        self.assertContainsRe(result, "added:\n  hello.txt\n" \
628
562
                                      "unknown:\n  world.txt\n")
629
563
        result2 = self.run_bzr("status -r 0..")[0]
630
 
        self.assertEqual(result2, result)
 
564
        self.assertEquals(result2, result)
631
565
 
632
566
    def test_status_short(self):
633
567
        tree = self.make_branch_and_tree('.')
645
579
        self.assertContainsRe(result, "[+]N  hello.txt\n")
646
580
 
647
581
        self.build_tree(['world.txt'])
648
 
        result = self.run_bzr("status -S -r 0")[0]
649
 
        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" \
650
584
                                      "[?]   world.txt\n")
651
 
        result2 = self.run_bzr("status -S -r 0..")[0]
652
 
        self.assertEqual(result2, result)
 
585
        result2 = self.run_bzr("status --short -r 0..")[0]
 
586
        self.assertEquals(result2, result)
653
587
 
654
588
    def test_status_versioned(self):
655
589
        tree = self.make_branch_and_tree('.')
671
605
        self.assertContainsRe(result, "added:\n  hello.txt\n")
672
606
        self.assertNotContainsRe(result, "unknown:\n  world.txt\n")
673
607
        result2 = self.run_bzr("status --versioned -r 0..")[0]
674
 
        self.assertEqual(result2, result)
 
608
        self.assertEquals(result2, result)
675
609
 
676
610
    def test_status_SV(self):
677
611
        tree = self.make_branch_and_tree('.')
693
627
        self.assertContainsRe(result, "[+]N  hello.txt\n")
694
628
 
695
629
        result2 = self.run_bzr("status -SV -r 0..")[0]
696
 
        self.assertEqual(result2, result)
 
630
        self.assertEquals(result2, result)
697
631
 
698
632
    def assertStatusContains(self, pattern, short=False):
699
633
        """Run status, and assert it contains the given pattern"""
710
644
        tree.commit('added file')
711
645
        unlink('file')
712
646
        self.build_tree(['file/'])
713
 
        self.assertStatusContains(
714
 
            'kind changed:\n  file \\(file => directory\\)')
 
647
        self.assertStatusContains('kind changed:\n  file \(file => directory\)')
715
648
        tree.rename_one('file', 'directory')
716
 
        self.assertStatusContains('renamed:\n  file => directory/\n'
 
649
        self.assertStatusContains('renamed:\n  file/ => directory/\n' \
717
650
                                  'modified:\n  directory/\n')
718
651
        rmdir('directory')
719
652
        self.assertStatusContains('removed:\n  file\n')
726
659
        unlink('file')
727
660
        self.build_tree(['file/'])
728
661
        self.assertStatusContains('K  file => file/',
729
 
                                  short=True)
 
662
                                   short=True)
730
663
        tree.rename_one('file', 'directory')
731
664
        self.assertStatusContains('RK  file => directory/',
732
 
                                  short=True)
 
665
                                   short=True)
733
666
        rmdir('directory')
734
667
        self.assertStatusContains('RD  file => directory',
735
 
                                  short=True)
 
668
                                   short=True)
736
669
 
737
670
    def test_status_illegal_revision_specifiers(self):
738
671
        out, err = self.run_bzr('status -r 1..23..123', retcode=3)
743
676
        self.build_tree(['a/a'])
744
677
        a_tree.add('a')
745
678
        a_tree.commit('a')
746
 
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
 
679
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
747
680
        self.build_tree(['b/b'])
748
681
        b_tree.add('b')
749
682
        b_tree.commit('b')
750
683
 
751
684
        self.run_bzr('merge ../b', working_dir='a')
752
685
        out, err = self.run_bzr('status --no-pending', working_dir='a')
753
 
        self.assertEqual(out, "added:\n  b\n")
 
686
        self.assertEquals(out, "added:\n  b\n")
754
687
 
755
688
    def test_pending_specific_files(self):
756
689
        """With a specific file list, pending merges are not shown."""
757
690
        tree = self.make_branch_and_tree('tree')
758
 
        self.build_tree_contents([('tree/a', b'content of a\n')])
 
691
        self.build_tree_contents([('tree/a', 'content of a\n')])
759
692
        tree.add('a')
760
693
        r1_id = tree.commit('one')
761
 
        alt = tree.controldir.sprout('alt').open_workingtree()
762
 
        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')])
763
696
        alt_id = alt.commit('alt')
764
697
        tree.merge_from_branch(alt.branch)
765
698
        output = self.make_utf8_encoded_stringio()
766
699
        show_tree_status(tree, to_file=output)
767
 
        self.assertContainsRe(output.getvalue(), b'pending merge')
 
700
        self.assertContainsRe(output.getvalue(), 'pending merge')
768
701
        out, err = self.run_bzr('status tree/a')
769
702
        self.assertNotContainsRe(out, 'pending merge')
770
703
 
771
704
 
772
705
class TestStatusEncodings(TestCaseWithTransport):
773
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
 
774
717
    def make_uncommitted_tree(self):
775
718
        """Build a branch with uncommitted unicode named changes in the cwd."""
776
719
        working_tree = self.make_branch_and_tree(u'.')
777
720
        filename = u'hell\u00d8'
778
721
        try:
779
 
            self.build_tree_contents([(filename, b'contents of hello')])
 
722
            self.build_tree_contents([(filename, 'contents of hello')])
780
723
        except UnicodeEncodeError:
781
724
            raise TestSkipped("can't build unicode working tree in "
782
 
                              "filesystem encoding %s" % sys.getfilesystemencoding())
 
725
                "filesystem encoding %s" % sys.getfilesystemencoding())
783
726
        working_tree.add(filename)
784
727
        return working_tree
785
728
 
786
729
    def test_stdout_ascii(self):
787
 
        self.overrideAttr(osutils, '_cached_user_encoding', 'ascii')
 
730
        sys.stdout = StringIO()
 
731
        osutils._cached_user_encoding = 'ascii'
788
732
        working_tree = self.make_uncommitted_tree()
789
733
        stdout, stderr = self.run_bzr("status")
790
734
 
791
 
        self.assertEqual(stdout, """\
 
735
        self.assertEquals(stdout, """\
792
736
added:
793
737
  hell?
794
738
""")
795
739
 
796
740
    def test_stdout_latin1(self):
797
 
        self.overrideAttr(osutils, '_cached_user_encoding', 'latin-1')
 
741
        sys.stdout = StringIO()
 
742
        osutils._cached_user_encoding = 'latin-1'
798
743
        working_tree = self.make_uncommitted_tree()
799
744
        stdout, stderr = self.run_bzr('status')
800
745
 
801
 
        expected = u"""\
 
746
        self.assertEquals(stdout, u"""\
802
747
added:
803
748
  hell\u00d8
804
 
"""
805
 
        if not PY3:
806
 
            expected = expected.encode('latin-1')
807
 
        self.assertEqual(stdout, expected)
 
749
""".encode('latin-1'))
 
750