/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-09-25 01:02:51 UTC
  • mfrom: (2853.1.1 transport.put)
  • Revision ID: pqm@pqm.ubuntu.com-20070925010251-tjzcun2wc2l4grec
(robertc) Transport.put_file now returns the number of bytes written. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
2
 
 
 
1
# Copyright (C) 2005, 2006 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
17
17
 
18
18
"""Tests for the commit CLI of bzr."""
19
19
 
20
 
from cStringIO import StringIO
21
20
import os
22
 
import re
23
 
import shutil
24
 
import sys
25
21
 
26
 
from bzrlib.branch import Branch
27
 
import bzrlib.bzrdir as bzrdir
28
 
from bzrlib.errors import BzrCommandError
 
22
from bzrlib import (
 
23
    osutils,
 
24
    ignores,
 
25
    )
 
26
from bzrlib.bzrdir import BzrDir
29
27
from bzrlib.tests.blackbox import ExternalBase
30
 
from bzrlib.workingtree import WorkingTree
31
28
 
32
29
 
33
30
class TestCommit(ExternalBase):
35
32
    def test_05_empty_commit(self):
36
33
        """Commit of tree with no versioned files should fail"""
37
34
        # If forced, it should succeed, but this is not tested here.
38
 
        self.runbzr("init")
 
35
        self.make_branch_and_tree('.')
39
36
        self.build_tree(['hello.txt'])
40
 
        self.runbzr("commit -m empty", retcode=3)
 
37
        out,err = self.run_bzr('commit -m empty', retcode=3)
 
38
        self.assertEqual('', out)
 
39
        self.assertContainsRe(err, 'bzr: ERROR: no changes to commit\.'
 
40
                                  ' use --unchanged to commit anyhow\n')
 
41
 
 
42
    def test_commit_success(self):
 
43
        """Successful commit should not leave behind a bzr-commit-* file"""
 
44
        self.make_branch_and_tree('.')
 
45
        self.run_bzr('commit --unchanged -m message')
 
46
        self.assertEqual('', self.run_bzr('unknowns')[0])
 
47
 
 
48
        # same for unicode messages
 
49
        self.run_bzr(["commit", "--unchanged", "-m", u'foo\xb5'])
 
50
        self.assertEqual('', self.run_bzr('unknowns')[0])
 
51
 
 
52
    def test_commit_with_path(self):
 
53
        """Commit tree with path of root specified"""
 
54
        a_tree = self.make_branch_and_tree('a')
 
55
        self.build_tree(['a/a_file'])
 
56
        a_tree.add('a_file')
 
57
        self.run_bzr(['commit', '-m', 'first commit', 'a'])
 
58
 
 
59
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
60
        self.build_tree_contents([('b/a_file', 'changes in b')])
 
61
        self.run_bzr(['commit', '-m', 'first commit in b', 'b'])
 
62
 
 
63
        self.build_tree_contents([('a/a_file', 'new contents')])
 
64
        self.run_bzr(['commit', '-m', 'change in a', 'a'])
 
65
 
 
66
        b_tree.merge_from_branch(a_tree.branch)
 
67
        self.assertEqual(len(b_tree.conflicts()), 1)
 
68
        self.run_bzr('resolved b/a_file')
 
69
        self.run_bzr(['commit', '-m', 'merge into b', 'b'])
 
70
 
41
71
 
42
72
    def test_10_verbose_commit(self):
43
73
        """Add one file and examine verbose commit output"""
44
 
        self.runbzr("init")
 
74
        tree = self.make_branch_and_tree('.')
45
75
        self.build_tree(['hello.txt'])
46
 
        self.runbzr("add hello.txt")
47
 
        out,err = self.run_bzr("commit", "-m", "added")
48
 
        self.assertEqual('', out)
49
 
        self.assertEqual('added hello.txt\n'
50
 
                         'Committed revision 1.\n',
51
 
                         err)
52
 
 
53
 
    def test_15_verbose_commit_with_unknown(self):
 
76
        tree.add("hello.txt")
 
77
        out,err = self.run_bzr('commit -m added')
 
78
        self.assertEqual('', out)
 
79
        self.assertContainsRe(err, '^Committing revision 1 to ".*"\.\n'
 
80
                              'added hello.txt\n'
 
81
                              'Committed revision 1.\n$',)
 
