/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 breezy/tests/blackbox/test_status.py

  • Committer: Jelmer Vernooij
  • Date: 2020-05-24 00:42:36 UTC
  • mto: This revision was merged to the branch mainline in revision 7505.
  • Revision ID: jelmer@jelmer.uk-20200524004236-jdj6obo4k5lznqw2
Cleanup Windows functions.

Show diffs side-by-side

added added

removed removed

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