~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

Fix BzrDir.create_workingtree for NULL_REVISION

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
 
 
1
# Copyright (C) 2005, 2006 by Canonical Ltd
 
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
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.
12
 
 
 
12
#
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
16
16
 
17
 
 
18
17
"""Tests of status command.
19
18
 
20
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.
21
23
"""
22
24
 
23
 
 
24
25
from cStringIO import StringIO
25
 
from os import mkdir
 
26
import codecs
 
27
from os import mkdir, chdir
 
28
import sys
26
29
from tempfile import TemporaryFile
27
 
import codecs
28
30
 
29
 
from bzrlib.tests import TestCaseInTempDir
 
31
from bzrlib import bzrdir, errors, ignores
 
32
import bzrlib.branch
 
33
from bzrlib.builtins import merge
 
34
from bzrlib.osutils import pathjoin
30
35
from bzrlib.revisionspec import RevisionSpec
31
 
from bzrlib.merge import merge
32
 
from bzrlib.status import show_status
33
 
from bzrlib.branch import Branch
34
 
from bzrlib.clone import copy_branch
35
 
 
36
 
class BranchStatus(TestCaseInTempDir):
37
 
    
38
 
    def test_branch_status(self): 
 
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):
 
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)
 
51
        self.assertEqual(output_lines, output_string.splitlines(True))
 
52
    
 
53
    def status_string(self, wt, revision=None):
 
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)
 
58
        tof.seek(0)
 
59
        return tof.read().decode('utf-8')
 
60
 
 
61
    def test_branch_status(self):
39
62
        """Test basic branch status"""
40
 
        from bzrlib.status import show_status
41
 
        from bzrlib.branch import Branch
42
 
        
43
 
        b = Branch.initialize(u'.')
44
 
 
45
 
        # status with nothing
46
 
        tof = StringIO()
47
 
        show_status(b, to_file=tof)
48
 
        self.assertEquals(tof.getvalue(), "")
49
 
 
50
 
        tof = StringIO()
 
63
        wt = self.make_branch_and_tree('.')
 
64
 
 
65
        ignores._set_user_ignores(['./.bazaar'])
 
66
 
 
67
        # status with no commits or files - it must
 
68
        # work and show no output. We do this with no
 
69
        # commits to be sure that it's not going to fail
 
70
        # as a corner case.
 
71
        self.assertStatus([], wt)
 
72
 
51
73
        self.build_tree(['hello.c', 'bye.c'])
52
 
        b.working_tree().add_pending_merge('pending@pending-0-0')
53
 
        show_status(b, to_file=tof)
54
 
        tof.seek(0)
55
 
        self.assertEquals(tof.readlines(),
56
 
                          ['unknown:\n',
57
 
                           '  bye.c\n',
58
 
                           '  hello.c\n',
59
 
                           'pending merges:\n',
60
 
                           '  pending@pending-0-0\n'
61
 
                           ])
 
74
        self.assertStatus([
 
75
                'unknown:\n',
 
76
                '  bye.c\n',
 
77
                '  hello.c\n',
 
78
            ],
 
79
            wt)
 
80
 
 
81
        # add a commit to allow showing pending merges.
 
82
        wt.commit('create a parent to allow testing merge output')
 
83
 
 
84
        wt.add_parent_tree_id('pending@pending-0-0')
 
85
        self.assertStatus([
 
86
                'unknown:\n',
 
87
                '  bye.c\n',
 
88
                '  hello.c\n',
 
89
                'pending merges:\n',
 
90
                '  pending@pending-0-0\n',
 
91
            ],
 
92
            wt)
62
93
 
63
94
    def test_branch_status_revisions(self):
64
95
        """Tests branch status with revisions"""
65
 
        
66
 
        b = Branch.initialize(u'.')
67
 
 
68
 
        tof = StringIO()
 
96
        wt = self.make_branch_and_tree('.')
 
97
 
 
98
        ignores._set_user_ignores(['./.bazaar'])
 
99
 
69
100
        self.build_tree(['hello.c', 'bye.c'])
70
 
        b.working_tree().add('hello.c')
71
 
        b.working_tree().add('bye.c')
72
 
        b.working_tree().commit('Test message')
 
101
        wt.add('hello.c')
 
102
        wt.add('bye.c')
 
103
        wt.commit('Test message')
73
104
 
74
 
        tof = StringIO()
75
 
        revs =[]
76
 
        revs.append(RevisionSpec(0))
77
 
        
78
 
        show_status(b, to_file=tof, revision=revs)
79
 
        
80
 
        tof.seek(0)
81
 
        self.assertEquals(tof.readlines(),
82
 
                          ['added:\n',
83
 
                           '  bye.c\n',
84
 
                           '  hello.c\n'])
 
105
        revs = [RevisionSpec(0)]
 