82
 
 
83
    def prepare_simple_history(self):
 
84
        """Prepare and return a working tree with one commit of one file"""
 
85
        # Commit with modified file should say so
 
86
        wt = BzrDir.create_standalone_workingtree('.')
 
87
        self.build_tree(['hello.txt', 'extra.txt'])
 
88
        wt.add(['hello.txt'])
 
89
        wt.commit(message='added')
 
90
        return wt
 
91
 
 
92
    def test_verbose_commit_modified(self):
 
93
        # Verbose commit of modified file should say so
 
94
        wt = self.prepare_simple_history()
 
95
        self.build_tree_contents([('hello.txt', 'new contents')])
 
96
        out, err = self.run_bzr('commit -m modified')
 
97
        self.assertEqual('', out)
 
98
        self.assertContainsRe(err, '^Committing revision 2 to ".*"\.\n'
 
99
                              'modified hello\.txt\n'
 
100
                              'Committed revision 2\.\n$')
 
101
 
 
102
    def test_verbose_commit_renamed(self):
 
103
        # Verbose commit of renamed file should say so
 
104
        wt = self.prepare_simple_history()
 
105
        wt.rename_one('hello.txt', 'gutentag.txt')
 
106
        out, err = self.run_bzr('commit -m renamed')
 
107
        self.assertEqual('', out)
 
108
        self.assertContainsRe(err, '^Committing revision 2 to ".*"\.\n'
 
109
                              'renamed hello\.txt => gutentag\.txt\n'
 
110
                              'Committed revision 2\.$\n')
 
111
 
 
112
    def test_verbose_commit_moved(self):
 
113
        # Verbose commit of file moved to new directory should say so
 
114
        wt = self.prepare_simple_history()
 
115
        os.mkdir('subdir')
 
116
        wt.add(['subdir'])
 
117
        wt.rename_one('hello.txt', 'subdir/hello.txt')
 
118
        out, err = self.run_bzr('commit -m renamed')
 
119
        self.assertEqual('', out)
 
120
        self.assertContainsRe(err, '^Committing revision 2 to ".*"\.\n'
 
121
                              'added subdir\n'
 
122
                              'renamed hello\.txt => subdir/hello\.txt\n'
 
123
                              'Committed revision 2\.\n$')
 
124
 
 
125
    def test_verbose_commit_with_unknown(self):
54
126
        """Unknown files should not be listed by default in verbose output"""
55
127
        # Is that really the best policy?
56
 
        self.runbzr("init")
 
128
        wt = BzrDir.create_standalone_workingtree('.')
57
129
        self.build_tree(['hello.txt', 'extra.txt'])
58
 
        self.runbzr("add hello.txt")
59
 
        out,err = self.run_bzr("commit", "-m", "added")
 
130
        wt.add(['hello.txt'])
 
131
        out,err = self.run_bzr('commit -m added')
60
132
        self.assertEqual('', out)
61
 
        self.assertEqual('added hello.txt\n'
62
 
                         'Committed revision 1.\n',
63
 
                         err)
 
133
        self.assertContainsRe(err, '^Committing revision 1 to ".*"\.\n'
 
134
                              'added hello\.txt\n'
 
135
                              'Committed revision 1\.\n$')
64
136
 
65
 
    def test_16_verbose_commit_with_unchanged(self):
 
137
    def test_verbose_commit_with_unchanged(self):
66
138
        """Unchanged files should not be listed by default in verbose output"""
67
 
        self.runbzr("init")
 
139
        tree = self.make_branch_and_tree('.')
68
140
        self.build_tree(['hello.txt', 'unchanged.txt'])
69
 
        self.runbzr('add unchanged.txt')
70
 
        self.runbzr('commit -m unchanged unchanged.txt')
71
 
        self.runbzr("add hello.txt")
72
 
        out,err = self.run_bzr("commit", "-m", "added")
73
 
        self.assertEqual('', out)
74
 
        self.assertEqual('added hello.txt\n'
75
 
                         'Committed revision 2.\n',
76
 
                         err)
 
141
        tree.add('unchanged.txt')
 
142
        self.run_bzr('commit -m unchanged unchanged.txt')
 
