1
# Copyright (C) 2005, 2006 by Canonical Ltd
1
# Copyright (C) 2005, 2006 Canonical Ltd
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
17
"""Tests of status command.
20
19
Most of these depend on the particular formatting used.
23
22
interface later, they will be non blackbox tests.
27
25
from cStringIO import StringIO
28
from os import mkdir, chdir
27
from os import mkdir, chdir, rmdir, unlink
29
29
from tempfile import TemporaryFile
31
from bzrlib import bzrdir, errors
32
32
import bzrlib.branch
33
33
from bzrlib.builtins import merge
34
import bzrlib.bzrdir as bzrdir
35
import bzrlib.errors as errors
36
34
from bzrlib.osutils import pathjoin
37
35
from bzrlib.revisionspec import RevisionSpec
38
36
from bzrlib.status import show_tree_status
39
from bzrlib.tests import TestCaseWithTransport
37
from bzrlib.tests import TestCaseWithTransport, TestSkipped
40
38
from bzrlib.workingtree import WorkingTree
43
41
class BranchStatus(TestCaseWithTransport):
45
def test_branch_status(self):
43
def assertStatus(self, expected_lines, working_tree,
44
revision=None, short=False):
45
"""Run status in working_tree and look for output.
47
:param expected_lines: The lines to look for.
48
:param working_tree: The tree to run status in.
50
output_string = self.status_string(working_tree, revision, short)
51
self.assertEqual(expected_lines, output_string.splitlines(True))
53
def status_string(self, wt, revision=None, short=False):
54
# use a real file rather than StringIO because it doesn't handle
56
tof = codecs.getwriter('utf-8')(TemporaryFile())
57
show_tree_status(wt, to_file=tof, revision=revision, short=short)
59
return tof.read().decode('utf-8')
61
def test_branch_status(self):
46
62
"""Test basic branch status"""
47
63
wt = self.make_branch_and_tree('.')
52
show_tree_status(wt, to_file=tof)
53
self.assertEquals(tof.getvalue(), "")
65
# status with no commits or files - it must
66
# work and show no output. We do this with no
67
# commits to be sure that it's not going to fail
69
self.assertStatus([], wt)
56
71
self.build_tree(['hello.c', 'bye.c'])
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'
84
# add a commit to allow showing pending merges.
85
wt.commit('create a parent to allow testing merge output')
87
wt.add_parent_tree_id('pending@pending-0-0')
93
' pending@pending-0-0\n',
99
'P pending@pending-0-0\n',
68
103
def test_branch_status_revisions(self):
69
104
"""Tests branch status with revisions"""
70
105
wt = self.make_branch_and_tree('.')
74
107
self.build_tree(['hello.c', 'bye.c'])
77
110
wt.commit('Test message')
81
revs.append(RevisionSpec(0))
83
show_tree_status(wt, to_file=tof, revision=revs)
86
self.assertEquals(tof.readlines(),
112
revs = [RevisionSpec.from_string('0')]
91
121
self.build_tree(['more.c'])
93
123
wt.commit('Another test message')
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')
125
revs.append(RevisionSpec.from_string('1'))
114
134
def test_pending(self):
115
135
"""Pending merges display works, including Unicode"""
123
143
wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
124
144
merge(["./branch", -1], [None, None], this_dir = './copy')
125
145
message = self.status_string(wt2)
126
self.assert_(message.startswith("pending merges:\n"))
127
self.assert_(message.endswith("Empty commit 2\n"))
146
self.assertStartsWith(message, "pending merges:\n")
147
self.assertEndsWith(message, "Empty commit 2\n")
128
148
wt2.commit("merged")
129
149
# must be long to make sure we see elipsis at the end
130
wt.commit("Empty commit 3 " +
131
"blah blah blah blah " * 10)
150
wt.commit("Empty commit 3 " +
151
"blah blah blah blah " * 100)
132
152
merge(["./branch", -1], [None, None], this_dir = './copy')
133
153
message = self.status_string(wt2)
134
self.assert_(message.startswith("pending merges:\n"))
154
self.assertStartsWith(message, "pending merges:\n")
135
155
self.assert_("Empty commit 3" in message)
136
self.assert_(message.endswith("...\n"))
138
def test_branch_status_specific_files(self):
156
self.assertEndsWith(message, "...\n")
158
def test_tree_status_ignores(self):
159
"""Tests branch status with ignores"""
160
wt = self.make_branch_and_tree('.')
161
self.run_bzr('ignore', '*~')
162
wt.commit('commit .bzrignore')
163
self.build_tree(['foo.c', 'foo.c~'])
174
def test_tree_status_specific_files(self):
139
175
"""Tests branch status with given specific files"""
140
176
wt = self.make_branch_and_tree('.')
182
234
out, err = self.run_bzr('status', 'does-not-exist', retcode=3)
183
235
self.assertContainsRe(err, r'do not exist.*does-not-exist')
237
def test_status_out_of_date(self):
238
"""Simulate status of out-of-date tree after remote push"""
239
tree = self.make_branch_and_tree('.')
240
self.build_tree_contents([('a', 'foo\n')])
244
tree.commit('add test file')
245
# simulate what happens after a remote push
246
tree.set_last_revision("0")
247
out, err = self.run_bzr('status')
248
self.assertEqual("working tree is out of date, run 'bzr update'\n",
186
254
class CheckoutStatus(BranchStatus):
202
270
def test_status(self):
203
271
self.run_bzr("init")
204
273
self.build_tree(['hello.txt'])
205
274
result = self.run_bzr("status")[0]
206
275
self.assert_("unknown:\n hello.txt\n" in result, result)
276
result = self.run_bzr("status","--short")[0]
277
self.assertContainsRe(result, "[?] hello.txt\n")
207
279
self.run_bzr("add", "hello.txt")
208
280
result = self.run_bzr("status")[0]
209
self.assert_("added:\n hello.txt\n" in result, result)
281
self.assertContainsRe(result, "added:\n hello.txt\n")
282
result = self.run_bzr("status","--short")[0]
283
self.assertContainsRe(result, "[+]N hello.txt\n")
210
285
self.run_bzr("commit", "-m", "added")
211
286
result = self.run_bzr("status", "-r", "0..1")[0]
212
self.assert_("added:\n hello.txt\n" in result, result)
287
self.assertContainsRe(result, "added:\n hello.txt\n")
288
result = self.run_bzr("status", "--short", "-r", "0..1")[0]
289
self.assertContainsRe(result, "[+]N hello.txt\n")
213
291
self.build_tree(['world.txt'])
214
292
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)
293
self.assertContainsRe(result, "added:\n hello.txt\n" \
294
"unknown:\n world.txt\n")
218
295
result2 = self.run_bzr("status", "-r", "0..")[0]
219
296
self.assertEquals(result2, result)
297
result = self.run_bzr("status", "--short", "-r", "0")[0]
298
self.assertContainsRe(result, "[+]N hello.txt\n" \
300
result2 = self.run_bzr("status", "--short", "-r", "0..")[0]
301
self.assertEquals(result2, result)
303
def assertStatusContains(self, pattern):
304
"""Run status, and assert it contains the given pattern"""
305
result = self.run_bzr("status", "--short")[0]
306
self.assertContainsRe(result, pattern)
308
def test_kind_change_short(self):
309
tree = self.make_branch_and_tree('.')
310
self.build_tree(['file'])
312
tree.commit('added file')
314
self.build_tree(['file/'])
315
self.assertStatusContains('K file => file/')
316
tree.rename_one('file', 'directory')
317
self.assertStatusContains('RK file => directory/')
319
self.assertStatusContains('RD file => directory')
322
class TestStatusEncodings(TestCaseWithTransport):
325
TestCaseWithTransport.setUp(self)
326
self.user_encoding = bzrlib.user_encoding
327
self.stdout = sys.stdout
330
bzrlib.user_encoding = self.user_encoding
331
sys.stdout = self.stdout
332
TestCaseWithTransport.tearDown(self)
334
def make_uncommitted_tree(self):
335
"""Build a branch with uncommitted unicode named changes in the cwd."""
336
working_tree = self.make_branch_and_tree(u'.')
337
filename = u'hell\u00d8'
339
self.build_tree_contents([(filename, 'contents of hello')])
340
except UnicodeEncodeError:
341
raise TestSkipped("can't build unicode working tree in "
342
"filesystem encoding %s" % sys.getfilesystemencoding())
343
working_tree.add(filename)
346
def test_stdout_ascii(self):
347
sys.stdout = StringIO()
348
bzrlib.user_encoding = 'ascii'
349
working_tree = self.make_uncommitted_tree()
350
stdout, stderr = self.run_bzr("status")
352
self.assertEquals(stdout, """\
357
def test_stdout_latin1(self):
358
sys.stdout = StringIO()
359
bzrlib.user_encoding = 'latin-1'
360
working_tree = self.make_uncommitted_tree()
361
stdout, stderr = self.run_bzr('status')
363
self.assertEquals(stdout, u"""\
366
""".encode('latin-1'))