22
23
interface later, they will be non blackbox tests.
25
27
from cStringIO import StringIO
28
from os import mkdir, chdir
29
from tempfile import TemporaryFile
27
from os import mkdir, chdir, rmdir, unlink
29
from tempfile import TemporaryFile
36
32
import bzrlib.branch
33
from bzrlib.builtins import merge
34
import bzrlib.bzrdir as bzrdir
35
import bzrlib.errors as errors
37
36
from bzrlib.osutils import pathjoin
38
37
from bzrlib.revisionspec import RevisionSpec
39
38
from bzrlib.status import show_tree_status
40
from bzrlib.tests import TestCaseWithTransport, TestSkipped
39
from bzrlib.tests import TestCaseWithTransport
41
40
from bzrlib.workingtree import WorkingTree
44
43
class BranchStatus(TestCaseWithTransport):
46
def assertStatus(self, expected_lines, working_tree,
47
revision=None, short=False, pending=True):
48
"""Run status in working_tree and look for output.
50
:param expected_lines: The lines to look for.
51
:param working_tree: The tree to run status in.
53
output_string = self.status_string(working_tree, revision, short,
55
self.assertEqual(expected_lines, output_string.splitlines(True))
57
def status_string(self, wt, revision=None, short=False, pending=True):
58
# use a real file rather than StringIO because it doesn't handle
60
tof = codecs.getwriter('utf-8')(TemporaryFile())
61
show_tree_status(wt, to_file=tof, revision=revision, short=short,
64
return tof.read().decode('utf-8')
66
def test_branch_status(self):
45
def test_branch_status(self):
67
46
"""Test basic branch status"""
68
47
wt = self.make_branch_and_tree('.')
70
# status with no commits or files - it must
71
# work and show no output. We do this with no
72
# commits to be sure that it's not going to fail
74
self.assertStatus([], wt)
52
show_tree_status(wt, to_file=tof)
53
self.assertEquals(tof.getvalue(), "")
76
56
self.build_tree(['hello.c', 'bye.c'])
89
# add a commit to allow showing pending merges.
90
wt.commit('create a parent to allow testing merge output')
92
wt.add_parent_tree_id('pending@pending-0-0')
98
' (ghost) pending@pending-0-0\n',
104
'P (ghost) pending@pending-0-0\n',
117
wt, short=True, pending=False)
57
wt.add_pending_merge('pending@pending-0-0')
58
show_tree_status(wt, to_file=tof)
60
self.assertEquals(tof.readlines(),
65
' pending@pending-0-0\n'
119
68
def test_branch_status_revisions(self):
120
69
"""Tests branch status with revisions"""
121
70
wt = self.make_branch_and_tree('.')
123
74
self.build_tree(['hello.c', 'bye.c'])
126
77
wt.commit('Test message')
128
revs = [RevisionSpec.from_string('0')]
81
revs.append(RevisionSpec(0))
83
show_tree_status(wt, to_file=tof, revision=revs)
86
self.assertEquals(tof.readlines(),
137
91
self.build_tree(['more.c'])
139
93
wt.commit('Another test message')
141
revs.append(RevisionSpec.from_string('1'))
96
revs.append(RevisionSpec(1))
98
show_tree_status(wt, to_file=tof, revision=revs)
101
self.assertEquals(tof.readlines(),
106
def status_string(self, wt):
107
# use a real file rather than StringIO because it doesn't handle
109
tof = codecs.getwriter('utf-8')(TemporaryFile())
110
show_tree_status(wt, to_file=tof)
112
return tof.read().decode('utf-8')
150
114
def test_pending(self):
151
115
"""Pending merges display works, including Unicode"""
157
121
b_2 = b_2_dir.open_branch()
158
122
wt2 = b_2_dir.open_workingtree()
159
123
wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
160
wt2.merge_from_branch(wt.branch)
124
merge(["./branch", -1], [None, None], this_dir = './copy')
161
125
message = self.status_string(wt2)
162
self.assertStartsWith(message, "pending merges:\n")
163
self.assertEndsWith(message, "Empty commit 2\n")
126
self.assert_(message.startswith("pending merges:\n"))
127
self.assert_(message.endswith("Empty commit 2\n"))
164
128
wt2.commit("merged")
165
129
# must be long to make sure we see elipsis at the end
166
wt.commit("Empty commit 3 " +
167
"blah blah blah blah " * 100)
168
wt2.merge_from_branch(wt.branch)
130
wt.commit("Empty commit 3 " +
131
"blah blah blah blah " * 10)
132
merge(["./branch", -1], [None, None], this_dir = './copy')
169
133
message = self.status_string(wt2)
170
self.assertStartsWith(message, "pending merges:\n")
134
self.assert_(message.startswith("pending merges:\n"))
171
135
self.assert_("Empty commit 3" in message)
172
self.assertEndsWith(message, "...\n")
174
def test_tree_status_ignores(self):
175
"""Tests branch status with ignores"""
176
wt = self.make_branch_and_tree('.')
177
self.run_bzr('ignore *~')
178
wt.commit('commit .bzrignore')
179
self.build_tree(['foo.c', 'foo.c~'])
190
def test_tree_status_specific_files(self):
136
self.assert_(message.endswith("...\n"))
138
def test_branch_status_specific_files(self):
191
139
"""Tests branch status with given specific files"""
192
140
wt = self.make_branch_and_tree('.')
226
168
' directory/hello.c\n'
229
show_tree_status(wt, specific_files=['directory'], to_file=tof,
232
self.assertEquals(tof.readlines(), ['? directory/hello.c\n'])
235
171
show_tree_status(wt, specific_files=['dir2'], to_file=tof)
237
173
self.assertEquals(tof.readlines(),
242
show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
244
self.assertEquals(tof.readlines(), ['? dir2/\n'])
247
revs = [RevisionSpec.from_string('0'), RevisionSpec.from_string('1')]
248
show_tree_status(wt, specific_files=['test.c'], to_file=tof,
249
short=True, revision=revs)
251
self.assertEquals(tof.readlines(), ['+N test.c\n'])
253
def test_specific_files_conflicts(self):
254
tree = self.make_branch_and_tree('.')
255
self.build_tree(['dir2/'])
257
tree.commit('added dir2')
258
tree.set_conflicts(conflicts.ConflictList(
259
[conflicts.ContentsConflict('foo')]))
261
show_tree_status(tree, specific_files=['dir2'], to_file=tof)
262
self.assertEqualDiff('', tof.getvalue())
263
tree.set_conflicts(conflicts.ConflictList(
264
[conflicts.ContentsConflict('dir2')]))
266
show_tree_status(tree, specific_files=['dir2'], to_file=tof)
267
self.assertEqualDiff('conflicts:\n Contents conflict in dir2\n',
270
tree.set_conflicts(conflicts.ConflictList(
271
[conflicts.ContentsConflict('dir2/file1')]))
273
show_tree_status(tree, specific_files=['dir2'], to_file=tof)
274
self.assertEqualDiff('conflicts:\n Contents conflict in dir2/file1\n',
277
178
def test_status_nonexistent_file(self):
278
179
# files that don't exist in either the basis tree or working tree
279
180
# should give an error
280
181
wt = self.make_branch_and_tree('.')
281
out, err = self.run_bzr('status does-not-exist', retcode=3)
182
out, err = self.run_bzr('status', 'does-not-exist', retcode=3)
282
183
self.assertContainsRe(err, r'do not exist.*does-not-exist')
284
def test_status_out_of_date(self):
285
"""Simulate status of out-of-date tree after remote push"""
286
tree = self.make_branch_and_tree('.')
287
self.build_tree_contents([('a', 'foo\n')])
291
tree.commit('add test file')
292
# simulate what happens after a remote push
293
tree.set_last_revision("0")
295
# before run another commands we should unlock tree
297
out, err = self.run_bzr('status')
298
self.assertEqual("working tree is out of date, run 'bzr update'\n",
302
186
class CheckoutStatus(BranchStatus):
316
200
class TestStatus(TestCaseWithTransport):
318
def test_status_plain(self):
319
tree = self.make_branch_and_tree('.')
321
self.build_tree(['hello.txt'])
322
result = self.run_bzr("status")[0]
323
self.assertContainsRe(result, "unknown:\n hello.txt\n")
325
tree.add("hello.txt")
326
result = self.run_bzr("status")[0]
327
self.assertContainsRe(result, "added:\n hello.txt\n")
329
tree.commit(message="added")
330
result = self.run_bzr("status -r 0..1")[0]
331
self.assertContainsRe(result, "added:\n hello.txt\n")
333
result = self.run_bzr("status -c 1")[0]
334
self.assertContainsRe(result, "added:\n hello.txt\n")
336
self.build_tree(['world.txt'])
337
result = self.run_bzr("status -r 0")[0]
338
self.assertContainsRe(result, "added:\n hello.txt\n" \
339
"unknown:\n world.txt\n")
340
result2 = self.run_bzr("status -r 0..")[0]
341
self.assertEquals(result2, result)
343
def test_status_short(self):
344
tree = self.make_branch_and_tree('.')
346
self.build_tree(['hello.txt'])
347
result = self.run_bzr("status --short")[0]
348
self.assertContainsRe(result, "[?] hello.txt\n")
350
tree.add("hello.txt")
351
result = self.run_bzr("status --short")[0]
352
self.assertContainsRe(result, "[+]N hello.txt\n")
354
tree.commit(message="added")
355
result = self.run_bzr("status --short -r 0..1")[0]
356
self.assertContainsRe(result, "[+]N hello.txt\n")
358
self.build_tree(['world.txt'])
359
result = self.run_bzr("status --short -r 0")[0]
360
self.assertContainsRe(result, "[+]N hello.txt\n" \
362
result2 = self.run_bzr("status --short -r 0..")[0]
363
self.assertEquals(result2, result)
365
def test_status_versioned(self):
366
tree = self.make_branch_and_tree('.')
368
self.build_tree(['hello.txt'])
369
result = self.run_bzr("status --versioned")[0]
370
self.assertNotContainsRe(result, "unknown:\n hello.txt\n")
372
tree.add("hello.txt")
373
result = self.run_bzr("status --versioned")[0]
374
self.assertContainsRe(result, "added:\n hello.txt\n")
377
result = self.run_bzr("status --versioned -r 0..1")[0]
378
self.assertContainsRe(result, "added:\n hello.txt\n")
380
self.build_tree(['world.txt'])
381
result = self.run_bzr("status --versioned -r 0")[0]
382
self.assertContainsRe(result, "added:\n hello.txt\n")
383
self.assertNotContainsRe(result, "unknown:\n world.txt\n")
384
result2 = self.run_bzr("status --versioned -r 0..")[0]
385
self.assertEquals(result2, result)
387
def test_status_SV(self):
388
tree = self.make_branch_and_tree('.')
390
self.build_tree(['hello.txt'])
391
result = self.run_bzr("status -SV")[0]
392
self.assertNotContainsRe(result, "hello.txt")
394
tree.add("hello.txt")
395
result = self.run_bzr("status -SV")[0]
396
self.assertContainsRe(result, "[+]N hello.txt\n")
398
tree.commit(message="added")
399
result = self.run_bzr("status -SV -r 0..1")[0]
400
self.assertContainsRe(result, "[+]N hello.txt\n")
402
self.build_tree(['world.txt'])
403
result = self.run_bzr("status -SV -r 0")[0]
404
self.assertContainsRe(result, "[+]N hello.txt\n")
406
result2 = self.run_bzr("status -SV -r 0..")[0]
407
self.assertEquals(result2, result)
409
def assertStatusContains(self, pattern):
410
"""Run status, and assert it contains the given pattern"""
411
result = self.run_bzr("status --short")[0]
412
self.assertContainsRe(result, pattern)
414
def test_kind_change_short(self):
415
tree = self.make_branch_and_tree('.')
416
self.build_tree(['file'])
418
tree.commit('added file')
420
self.build_tree(['file/'])
421
self.assertStatusContains('K file => file/')
422
tree.rename_one('file', 'directory')
423
self.assertStatusContains('RK file => directory/')
425
self.assertStatusContains('RD file => directory')
427
def test_status_illegal_revision_specifiers(self):
428
out, err = self.run_bzr('status -r 1..23..123', retcode=3)
429
self.assertContainsRe(err, 'one or two revision specifiers')
431
def test_status_no_pending(self):
432
a_tree = self.make_branch_and_tree('a')
433
self.build_tree(['a/a'])
436
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
437
self.build_tree(['b/b'])
442
self.run_bzr('merge ../b')
443
out, err = self.run_bzr('status --no-pending')
444
self.assertEquals(out, "added:\n b\n")
448
class TestStatusEncodings(TestCaseWithTransport):
451
TestCaseWithTransport.setUp(self)
452
self.user_encoding = bzrlib.user_encoding
453
self.stdout = sys.stdout
456
bzrlib.user_encoding = self.user_encoding
457
sys.stdout = self.stdout
458
TestCaseWithTransport.tearDown(self)
460
def make_uncommitted_tree(self):
461
"""Build a branch with uncommitted unicode named changes in the cwd."""
462
working_tree = self.make_branch_and_tree(u'.')
463
filename = u'hell\u00d8'
465
self.build_tree_contents([(filename, 'contents of hello')])
466
except UnicodeEncodeError:
467
raise TestSkipped("can't build unicode working tree in "
468
"filesystem encoding %s" % sys.getfilesystemencoding())
469
working_tree.add(filename)
472
def test_stdout_ascii(self):
473
sys.stdout = StringIO()
474
bzrlib.user_encoding = 'ascii'
475
working_tree = self.make_uncommitted_tree()
476
stdout, stderr = self.run_bzr("status")
478
self.assertEquals(stdout, """\
483
def test_stdout_latin1(self):
484
sys.stdout = StringIO()
485
bzrlib.user_encoding = 'latin-1'
486
working_tree = self.make_uncommitted_tree()
487
stdout, stderr = self.run_bzr('status')
489
self.assertEquals(stdout, u"""\
492
""".encode('latin-1'))
202
def test_status(self):
204
self.build_tree(['hello.txt'])
205
result = self.run_bzr("status")[0]
206
self.assert_("unknown:\n hello.txt\n" in result, result)
207
self.run_bzr("add", "hello.txt")
208
result = self.run_bzr("status")[0]
209
self.assert_("added:\n hello.txt\n" in result, result)
210
self.run_bzr("commit", "-m", "added")
211
result = self.run_bzr("status", "-r", "0..1")[0]
212
self.assert_("added:\n hello.txt\n" in result, result)
213
self.build_tree(['world.txt'])
214
result = self.run_bzr("status", "-r", "0")[0]
215
self.assert_("added:\n hello.txt\n" \
216
"unknown:\n world.txt\n" in result, result)
218
result2 = self.run_bzr("status", "-r", "0..")[0]
219
self.assertEquals(result2, result)