22
22
interface later, they will be non blackbox tests.
25
from cStringIO import StringIO
27
26
from os import mkdir, chdir, rmdir, unlink
29
from tempfile import TemporaryFile
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
35
from breezy.bzr import (
39
from ...osutils import pathjoin
40
from ...revisionspec import RevisionSpec
41
from ...sixish import (
46
from ...status import show_tree_status
47
from .. import TestCaseWithTransport, TestSkipped
48
from ...workingtree import WorkingTree
45
51
class BranchStatus(TestCaseWithTransport):
47
def assertStatus(self, expected_lines, working_tree,
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,
61
def assertStatus(self, expected_lines, working_tree, specific_files=None,
48
62
revision=None, short=False, pending=True, verbose=False):
49
63
"""Run status in working_tree and look for output.
51
65
:param expected_lines: The lines to look for.
52
66
:param working_tree: The tree to run status in.
54
output_string = self.status_string(working_tree, revision, short,
68
output_string = self.status_string(working_tree, specific_files, revision, short,
56
70
self.assertEqual(expected_lines, output_string.splitlines(True))
58
def status_string(self, wt, revision=None, short=False, pending=True,
60
# use a real file rather than StringIO because it doesn't handle
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)
66
return tof.read().decode('utf-8')
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,
78
return uio.getvalue().decode('utf-8')
68
80
def test_branch_status(self):
69
81
"""Test basic branch status"""
218
236
self.assertStatus([
221
'? directory/hello.c\n'
239
'? directory/hello.c\n',
226
245
self.assertRaises(errors.PathsDoNotExist,
227
246
show_tree_status,
228
wt, specific_files=['bye.c','test.c','absent.c'],
247
wt, specific_files=['bye.c', 'test.c', 'absent.c'],
232
251
show_tree_status(wt, specific_files=['directory'], to_file=tof)
234
self.assertEquals(tof.readlines(),
253
self.assertEqual(tof.readlines(),
236
255
' directory/hello.c\n'
239
258
show_tree_status(wt, specific_files=['directory'], to_file=tof,
242
self.assertEquals(tof.readlines(), ['? directory/hello.c\n'])
261
self.assertEqual(tof.readlines(), ['? directory/hello.c\n'])
245
264
show_tree_status(wt, specific_files=['dir2'], to_file=tof)
247
self.assertEquals(tof.readlines(),
266
self.assertEqual(tof.readlines(),
252
271
show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
254
self.assertEquals(tof.readlines(), ['? dir2/\n'])
273
self.assertEqual(tof.readlines(), ['? dir2/\n'])
257
276
revs = [RevisionSpec.from_string('0'), RevisionSpec.from_string('1')]
258
277
show_tree_status(wt, specific_files=['test.c'], to_file=tof,
259
278
short=True, revision=revs)
261
self.assertEquals(tof.readlines(), ['+N test.c\n'])
280
self.assertEqual(tof.readlines(), ['+N test.c\n'])
283
show_tree_status(wt, specific_files=['missing.c'], to_file=tof)
285
self.assertEqual(tof.readlines(),
290
show_tree_status(wt, specific_files=['missing.c'], to_file=tof,
293
self.assertEqual(tof.readlines(),
263
296
def test_specific_files_conflicts(self):
264
297
tree = self.make_branch_and_tree('.')
296
329
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.')
330
with open('FILE_B', 'w') as f: f.write('Modification to file FILE_B.')
331
with open('FILE_C', 'w') as f: f.write('Modification to file FILE_C.')
299
332
unlink('FILE_E') # FILE_E will be versioned but missing
300
open('FILE_Q', 'w').write('FILE_Q is added but not committed.')
333
with open('FILE_Q', 'w') as f: f.write('FILE_Q is added but not committed.')
301
334
wt.add('FILE_Q') # FILE_Q will be added but not committed
302
335
open('UNVERSIONED_BUT_EXISTING', 'w')
439
472
self.assertContainsRe(err,
440
473
r'.*ERROR: Path\(s\) do not exist: '
444
477
'? UNVERSIONED_BUT_EXISTING\n',
448
481
'X NONEXISTENT\n',
450
483
out, err = self.run_bzr('status --short NONEXISTENT '
451
484
'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
452
485
'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
453
self.assertEqual(expected, out.splitlines(True))
486
actual = out.splitlines(True)
488
self.assertEqual(expected, actual)
454
489
self.assertContainsRe(err,
455
490
r'.*ERROR: Path\(s\) do not exist: '
458
493
def test_status_out_of_date(self):
459
494
"""Simulate status of out-of-date tree after remote push"""
460
495
tree = self.make_branch_and_tree('.')
461
self.build_tree_contents([('a', 'foo\n')])
496
self.build_tree_contents([('a', b'foo\n')])
462
497
tree.lock_write()
465
500
tree.commit('add test file')
466
501
# simulate what happens after a remote push
467
tree.set_last_revision("0")
502
tree.set_last_revision(b"0")
469
504
# before run another commands we should unlock tree
471
506
out, err = self.run_bzr('status')
472
self.assertEqual("working tree is out of date, run 'bzr update'\n",
507
self.assertEqual("working tree is out of date, run 'brz update'\n",
475
510
def test_status_on_ignored(self):
483
518
result = self.run_bzr('status')[0]
484
519
self.assertContainsRe(result, "unknown:\n test1.c\n")
485
520
short_result = self.run_bzr('status --short')[0]
486
self.assertContainsRe(short_result, "\? test1.c\n")
521
self.assertContainsRe(short_result, "\\? test1.c\n")
488
523
result = self.run_bzr('status test1.c')[0]
489
524
self.assertContainsRe(result, "unknown:\n test1.c\n")
490
525
short_result = self.run_bzr('status --short test1.c')[0]
491
self.assertContainsRe(short_result, "\? test1.c\n")
526
self.assertContainsRe(short_result, "\\? test1.c\n")
493
528
result = self.run_bzr('status test1.c~')[0]
494
529
self.assertContainsRe(result, "ignored:\n test1.c~\n")
515
550
wt = self.make_branch_and_tree('branch1')
517
552
wt.commit('Empty commit 1')
518
wt2 = b.bzrdir.sprout('branch2').open_workingtree()
553
wt2 = b.controldir.sprout('branch2').open_workingtree()
519
554
wt2.commit('Empty commit 2')
520
555
out, err = self.run_bzr('status branch1 -rbranch:branch2')
521
556
self.assertEqual('', out)
558
def test_status_with_shelves(self):
559
"""Ensure that _show_shelve_summary handler works.
561
wt = self.make_branch_and_tree('.')
562
self.build_tree(['hello.c'])
564
self.run_bzr(['shelve', '--all', '-m', 'foo'])
565
self.build_tree(['bye.c'])
570
'1 shelf exists. See "brz shelve --list" for details.\n',
573
self.run_bzr(['shelve', '--all', '-m', 'bar'])
574
self.build_tree(['eggs.c', 'spam.c'])
581
'2 shelves exist. See "brz shelve --list" for details.\n',
589
specific_files=['spam.c'])
524
592
class CheckoutStatus(BranchStatus):
579
646
self.assertContainsRe(result, "[+]N hello.txt\n")
581
648
self.build_tree(['world.txt'])
582
result = self.run_bzr("status --short -r 0")[0]
649
result = self.run_bzr("status -S -r 0")[0]
583
650
self.assertContainsRe(result, "[+]N hello.txt\n" \
584
651
"[?] world.txt\n")
585
result2 = self.run_bzr("status --short -r 0..")[0]
586
self.assertEquals(result2, result)
652
result2 = self.run_bzr("status -S -r 0..")[0]
653
self.assertEqual(result2, result)
588
655
def test_status_versioned(self):
589
656
tree = self.make_branch_and_tree('.')
676
743
self.build_tree(['a/a'])
678
745
a_tree.commit('a')
679
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
746
b_tree = a_tree.controldir.sprout('b').open_workingtree()
680
747
self.build_tree(['b/b'])
682
749
b_tree.commit('b')
684
751
self.run_bzr('merge ../b', working_dir='a')
685
752
out, err = self.run_bzr('status --no-pending', working_dir='a')
686
self.assertEquals(out, "added:\n b\n")
753
self.assertEqual(out, "added:\n b\n")
688
755
def test_pending_specific_files(self):
689
756
"""With a specific file list, pending merges are not shown."""
690
757
tree = self.make_branch_and_tree('tree')
691
self.build_tree_contents([('tree/a', 'content of a\n')])
758
self.build_tree_contents([('tree/a', b'content of a\n')])
693
760
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')])
761
alt = tree.controldir.sprout('alt').open_workingtree()
762
self.build_tree_contents([('alt/a', b'content of a\nfrom alt\n')])
696
763
alt_id = alt.commit('alt')
697
764
tree.merge_from_branch(alt.branch)
698
765
output = self.make_utf8_encoded_stringio()
699
766
show_tree_status(tree, to_file=output)
700
self.assertContainsRe(output.getvalue(), 'pending merge')
767
self.assertContainsRe(output.getvalue(), b'pending merge')
701
768
out, err = self.run_bzr('status tree/a')
702
769
self.assertNotContainsRe(out, 'pending merge')
705
772
class TestStatusEncodings(TestCaseWithTransport):
708
TestCaseWithTransport.setUp(self)
709
self.user_encoding = osutils._cached_user_encoding
710
self.stdout = sys.stdout
713
osutils._cached_user_encoding = self.user_encoding
714
sys.stdout = self.stdout
715
TestCaseWithTransport.tearDown(self)
717
774
def make_uncommitted_tree(self):
718
775
"""Build a branch with uncommitted unicode named changes in the cwd."""
719
776
working_tree = self.make_branch_and_tree(u'.')
720
777
filename = u'hell\u00d8'
722
self.build_tree_contents([(filename, 'contents of hello')])
779
self.build_tree_contents([(filename, b'contents of hello')])
723
780
except UnicodeEncodeError:
724
781
raise TestSkipped("can't build unicode working tree in "
725
782
"filesystem encoding %s" % sys.getfilesystemencoding())
727
784
return working_tree
729
786
def test_stdout_ascii(self):
730
sys.stdout = StringIO()
731
osutils._cached_user_encoding = 'ascii'
787
self.overrideAttr(osutils, '_cached_user_encoding', 'ascii')
732
788
working_tree = self.make_uncommitted_tree()
733
789
stdout, stderr = self.run_bzr("status")
735
self.assertEquals(stdout, """\
791
self.assertEqual(stdout, """\
740
796
def test_stdout_latin1(self):
741
sys.stdout = StringIO()
742
osutils._cached_user_encoding = 'latin-1'
797
self.overrideAttr(osutils, '_cached_user_encoding', 'latin-1')
743
798
working_tree = self.make_uncommitted_tree()
744
799
stdout, stderr = self.run_bzr('status')
746
self.assertEquals(stdout, u"""\
749
""".encode('latin-1'))
806
expected = expected.encode('latin-1')
807
self.assertEqual(stdout, expected)