~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Launchpad Translations on behalf of bzr-core
  • Date: 2012-12-17 04:30:37 UTC
  • mto: (6581.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 6582.
  • Revision ID: launchpad_translations_on_behalf_of_bzr-core-20121217043037-gdkzkow6s9fsa4o0
Launchpad automatic translations update.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
# -*- coding: utf-8 -*-
3
 
 
 
3
#
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
6
6
# the Free Software Foundation; either version 2 of the License, or
7
7
# (at your option) any later version.
8
 
 
 
8
#
9
9
# This program is distributed in the hope that it will be useful,
10
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
12
# GNU General Public License for more details.
13
 
 
 
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
 
19
19
"""Black-box tests for bzr.
20
20
 
21
21
These check that it behaves properly when it's invoked through the regular
22
 
command-line interface. This doesn't actually run a new interpreter but 
 
22
command-line interface. This doesn't actually run a new interpreter but
23
23
rather starts again from the run_bzr function.
24
24
"""
25
25
 
26
26
 
27
 
from cStringIO import StringIO
28
 
import os
29
 
import shutil
30
 
import sys
31
 
import os
32
 
 
33
 
from bzrlib.branch import Branch
34
 
from bzrlib.clone import copy_branch
35
 
from bzrlib.errors import BzrCommandError
36
 
from bzrlib.osutils import has_symlinks
37
 
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
38
 
from bzrlib.annotate import annotate_file
39
 
 
40
 
 
41
 
class TestAnnotate(TestCaseInTempDir):
 
27
from bzrlib import (
 
28
    config,
 
29
    tests,
 
30
    )
 
31
 
 
32
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
33
from bzrlib.urlutils import joinpath
 
34
 
 
35
 
 
36
class TestAnnotate(tests.TestCaseWithTransport):
 
37
 
42
38
    def setUp(self):
43
39
        super(TestAnnotate, self).setUp()
44
 
        b = Branch.initialize('.')
45
 
        self.build_tree_contents([('hello.txt', 'my helicopter\n')])
46
 
        b.add(['hello.txt'])
47
 
        b.commit('add hello', 
48
 
                 committer='test@user')
 
40
        wt = self.make_branch_and_tree('.')
 
41
        b = wt.branch
 
42
        self.build_tree_contents([('hello.txt', 'my helicopter\n'),
 
43
                                  ('nomail.txt', 'nomail\n')])
 
44
        wt.add(['hello.txt'])
 
45
        self.revision_id_1 = wt.commit('add hello',
 
46
                              committer='test@user',
 
47
                              timestamp=1165960000.00, timezone=0)
 
48
        wt.add(['nomail.txt'])
 
49
        self.revision_id_2 = wt.commit('add nomail',
 
50
                              committer='no mail',
 
51
                              timestamp=1165970000.00, timezone=0)
 
52
        self.build_tree_contents([('hello.txt', 'my helicopter\n'
 
53
                                                'your helicopter\n')])
 
54
        self.revision_id_3 = wt.commit('mod hello',
 
55
                              committer='user@test',
 
56
                              timestamp=1166040000.00, timezone=0)
 
57
        self.build_tree_contents([('hello.txt', 'my helicopter\n'
 
58
                                                'your helicopter\n'
 
59
                                                'all of\n'
 
60
                                                'our helicopters\n'
 
61
                                  )])
 
62
        self.revision_id_4 = wt.commit('mod hello',
 
63
                              committer='user@test',
 
64
                              timestamp=1166050000.00, timezone=0)
49
65
 
50
66
    def test_help_annotate(self):
51
67
        """Annotate command exists"""
52
 
        out, err = self.run_bzr_captured(['--no-plugins', 'annotate', '--help'])
 
68
        out, err = self.run_bzr('--no-plugins annotate --help')
53
69
 
54
70
    def test_annotate_cmd(self):
55
 
        out, err = self.run_bzr_captured(['annotate', 'hello.txt'])
56
 
        self.assertEquals(err, '')
57
 
        self.assertEqualDiff(out, '''\
58
 
    1 test@us | my helicopter
59
 
''')
 
71
        out, err = self.run_bzr('annotate hello.txt')
 
72
        self.assertEqual('', err)
 
73
        self.assertEqualDiff('''\
 
74
1   test@us | my helicopter
 
75
3   user@te | your helicopter
 
76
4   user@te | all of
 
77
            | our helicopters
 
78
''', out)
 
79
 
 
80
    def test_annotate_cmd_full(self):
 
81
        out, err = self.run_bzr('annotate hello.txt --all')
 
82
        self.assertEqual('', err)
 
83
        self.assertEqualDiff('''\
 
84
1   test@us | my helicopter
 
85
3   user@te | your helicopter
 
86
4   user@te | all of
 
87
4   user@te | our helicopters
 
88
''', out)
 
89
 
 
90
    def test_annotate_cmd_long(self):
 
91
        out, err = self.run_bzr('annotate hello.txt --long')
 
92
        self.assertEqual('', err)
 
93
        self.assertEqualDiff('''\
 
94
1   test@user 20061212 | my helicopter
 
95
3   user@test 20061213 | your helicopter
 
96
4   user@test 20061213 | all of
 
97
                       | our helicopters
 
98
''', out)
 
99
 
 
100
    def test_annotate_cmd_show_ids(self):
 
101
        out, err = self.run_bzr('annotate hello.txt --show-ids')
 
102
        max_len = max([len(self.revision_id_1),
 
103
                       len(self.revision_id_3),
 
104
                       len(self.revision_id_4)])
 
105
        self.assertEqual('', err)
 
106
        self.assertEqualDiff('''\
 
107
%*s | my helicopter
 
108
%*s | your helicopter
 
109
%*s | all of
 
110
%*s | our helicopters
 
111
''' % (max_len, self.revision_id_1,
 
112
       max_len, self.revision_id_3,
 
113
       max_len, self.revision_id_4,
 
114
       max_len, '',
 
115
      )
 
116
, out)
 
117
 
 
118
    def test_no_mail(self):
 
119
        out, err = self.run_bzr('annotate nomail.txt')
 
120
        self.assertEqual('', err)
 
121
        self.assertEqualDiff('''\
 
122
2   no mail | nomail
 
123
''', out)
 
124
 
 
125
    def test_annotate_cmd_revision(self):
 
126
        out, err = self.run_bzr('annotate hello.txt -r1')
 
127
        self.assertEqual('', err)
 
128
        self.assertEqualDiff('''\
 
129
1   test@us | my helicopter
 
130
''', out)
 
131
 
 
132
    def test_annotate_cmd_revision3(self):
 
133
        out, err = self.run_bzr('annotate hello.txt -r3')
 
134
        self.assertEqual('', err)
 
135
        self.assertEqualDiff('''\
 
136
1   test@us | my helicopter
 
137
3   user@te | your helicopter
 
138
''', out)
 
139
 
 
140
    def test_annotate_cmd_unknown_revision(self):
 
141
        out, err = self.run_bzr('annotate hello.txt -r 10',
 
142
                                retcode=3)
 
143
        self.assertEqual('', out)
 
144
        self.assertContainsRe(err, "Requested revision: '10' does not exist")
 
145
 
 
146
    def test_annotate_cmd_two_revisions(self):
 
147
        out, err = self.run_bzr('annotate hello.txt -r1..2',
 
148
                                retcode=3)
 
149
        self.assertEqual('', out)
 
150
        self.assertEqual('bzr: ERROR: bzr annotate --revision takes'
 
151
                         ' exactly one revision identifier\n',
 
152
                         err)
 
153
 
 
154
 
 
155
class TestSimpleAnnotate(tests.TestCaseWithTransport):
 
156
    """Annotate tests with no complex setup."""
 
157
 
 
158
    def _setup_edited_file(self, relpath='.'):
 
159
        """Create a tree with a locally edited file."""
 
160
        tree = self.make_branch_and_tree(relpath)
 
161
        file_relpath = joinpath(relpath, 'file')
 
162
        self.build_tree_contents([(file_relpath, 'foo\ngam\n')])
 
163
        tree.add('file')
 
164
        tree.commit('add file', committer="test@host", rev_id="rev1")
 
165
        self.build_tree_contents([(file_relpath, 'foo\nbar\ngam\n')])
 
166
        return tree
 
167
 
 
168
    def test_annotate_cmd_revspec_branch(self):
 
169
        tree = self._setup_edited_file('trunk')
 
170
        tree.branch.create_checkout(self.get_url('work'), lightweight=True)
 
171
        out, err = self.run_bzr(['annotate', 'file', '-r', 'branch:../trunk'],
 
172
                                working_dir='work')
 
173
        self.assertEqual('', err)
 
174
        self.assertEqual(
 
175
            '1   test@ho | foo\n'
 
176
            '            | gam\n',
 
177
            out)
 
178
 
 
179
    def test_annotate_edited_file(self):
 
180
        tree = self._setup_edited_file()
 
181
        self.overrideEnv('BZR_EMAIL', 'current@host2')
 
182
        out, err = self.run_bzr('annotate file')
 
183
        self.assertEqual(
 
184
            '1   test@ho | foo\n'
 
185
            '2?  current | bar\n'
 
186
            '1   test@ho | gam\n',
 
187
            out)
 
188
 
 
189
    def test_annotate_edited_file_no_default(self):
 
190
        # Ensure that when no username is available annotate still works.
 
191
        self.overrideEnv('EMAIL', None)
 
192
        self.overrideEnv('BZR_EMAIL', None)
 
193
        # Also, make sure that it's not inferred from mailname.
 
194
        self.overrideAttr(config, '_auto_user_id',
 
195
            lambda: (None, None))
 
196
        tree = self._setup_edited_file()
 
197
        out, err = self.run_bzr('annotate file')
 
198
        self.assertEqual(
 
199
            '1   test@ho | foo\n'
 
200
            '2?  local u | bar\n'
 
201
            '1   test@ho | gam\n',
 
202
            out)
 
203
 
 
204
    def test_annotate_edited_file_show_ids(self):
 
205
        tree = self._setup_edited_file()
 
206
        self.overrideEnv('BZR_EMAIL', 'current@host2')
 
207
        out, err = self.run_bzr('annotate file --show-ids')
 
208
        self.assertEqual(
 
209
            '    rev1 | foo\n'
 
210
            'current: | bar\n'
 
211
            '    rev1 | gam\n',
 
212
            out)
 
213
 
 
214
    def _create_merged_file(self):
 
215
        """Create a file with a pending merge and local edit."""
 
216
        tree = self.make_branch_and_tree('.')
 
217
        self.build_tree_contents([('file', 'foo\ngam\n')])
 
218
        tree.add('file')
 
219
        tree.commit('add file', rev_id="rev1", committer="test@host")
 
220
        # right side
 
221
        self.build_tree_contents([('file', 'foo\nbar\ngam\n')])
 
222
        tree.commit("right", rev_id="rev1.1.1", committer="test@host")
 
223
        tree.pull(tree.branch, True, "rev1")
 
224
        # left side
 
225
        self.build_tree_contents([('file', 'foo\nbaz\ngam\n')])
 
226
        tree.commit("left", rev_id="rev2", committer="test@host")
 
227
        # merge
 
228
        tree.merge_from_branch(tree.branch, "rev1.1.1")
 
229
        # edit the file to be 'resolved' and have a further local edit
 
230
        self.build_tree_contents([('file', 'local\nfoo\nbar\nbaz\ngam\n')])
 
231
        return tree
 
232
 
 
233
    def test_annotated_edited_merged_file_revnos(self):
 
234
        wt = self._create_merged_file()
 
235
        out, err = self.run_bzr(['annotate', 'file'])
 
236
        email = config.extract_email_address(
 
237
            wt.branch.get_config_stack().get('email'))
 
238
        self.assertEqual(
 
239
            '3?    %-7s | local\n'
 
240
            '1     test@ho | foo\n'
 
241
            '1.1.1 test@ho | bar\n'
 
242
            '2     test@ho | baz\n'
 
243
            '1     test@ho | gam\n' % email[:7],
 
244
            out)
 
245
 
 
246
    def test_annotated_edited_merged_file_ids(self):
 
247
        self._create_merged_file()
 
248
        out, err = self.run_bzr(['annotate', 'file', '--show-ids'])
 
249
        self.assertEqual(
 
250
            'current: | local\n'
 
251
            '    rev1 | foo\n'
 
252
            'rev1.1.1 | bar\n'
 
253
            '    rev2 | baz\n'
 
254
            '    rev1 | gam\n',
 
255
            out)
 
256
 
 
257
    def test_annotate_empty_file(self):
 
258
        tree = self.make_branch_and_tree('.')
 
259
        self.build_tree_contents([('empty', '')])
 
260
        tree.add('empty')
 
261
        tree.commit('add empty file')
 
262
        out, err = self.run_bzr(['annotate', 'empty'])
 
263
        self.assertEqual('', out)
 
264
 
 
265
    def test_annotate_removed_file(self):
 
266
        tree = self.make_branch_and_tree('.')
 
267
        self.build_tree_contents([('empty', '')])
 
268
        tree.add('empty')
 
269
        tree.commit('add empty file')
 
270
        # delete the file.
 
271
        tree.remove('empty')
 
272
        tree.commit('remove empty file')
 
273
        out, err = self.run_bzr(['annotate', '-r1', 'empty'])
 
274
        self.assertEqual('', out)
 
275
 
 
276
    def test_annotate_empty_file_show_ids(self):
 
277
        tree = self.make_branch_and_tree('.')
 
278
        self.build_tree_contents([('empty', '')])
 
279
        tree.add('empty')
 
280
        tree.commit('add empty file')
 
281
        out, err = self.run_bzr(['annotate', '--show-ids', 'empty'])
 
282
        self.assertEqual('', out)
 
283
 
 
284
    def test_annotate_nonexistant_file(self):
 
285
        tree = self.make_branch_and_tree('.')
 
286
        self.build_tree(['file'])
 
287
        tree.add(['file'])
 
288
        tree.commit('add a file')
 
289
        out, err = self.run_bzr(['annotate', 'doesnotexist'], retcode=3)
 
290
        self.assertEqual('', out)
 
291
        self.assertEqual("bzr: ERROR: doesnotexist is not versioned.\n", err)
 
292
 
 
293
    def test_annotate_without_workingtree(self):
 
294
        tree = self.make_branch_and_tree('.')
 
295
        self.build_tree_contents([('empty', '')])
 
296
        tree.add('empty')
 
297
        tree.commit('add empty file')
 
298
        bzrdir = tree.branch.bzrdir
 
299
        bzrdir.destroy_workingtree()
 
300
        self.assertFalse(bzrdir.has_workingtree())
 
301
        out, err = self.run_bzr(['annotate', 'empty'])
 
302
        self.assertEqual('', out)
 
303
 
 
304
    def test_annotate_directory(self):
 
305
        """Test --directory option"""
 
306
        wt = self.make_branch_and_tree('a')
 
307
        self.build_tree_contents([('a/hello.txt', 'my helicopter\n')])
 
308
        wt.add(['hello.txt'])
 
309
        wt.commit('commit', committer='test@user')
 
310
        out, err = self.run_bzr(['annotate', '-d', 'a', 'hello.txt'])
 
311
        self.assertEqualDiff('1   test@us | my helicopter\n', out)
 
312
 
 
313
 
 
314
class TestSmartServerAnnotate(tests.TestCaseWithTransport):
 
315
 
 
316
    def test_simple_annotate(self):
 
317
        self.setup_smart_server_with_call_log()
 
318
        wt = self.make_branch_and_tree('branch')
 
319
        self.build_tree_contents([('branch/hello.txt', 'my helicopter\n')])
 
320
        wt.add(['hello.txt'])
 
321
        wt.commit('commit', committer='test@user')
 
322
        self.reset_smart_call_log()
 
323
        out, err = self.run_bzr(['annotate', "-d", self.get_url('branch'),
 
324
            "hello.txt"])
 
325
        # This figure represent the amount of work to perform this use case. It
 
326
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
327
        # being too low. If rpc_count increases, more network roundtrips have
 
328
        # become necessary for this use case. Please do not adjust this number
 
329
        # upwards without agreement from bzr's network support maintainers.
 
330
        self.assertLength(16, self.hpss_calls)
 
331
        self.assertLength(1, self.hpss_connections)
 
332
        self.expectFailure("annotate accesses inventories, which require VFS access",
 
333
            self.assertThat, self.hpss_calls, ContainsNoVfsCalls)