143
        tree.add("hello.txt")
 
144
        out,err = self.run_bzr('commit -m added')
 
145
        self.assertEqual('', out)
 
146
        self.assertContainsRe(err, '^Committing revision 2 to ".*"\.\n'
 
147
                              'added hello\.txt\n'
 
148
                              'Committed revision 2\.$\n')
 
149
 
 
150
    def test_verbose_commit_includes_master_location(self):
 
151
        """Location of master is displayed when committing to bound branch"""
 
152
        a_tree = self.make_branch_and_tree('a')
 
153
        self.build_tree(['a/b'])
 
154
        a_tree.add('b')
 
155
        a_tree.commit(message='Initial message')
 
156
 
 
157
        b_tree = a_tree.branch.create_checkout('b')
 
158
        expected = "%s/" % (osutils.abspath('a'), )
 
159
        out, err = self.run_bzr('commit -m blah --unchanged', working_dir='b')
 
160
        self.assertEqual(err, 'Committing revision 2 to "%s".\n'
 
161
                         'Committed revision 2.\n' % expected)
 
162
 
 
163
    def test_commit_merge_reports_all_modified_files(self):
 
164
        # the commit command should show all the files that are shown by
 
165
        # bzr diff or bzr status when committing, even when they were not
 
166
        # changed by the user but rather through doing a merge.
 
167
        this_tree = self.make_branch_and_tree('this')
 
168
        # we need a bunch of files and dirs, to perform one action on each.
 
169
        self.build_tree([
 
170
            'this/dirtorename/',
 
171
            'this/dirtoreparent/',
 
172
            'this/dirtoleave/',
 
173
            'this/dirtoremove/',
 
174
            'this/filetoreparent',
 
175
            'this/filetorename',
 
176
            'this/filetomodify',
 
177
            'this/filetoremove',
 
178
            'this/filetoleave']
 
179
            )
 
180
        this_tree.add([
 
181
            'dirtorename',
 
182
            'dirtoreparent',
 
183
            'dirtoleave',
 
184
            'dirtoremove',
 
185
            'filetoreparent',
 
186
            'filetorename',
 
187
            'filetomodify',
 
188
            'filetoremove',
 
189
            'filetoleave']
 
190
            )
 
191
        this_tree.commit('create_files')
 
192
        other_dir = this_tree.bzrdir.sprout('other')
 
193
        other_tree = other_dir.open_workingtree()
 
194
        other_tree.lock_write()
 
195
        # perform the needed actions on the files and dirs.
 
196
        try:
 
197
            other_tree.rename_one('dirtorename', 'renameddir')
 
198
            other_tree.rename_one('dirtoreparent', 'renameddir/reparenteddir')
 
199
            other_tree.rename_one('filetorename', 'renamedfile')
 
200
            other_tree.rename_one('filetoreparent',
 
201
                                  'renameddir/reparentedfile')
 
202
            other_tree.remove(['dirtoremove', 'filetoremove'])
 
203
            self.build_tree_contents([
 
204
                ('other/newdir/',),
 
205
                ('other/filetomodify', 'new content'),
 
206
                ('other/newfile', 'new file content')])
 
207
            other_tree.add('newfile')
 
208
            other_tree.add('newdir/')
 
209
            other_tree.commit('modify all sample files and dirs.')
 
210
        finally:
 
211
            other_tree.unlock()
 
212
        this_tree.merge_from_branch(other_tree.branch)
 
213
        os.chdir('this')
 
214
        out,err = self.run_bzr('commit -m added')
 
215
        self.assertEqual('', out)
 
216
        expected = '%s/' % (osutils.getcwd(), )
 
217
        self.assertEqualDiff(
 
218
            'Committing revision 2 to "%s".\n'
 
219
            'modified filetomodify\n'
 
220
            'added newdir\n'
 
221
            'added newfile\n'
 
222
            'renamed dirtorename => renameddir\n'
 
223
            'renamed filetorename => renamedfile\n'
 
224
            'renamed dirtoreparent => renameddir/reparenteddir\n'
 
225
            'renamed filetoreparent => renameddir/reparentedfile\n'
 
226
            'deleted dirtoremove\n'
 
227
            'deleted filetoremove\n'
 
228
            'Committed revision 2.\n' % (expected, ),
 
229
            err)
