/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.3 by John Arbash Meinel
Merge bzr.dev 5007, resolve conflict, update NEWS
1
# Copyright (C) 2006-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
16
17
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
18
"""Black-box tests for bzr log."""
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
19
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
20
from itertools import izip
4325.4.3 by Vincent Ladeuil
More cleanups.
21
import os
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
22
4325.4.3 by Vincent Ladeuil
More cleanups.
23
from bzrlib import (
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
24
    branchbuilder,
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
25
    errors,
4955.5.2 by Vincent Ladeuil
Simplify tests.
26
    log,
4325.4.3 by Vincent Ladeuil
More cleanups.
27
    osutils,
28
    tests,
2978.6.1 by Kent Gibson
Use normalize_log to more accurately test blackbox log output.
29
    )
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
30
from bzrlib.tests import (
31
    test_log,
5971.1.49 by Jonathan Riddell
import features in test
32
    features,
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
33
    )
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
34
35
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
36
class TestLog(tests.TestCaseWithTransport, test_log.TestLogMixin):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
37
38
    def make_minimal_branch(self, path='.', format=None):
39
        tree = self.make_branch_and_tree(path, format=format)
40
        self.build_tree([path + '/hello.txt'])
41
        tree.add('hello.txt')
42
        tree.commit(message='message1')
43
        return tree
44
45
    def make_linear_branch(self, path='.', format=None):
2809.1.2 by Daniel Watkins
Removed unnecessary check as per abentley's on-list comments.
46
        tree = self.make_branch_and_tree(path, format=format)
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
47
        self.build_tree(
48
            [path + '/hello.txt', path + '/goodbye.txt', path + '/meep.txt'])
49
        tree.add('hello.txt')
50
        tree.commit(message='message1')
51
        tree.add('goodbye.txt')
52
        tree.commit(message='message2')
53
        tree.add('meep.txt')
54
        tree.commit(message='message3')
55
        return tree
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
56
4369.2.1 by Marius Kruger
add some leftover log tests
57
    def make_merged_branch(self, path='.', format=None):
4369.2.2 by Marius Kruger
use make_linear_branch in make_merged_branch
58
        tree = self.make_linear_branch(path, format)
59
        tree2 = tree.bzrdir.sprout('tree2',
60
            revision_id=tree.branch.get_rev_id(1)).open_workingtree()
4369.2.1 by Marius Kruger
add some leftover log tests
61
        tree2.commit(message='tree2 message2')
62
        tree2.commit(message='tree2 message3')
63
        tree.merge_from_branch(tree2.branch)
64
        tree.commit(message='merge')
65
        return tree
66
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
67
4955.5.2 by Vincent Ladeuil
Simplify tests.
68
class TestLogWithLogCatcher(TestLog):
69
70
    def setUp(self):
71
        super(TestLogWithLogCatcher, self).setUp()
5340.12.14 by Martin
Revert changes to bb.test_log which caused some failures
72
        # Capture log formatter creations
4955.5.2 by Vincent Ladeuil
Simplify tests.
73
        class MyLogFormatter(test_log.LogCatcher):
74
5340.12.14 by Martin
Revert changes to bb.test_log which caused some failures
75
            def __new__(klass, *args, **kwargs):
76
                self.log_catcher = test_log.LogCatcher(*args, **kwargs)
77
                # Always return our own log formatter
78
                return self.log_catcher
5901.1.1 by John Arbash Meinel
Re-apply the bits of TestCase that I wanted, on the new bzr.dev tip.
79
        # Break cycle with closure over self on cleanup by removing method
80
        self.addCleanup(setattr, MyLogFormatter, "__new__", None)
4955.5.2 by Vincent Ladeuil
Simplify tests.
81
82
        def getme(branch):
83
                # Always return our own log formatter class hijacking the
84
                # default behavior (which requires setting up a config
85
                # variable)
86
            return MyLogFormatter
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
87
        self.overrideAttr(log.log_formatter_registry, 'get_default', getme)
4955.5.2 by Vincent Ladeuil
Simplify tests.
88
4955.4.8 by Vincent Ladeuil
Simplify more tests.
89
    def get_captured_revisions(self):
5340.12.14 by Martin
Revert changes to bb.test_log which caused some failures
90
        return self.log_catcher.revisions
4955.4.8 by Vincent Ladeuil
Simplify more tests.
91
92
    def assertLogRevnos(self, args, expected_revnos, working_dir='.'):
93
        self.run_bzr(['log'] + args, working_dir=working_dir)
94
        self.assertEqual(expected_revnos,
95
                         [r.revno for r in self.get_captured_revisions()])
96
97
    def assertLogRevnosAndDepths(self, args, expected_revnos_and_depths,
98
                                working_dir='.'):
99
        self.run_bzr(['log'] + args, working_dir=working_dir)
100
        self.assertEqual(expected_revnos_and_depths,
101
                         [(r.revno, r.merge_depth)
102
                           for r in self.get_captured_revisions()])
4955.5.2 by Vincent Ladeuil
Simplify tests.
103
104
105
class TestLogRevSpecs(TestLogWithLogCatcher):
106
107
    def test_log_no_revspec(self):
108
        self.make_linear_branch()
