~bzr-pqm/bzr/bzr.dev

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