/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: 2018-07-08 14:45:27 UTC
  • mto: This revision was merged to the branch mainline in revision 7036.
  • Revision ID: jelmer@jelmer.uk-20180708144527-codhlvdcdg9y0nji
Fix a bunch of merge tests.

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