77
230
 
78
231
    def test_empty_commit_message(self):
79
 
        self.runbzr("init")
80
 
        file('foo.c', 'wt').write('int main() {}')
81
 
        self.runbzr(['add', 'foo.c'])
82
 
        self.runbzr(["commit", "-m", ""] , retcode=3)
 
232
        tree = self.make_branch_and_tree('.')
 
233
        self.build_tree_contents([('foo.c', 'int main() {}')])
 
234
        tree.add('foo.c')
 
235
        self.run_bzr('commit -m ""', retcode=3)
 
236
 
 
237
    def test_unsupported_encoding_commit_message(self):
 
238
        tree = self.make_branch_and_tree('.')
 
239
        self.build_tree_contents([('foo.c', 'int main() {}')])
 
240
        tree.add('foo.c')
 
241
        out,err = self.run_bzr_subprocess('commit -m "\xff"', retcode=1,
 
242
                                                    env_changes={'LANG': 'C'})
 
243
        self.assertContainsRe(err, r'bzrlib.errors.BzrError: Parameter.*is '
 
244
                                    'unsupported by the current encoding.')
83
245
 
84
246
    def test_other_branch_commit(self):
85
247
        # this branch is to ensure consistent behaviour, whether we're run
86
248
        # inside a branch, or not.
87
 
        os.mkdir('empty_branch')
88
 
        os.chdir('empty_branch')
89
 
        self.runbzr('init')
90
 
        os.mkdir('branch')
91
 
        os.chdir('branch')
92
 
        self.runbzr('init')
93
 
        file('foo.c', 'wt').write('int main() {}')
94
 
        file('bar.c', 'wt').write('int main() {}')
95
 
        os.chdir('..')
96
 
        self.runbzr(['add', 'branch/foo.c'])
97
 
        self.runbzr(['add', 'branch'])
 
249
        outer_tree = self.make_branch_and_tree('.')
 
250
        inner_tree = self.make_branch_and_tree('branch')
 
251
        self.build_tree_contents([
 
252
            ('branch/foo.c', 'int main() {}'),
 
253
            ('branch/bar.c', 'int main() {}')])
 
254
        inner_tree.add('foo.c')
 
255
        inner_tree.add('bar.c')
98
256
        # can't commit files in different trees; sane error
99
 
        self.runbzr('commit -m newstuff branch/foo.c .', retcode=3)
100
 
        self.runbzr('commit -m newstuff branch/foo.c')
101
 
        self.runbzr('commit -m newstuff branch')
102
 
        self.runbzr('commit -m newstuff branch', retcode=3)
 
257
        self.run_bzr('commit -m newstuff branch/foo.c .', retcode=3)
 
258
        self.run_bzr('commit -m newstuff branch/foo.c')
 
259
        self.run_bzr('commit -m newstuff branch')
 
260
        self.run_bzr('commit -m newstuff branch', retcode=3)
103
261
 
104
262
    def test_out_of_date_tree_commit(self):
105
263
        # check we get an error code and a clear message committing with an out
106
264
        # of date checkout
107
 
        self.make_branch_and_tree('branch')
 
265
        tree = self.make_branch_and_tree('branch')
108
266
        # make a checkout
109
 
        self.runbzr('checkout --lightweight branch checkout')
 
267
        checkout = tree.branch.create_checkout('checkout', lightweight=True)
110
268
        # commit to the original branch to make the checkout out of date
111
 
        self.runbzr('commit --unchanged -m message branch')
 
269
        tree.commit('message branch', allow_pointless=True)
112
270
        # now commit to the checkout should emit
113
271
        # ERROR: Out of date with the branch, 'bzr update' is suggested
114
 
        output = self.runbzr('commit --unchanged -m checkout_message '
 
272
        output = self.run_bzr('commit --unchanged -m checkout_message '
115
273
                             'checkout', retcode=3)
116
274
        self.assertEqual(output,
117
275
                         ('',
118
 
                          "bzr: ERROR: Working tree is out of date, please run "
119
 
                          "'bzr update'.\n"))
 
276
                          "bzr: ERROR: Working tree is out of date, please "
 
277
                          "run 'bzr update'.\n"))