109
        self.assertLogRevnos([], ['3', '2', '1'])
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
110
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
111
    def test_log_null_end_revspec(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
112
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
113
        self.assertLogRevnos(['-r1..'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
114
115
    def test_log_null_begin_revspec(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
116
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
117
        self.assertLogRevnos(['-r..3'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
118
119
    def test_log_null_both_revspecs(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
120
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
121
        self.assertLogRevnos(['-r..'], ['3', '2', '1'])
2978.4.1 by Kent Gibson
Logging revision 0 returns error.
122
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
123
    def test_log_negative_begin_revspec_full_log(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
124
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
125
        self.assertLogRevnos(['-r-3..'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
126
127
    def test_log_negative_both_revspec_full_log(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
128
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
129
        self.assertLogRevnos(['-r-3..-1'], ['3', '2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
130
131
    def test_log_negative_both_revspec_partial(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
132
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
133
        self.assertLogRevnos(['-r-3..-2'], ['2', '1'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
134
135
    def test_log_negative_begin_revspec(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
136
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
137
        self.assertLogRevnos(['-r-2..'], ['3', '2'])
1553.4.2 by Michael Ellerman
Make bzr log -r .. work, fixes bug #4609. Add a bunch of tests to make sure
138
2978.4.1 by Kent Gibson
Logging revision 0 returns error.
139
    def test_log_positive_revspecs(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
140
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
141
        self.assertLogRevnos(['-r1..3'], ['3', '2', '1'])
1624.1.3 by Robert Collins
Convert log to use the new tsort.merge_sort routine.
142
4369.2.1 by Marius Kruger
add some leftover log tests
143
    def test_log_dotted_revspecs(self):
144
        self.make_merged_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
145
        self.assertLogRevnos(['-n0', '-r1..1.1.1'], ['1.1.1', '1'])
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
146
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
147
    def test_log_limit(self):
148
        tree = self.make_branch_and_tree('.')
149
        # We want more commits than our batch size starts at
150
        for pos in range(10):
151
            tree.commit("%s" % pos)
4955.5.2 by Vincent Ladeuil
Simplify tests.
152
        self.assertLogRevnos(['--limit', '2'], ['10', '9'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
153
154
    def test_log_limit_short(self):
155
        self.make_linear_branch()
4955.5.2 by Vincent Ladeuil
Simplify tests.
156
        self.assertLogRevnos(['-l', '2'], ['3', '2'])
157
4955.4.7 by Vincent Ladeuil
Some more cleanup.
158
    def test_log_change_revno(self):
159
        self.make_linear_branch()
160
        self.assertLogRevnos(['-c1'], ['1'])
161
5318.1.2 by Martin von Gagern
Add blackbox test for "bzr log -r branch:../bar".
162
    def test_branch_revspec(self):
163
        foo = self.make_branch_and_tree('foo')
164
        bar = self.make_branch_and_tree('bar')
165
        self.build_tree(['foo/foo.txt', 'bar/bar.txt'])
166
        foo.add('foo.txt')
167
        bar.add('bar.txt')
168
        foo.commit(message='foo')
169
        bar.commit(message='bar')
170
        self.run_bzr('log -r branch:../bar', working_dir='foo')
171
        self.assertEqual([bar.branch.get_rev_id(1)],
172
                         [r.rev.revision_id
173
                          for r in self.get_captured_revisions()])
174
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
175
5268.4.1 by Vincent Ladeuil
Failing test for bug #575631.
176
class TestLogExcludeCommonAncestry(TestLogWithLogCatcher):
177
178
    def test_exclude_common_ancestry_simple_revnos(self):
179
        self.make_linear_branch()
180
        self.assertLogRevnos(['-r1..3', '--exclude-common-ancestry'],
181
                             ['3', '2'])
182
183
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
184
class TestLogMergedLinearAncestry(TestLogWithLogCatcher):
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
185
186
    def setUp(self):
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
187
        super(TestLogMergedLinearAncestry, self).setUp()
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
188
        # FIXME: Using a MemoryTree would be even better here (but until we
189
        # stop calling run_bzr, there is no point) --vila 100118.
190
        builder = branchbuilder.BranchBuilder(self.get_transport())
191
        builder.start_series()
5268.4.1 by Vincent Ladeuil
Failing test for bug #575631.
192
        # 1
193
        # | \
194
        # 2  1.1.1
195
        # | / |
196
        # 3  1.1.2
197
        # |   |
198
        # |  1.1.3
199
        # | / |
200
        # 4  1.1.4
201
        # | /
202
        # 5
203
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
204
        # mainline
205
        builder.build_snapshot('1', None, [
206
            ('add', ('', 'root-id', 'directory', ''))])
207
        builder.build_snapshot('2', ['1'], [])
208
        # branch
209
        builder.build_snapshot('1.1.1', ['1'], [])
210
        # merge branch into mainline
211
        builder.build_snapshot('3', ['2', '1.1.1'], [])
212
        # new commits in branch
213
        builder.build_snapshot('1.1.2', ['1.1.1'], [])
214
        builder.build_snapshot('1.1.3', ['1.1.2'], [])
215
        # merge branch into mainline
216
        builder.build_snapshot('4', ['3', '1.1.3'], [])
217
        # merge mainline into branch
218
        builder.build_snapshot('1.1.4', ['1.1.3', '4'], [])
219
        # merge branch into mainline
220
        builder.build_snapshot('5', ['4', '1.1.4'], [])
221
        builder.finish_series()
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
222
223
    def test_n0(self):
224
        self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4'],
225
                             ['1.1.4', '4', '1.1.3', '1.1.2', '3', '1.1.1'])
226
    def test_n0_forward(self):
227
        self.assertLogRevnos(['-n0', '-r1.1.1..1.1.4', '--forward'],
228
                             ['3', '1.1.1', '4', '1.1.2', '1.1.3', '1.1.4'])
229
230
    def test_n1(self):
4955.4.6 by Vincent Ladeuil
Switch to branchbuilder to avoid the cost of test.script.
231
        # starting from 1.1.4 we follow the left-hand ancestry
4955.4.5 by Vincent Ladeuil
Start reproducing the problems reported in the bug.
232
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4'],
233
                             ['1.1.4', '1.1.3', '1.1.2', '1.1.1'])
234
235
    def test_n1_forward(self):
236
        self.assertLogRevnos(['-n1', '-r1.1.1..1.1.4', '--forward'],
237
                             ['1.1.1', '1.1.2', '1.1.3', '1.1.4'])
238
4955.5.2 by Vincent Ladeuil
Simplify tests.
239
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
240
class Test_GenerateAllRevisions(TestLogWithLogCatcher):
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
241
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
242
    def setUp(self):
243
        super(Test_GenerateAllRevisions, self).setUp()
244
        builder = self.make_branch_with_many_merges()
245
        b = builder.get_branch()
246
        b.lock_read()
247
        self.addCleanup(b.unlock)
248
        self.branch = b
249
4955.7.5 by Vincent Ladeuil
Fixed as per Ian's review.
250
    def make_branch_with_many_merges(self, path='.', format=None):
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
251
        builder = branchbuilder.BranchBuilder(self.get_transport())
252
        builder.start_series()
253
        # The graph below may look a bit complicated (and it may be but I've
254
        # banged my head enough on it) but the bug requires at least dotted
255
        # revnos *and* merged revisions below that.
256
        builder.build_snapshot('1', None, [
257
            ('add', ('', 'root-id', 'directory', ''))])
258
        builder.build_snapshot('2', ['1'], [])
259
        builder.build_snapshot('1.1.1', ['1'], [])
260
        builder.build_snapshot('2.1.1', ['2'], [])
261
        builder.build_snapshot('3', ['2', '1.1.1'], [])
262
        builder.build_snapshot('2.1.2', ['2.1.1'], [])
263
        builder.build_snapshot('2.2.1', ['2.1.1'], [])
264
        builder.build_snapshot('2.1.3', ['2.1.2', '2.2.1'], [])
265
        builder.build_snapshot('4', ['3', '2.1.3'], [])
266
        builder.build_snapshot('5', ['4', '2.1.2'], [])
267
        builder.finish_series()
268
        return builder
269
270
    def test_not_an_ancestor(self):
271
        self.assertRaises(errors.BzrCommandError,
272
                          log._generate_all_revisions,
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
273
                          self.branch, '1.1.1', '2.1.3', 'reverse',
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
274
                          delayed_graph_generation=True)
275
276
    def test_wrong_order(self):
277
        self.assertRaises(errors.BzrCommandError,
278
                          log._generate_all_revisions,
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
279
                          self.branch, '5', '2.1.3', 'reverse',
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
280
                          delayed_graph_generation=True)
281
5092.1.1 by Vincent Ladeuil
Reproduce bug #519862.
282
    def test_no_start_rev_id_with_end_rev_id_being_a_merge(self):
283
        revs = log._generate_all_revisions(
284
            self.branch, None, '2.1.3',
285
            'reverse', delayed_graph_generation=True)
286
4955.7.3 by Vincent Ladeuil
Check ancestry so we don't output random revisions.
287
4955.5.2 by Vincent Ladeuil
Simplify tests.
288
class TestLogRevSpecsWithPaths(TestLogWithLogCatcher):
289
290
    def test_log_revno_n_path_wrong_namespace(self):
291
        self.make_linear_branch('branch1')
292
        self.make_linear_branch('branch2')
293
        # There is no guarantee that a path exist between two arbitrary
294
        # revisions.
295
        self.run_bzr("log -r revno:2:branch1..revno:3:branch2", retcode=3)
296
297
    def test_log_revno_n_path_correct_order(self):
298
        self.make_linear_branch('branch2')
299
        self.assertLogRevnos(['-rrevno:1:branch2..revno:3:branch2'],
300
                             ['3', '2','1'])
301
302
    def test_log_revno_n_path(self):
303
        self.make_linear_branch('branch2')
304
        self.assertLogRevnos(['-rrevno:1:branch2'],
305
                             ['1'])
306
        rev_props = self.log_catcher.revisions[0].rev.properties
307
        self.assertEqual('branch2', rev_props['branch-nick'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
308
309
310
class TestLogErrors(TestLog):
311
4955.5.2 by Vincent Ladeuil
Simplify tests.
312
    def test_log_zero_revspec(self):
313
        self.make_minimal_branch()
314
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
315
                           ['log', '-r0'])
316
317
    def test_log_zero_begin_revspec(self):
318
        self.make_linear_branch()
319
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
320
                           ['log', '-r0..2'])
321
322
    def test_log_zero_end_revspec(self):
323
        self.make_linear_branch()
324
        self.run_bzr_error(['bzr: ERROR: Logging revision 0 is invalid.'],
325
                           ['log', '-r-2..0'])
326
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
327
    def test_log_nonexistent_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
328
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
329
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
330
                            "does not exist in branch:"],
331
                           ['log', '-r1234'])
3878.3.3 by Marius Kruger
Add tests for log -r with non-exising revno's
332
333
    def test_log_nonexistent_dotted_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
334
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
335
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
336
                            "does not exist in branch:"],
337
                           ['log',  '-r123.123'])
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
338
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
339
    def test_log_change_nonexistent_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
340
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
341
        self.run_bzr_error(["bzr: ERROR: Requested revision: '1234' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
342
                            "does not exist in branch:"],
343
                           ['log',  '-c1234'])
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
344
345
    def test_log_change_nonexistent_dotted_revno(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
346
        self.make_minimal_branch()
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
347
        self.run_bzr_error(["bzr: ERROR: Requested revision: '123.123' "
4955.4.7 by Vincent Ladeuil
Some more cleanup.
348
                            "does not exist in branch:"],
349
                           ['log', '-c123.123'])
3878.3.2 by Marius Kruger
Add tests for log -c with non-exising revno's
350
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
351
    def test_log_change_single_revno_only(self):
352
        self.make_minimal_branch()
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
353
        self.run_bzr_error(['bzr: ERROR: Option --change does not'
354
                           ' accept revision ranges'],
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
355
                           ['log', '--change', '2..3'])
356
357
    def test_log_change_incompatible_with_revision(self):
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
358
        self.run_bzr_error(['bzr: ERROR: --revision and --change'
359
                           ' are mutually exclusive'],
3734.1.1 by Vincent Ladeuil
Fix bug #248427 by adding a --change option to log.
360
                           ['log', '--change', '2', '--revision', '3'])
361
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
362
    def test_log_nonexistent_file(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
363
        self.make_minimal_branch()
2100.1.1 by wang
Running ``bzr log`` on nonexistent file gives an error instead of the
364
        # files that don't exist in either the basis tree or working tree
365
        # should give an error
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
366
        out, err = self.run_bzr('log does-not-exist', retcode=3)
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
367
        self.assertContainsRe(err,
368
                              'Path unknown at end or start of revision range: '
369
                              'does-not-exist')
2388.1.11 by Alexander Belchenko
changes after John's review
370
4955.5.2 by Vincent Ladeuil
Simplify tests.
371
    def test_log_reversed_revspecs(self):
372
        self.make_linear_branch()
373
        self.run_bzr_error(('bzr: ERROR: Start revision must be older than '
374
                            'the end revision.\n',),
375
                           ['log', '-r3..1'])
376
377
    def test_log_reversed_dotted_revspecs(self):
378
        self.make_merged_branch()
379
        self.run_bzr_error(('bzr: ERROR: Start revision not found in '
380
                            'left-hand history of end revision.\n',),
381
                           "log -r 1.1.1..1")
382
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
383
    def test_log_bad_message_re(self):
384
        """Bad --message argument gives a sensible message
5326.2.1 by Parth Malwankar
added InvalidPattern error.
385
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
386
        See https://bugs.launchpad.net/bzr/+bug/251352
387
        """
388
        self.make_minimal_branch()
389
        out, err = self.run_bzr(['log', '-m', '*'], retcode=3)
5326.2.1 by Parth Malwankar
added InvalidPattern error.
390
        self.assertContainsRe(err, "ERROR.*Invalid pattern.*nothing to repeat")
5339.1.1 by Parth Malwankar
fixes errors.InvalidPattern to work on Python2.5
391
        self.assertNotContainsRe(err, "Unprintable exception")
5326.2.1 by Parth Malwankar
added InvalidPattern error.
392
        self.assertEqual(out, '')
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
393
4955.4.7 by Vincent Ladeuil
Some more cleanup.
394
    def test_log_unsupported_timezone(self):
395
        self.make_linear_branch()
396
        self.run_bzr_error(['bzr: ERROR: Unsupported timezone format "foo", '
397
                            'options are "utc", "original", "local".'],
398
                           ['log', '--timezone', 'foo'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
399
5097.1.13 by Vincent Ladeuil
Add more tests.
400
    def test_log_exclude_ancestry_no_range(self):
401
        self.make_linear_branch()
402
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
403
                            ' requires -r with two revisions'],
404
                           ['log', '--exclude-common-ancestry'])
405
406
    def test_log_exclude_ancestry_single_revision(self):
407
        self.make_merged_branch()
408
        self.run_bzr_error(['bzr: ERROR: --exclude-common-ancestry'
409
                            ' requires two different revisions'],
410
                           ['log', '--exclude-common-ancestry',
411
                            '-r1.1.1..1.1.1'])
4955.5.1 by Vincent Ladeuil
Split some tests to better characterize the classes
412
413
class TestLogTags(TestLog):
414
2388.1.3 by Erik Bagfors
tests for tags in log output
415
    def test_log_with_tags(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
416
        tree = self.make_linear_branch(format='dirstate-tags')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
417
        branch = tree.branch
418
        branch.tags.set_tag('tag1', branch.get_rev_id(1))
419
        branch.tags.set_tag('tag1.1', branch.get_rev_id(1))
3842.2.5 by Vincent Ladeuil
Better fix for bug #300055.
420
        branch.tags.set_tag('tag3', branch.last_revision())
421
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
422
        log = self.run_bzr("log -r-1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
423
        self.assertTrue('tags: tag3' in log)
424
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
425
        log = self.run_bzr("log -r1")[0]
2388.1.3 by Erik Bagfors
tests for tags in log output
426
        # I guess that we can't know the order of tags in the output
427
        # since dicts are unordered, need to check both possibilities
2388.1.11 by Alexander Belchenko
changes after John's review
428
        self.assertContainsRe(log, r'tags: (tag1, tag1\.1|tag1\.1, tag1)')
429
2388.1.9 by Erik Bagfors
test for merges with tags in log
430
    def test_merged_log_with_tags(self):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
431
        branch1_tree = self.make_linear_branch('branch1',
432
                                               format='dirstate-tags')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
433
        branch1 = branch1_tree.branch
434
        branch2_tree = branch1_tree.bzrdir.sprout('branch2').open_workingtree()
435
        branch1_tree.commit(message='foobar', allow_pointless=True)
436
        branch1.tags.set_tag('tag1', branch1.last_revision())
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
437
        # tags don't propagate if we don't merge
438
        self.run_bzr('merge ../branch1', working_dir='branch2')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
439
        branch2_tree.commit(message='merge branch 1')
4511.3.11 by Marius Kruger
* fix tests again
440
        log = self.run_bzr("log -n0 -r-1", working_dir='branch2')[0]
2388.1.11 by Alexander Belchenko
changes after John's review
441
        self.assertContainsRe(log, r'    tags: tag1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
442
        log = self.run_bzr("log -n0 -r3.1.1", working_dir='branch2')[0]
2466.12.2 by Kent Gibson
shift log output with only merge revisions to the left margin
443
        self.assertContainsRe(log, r'tags: tag1')
2388.1.3 by Erik Bagfors
tests for tags in log output
444
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
445
5971.1.44 by Jonathan Riddell
add testcase for --signatures
446
class TestLogSignatures(TestLog):
447
448
    def test_log_with_signatures(self):
449
        self.requireFeature(features.gpgme)
450
451
        tree = self.make_linear_branch(format='dirstate-tags')
452
453
        log = self.run_bzr("log --signatures")[0]
454
        self.assertTrue('signature: no signature' in log)
455
456
    def test_log_without_signatures(self):
457
        self.requireFeature(features.gpgme)
458
459
        tree = self.make_linear_branch(format='dirstate-tags')
460
461
        log = self.run_bzr("log")[0]
462
        self.assertFalse('signature: no signature' in log)
463
464
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
465
class TestLogVerbose(TestLog):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
466
467
    def setUp(self):
468
        super(TestLogVerbose, self).setUp()
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
469
        self.make_minimal_branch()
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
470
471
    def assertUseShortDeltaFormat(self, cmd):
472
        log = self.run_bzr(cmd)[0]
473
        # Check that we use the short status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
474
        self.assertContainsRe(log, '(?m)^\s*A  hello.txt$')
475
        self.assertNotContainsRe(log, '(?m)^\s*added:$')
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
476
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
477
    def assertUseLongDeltaFormat(self, cmd):
478
        log = self.run_bzr(cmd)[0]
479
        # Check that we use the long status format
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
480
        self.assertNotContainsRe(log, '(?m)^\s*A  hello.txt$')
481
        self.assertContainsRe(log, '(?m)^\s*added:$')
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
482
483
    def test_log_short_verbose(self):
484
        self.assertUseShortDeltaFormat(['log', '--short', '-v'])
485
5945.1.3 by Martin von Gagern
Add blackbox tests for -S as an alias to --short.
486
    def test_log_s_verbose(self):
487
        self.assertUseShortDeltaFormat(['log', '-S', '-v'])
488
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
489
    def test_log_short_verbose_verbose(self):
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
490
        self.assertUseLongDeltaFormat(['log', '--short', '-vv'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
491
492
    def test_log_long_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
493
        # Check that we use the long status format, ignoring the verbosity
494
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
495
        self.assertUseLongDeltaFormat(['log', '--long', '-v'])
3874.1.4 by Vincent Ladeuil
Fixed as per Aarons' comment.
496
497
    def test_log_long_verbose_verbose(self):
3874.1.7 by Vincent Ladeuil
Restrict '-v' change to log --short only.
498
        # Check that we use the long status format, ignoring the verbosity
499
        # level
3874.1.8 by Vincent Ladeuil
Fixed as ber Robert's review.
500
        self.assertUseLongDeltaFormat(['log', '--long', '-vv'])
3874.1.1 by Vincent Ladeuil
Fix #87179 by using the short status format when the short format is used for log.
501
3144.7.9 by Guillermo Gonzalez
* bzrlib.log.show_roperties don't hide handler errors
502
4955.4.8 by Vincent Ladeuil
Simplify more tests.
503
class TestLogMerges(TestLogWithLogCatcher):
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
504
505
    def setUp(self):
506
        super(TestLogMerges, self).setUp()
507
        self.make_branches_with_merges()
508
509
    def make_branches_with_merges(self):
510
        level0 = self.make_branch_and_tree('level0')
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
511
        self.wt_commit(level0, 'in branch level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
512
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
513
        self.wt_commit(level1, 'in branch level1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
514
        level2 = level1.bzrdir.sprout('level2').open_workingtree()
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
515
        self.wt_commit(level2, 'in branch level2')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
516
        level1.merge_from_branch(level2.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
517
        self.wt_commit(level1, 'merge branch level2')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
518
        level0.merge_from_branch(level1.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
519
        self.wt_commit(level0, 'merge branch level1')
3947.1.3 by Ian Clatworthy
blackbox tests
520
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
521
    def test_merges_are_indented_by_level(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
522
        self.run_bzr(['log', '-n0'], working_dir='level0')
523
        revnos_and_depth = [(r.revno, r.merge_depth)
524
                            for r in self.get_captured_revisions()]
525
        self.assertEqual([('2', 0), ('1.1.2', 1), ('1.2.1', 2), ('1.1.1', 1),
526
                          ('1', 0)],
527
                         [(r.revno, r.merge_depth)
528
                            for r in self.get_captured_revisions()])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
529
3947.1.3 by Ian Clatworthy
blackbox tests
530
    def test_force_merge_revisions_off(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
531
        self.assertLogRevnos(['-n1'], ['2', '1'], working_dir='level0')
3947.1.3 by Ian Clatworthy
blackbox tests
532
533
    def test_force_merge_revisions_on(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
534
        self.assertLogRevnos(['-n0'], ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
535
                             working_dir='level0')
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
536
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
537
    def test_include_merges(self):
538
        # Confirm --include-merges gives the same output as -n0
4955.4.8 by Vincent Ladeuil
Simplify more tests.
539
        self.assertLogRevnos(['--include-merges'],
540
                             ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
541
                             working_dir='level0')
542
        self.assertLogRevnos(['--include-merges'],
543
                             ['2', '1.1.2', '1.2.1', '1.1.1', '1'],
544
                             working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
545
        out_im, err_im = self.run_bzr('log --include-merges',
546
                                      working_dir='level0')
547
        out_n0, err_n0 = self.run_bzr('log -n0', working_dir='level0')
548
        self.assertEqual('', err_im)
549
        self.assertEqual('', err_n0)
4221.2.1 by Ian Clatworthy
--include-merges as an alias for --levels 0 in log
550
        self.assertEqual(out_im, out_n0)
551
3947.1.7 by Ian Clatworthy
tweak indenting/offsetting for --short given dotted revno lengths
552
    def test_force_merge_revisions_N(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
553
        self.assertLogRevnos(['-n2'],
554
                             ['2', '1.1.2', '1.1.1', '1'],
555
                             working_dir='level0')
3947.1.3 by Ian Clatworthy
blackbox tests
556
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
557
    def test_merges_single_merge_rev(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
558
        self.assertLogRevnosAndDepths(['-n0', '-r1.1.2'],
559
                                      [('1.1.2', 0), ('1.2.1', 1)],
560
                                      working_dir='level0')
2466.12.1 by Kent Gibson
Fix ``bzr log -r`` to support selecting merge revisions.
561
562
    def test_merges_partial_range(self):
4955.4.8 by Vincent Ladeuil
Simplify more tests.
563
        self.assertLogRevnosAndDepths(
564
                ['-n0', '-r1.1.1..1.1.2'],
565
                [('1.1.2', 0), ('1.2.1', 1), ('1.1.1', 0)],
566
                working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
567
4511.3.1 by Marius Kruger
add test_merges_partial_range_ignore_before_lower_bound
568
    def test_merges_partial_range_ignore_before_lower_bound(self):
4511.3.11 by Marius Kruger
* fix tests again
569
        """Dont show revisions before the lower bound's merged revs"""
4955.4.8 by Vincent Ladeuil
Simplify more tests.
570
        self.assertLogRevnosAndDepths(
571
                ['-n0', '-r1.1.2..2'],
572
                [('2', 0), ('1.1.2', 1), ('1.2.1', 2)],
573
                working_dir='level0')
4511.3.1 by Marius Kruger
add test_merges_partial_range_ignore_before_lower_bound
574
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
575
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
576
class TestLogDiff(TestLogWithLogCatcher):
577
578
    # FIXME: We need specific tests for each LogFormatter about how the diffs
579
    # are displayed: --long indent them by depth, --short use a fixed
580
    # indent and --line does't display them. -- vila 10019
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
581
582
    def setUp(self):
583
        super(TestLogDiff, self).setUp()
584
        self.make_branch_with_diffs()
585
586
    def make_branch_with_diffs(self):
587
        level0 = self.make_branch_and_tree('level0')
588
        self.build_tree(['level0/file1', 'level0/file2'])
589
        level0.add('file1')
590
        level0.add('file2')
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
591
        self.wt_commit(level0, 'in branch level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
592
593
        level1 = level0.bzrdir.sprout('level1').open_workingtree()
594
        self.build_tree_contents([('level1/file2', 'hello\n')])
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
595
        self.wt_commit(level1, 'in branch level1')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
596
        level0.merge_from_branch(level1.branch)
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
597
        self.wt_commit(level0, 'merge branch level1')
3943.5.3 by Ian Clatworthy
add tests
598
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
599
    def _diff_file1_revno1(self):
600
        return """=== added file 'file1'
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
601
--- file1\t1970-01-01 00:00:00 +0000
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
602
+++ file1\t2005-11-22 00:00:00 +0000
3943.5.6 by Ian Clatworthy
feedback from jam's review
603
@@ -0,0 +1,1 @@
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
604
+contents of level0/file1
3943.5.6 by Ian Clatworthy
feedback from jam's review
605
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
606
"""
607
608
    def _diff_file2_revno2(self):
609
        return """=== modified file 'file2'
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
610
--- file2\t2005-11-22 00:00:00 +0000
611
+++ file2\t2005-11-22 00:00:01 +0000
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
612
@@ -1,1 +1,1 @@
613
-contents of level0/file2
614
+hello
615
616
"""
617
618
    def _diff_file2_revno1_1_1(self):
619
        return """=== modified file 'file2'
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
620
--- file2\t2005-11-22 00:00:00 +0000
621
+++ file2\t2005-11-22 00:00:01 +0000
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
622
@@ -1,1 +1,1 @@
623
-contents of level0/file2
624
+hello
625
626
"""
627
628
    def _diff_file2_revno1(self):
629
        return """=== added file 'file2'
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
630
--- file2\t1970-01-01 00:00:00 +0000
4955.4.17 by Vincent Ladeuil
Use a data factory for commit properties and reduce code duplication.
631
+++ file2\t2005-11-22 00:00:00 +0000
3943.5.6 by Ian Clatworthy
feedback from jam's review
632
@@ -0,0 +1,1 @@
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
633
+contents of level0/file2
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
634
635
"""
636
4955.4.13 by Vincent Ladeuil
Remove dead code.
637
    def assertLogRevnosAndDiff(self, args, expected,
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
638
                            working_dir='.'):
639
        self.run_bzr(['log', '-p'] + args, working_dir=working_dir)
640
        expected_revnos_and_depths = [
641
            (revno, depth) for revno, depth, diff in expected]
642
        # Check the revnos and depths first to make debugging easier
643
        self.assertEqual(expected_revnos_and_depths,
644
                         [(r.revno, r.merge_depth)
645
                           for r in self.get_captured_revisions()])
646
        # Now check the diffs, adding the revno  in case of failure
647
        fmt = 'In revno %s\n%s'
648
        for expected_rev, actual_rev in izip(expected,
649
                                             self.get_captured_revisions()):
650
            revno, depth, expected_diff = expected_rev
651
            actual_diff = actual_rev.diff
652
            self.assertEqualDiff(fmt % (revno, expected_diff),
653
                                 fmt % (revno, actual_diff))
654
655
    def test_log_diff_with_merges(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
656
        self.assertLogRevnosAndDiff(
657
            ['-n0'],
658
            [('2', 0, self._diff_file2_revno2()),
659
             ('1.1.1', 1, self._diff_file2_revno1_1_1()),
660
             ('1', 0, self._diff_file1_revno1()
661
              + self._diff_file2_revno1())],
662
            working_dir='level0')
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
663
664
665
    def test_log_diff_file1(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
666
        self.assertLogRevnosAndDiff(['-n0', 'file1'],
667
                                    [('1', 0, self._diff_file1_revno1())],
668
                                    working_dir='level0')
4955.4.11 by Vincent Ladeuil
Give some tests a better focus and simplify them accordingly.
669
670
    def test_log_diff_file2(self):
4955.4.13 by Vincent Ladeuil
Remove dead code.
671
        self.assertLogRevnosAndDiff(['-n1', 'file2'],
672
                                    [('2', 0, self._diff_file2_revno2()),
673
                                     ('1', 0, self._diff_file2_revno1())],
674
                                    working_dir='level0')
4325.4.5 by Vincent Ladeuil
Some cleanup in blackbox log tests.
675
676
677
class TestLogUnicodeDiff(TestLog):
3943.5.4 by Ian Clatworthy
filter diff by file
678
4110.1.1 by Alexander Belchenko
Fixed problem with `log -p` and non-ascii content of files: show_diff should write the diff to exact [stdout] stream.
679
    def test_log_show_diff_non_ascii(self):
680
        # Smoke test for bug #328007 UnicodeDecodeError on 'log -p'
681
        message = u'Message with \xb5'
682
        body = 'Body with \xb5\n'
683
        wt = self.make_branch_and_tree('.')
684
        self.build_tree_contents([('foo', body)])
685
        wt.add('foo')
686
        wt.commit(message=message)
687
        # check that command won't fail with unicode error
688
        # don't care about exact output because we have other tests for this
689
        out,err = self.run_bzr('log -p --long')
690
        self.assertNotEqual('', out)
691
        self.assertEqual('', err)
692
        out,err = self.run_bzr('log -p --short')
693
        self.assertNotEqual('', out)
694
        self.assertEqual('', err)
695
        out,err = self.run_bzr('log -p --line')
696
        self.assertNotEqual('', out)
697
        self.assertEqual('', err)
698
3943.5.3 by Ian Clatworthy
add tests
699
4325.4.3 by Vincent Ladeuil
More cleanups.
700
class TestLogEncodings(tests.TestCaseInTempDir):
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
701
702
    _mu = u'\xb5'
703
    _message = u'Message with \xb5'
704
705
    # Encodings which can encode mu
706
    good_encodings = [
707
        'utf-8',
708
        'latin-1',
709
        'iso-8859-1',
710
        'cp437', # Common windows encoding
4110.1.1 by Alexander Belchenko
Fixed problem with `log -p` and non-ascii content of files: show_diff should write the diff to exact [stdout] stream.
711
        'cp1251', # Russian windows encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
712
        'cp1258', # Common windows encoding
713
    ]
714
    # Encodings which cannot encode mu
715
    bad_encodings = [
716
        'ascii',
717
        'iso-8859-2',
718
        'koi8_r',
719
    ]
720
721
    def setUp(self):
4325.4.3 by Vincent Ladeuil
More cleanups.
722
        super(TestLogEncodings, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
723
        self.overrideAttr(osutils, '_cached_user_encoding')
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
724
725
    def create_branch(self):
726
        bzr = self.run_bzr
727
        bzr('init')
4955.4.16 by Vincent Ladeuil
Be windows-friendly and don't left opened files behind.
728
        self.build_tree_contents([('a', 'some stuff\n')])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
729
        bzr('add a')
730
        bzr(['commit', '-m', self._message])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
731
732
    def try_encoding(self, encoding, fail=False):
733
        bzr = self.run_bzr
734
        if fail:
735
            self.assertRaises(UnicodeEncodeError,
736
                self._mu.encode, encoding)
737
            encoded_msg = self._message.encode(encoding, 'replace')
738
        else:
739
            encoded_msg = self._message.encode(encoding)
740
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
741
        old_encoding = osutils._cached_user_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
742
        # This test requires that 'run_bzr' uses the current
743
        # bzrlib, because we override user_encoding, and expect
744
        # it to be used
745
        try:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
746
            osutils._cached_user_encoding = 'ascii'
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
747
            # We should be able to handle any encoding
748
            out, err = bzr('log', encoding=encoding)
749
            if not fail:
750
                # Make sure we wrote mu as we expected it to exist
751
                self.assertNotEqual(-1, out.find(encoded_msg))
752
                out_unicode = out.decode(encoding)
753
                self.assertNotEqual(-1, out_unicode.find(self._message))
754
            else:
755
                self.assertNotEqual(-1, out.find('Message with ?'))
756
        finally:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
757
            osutils._cached_user_encoding = old_encoding
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
758
759
    def test_log_handles_encoding(self):
760
        self.create_branch()
761
762
        for encoding in self.good_encodings:
763
            self.try_encoding(encoding)
764
765
    def test_log_handles_bad_encoding(self):
766
        self.create_branch()
767
768
        for encoding in self.bad_encodings:
769
            self.try_encoding(encoding, fail=True)
770
771
    def test_stdout_encoding(self):
772
        bzr = self.run_bzr
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
773
        osutils._cached_user_encoding = "cp1251"
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
774
775
        bzr('init')
776
        self.build_tree(['a'])
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
777
        bzr('add a')
778
        bzr(['commit', '-m', u'\u0422\u0435\u0441\u0442'])
1685.1.5 by John Arbash Meinel
Merged test_log.py.moved into test_log.py
779
        stdout, stderr = self.run_bzr('log', encoding='cp866')
780
781
        message = stdout.splitlines()[-1]
782
783
        # explanation of the check:
784
        # u'\u0422\u0435\u0441\u0442' is word 'Test' in russian
785
        # in cp866  encoding this is string '\x92\xa5\xe1\xe2'
786
        # in cp1251 encoding this is string '\xd2\xe5\xf1\xf2'
787
        # This test should check that output of log command
788
        # encoded to sys.stdout.encoding
789
        test_in_cp866 = '\x92\xa5\xe1\xe2'
790
        test_in_cp1251 = '\xd2\xe5\xf1\xf2'
791
        # Make sure the log string is encoded in cp866
792
        self.assertEquals(test_in_cp866, message[2:])
793
        # Make sure the cp1251 string is not found anywhere
794
        self.assertEquals(-1, stdout.find(test_in_cp1251))
795
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
796
4955.4.9 by Vincent Ladeuil
More simplifications.
797
class TestLogFile(TestLogWithLogCatcher):
1551.10.18 by Aaron Bentley
Log works in local treeless branches (#84247)
798
799
    def test_log_local_branch_file(self):
800
        """We should be able to log files in local treeless branches"""
801
        tree = self.make_branch_and_tree('tree')
802
        self.build_tree(['tree/file'])
803
        tree.add('file')
804
        tree.commit('revision 1')
805
        tree.bzrdir.destroy_workingtree()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
806
        self.run_bzr('log tree/file')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
807
3943.6.1 by Ian Clatworthy
find file using the end revision
808
    def prepare_tree(self, complex=False):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
809
        # The complex configuration includes deletes and renames
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
810
        tree = self.make_branch_and_tree('parent')
811
        self.build_tree(['parent/file1', 'parent/file2', 'parent/file3'])
812
        tree.add('file1')
813
        tree.commit('add file1')
814
        tree.add('file2')
815
        tree.commit('add file2')
816
        tree.add('file3')
817
        tree.commit('add file3')
2664.14.1 by Daniel Watkins
Fixed tests.blackbox.test_log to use internals where appropriate.
818
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
819
        self.build_tree_contents([('child/file2', 'hello')])
820
        child_tree.commit(message='branch 1')
821
        tree.merge_from_branch(child_tree.branch)
822
        tree.commit(message='merge child branch')
3943.6.1 by Ian Clatworthy
find file using the end revision
823
        if complex:
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
824
            tree.remove('file2')
825
            tree.commit('remove file2')
826
            tree.rename_one('file3', 'file4')
827
            tree.commit('file3 is now called file4')
3943.6.1 by Ian Clatworthy
find file using the end revision
828
            tree.remove('file1')
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
829
            tree.commit('remove file1')
2359.1.1 by Kent Gibson
Fix ``bzr log <file>`` so it only logs the revisions that changed the file, and does it faster.
830
        os.chdir('parent')
3940.1.2 by Ian Clatworthy
add test
831
4955.4.9 by Vincent Ladeuil
More simplifications.
832
    # FIXME: It would be good to parametrize the following tests against all
833
    # formatters. But the revisions selection is not *currently* part of the
834
    # LogFormatter contract, so using LogCatcher is sufficient -- vila 100118
835
    def test_log_file1(self):
836
        self.prepare_tree()
837
        self.assertLogRevnos(['-n0', 'file1'], ['1'])
838
839
    def test_log_file2(self):
840
        self.prepare_tree()
841
        # file2 full history
842
        self.assertLogRevnos(['-n0', 'file2'], ['4', '3.1.1', '2'])
843
        # file2 in a merge revision
844
        self.assertLogRevnos(['-n0', '-r3.1.1', 'file2'], ['3.1.1'])
845
        # file2 in a mainline revision
846
        self.assertLogRevnos(['-n0', '-r4', 'file2'], ['4', '3.1.1'])
847
        # file2 since a revision
848
        self.assertLogRevnos(['-n0', '-r3..', 'file2'], ['4', '3.1.1'])
849
        # file2 up to a revision
850
        self.assertLogRevnos(['-n0', '-r..3', 'file2'], ['2'])
851
852
    def test_log_file3(self):
853
        self.prepare_tree()
854
        self.assertLogRevnos(['-n0', 'file3'], ['3'])
3940.1.2 by Ian Clatworthy
add test
855
3943.6.4 by Ian Clatworthy
review feedback from vila
856
    def test_log_file_historical_missing(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
857
        # Check logging a deleted file gives an error if the
858
        # file isn't found at the end or start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
859
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
860
        err_msg = "Path unknown at end or start of revision range: file2"
861
        err = self.run_bzr('log file2', retcode=3)[1]
3943.6.1 by Ian Clatworthy
find file using the end revision
862
        self.assertContainsRe(err, err_msg)
863
3943.6.4 by Ian Clatworthy
review feedback from vila
864
    def test_log_file_historical_end(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
865
        # Check logging a deleted file is ok if the file existed
866
        # at the end the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
867
        self.prepare_tree(complex=True)
4955.4.9 by Vincent Ladeuil
More simplifications.
868
        self.assertLogRevnos(['-n0', '-r..4', 'file2'], ['4', '3.1.1', '2'])
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
869
3943.6.4 by Ian Clatworthy
review feedback from vila
870
    def test_log_file_historical_start(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
871
        # Check logging a deleted file is ok if the file existed
872
        # at the start of the revision range
3943.6.4 by Ian Clatworthy
review feedback from vila
873
        self.prepare_tree(complex=True)
4955.4.9 by Vincent Ladeuil
More simplifications.
874
        self.assertLogRevnos(['file1'], ['1'])
3943.6.1 by Ian Clatworthy
find file using the end revision
875
876
    def test_log_file_renamed(self):
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
877
        """File matched against revision range, not current tree."""
3943.6.1 by Ian Clatworthy
find file using the end revision
878
        self.prepare_tree(complex=True)
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
879
3943.6.1 by Ian Clatworthy
find file using the end revision
880
        # Check logging a renamed file gives an error by default
3943.6.3 by Ian Clatworthy
search the start tree if the end tree doesn't have a file
881
        err_msg = "Path unknown at end or start of revision range: file3"
3943.6.1 by Ian Clatworthy
find file using the end revision
882
        err = self.run_bzr('log file3', retcode=3)[1]
883
        self.assertContainsRe(err, err_msg)
884
885
        # Check we can see a renamed file if we give the right end revision
4955.4.9 by Vincent Ladeuil
More simplifications.
886
        self.assertLogRevnos(['-r..4', 'file3'], ['3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
887
888
4955.4.10 by Vincent Ladeuil
More simplification.
889
class TestLogMultiple(TestLogWithLogCatcher):
4202.2.1 by Ian Clatworthy
get directory logging working again
890
891
    def prepare_tree(self):
892
        tree = self.make_branch_and_tree('parent')
893
        self.build_tree([
894
            'parent/file1',
895
            'parent/file2',
896
            'parent/dir1/',
897
            'parent/dir1/file5',
898
            'parent/dir1/dir2/',
899
            'parent/dir1/dir2/file3',
900
            'parent/file4'])
901
        tree.add('file1')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
902
        tree.commit('add file1')
4202.2.1 by Ian Clatworthy
get directory logging working again
903
        tree.add('file2')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
904
        tree.commit('add file2')
4202.2.1 by Ian Clatworthy
get directory logging working again
905
        tree.add(['dir1', 'dir1/dir2', 'dir1/dir2/file3'])
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
906
        tree.commit('add file3')
4202.2.1 by Ian Clatworthy
get directory logging working again
907
        tree.add('file4')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
908
        tree.commit('add file4')
4202.2.1 by Ian Clatworthy
get directory logging working again
909
        tree.add('dir1/file5')
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
910
        tree.commit('add file5')
4202.2.1 by Ian Clatworthy
get directory logging working again
911
        child_tree = tree.bzrdir.sprout('child').open_workingtree()
912
        self.build_tree_contents([('child/file2', 'hello')])
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
913
        child_tree.commit(message='branch 1')
4202.2.1 by Ian Clatworthy
get directory logging working again
914
        tree.merge_from_branch(child_tree.branch)
4202.2.2 by Ian Clatworthy
improve signal-to-noise ratio in tests
915
        tree.commit(message='merge child branch')
4202.2.1 by Ian Clatworthy
get directory logging working again
916
        os.chdir('parent')
917
918
    def test_log_files(self):
919
        """The log for multiple file should only list revs for those files"""
920
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
921
        self.assertLogRevnos(['file1', 'file2', 'dir1/dir2/file3'],
922
                             ['6', '5.1.1', '3', '2', '1'])
4202.2.1 by Ian Clatworthy
get directory logging working again
923
924
    def test_log_directory(self):
925
        """The log for a directory should show all nested files."""
926
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
927
        self.assertLogRevnos(['dir1'], ['5', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
928
929
    def test_log_nested_directory(self):
930
        """The log for a directory should show all nested files."""
931
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
932
        self.assertLogRevnos(['dir1/dir2'], ['3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
933
934
    def test_log_in_nested_directory(self):
935
        """The log for a directory should show all nested files."""
936
        self.prepare_tree()
937
        os.chdir("dir1")
4955.4.10 by Vincent Ladeuil
More simplification.
938
        self.assertLogRevnos(['.'], ['5', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
939
940
    def test_log_files_and_directories(self):
941
        """Logging files and directories together should be fine."""
942
        self.prepare_tree()
4955.4.10 by Vincent Ladeuil
More simplification.
943
        self.assertLogRevnos(['file4', 'dir1/dir2'], ['4', '3'])
4202.2.1 by Ian Clatworthy
get directory logging working again
944
945
    def test_log_files_and_dirs_in_nested_directory(self):
946
        """The log for a directory should show all nested files."""
947
        self.prepare_tree()
948
        os.chdir("dir1")
4955.4.10 by Vincent Ladeuil
More simplification.
949
        self.assertLogRevnos(['dir2', 'file5'], ['5', '3'])
5691.1.2 by Jelmer Vernooij
Add tests for ghosts in mainline during log.
950
951
952
class MainlineGhostTests(TestLogWithLogCatcher):
953
954
    def setUp(self):
955
        super(MainlineGhostTests, self).setUp()
956
        tree = self.make_branch_and_tree('')
957
        tree.set_parent_ids(["spooky"], allow_leftmost_as_ghost=True)
958
        tree.add('')
959
        tree.commit('msg1', rev_id='rev1')
960
        tree.commit('msg2', rev_id='rev2')
961
962
    def test_log_range(self):
963
        self.assertLogRevnos(["-r1..2"], ["2", "1"])
964
965
    def test_log_norange(self):
966
        self.assertLogRevnos([], ["2", "1"])
967
968
    def test_log_range_open_begin(self):
6050.1.2 by Martin
Make tests raising KnownFailure use the knownFailure method instead
969
        self.knownFailure("log with ghosts fails. bug #726466")
5691.1.2 by Jelmer Vernooij
Add tests for ghosts in mainline during log.
970
        (stdout, stderr) = self.run_bzr(['log', '-r..2'], retcode=3)
971
        self.assertEqual(["2", "1"],
972
                         [r.revno for r in self.get_captured_revisions()])
973
        self.assertEquals("bzr: ERROR: Further revision history missing.", stderr)
974
975
    def test_log_range_open_end(self):
976
        self.assertLogRevnos(["-r1.."], ["2", "1"])
5935.2.1 by Jacek Sieka
Change the meaning of the log -m option to match and make it match message, committer, authors and bugs. --match-message and friends can be used to make more specific matches.
977
978
class TestLogMatch(TestLogWithLogCatcher):
979
    def prepare_tree(self):
980
        tree = self.make_branch_and_tree('')
981
        self.build_tree(
982
            ['/hello.txt', '/goodbye.txt'])
983
        tree.add('hello.txt')
984
        tree.commit(message='message1', committer='committer1', authors=['author1'])
985
        tree.add('goodbye.txt')
986
        tree.commit(message='message2', committer='committer2', authors=['author2'])
987
    
988
    def test_message(self):
989
        self.prepare_tree()
990
        self.assertLogRevnos(["-m", "message1"], ["1"])
991
        self.assertLogRevnos(["-m", "message2"], ["2"])
992
        self.assertLogRevnos(["-m", "message"], ["2", "1"])
993
        self.assertLogRevnos(["-m", "message1", "-m", "message2"], ["2", "1"])
994
        self.assertLogRevnos(["--match-message", "message1"], ["1"])
995
        self.assertLogRevnos(["--match-message", "message2"], ["2"])
996
        self.assertLogRevnos(["--match-message", "message"], ["2", "1"])
997
        self.assertLogRevnos(["--match-message", "message1", 
998
                              "--match-message", "message2"], ["2", "1"])
999
        self.assertLogRevnos(["--message", "message1"], ["1"])
1000
        self.assertLogRevnos(["--message", "message2"], ["2"])
1001
        self.assertLogRevnos(["--message", "message"], ["2", "1"])
1002
        self.assertLogRevnos(["--match-message", "message1", 
1003
                              "--message", "message2"], ["2", "1"])
1004
        self.assertLogRevnos(["--message", "message1", 
1005
                              "--match-message", "message2"], ["2", "1"])
1006
1007
    def test_committer(self):
1008
        self.prepare_tree()
1009
        self.assertLogRevnos(["-m", "committer1"], ["1"])
1010
        self.assertLogRevnos(["-m", "committer2"], ["2"])
1011
        self.assertLogRevnos(["-m", "committer"], ["2", "1"])
1012
        self.assertLogRevnos(["-m", "committer1", "-m", "committer2"], 
1013
                             ["2", "1"])
1014
        self.assertLogRevnos(["--match-committer", "committer1"], ["1"])
1015
        self.assertLogRevnos(["--match-committer", "committer2"], ["2"])
1016
        self.assertLogRevnos(["--match-committer", "committer"], ["2", "1"])
1017
        self.assertLogRevnos(["--match-committer", "committer1", 
1018
                              "--match-committer", "committer2"], ["2", "1"])
1019
1020
    def test_author(self):
1021
        self.prepare_tree()
1022
        self.assertLogRevnos(["-m", "author1"], ["1"])
1023
        self.assertLogRevnos(["-m", "author2"], ["2"])
1024
        self.assertLogRevnos(["-m", "author"], ["2", "1"])
1025
        self.assertLogRevnos(["-m", "author1", "-m", "author2"], 
1026
                             ["2", "1"])
1027
        self.assertLogRevnos(["--match-author", "author1"], ["1"])
1028
        self.assertLogRevnos(["--match-author", "author2"], ["2"])
1029
        self.assertLogRevnos(["--match-author", "author"], ["2", "1"])
1030
        self.assertLogRevnos(["--match-author", "author1", 
1031
                              "--match-author", "author2"], ["2", "1"])