~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_status.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-12-20 18:52:55 UTC
  • mfrom: (2204.2.1 bzr.dev)
  • Revision ID: pqm@pqm.ubuntu.com-20061220185255-86cd0a40a9c2e76e
(Wouter van Heyst) Mention the revisionspec topic in the revision option help (#31633).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests of status command.
 
18
 
 
19
Most of these depend on the particular formatting used.
 
20
As such they really are blackbox tests even though some of the 
 
21
tests are not using self.capture. If we add tests for the programmatic
 
22
interface later, they will be non blackbox tests.
 
23
"""
 
24
 
 
25
from cStringIO import StringIO
 
26
import codecs
 
27
from os import mkdir, chdir
 
28
import sys
 
29
from tempfile import TemporaryFile
 
30
 
 
31
from bzrlib import bzrdir, errors
 
32
import bzrlib.branch
 
33
from bzrlib.builtins import merge
 
34
from bzrlib.osutils import pathjoin
 
35
from bzrlib.revisionspec import RevisionSpec
 
36
from bzrlib.status import show_tree_status
 
37
from bzrlib.tests import TestCaseWithTransport, TestSkipped
 
38
from bzrlib.workingtree import WorkingTree
 
39
 
 
40
 
 
41
class BranchStatus(TestCaseWithTransport):
 
42
    
 
43
    def assertStatus(self, output_lines, working_tree,
 
44
        revision=None, short=False):
 
45
        """Run status in working_tree and look for output.
 
46
        
 
47
        :param output_lines: The lines to look for.
 
48
        :param working_tree: The tree to run status in.
 
49
        """
 
50
        output_string = self.status_string(working_tree, revision, short)
 
51
        self.assertEqual(output_lines, output_string.splitlines(True))
 
52
    
 
53
    def status_string(self, wt, revision=None, short=False):
 
54
        # use a real file rather than StringIO because it doesn't handle
 
55
        # Unicode very well.
 
56
        tof = codecs.getwriter('utf-8')(TemporaryFile())
 
57
        show_tree_status(wt, to_file=tof, revision=revision, short=short)
 
58
        tof.seek(0)
 
59
        return tof.read().decode('utf-8')
 
60
 
 
61
    def test_branch_status(self):
 
62
        """Test basic branch status"""
 
63
        wt = self.make_branch_and_tree('.')
 
64
 
 
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
 
68
        # as a corner case.
 
69
        self.assertStatus([], wt)
 
70
 
 
71
        self.build_tree(['hello.c', 'bye.c'])
 
72
        self.assertStatus([
 
73
                'unknown:\n',
 
74
                '  bye.c\n',
 
75
                '  hello.c\n',
 
76
            ],
 
77
            wt)
 
78
        self.assertStatus([
 
79
                '?  bye.c\n',
 
80
                '?  hello.c\n',
 
81
            ],
 
82
            wt, short=True)
 
83
 
 
84
        # add a commit to allow showing pending merges.
 
85
        wt.commit('create a parent to allow testing merge output')
 
86
 
 
87
        wt.add_parent_tree_id('pending@pending-0-0')
 
88
        self.assertStatus([
 
89
                'unknown:\n',
 
90
                '  bye.c\n',
 
91
                '  hello.c\n',
 
92
                'pending merges:\n',
 
93
                '  pending@pending-0-0\n',
 
94
            ],
 
95
            wt)
 
96
        self.assertStatus([
 
97
                '?  bye.c\n',
 
98
                '?  hello.c\n',
 
99
                'P  pending@pending-0-0\n',
 
100
            ],
 
101
            wt, short=True)
 
102
 
 
103
    def test_branch_status_revisions(self):
 
104
        """Tests branch status with revisions"""
 
105
        wt = self.make_branch_and_tree('.')
 
106
 
 
107
        self.build_tree(['hello.c', 'bye.c'])
 
108
        wt.add('hello.c')
 
109
        wt.add('bye.c')
 
110
        wt.commit('Test message')
 
111
 
 
112
        revs = [RevisionSpec.from_string('0')]
 
113
        self.assertStatus([
 
114
                'added:\n',
 
115
                '  bye.c\n',
 
116
                '  hello.c\n'
 
117
            ],
 
118
            wt,
 
119
            revision=revs)
 
120
 
 
121
        self.build_tree(['more.c'])
 
122
        wt.add('more.c')
 
123
        wt.commit('Another test message')
 
124
        
 
125
        revs.append(RevisionSpec.from_string('1'))
 
126
        self.assertStatus([
 
127
                'added:\n',
 
128
                '  bye.c\n',
 
129
                '  hello.c\n',
 
130
            ],
 
131
            wt,
 
132
            revision=revs)
 
133
 
 
134
    def test_pending(self):
 
135
        """Pending merges display works, including Unicode"""
 
136
        mkdir("./branch")
 
137
        wt = self.make_branch_and_tree('branch')
 
138
        b = wt.branch
 
139
        wt.commit("Empty commit 1")
 
140
        b_2_dir = b.bzrdir.sprout('./copy')
 
141
        b_2 = b_2_dir.open_branch()
 
142
        wt2 = b_2_dir.open_workingtree()
 
143
        wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
 
144
        merge(["./branch", -1], [None, None], this_dir = './copy')
 
145
        message = self.status_string(wt2)
 
146
        self.assert_(message.startswith("pending merges:\n"))
 
147
        self.assert_(message.endswith("Empty commit 2\n")) 
 
148
        wt2.commit("merged")
 
149
        # must be long to make sure we see elipsis at the end
 
150
        wt.commit("Empty commit 3 " + 
 
151
                   "blah blah blah blah " * 10)
 
152
        merge(["./branch", -1], [None, None], this_dir = './copy')
 
153
        message = self.status_string(wt2)
 
154
        self.assert_(message.startswith("pending merges:\n"))
 
155
        self.assert_("Empty commit 3" in message)
 
156
        self.assert_(message.endswith("...\n")) 
 
157
 
 
158
    def test_branch_status_specific_files(self): 
 
159
        """Tests branch status with given specific files"""
 
160
        wt = self.make_branch_and_tree('.')
 
161
        b = wt.branch
 
162
 
 
163
        self.build_tree(['directory/','directory/hello.c', 'bye.c','test.c','dir2/'])
 
164
        wt.add('directory')
 
165
        wt.add('test.c')
 
166
        wt.commit('testing')
 
167
        
 
168
        self.assertStatus([
 
169
                'unknown:\n',
 
170
                '  bye.c\n',
 
171
                '  dir2\n',
 
172
                '  directory/hello.c\n'
 
173
                ],
 
174
                wt)
 
175
 
 
176
        self.assertStatus([
 
177
                '?  bye.c\n',
 
178
                '?  dir2\n',
 
179
                '?  directory/hello.c\n'
 
180
                ],
 
181
                wt, short=True)
 
182
 
 
183
        tof = StringIO()
 
184
        self.assertRaises(errors.PathsDoNotExist,
 
185
                          show_tree_status,
 
186
                          wt, specific_files=['bye.c','test.c','absent.c'], 
 
187
                          to_file=tof)
 
188
        
 
189
        tof = StringIO()
 
190
        show_tree_status(wt, specific_files=['directory'], to_file=tof)
 
191
        tof.seek(0)
 
192
        self.assertEquals(tof.readlines(),
 
193
                          ['unknown:\n',
 
194
                           '  directory/hello.c\n'
 
195
                           ])
 
196
        tof = StringIO()
 
197
        show_tree_status(wt, specific_files=['directory'], to_file=tof,
 
198
                         short=True)
 
199
        tof.seek(0)
 
200
        self.assertEquals(tof.readlines(), ['?  directory/hello.c\n'])
 
201
 
 
202
        tof = StringIO()
 
203
        show_tree_status(wt, specific_files=['dir2'], to_file=tof)
 
204
        tof.seek(0)
 
205
        self.assertEquals(tof.readlines(),
 
206
                          ['unknown:\n',
 
207
                           '  dir2\n'
 
208
                           ])
 
209
        tof = StringIO()
 
210
        show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
 
211
        tof.seek(0)
 
212
        self.assertEquals(tof.readlines(), ['?  dir2\n'])
 
213
 
 
214
    def test_status_nonexistent_file(self):
 
215
        # files that don't exist in either the basis tree or working tree
 
216
        # should give an error
 
217
        wt = self.make_branch_and_tree('.')
 
218
        out, err = self.run_bzr('status', 'does-not-exist', retcode=3)
 
219
        self.assertContainsRe(err, r'do not exist.*does-not-exist')
 
220
 
 
221
    def test_status_out_of_date(self):
 
222
        """Simulate status of out-of-date tree after remote push"""
 
223
        tree = self.make_branch_and_tree('.')
 
224
        self.build_tree_contents([('a', 'foo\n')])
 
225
        tree.lock_write()
 
226
        try:
 
227
            tree.add(['a'])
 
228
            tree.commit('add test file')
 
229
            # simulate what happens after a remote push
 
230
            tree.set_last_revision("0")
 
231
            out, err = self.run_bzr('status')
 
232
            self.assertEqual("working tree is out of date, run 'bzr update'\n",
 
233
                             err)
 
234
        finally:
 
235
            tree.unlock()
 
236
 
 
237
 
 
238
class CheckoutStatus(BranchStatus):
 
239
 
 
240
    def setUp(self):
 
241
        super(CheckoutStatus, self).setUp()
 
242
        mkdir('codir')
 
243
        chdir('codir')
 
244
        
 
245
    def make_branch_and_tree(self, relpath):
 
246
        source = self.make_branch(pathjoin('..', relpath))
 
247
        checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
 
248
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
 
249
        return checkout.create_workingtree()
 
250
 
 
251
 
 
252
class TestStatus(TestCaseWithTransport):
 
253
 
 
254
    def test_status(self):
 
255
        self.run_bzr("init")
 
256
 
 
257
        self.build_tree(['hello.txt'])
 
258
        result = self.run_bzr("status")[0]
 
259
        self.assert_("unknown:\n  hello.txt\n" in result, result)
 
260
        result = self.run_bzr("status","--short")[0]
 
261
        self.assert_("?  hello.txt\n" in result, result)
 
262
 
 
263
        self.run_bzr("add", "hello.txt")
 
264
        result = self.run_bzr("status")[0]
 
265
        self.assert_("added:\n  hello.txt\n" in result, result)
 
266
        result = self.run_bzr("status","--short")[0]
 
267
        self.assert_("A  hello.txt\n" in result, result)
 
268
 
 
269
        self.run_bzr("commit", "-m", "added")
 
270
        result = self.run_bzr("status", "-r", "0..1")[0]
 
271
        self.assert_("added:\n  hello.txt\n" in result, result)
 
272
        result = self.run_bzr("status", "--short", "-r", "0..1")[0]
 
273
        self.assert_("A  hello.txt\n" in result, result)
 
274
 
 
275
        self.build_tree(['world.txt'])
 
276
        result = self.run_bzr("status", "-r", "0")[0]
 
277
        self.assert_("added:\n  hello.txt\n" \
 
278
                     "unknown:\n  world.txt\n" in result, result)
 
279
        result2 = self.run_bzr("status", "-r", "0..")[0]
 
280
        self.assertEquals(result2, result)
 
281
        result = self.run_bzr("status", "--short", "-r", "0")[0]
 
282
        self.assert_("A  hello.txt\n" \
 
283
                     "?  world.txt\n" in result, result)
 
284
        result2 = self.run_bzr("status", "--short", "-r", "0..")[0]
 
285
        self.assertEquals(result2, result)
 
286
 
 
287
 
 
288
class TestStatusEncodings(TestCaseWithTransport):
 
289
    
 
290
    def setUp(self):
 
291
        TestCaseWithTransport.setUp(self)
 
292
        self.user_encoding = bzrlib.user_encoding
 
293
        self.stdout = sys.stdout
 
294
 
 
295
    def tearDown(self):
 
296
        bzrlib.user_encoding = self.user_encoding
 
297
        sys.stdout = self.stdout
 
298
        TestCaseWithTransport.tearDown(self)
 
299
 
 
300
    def make_uncommitted_tree(self):
 
301
        """Build a branch with uncommitted unicode named changes in the cwd."""
 
302
        working_tree = self.make_branch_and_tree(u'.')
 
303
        filename = u'hell\u00d8'
 
304
        try:
 
305
            self.build_tree_contents([(filename, 'contents of hello')])
 
306
        except UnicodeEncodeError:
 
307
            raise TestSkipped("can't build unicode working tree in "
 
308
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
309
        working_tree.add(filename)
 
310
        return working_tree
 
311
 
 
312
    def test_stdout_ascii(self):
 
313
        sys.stdout = StringIO()
 
314
        bzrlib.user_encoding = 'ascii'
 
315
        working_tree = self.make_uncommitted_tree()
 
316
        stdout, stderr = self.run_bzr("status")
 
317
 
 
318
        self.assertEquals(stdout, """\
 
319
added:
 
320
  hell?
 
321
""")
 
322
 
 
323
    def test_stdout_latin1(self):
 
324
        sys.stdout = StringIO()
 
325
        bzrlib.user_encoding = 'latin-1'
 
326
        working_tree = self.make_uncommitted_tree()
 
327
        stdout, stderr = self.run_bzr('status')
 
328
 
 
329
        self.assertEquals(stdout, u"""\
 
330
added:
 
331
  hell\u00d8
 
332
""".encode('latin-1'))
 
333