120
278
 
121
279
    def test_local_commit_unbound(self):
122
280
        # a --local commit on an unbound branch is an error
123
281
        self.make_branch_and_tree('.')
124
 
        out, err = self.run_bzr('commit', '--local', retcode=3)
 
282
        out, err = self.run_bzr('commit --local', retcode=3)
125
283
        self.assertEqualDiff('', out)
126
284
        self.assertEqualDiff('bzr: ERROR: Cannot perform local-only commits '
127
285
                             'on unbound branches.\n', err)
 
286
 
 
287
    def test_commit_a_text_merge_in_a_checkout(self):
 
288
        # checkouts perform multiple actions in a transaction across bond
 
289
        # branches and their master, and have been observed to fail in the
 
290
        # past. This is a user story reported to fail in bug #43959 where 
 
291
        # a merge done in a checkout (using the update command) failed to
 
292
        # commit correctly.
 
293
        trunk = self.make_branch_and_tree('trunk')
 
294
 
 
295
        u1 = trunk.branch.create_checkout('u1')
 
296
        self.build_tree_contents([('u1/hosts', 'initial contents')])
 
297
        u1.add('hosts')
 
298
        self.run_bzr('commit -m add-hosts u1')
 
299
 
 
300
        u2 = trunk.branch.create_checkout('u2')
 
301
        self.build_tree_contents([('u2/hosts', 'altered in u2')])
 
302
        self.run_bzr('commit -m checkin-from-u2 u2')
 
303
 
 
304
        # make an offline commits
 
305
        self.build_tree_contents([('u1/hosts', 'first offline change in u1')])
 
306
        self.run_bzr('commit -m checkin-offline --local u1')
 
307
 
 
308
        # now try to pull in online work from u2, and then commit our offline
 
309
        # work as a merge
 
310
        # retcode 1 as we expect a text conflict
 
311
        self.run_bzr('update u1', retcode=1)
 
312
        self.run_bzr('resolved u1/hosts')
 
313
        # add a text change here to represent resolving the merge conflicts in
 
314
        # favour of a new version of the file not identical to either the u1
 
315
        # version or the u2 version.
 
316
        self.build_tree_contents([('u1/hosts', 'merge resolution\n')])
 
317
        self.run_bzr('commit -m checkin-merge-of-the-offline-work-from-u1 u1')
 
318
 
 
319
    def test_commit_respects_spec_for_removals(self):
 
320
        """Commit with a file spec should only commit removals that match"""
 
321
        t = self.make_branch_and_tree('.')
 
322
        self.build_tree(['file-a', 'dir-a/', 'dir-a/file-b'])
 
323
        t.add(['file-a', 'dir-a', 'dir-a/file-b'])
 
324
        t.commit('Create')
 
325
        t.remove(['file-a', 'dir-a/file-b'])
 
326
        os.chdir('dir-a')
 
327
        result = self.run_bzr('commit . -m removed-file-b')[1]
 
328
        self.assertNotContainsRe(result, 'file-a')
 
329
        result = self.run_bzr('status')[0]
 
330
        self.assertContainsRe(result, 'removed:\n  file-a')
 
331
 
 
332
    def test_strict_commit(self):
 
333
        """Commit with --strict works if everything is known"""
 
334
        ignores._set_user_ignores([])
 
335
        tree = self.make_branch_and_tree('tree')
 
336
        self.build_tree(['tree/a'])
 
337
        tree.add('a')
 
338
        # A simple change should just work
 
339
        self.run_bzr('commit --strict -m adding-a',
 
340
                     working_dir='tree')
 
341
 
 
342
    def test_strict_commit_no_changes(self):
 
343
        """commit --strict gives "no changes" if there is nothing to commit"""
 
344
        tree = self.make_branch_and_tree('tree')
 
345
        self.build_tree(['tree/a'])
 
346
        tree.add('a')
 
347
        tree.commit('adding a')
 
348
 
 
349
        # With no changes, it should just be 'no changes'
 
350
        # Make sure that commit is failing because there is nothing to do
 
351
        self.run_bzr_error(['no changes to commit'],
 
352
                           'commit --strict -m no-changes',
 
353
                           working_dir='tree')
 