106
        self.assertStatus([
 
107
                'added:\n',
 
108
                '  bye.c\n',
 
109
                '  hello.c\n'
 
110
            ],
 
111
            wt,
 
112
            revision=revs)
85
113
 
86
114
        self.build_tree(['more.c'])
87
 
        b.working_tree().add('more.c')
88
 
        b.working_tree().commit('Another test message')
 
115
        wt.add('more.c')
 
116
        wt.commit('Another test message')
89
117
        
90
 
        tof = StringIO()
91
118
        revs.append(RevisionSpec(1))
92
 
        
93
 
        show_status(b, to_file=tof, revision=revs)
94
 
        
95
 
        tof.seek(0)
96
 
        self.assertEquals(tof.readlines(),
97
 
                          ['added:\n',
98
 
                           '  bye.c\n',
99
 
                           '  hello.c\n'])
100
 
 
101
 
    def status_string(self, branch):
102
 
        # use a real file rather than StringIO because it doesn't handle
103
 
        # Unicode very well.
104
 
        tof = codecs.getwriter('utf-8')(TemporaryFile())
105
 
        show_status(branch, to_file=tof)
106
 
        tof.seek(0)
107
 
        return tof.read().decode('utf-8')
 
119
        self.assertStatus([
 
120
                'added:\n',
 
121
                '  bye.c\n',
 
122
                '  hello.c\n',
 
123
            ],
 
124
            wt,
 
125
            revision=revs)
108
126
 
109
127
    def test_pending(self):
110
128
        """Pending merges display works, including Unicode"""
111
129
        mkdir("./branch")
112
 
        b = Branch.initialize('./branch')
113
 
        b.working_tree().commit("Empty commit 1")
114
 
        b_2 = copy_branch(b, './copy')
115
 
        b.working_tree().commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
 
130
        wt = self.make_branch_and_tree('branch')
 
131
        b = wt.branch
 
132
        wt.commit("Empty commit 1")
 
133
        b_2_dir = b.bzrdir.sprout('./copy')
 
134
        b_2 = b_2_dir.open_branch()
 
135
        wt2 = b_2_dir.open_workingtree()
 
136
        wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
116
137
        merge(["./branch", -1], [None, None], this_dir = './copy')
117
 
        message = self.status_string(b_2)
 
138
        message = self.status_string(wt2)
118
139
        self.assert_(message.startswith("pending merges:\n"))
119
140
        self.assert_(message.endswith("Empty commit 2\n")) 
120
 
        b_2.working_tree().commit("merged")
 
141
        wt2.commit("merged")
121
142
        # must be long to make sure we see elipsis at the end
122
 
        b.working_tree().commit("Empty commit 3 " + 
123
 
                                "blah blah blah blah " * 10)
 
143
        wt.commit("Empty commit 3 " + 
 
144
                   "blah blah blah blah " * 10)
124
145
        merge(["./branch", -1], [None, None], this_dir = './copy')
125
 
        message = self.status_string(b_2)
 
146
        message = self.status_string(wt2)
126
147
        self.assert_(message.startswith("pending merges:\n"))
127
148
        self.assert_("Empty commit 3" in message)
128
149
        self.assert_(message.endswith("...\n")) 
129
150
 
130
151
    def test_branch_status_specific_files(self): 
131
152
        """Tests branch status with given specific files"""
132
 
        from cStringIO import StringIO
133
 
        from bzrlib.status import show_status
134
 
        from bzrlib.branch import Branch
135
 
        
136
 
        b = Branch.initialize(u'.')
 
153
        wt = self.make_branch_and_tree('.')
 
154
        b = wt.branch
 
155
 
 
156
        ignores._set_user_ignores(['./.bazaar'])
137
157
 
138
158
        self.build_tree(['directory/','directory/hello.c', 'bye.c','test.c','dir2/'])
139
 
        b.working_tree().add('directory')
140
 
        b.working_tree().add('test.c')
141
 
        b.working_tree().commit('testing')
 
159
        wt.add('directory')
 
160
        wt.add('test.c')
 
161
        wt.commit('testing')
142
162
        
143
163
        tof = StringIO()
144
 
        show_status(b, to_file=tof)
 
164
        show_tree_status(wt, to_file=tof)
145
165
        tof.seek(0)
146
166
        self.assertEquals(tof.readlines(),
147
167
                          ['unknown:\n',
150
170
                           '  directory/hello.c\n'
151
171
                           ])
152
172
 
153
 
        tof = StringIO()
154
 
        show_status(b, specific_files=['bye.c','test.c','absent.c'], to_file=tof)
155
 
        tof.seek(0)
156
 
        self.assertEquals(tof.readlines(),
157
 
                          ['unknown:\n',
158
 
                           '  bye.c\n'
159
 
                           ])
 
173
        self.assertRaises(errors.PathsDoNotExist,
 
174
                          show_tree_status,
 
175
                          wt, specific_files=['bye.c','test.c','absent.c'], 
 
176
                          to_file=tof)
