~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.

This is used to replace various ad hoc implementations of the same logic,
notably the version used in registry's _LazyObjectGetter which had a bug when
getting a module without also getting a member.  And of course, this new
function has unit tests, unlike the replaced code.

This also adds a KnownHooksRegistry subclass to provide a more natural home for
some other logic.

I'm not thrilled about the name of the new module or the new functions, but it's
hard to think of good names for such generic functionality.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 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
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
27
import os
28
28
 
 
29
from bzrlib.branch import Branch
 
30
from bzrlib.config import extract_email_address
29
31
from bzrlib.tests import TestCaseWithTransport
 
32
from bzrlib.urlutils import joinpath
30
33
 
31
34
 
32
35
class TestAnnotate(TestCaseWithTransport):
61
64
 
62
65
    def test_help_annotate(self):
63
66
        """Annotate command exists"""
64
 
        out, err = self.run_bzr('--no-plugins', 'annotate', '--help')
 
67
        out, err = self.run_bzr('--no-plugins annotate --help')
65
68
 
66
69
    def test_annotate_cmd(self):
67
 
        out, err = self.run_bzr('annotate', 'hello.txt')
 
70
        out, err = self.run_bzr('annotate hello.txt')
68
71
        self.assertEqual('', err)
69
72
        self.assertEqualDiff('''\
70
73
1   test@us | my helicopter
74
77
''', out)
75
78
 
76
79
    def test_annotate_cmd_full(self):
77
 
        out, err = self.run_bzr('annotate', 'hello.txt', '--all')
 
80
        out, err = self.run_bzr('annotate hello.txt --all')
78
81
        self.assertEqual('', err)
79
82
        self.assertEqualDiff('''\
80
83
1   test@us | my helicopter
84
87
''', out)
85
88
 
86
89
    def test_annotate_cmd_long(self):
87
 
        out, err = self.run_bzr('annotate', 'hello.txt', '--long')
 
90
        out, err = self.run_bzr('annotate hello.txt --long')
88
91
        self.assertEqual('', err)
89
92
        self.assertEqualDiff('''\
90
93
1   test@user 20061212 | my helicopter
94
97
''', out)
95
98
 
96
99
    def test_annotate_cmd_show_ids(self):
97
 
        out, err = self.run_bzr('annotate', 'hello.txt', '--show-ids')
 
100
        out, err = self.run_bzr('annotate hello.txt --show-ids')
98
101
        max_len = max([len(self.revision_id_1),
99
102
                       len(self.revision_id_3),
100
103
                       len(self.revision_id_4)])
112
115
, out)
113
116
 
114
117
    def test_no_mail(self):
115
 
        out, err = self.run_bzr('annotate', 'nomail.txt')
 
118
        out, err = self.run_bzr('annotate nomail.txt')
116
119
        self.assertEqual('', err)
117
120
        self.assertEqualDiff('''\
118
121
2   no mail | nomail
119
122
''', out)
120
123
 
121
124
    def test_annotate_cmd_revision(self):
122
 
        out, err = self.run_bzr('annotate', 'hello.txt', '-r1')
 
125
        out, err = self.run_bzr('annotate hello.txt -r1')
123
126
        self.assertEqual('', err)
124
127
        self.assertEqualDiff('''\
125
128
1   test@us | my helicopter
126
129
''', out)
127
130
 
128
131
    def test_annotate_cmd_revision3(self):
129
 
        out, err = self.run_bzr('annotate', 'hello.txt', '-r3')
 
132
        out, err = self.run_bzr('annotate hello.txt -r3')
130
133
        self.assertEqual('', err)
131
134
        self.assertEqualDiff('''\
132
135
1   test@us | my helicopter
134
137
''', out)
135
138
 
136
139
    def test_annotate_cmd_unknown_revision(self):