354
 
 
355
        # But --strict doesn't care if you supply --unchanged
 
356
        self.run_bzr('commit --strict --unchanged -m no-changes',
 
357
                     working_dir='tree')
 
358
 
 
359
    def test_strict_commit_unknown(self):
 
360
        """commit --strict fails if a file is unknown"""
 
361
        tree = self.make_branch_and_tree('tree')
 
362
        self.build_tree(['tree/a'])
 
363
        tree.add('a')
 
364
        tree.commit('adding a')
 
365
 
 
366
        # Add one file so there is a change, but forget the other
 
367
        self.build_tree(['tree/b', 'tree/c'])
 
368
        tree.add('b')
 
369
        self.run_bzr_error(['Commit refused because there are unknown files'],
 
370
                           'commit --strict -m add-b',
 
371
                           working_dir='tree')
 
372
 
 
373
        # --no-strict overrides --strict
 
374
        self.run_bzr('commit --strict -m add-b --no-strict',
 
375
                     working_dir='tree')
 
376
 
 
377
    def test_fixes_bug_output(self):
 
378
        """commit --fixes=lp:23452 succeeds without output."""
 
379
        tree = self.make_branch_and_tree('tree')
 
380
        self.build_tree(['tree/hello.txt'])
 
381
        tree.add('hello.txt')
 
382
        output, err = self.run_bzr(
 
383
            'commit -m hello --fixes=lp:23452 tree/hello.txt')
 
384
        self.assertEqual('', output)
 
385
        self.assertContainsRe(err, 'Committing revision 1 to ".*"\.\n'
 
386
                              'added hello\.txt\n'
 
387
                              'Committed revision 1\.\n')
 
388
 
 
389
    def test_no_bugs_no_properties(self):
 
390
        """If no bugs are fixed, the bugs property is not set.
 
391
 
 
392
        see https://beta.launchpad.net/bzr/+bug/109613
 
393
        """
 
394
        tree = self.make_branch_and_tree('tree')
 
395
        self.build_tree(['tree/hello.txt'])
 
396
        tree.add('hello.txt')
 
397
        self.run_bzr( 'commit -m hello tree/hello.txt')
 
398
        # Get the revision properties, ignoring the branch-nick property, which
 
399
        # we don't care about for this test.
 
400
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
401
        properties = dict(last_rev.properties)
 
402
        del properties['branch-nick']
 
403
        self.assertFalse('bugs' in properties)
 
404
 
 
405
    def test_fixes_bug_sets_property(self):
 
406
        """commit --fixes=lp:234 sets the lp:234 revprop to 'fixed'."""
 
407
        tree = self.make_branch_and_tree('tree')
 
408
        self.build_tree(['tree/hello.txt'])
 
409
        tree.add('hello.txt')
 
410
        self.run_bzr('commit -m hello --fixes=lp:234 tree/hello.txt')
 
411
 
 
412
        # Get the revision properties, ignoring the branch-nick property, which
 
413
        # we don't care about for this test.
 
414
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
415
        properties = dict(last_rev.properties)
 
416
        del properties['branch-nick']
 
417
 
 
418
        self.assertEqual({'bugs': 'https://launchpad.net/bugs/234 fixed'},
 
419
                         properties)
 
420
 
 
421
    def test_fixes_multiple_bugs_sets_properties(self):
 
422
        """--fixes can be used more than once to show that bugs are fixed."""
 
423
        tree = self.make_branch_and_tree('tree')
 
424
        self.build_tree(['tree/hello.txt'])
 
425
        tree.add('hello.txt')
 
426
        self.run_bzr('commit -m hello --fixes=lp:123 --fixes=lp:235'
 
427
                     ' tree/hello.txt')
 
428
 
 
429
        # Get the revision properties, ignoring the branch-nick property, which
 
430
        # we don't care about for this test.
 
431
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
432
        properties = dict(last_rev.properties)
 
433
        del properties['branch-nick']
 
434
 
 
435
        self.assertEqual(
 
436
            {'bugs': 'https://launchpad.net/bugs/123 fixed\n'
 
437
                     'https://launchpad.net/bugs/235 fixed'},
 
438
            properties)
 
439
 
 
440
    def test_fixes_bug_with_alternate_trackers(self):
 