160
177
        
161
178
        tof = StringIO()
162
 
        show_status(b, specific_files=['directory'], to_file=tof)
 
179
        show_tree_status(wt, specific_files=['directory'], to_file=tof)
163
180
        tof.seek(0)
164
181
        self.assertEquals(tof.readlines(),
165
182
                          ['unknown:\n',
166
183
                           '  directory/hello.c\n'
167
184
                           ])
168
185
        tof = StringIO()
169
 
        show_status(b, specific_files=['dir2'], to_file=tof)
 
186
        show_tree_status(wt, specific_files=['dir2'], to_file=tof)
170
187
        tof.seek(0)
171
188
        self.assertEquals(tof.readlines(),
172
189
                          ['unknown:\n',
173
190
                           '  dir2\n'
174
191
                           ])
 
192
 
 
193
    def test_status_nonexistent_file(self):
 
194
        # files that don't exist in either the basis tree or working tree
 
195
        # should give an error
 
196
        wt = self.make_branch_and_tree('.')
 
197
        out, err = self.run_bzr('status', 'does-not-exist', retcode=3)
 
198
        self.assertContainsRe(err, r'do not exist.*does-not-exist')
 
199
 
 
200
 
 
201
class CheckoutStatus(BranchStatus):
 
202
 
 
203
    def setUp(self):
 
204
        super(CheckoutStatus, self).setUp()
 
205
        mkdir('codir')
 
206
        chdir('codir')
 
207
        
 
208
    def make_branch_and_tree(self, relpath):
 
209
        source = self.make_branch(pathjoin('..', relpath))
 
210
        checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
 
211
        bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
 
212
        return checkout.create_workingtree()
 
213
 
 
214
 
 
215
class TestStatus(TestCaseWithTransport):
 
216
 
 
217
    def test_status(self):
 
218
        ignores._set_user_ignores(['./.bazaar'])
 
219
 
 
220
        self.run_bzr("init")
 
221
        self.build_tree(['hello.txt'])
 
222
        result = self.run_bzr("status")[0]
 
223
        self.assert_("unknown:\n  hello.txt\n" in result, result)
 
224
        self.run_bzr("add", "hello.txt")
 
225
        result = self.run_bzr("status")[0]
 
226
        self.assert_("added:\n  hello.txt\n" in result, result)
 
227
        self.run_bzr("commit", "-m", "added")
 
228
        result = self.run_bzr("status", "-r", "0..1")[0]
 
229
        self.assert_("added:\n  hello.txt\n" in result, result)
 
230
        self.build_tree(['world.txt'])
 
231
        result = self.run_bzr("status", "-r", "0")[0]
 
232
        self.assert_("added:\n  hello.txt\n" \
 
233
                     "unknown:\n  world.txt\n" in result, result)
 
234
 
 
235
        result2 = self.run_bzr("status", "-r", "0..")[0]
 
236
        self.assertEquals(result2, result)
 
237
 
 
238
 
 
239
class TestStatusEncodings(TestCaseWithTransport):
 
240
    
 
241
    def setUp(self):
 
242
        TestCaseWithTransport.setUp(self)
 
243
        self.user_encoding = bzrlib.user_encoding
 
244
        self.stdout = sys.stdout
 
245
 
 
246
    def tearDown(self):
 
247
        bzrlib.user_encoding = self.user_encoding
 
248
        sys.stdout = self.stdout
 
249
        TestCaseWithTransport.tearDown(self)
 
250
 
 
251
    def make_uncommitted_tree(self):
 
252
        """Build a branch with uncommitted unicode named changes in the cwd."""
 
253
        working_tree = self.make_branch_and_tree(u'.')
 
254
        filename = u'hell\u00d8'
 
255
        try:
 
256
            self.build_tree_contents([(filename, 'contents of hello')])
 
257
        except UnicodeEncodeError:
 
258
            raise TestSkipped("can't build unicode working tree in "
 
259
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
260
        working_tree.add(filename)
 
261
        return working_tree
 
262
 
 
263
    def test_stdout_ascii(self):
 
264
        sys.stdout = StringIO()
 
265
        bzrlib.user_encoding = 'ascii'
 
266
        working_tree = self.make_uncommitted_tree()
 
267
        stdout, stderr = self.run_bzr("status")
 
268
 
 
269
        self.assertEquals(stdout, """\
 
270
added:
 
271
  hell?
 
272
""")
 
273
 
 
274
    def test_stdout_latin1(self):
 
275
        sys.stdout = StringIO()
 
276
        bzrlib.user_encoding = 'latin-1'
 
277
        working_tree = self.make_uncommitted_tree()
 
278
        stdout, stderr = self.run_bzr('status')
 
279
 
 
280
        self.assertEquals(stdout, u"""\
 
281
added:
 
282
  hell\u00d8
 
283
""".encode('latin-1'))
 
284