137
 
        out, err = self.run_bzr('annotate', 'hello.txt', '-r', '10',
 
140
        out, err = self.run_bzr('annotate hello.txt -r 10',
138
141
                                retcode=3)
139
142
        self.assertEqual('', out)
140
 
        self.assertContainsRe(err, 'Requested revision: \'10\' does not exist')
 
143
        self.assertContainsRe(err, "Requested revision: '10' does not exist")
141
144
 
142
145
    def test_annotate_cmd_two_revisions(self):
143
 
        out, err = self.run_bzr('annotate', 'hello.txt', '-r1..2',
 
146
        out, err = self.run_bzr('annotate hello.txt -r1..2',
144
147
                                retcode=3)
145
148
        self.assertEqual('', out)
146
149
        self.assertEqual('bzr: ERROR: bzr annotate --revision takes'
147
 
                         ' exactly 1 argument\n',
 
150
                         ' exactly one revision identifier\n',
148
151
                         err)
149
152
 
 
153
 
 
154
class TestSimpleAnnotate(TestCaseWithTransport):
 
155
    """Annotate tests with no complex setup."""
 
156
 
 
157
    def _setup_edited_file(self, relpath='.'):
 
158
        """Create a tree with a locally edited file."""
 
159
        tree = self.make_branch_and_tree(relpath)
 
160
        file_relpath = joinpath(relpath, 'file')
 
161
        self.build_tree_contents([(file_relpath, 'foo\ngam\n')])
 
162
        tree.add('file')
 
163
        tree.commit('add file', committer="test@host", rev_id="rev1")
 
164
        self.build_tree_contents([(file_relpath, 'foo\nbar\ngam\n')])
 
165
        tree.branch.get_config().set_user_option('email', 'current@host2')
 
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
        os.chdir('work')
 
172
        out, err = self.run_bzr('annotate file -r branch:../trunk')
 
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
        out, err = self.run_bzr('annotate file')
 
182
        self.assertEqual(
 
183
            '1   test@ho | foo\n'
 
184
            '2?  current | bar\n'
 
185
            '1   test@ho | gam\n',
 
186
            out)
 
187
 
 
188
    def test_annotate_edited_file_show_ids(self):
 
189
        tree = self._setup_edited_file()
 
190
        out, err = self.run_bzr('annotate file --show-ids')
 
191
        self.assertEqual(
 
192
            '    rev1 | foo\n'
 
193
            'current: | bar\n'
 
194
            '    rev1 | gam\n',
 
195
            out)
 
196
 
 
197
    def _create_merged_file(self):
 
198
        """Create a file with a pending merge and local edit."""
 
199
        tree = self.make_branch_and_tree('.')
 
200
        self.build_tree_contents([('file', 'foo\ngam\n')])
 
201
        tree.add('file')
 
202
        tree.commit('add file', rev_id="rev1", committer="test@host")
 
203
        # right side
 
204
        self.build_tree_contents([('file', 'foo\nbar\ngam\n')])
 
205
        tree.commit("right", rev_id="rev1.1.1", committer="test@host")
 
206
        tree.pull(tree.branch, True, "rev1")
 
207
        # left side
 
208
        self.build_tree_contents([('file', 'foo\nbaz\ngam\n')])
 
209
        tree.commit("left", rev_id="rev2", committer="test@host")
 
210
        # merge
 
211
        tree.merge_from_branch(tree.branch, "rev1.1.1")
 
212
        # edit the file to be 'resolved' and have a further local edit
 
213
        self.build_tree_contents([('file', 'local\nfoo\nbar\nbaz\ngam\n')])
 
214
 
 
215
    def test_annotated_edited_merged_file_revnos(self):
 
216
        self._create_merged_file()
 
217
        out, err = self.run_bzr('annotate file')
 
218
        email = extract_email_address(Branch.open('.').get_config().username())
 
219
        self.assertEqual(
 
220
            '3?    %-7s | local\n'
 
221
            '1     test@ho | foo\n'
 
222
            '1.1.1 test@ho | bar\n'
 
223
            '2     test@ho | baz\n'
 
224
            '1     test@ho | gam\n' % email[:7],
 
225
            out)
 
226
 
 
227
    def test_annotated_edited_merged_file_ids(self):
 
228
        self._create_merged_file()
 
229
        out, err = self.run_bzr('annotate file --show-ids')
 
230
        self.assertEqual(
 
231
            'current: | local\n'
 
232
            '    rev1 | foo\n'
 
233
            'rev1.1.1 | bar\n'
 
234
            '    rev2 | baz\n'
 
235
            '    rev1 | gam\n',
 
236
            out)
 
237
 
150
238
    def test_annotate_empty_file(self):
151
239
        tree = self.make_branch_and_tree('tree')
152
240
        self.build_tree_contents([('tree/empty', '')])
154
242
        tree.commit('add empty file')
155
243
 
156
244
        os.chdir('tree')
157
 
        out, err = self.run_bzr('annotate', 'empty')
158
 
        self.assertEqual('', out)
 
245
        out, err = self.run_bzr('annotate empty')
 
246
        self.assertEqual('', out)
 
247
 
 
248
    def test_annotate_empty_file_show_ids(self):
 
249
        tree = self.make_branch_and_tree('tree')
 
250
        self.build_tree_contents([('tree/empty', '')])
 
251
        tree.add('empty')
 
252
        tree.commit('add empty file')
 
253
 
 
254
        os.chdir('tree')
 
255
        out, err = self.run_bzr(['annotate', '--show-ids', 'empty'])
 
256
        self.assertEqual('', out)
 
257
 
 
258
    def test_annotate_nonexistant_file(self):
 
259
        tree = self.make_branch_and_tree('tree')
 
260
        self.build_tree(['tree/file'])
 
261
        tree.add(['file'])
 
262
        tree.commit('add a file')
 
263
 
 
264
        os.chdir('tree')
 
265
        out, err = self.run_bzr("annotate doesnotexist", retcode=3)
 
266
        self.assertEqual('', out)
 
267
        self.assertEqual("bzr: ERROR: doesnotexist is not versioned.\n", err)
 
268
 
 
269
    def test_annotate_without_workingtree(self):
 
270
        tree = self.make_branch_and_tree('branch')
 
271
        self.build_tree_contents([('branch/empty', '')])
 
272
        tree.add('empty')
 
273
        tree.commit('add empty file')
 
274
        bzrdir = tree.branch.bzrdir
 
275
        bzrdir.destroy_workingtree()
 
276
        self.assertFalse(bzrdir.has_workingtree())
 
277
 
 
278
        os.chdir('branch')
 
279
        out, err = self.run_bzr('annotate empty')
 
280
        self.assertEqual('', out)
 
281
 
 
282
    def test_annotate_directory(self):
 
283
        """Test --directory option"""
 
284
        wt = self.make_branch_and_tree('a')
 
285
        self.build_tree_contents([('a/hello.txt', 'my helicopter\n')])
 
286
        wt.add(['hello.txt'])
 
287
        wt.commit('commit', committer='test@user')
 
288
        out, err = self.run_bzr('annotate -d a hello.txt')
 
289
        self.assertEqualDiff('1   test@us | my helicopter\n', out)