441
        """--fixes can be used on a properly configured branch to mark bug
 
442
        fixes on multiple trackers.
 
443
        """
 
444
        tree = self.make_branch_and_tree('tree')
 
445
        tree.branch.get_config().set_user_option(
 
446
            'trac_twisted_url', 'http://twistedmatrix.com/trac')
 
447
        self.build_tree(['tree/hello.txt'])
 
448
        tree.add('hello.txt')
 
449
        self.run_bzr('commit -m hello --fixes=lp:123 --fixes=twisted:235 tree/')
 
450
 
 
451
        # Get the revision properties, ignoring the branch-nick property, which
 
452
        # we don't care about for this test.
 
453
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
454
        properties = dict(last_rev.properties)
 
455
        del properties['branch-nick']
 
456
 
 
457
        self.assertEqual(
 
458
            {'bugs': 'https://launchpad.net/bugs/123 fixed\n'
 
459
                     'http://twistedmatrix.com/trac/ticket/235 fixed'},
 
460
            properties)
 
461
 
 
462
    def test_fixes_unknown_bug_prefix(self):
 
463
        tree = self.make_branch_and_tree('tree')
 
464
        self.build_tree(['tree/hello.txt'])
 
465
        tree.add('hello.txt')
 
466
        self.run_bzr_error(
 
467
            ["Unrecognized bug %s. Commit refused." % 'xxx:123'],
 
468
            'commit -m add-b --fixes=xxx:123',
 
469
            working_dir='tree')
 
470
 
 
471
    def test_fixes_invalid_bug_number(self):
 
472
        tree = self.make_branch_and_tree('tree')
 
473
        self.build_tree(['tree/hello.txt'])
 
474
        tree.add('hello.txt')
 
475
        self.run_bzr_error(
 
476
            ["Invalid bug identifier for %s. Commit refused." % 'lp:orange'],
 
477
            'commit -m add-b --fixes=lp:orange',
 
478
            working_dir='tree')
 
479
 
 
480
    def test_fixes_invalid_argument(self):
 
481
        """Raise an appropriate error when the fixes argument isn't tag:id."""
 
482
        tree = self.make_branch_and_tree('tree')
 
483
        self.build_tree(['tree/hello.txt'])
 
484
        tree.add('hello.txt')
 
485
        self.run_bzr_error(
 
486
            [r"Invalid bug orange. Must be in the form of 'tag:id'\. "
 
487
             r"Commit refused\."],
 
488
            'commit -m add-b --fixes=orange',
 
489
            working_dir='tree')
 
490
 
 
491
    def test_no_author(self):
 
492
        """If the author is not specified, the author property is not set."""
 
493
        tree = self.make_branch_and_tree('tree')
 
494
        self.build_tree(['tree/hello.txt'])
 
495
        tree.add('hello.txt')
 
496
        self.run_bzr( 'commit -m hello tree/hello.txt')
 
497
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
498
        properties = last_rev.properties
 
499
        self.assertFalse('author' in properties)
 
500
 
 
501
    def test_author_sets_property(self):
 
502
        """commit --author='John Doe <jdoe@example.com>' sets the author
 
503
           revprop.
 
504
        """
 
505
        tree = self.make_branch_and_tree('tree')
 
506
        self.build_tree(['tree/hello.txt'])
 
507
        tree.add('hello.txt')
 
508
        self.run_bzr("commit -m hello --author='John Doe <jdoe@example.com>' "
 
509
                     "tree/hello.txt")
 
510
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
511
        properties = last_rev.properties
 
512
        self.assertEqual('John Doe <jdoe@example.com>', properties['author'])
 
513
 
 
514
    def test_author_no_email(self):
 
515
        """Author's name without an email address is allowed, too."""
 
516
        tree = self.make_branch_and_tree('tree')
 
517
        self.build_tree(['tree/hello.txt'])
 
518
        tree.add('hello.txt')
 
519
        out, err = self.run_bzr("commit -m hello --author='John Doe' "
 
520
                                "tree/hello.txt")
 
521
        last_rev = tree.branch.repository.get_revision(tree.last_revision())
 
522
        properties = last_rev.properties
 
523
        self.assertEqual('John Doe', properties['author'])