~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2006-2009, 2011 Canonical Ltd
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
2
#
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.
7
#
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.
12
#
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
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
16
17
"""Whitebox tests for annotate functionality."""
18
2593.1.1 by Adeodato Simó
Improve annotate to prevent unicode exceptions in certain situations.
19
import codecs
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
20
from cStringIO import StringIO
21
22
from bzrlib import (
23
    annotate,
24
    tests,
25
    )
26
27
1551.9.19 by Aaron Bentley
Merge from bzr.dev
28
def annotation(text):
29
    return [tuple(l.split(' ', 1)) for l in text.splitlines(True)]
30
31
32
parent_1 = annotation("""\
33
rev1 a
34
rev2 b
35
rev3 c
36
rev4 d
37
rev5 e
38
""")
39
40
41
parent_2 = annotation("""\
42
rev1 a
43
rev3 c
44
rev4 d
45
rev6 f
46
rev7 e
47
rev8 h
48
""")
49
50
51
expected_2_1 = annotation("""\
52
rev1 a
53
blahblah b
54
rev3 c
55
rev4 d
56
rev7 e
57
""")
58
59
60
# a: in both, same value, kept
61
# b: in 1, kept
62
# c: in both, same value, kept
63
# d: in both, same value, kept
64
# e: 1 and 2 disagree, so it goes to blahblah
65
# f: in 2, but not in new, so ignored
66
# g: not in 1 or 2, so it goes to blahblah
67
# h: only in parent 2, so 2 gets it
68
expected_1_2_2 = annotation("""\
69
rev1 a
70
rev2 b
71
rev3 c
72
rev4 d
73
blahblah e
74
blahblah g
75
rev8 h
76
""")
77
78
79
new_1 = """\
80
a
81
b
82
c
83
d
84
e
85
""".splitlines(True)
86
2770.1.1 by Aaron Bentley
Initial implmentation of plain knit annotation
87
expected_1 = annotation("""\
88
blahblah a
89
blahblah b
90
blahblah c
91
blahblah d
92
blahblah e
93
""")
94
1551.9.19 by Aaron Bentley
Merge from bzr.dev
95
96
new_2 = """\
97
a
98
b
99
c
100
d
101
e
102
g
103
h
104
""".splitlines(True)
105
106
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
107
# For the 'duplicate' series, both sides introduce the same change, which then
108
# gets merged around. The last-modified should properly reflect this.
109
# We always change the fourth line so that the file is properly tracked as
110
# being modified in each revision. In reality, this probably would happen over
111
# many revisions, and it would be a different line that changes.
112
# BASE
113
#  |\
114
#  A B  # line should be annotated as new for A and B
115
#  |\|
3588.3.1 by John Arbash Meinel
Simple patch to the annotate logic to handle bug #232188
116
#  C D  # line should 'converge' and say A
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
117
#  |/
118
#  E    # D should supersede A and stay as D (not become E because C references
119
#         A)
120
duplicate_base = annotation("""\
121
rev-base first
122
rev-base second
123
rev-base third
124
rev-base fourth-base
125
""")
126
127
duplicate_A = annotation("""\
128
rev-base first
129
rev-A alt-second
130
rev-base third
131
rev-A fourth-A
132
""")
133
134
duplicate_B = annotation("""\
135
rev-base first
136
rev-B alt-second
137
rev-base third
138
rev-B fourth-B
139
""")
140
141
duplicate_C = annotation("""\
142
rev-base first
143
rev-A alt-second
144
rev-base third
145
rev-C fourth-C
146
""")
147
148
duplicate_D = annotation("""\
149
rev-base first
3588.3.1 by John Arbash Meinel
Simple patch to the annotate logic to handle bug #232188
150
rev-A alt-second
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
151
rev-base third
152
rev-D fourth-D
153
""")
154
155
duplicate_E = annotation("""\
156
rev-base first
3588.3.1 by John Arbash Meinel
Simple patch to the annotate logic to handle bug #232188
157
rev-A alt-second
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
158
rev-base third
159
rev-E fourth-E
160
""")
161
162
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
163
class TestAnnotate(tests.TestCaseWithTransport):
164
165
    def create_merged_trees(self):
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
166
        """create 2 trees with merges between them.
167
168
        rev-1 --+
169
         |      |
170
        rev-2  rev-1_1_1
171
         |      |
172
         +------+
173
         |
174
        rev-3
175
        """
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
176
        builder = self.make_branch_builder('branch')
177
        builder.start_series()
178
        self.addCleanup(builder.finish_series)
179
        builder.build_snapshot('rev-1', None, [
180
            ('add', ('', 'root-id', 'directory', None)),
181
            ('add', ('a', 'a-id', 'file', 'first\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
182
            ], timestamp=1166046000.00, timezone=0, committer="joe@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
183
        builder.build_snapshot('rev-2', ['rev-1'], [
184
            ('modify', ('a-id', 'first\nsecond\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
185
            ], timestamp=1166046001.00, timezone=0, committer="joe@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
186
        builder.build_snapshot('rev-1_1_1', ['rev-1'], [
187
            ('modify', ('a-id', 'first\nthird\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
188
            ], timestamp=1166046002.00, timezone=0, committer="barry@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
189
        builder.build_snapshot('rev-3', ['rev-2', 'rev-1_1_1'], [
190
            ('modify', ('a-id', 'first\nsecond\nthird\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
191
            ], timestamp=1166046003.00, timezone=0, committer="sal@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
192
        return builder
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
193
194
    def create_deeply_merged_trees(self):
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
195
        """Create some trees with a more complex merge history.
196
197
        rev-1 --+
198
         |      |
199
        rev-2  rev-1_1_1 --+
200
         |      |          |
201
         +------+          |
202
         |      |          |
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
203
        rev-3  rev-1_1_2  rev-1_2_1 ------+
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
204
         |      |          |              |
205
         +------+          |              |
206
         |                 |              |
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
207
        rev-4             rev-1_2_2  rev-1_3_1
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
208
         |                 |              |
209
         +-----------------+              |
210
         |                                |
211
        rev-5                             |
212
         |                                |
213
         +--------------------------------+
214
         |
215
        rev-6
216
        """
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
217
        builder = self.create_merged_trees()
218
        builder.build_snapshot('rev-1_1_2', ['rev-1_1_1'], [])
219
        builder.build_snapshot('rev-4', ['rev-3', 'rev-1_1_2'], [])
220
        builder.build_snapshot('rev-1_2_1', ['rev-1_1_1'], [
221
            ('modify', ('a-id', 'first\nthird\nfourth\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
222
            ], timestamp=1166046003.00, timezone=0, committer="jerry@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
223
        builder.build_snapshot('rev-1_2_2', ['rev-1_2_1'], [],
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
224
            timestamp=1166046004.00, timezone=0, committer="jerry@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
225
        builder.build_snapshot('rev-5', ['rev-4', 'rev-1_2_2'], [
226
            ('modify', ('a-id', 'first\nsecond\nthird\nfourth\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
227
            ], timestamp=1166046004.00, timezone=0, committer="jerry@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
228
        builder.build_snapshot('rev-1_3_1', ['rev-1_2_1'], [
229
            ('modify', ('a-id', 'first\nthird\nfourth\nfifth\nsixth\n')),
4523.2.1 by Vincent Ladeuil
Fix TZ-dependent tests.
230
            ], timestamp=1166046005.00, timezone=0, committer="george@foo.com")
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
231
        builder.build_snapshot('rev-6', ['rev-5', 'rev-1_3_1'], [
232
            ('modify', ('a-id',
233
                        'first\nsecond\nthird\nfourth\nfifth\nsixth\n')),
234
            ])
235
        return builder
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
236
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
237
    def create_duplicate_lines_tree(self):
4454.3.25 by John Arbash Meinel
Use BranchBuilder for duplicate_lines_tree
238
        builder = self.make_branch_builder('branch')
239
        builder.start_series()
240
        self.addCleanup(builder.finish_series)
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
241
        base_text = ''.join(l for r, l in duplicate_base)
242
        a_text = ''.join(l for r, l in duplicate_A)
243
        b_text = ''.join(l for r, l in duplicate_B)
244
        c_text = ''.join(l for r, l in duplicate_C)
245
        d_text = ''.join(l for r, l in duplicate_D)
246
        e_text = ''.join(l for r, l in duplicate_E)
4454.3.25 by John Arbash Meinel
Use BranchBuilder for duplicate_lines_tree
247
        builder.build_snapshot('rev-base', None, [
248
            ('add', ('', 'root-id', 'directory', None)),
249
            ('add', ('file', 'file-id', 'file', base_text)),
250
            ])
251
        builder.build_snapshot('rev-A', ['rev-base'], [
252
            ('modify', ('file-id', a_text))])
253
        builder.build_snapshot('rev-B', ['rev-base'], [
254
            ('modify', ('file-id', b_text))])
255
        builder.build_snapshot('rev-C', ['rev-A'], [
256
            ('modify', ('file-id', c_text))])
257
        builder.build_snapshot('rev-D', ['rev-B', 'rev-A'], [
258
            ('modify', ('file-id', d_text))])
259
        builder.build_snapshot('rev-E', ['rev-C', 'rev-D'], [
260
            ('modify', ('file-id', e_text))])
261
        return builder
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
262
263
    def assertRepoAnnotate(self, expected, repo, file_id, revision_id):
264
        """Assert that the revision is properly annotated."""
265
        actual = list(repo.revision_tree(revision_id).annotate_iter(file_id))
266
        if actual != expected:
267
            # Create an easier to understand diff when the lines don't actually
268
            # match
269
            self.assertEqualDiff(''.join('\t'.join(l) for l in expected),
270
                                 ''.join('\t'.join(l) for l in actual))
271
272
    def test_annotate_duplicate_lines(self):
3689.1.4 by John Arbash Meinel
Doc strings that reference repository_implementations
273
        # XXX: Should this be a per_repository test?
4454.3.25 by John Arbash Meinel
Use BranchBuilder for duplicate_lines_tree
274
        builder = self.create_duplicate_lines_tree()
275
        repo = builder.get_branch().repository
3224.1.4 by John Arbash Meinel
Add a *failing* test to expose why we need better handling when a line is introduced on two sides of a merge.
276
        repo.lock_read()
277
        self.addCleanup(repo.unlock)
278
        self.assertRepoAnnotate(duplicate_base, repo, 'file-id', 'rev-base')
279
        self.assertRepoAnnotate(duplicate_A, repo, 'file-id', 'rev-A')
280
        self.assertRepoAnnotate(duplicate_B, repo, 'file-id', 'rev-B')
281
        self.assertRepoAnnotate(duplicate_C, repo, 'file-id', 'rev-C')
282
        self.assertRepoAnnotate(duplicate_D, repo, 'file-id', 'rev-D')
283
        self.assertRepoAnnotate(duplicate_E, repo, 'file-id', 'rev-E')
284
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
285
    def test_annotate_shows_dotted_revnos(self):
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
286
        builder = self.create_merged_trees()
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
287
288
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
289
        annotate.annotate_file(builder.get_branch(), 'rev-3', 'a-id',
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
290
                               to_file=sio)
291
        self.assertEqualDiff('1     joe@foo | first\n'
292
                             '2     joe@foo | second\n'
293
                             '1.1.1 barry@f | third\n',
294
                             sio.getvalue())
295
296
    def test_annotate_limits_dotted_revnos(self):
297
        """Annotate should limit dotted revnos to a depth of 12"""
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
298
        builder = self.create_deeply_merged_trees()
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
299
300
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
301
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
302
                               to_file=sio, verbose=False, full=False)
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
303
        self.assertEqualDiff('1     joe@foo | first\n'
304
                             '2     joe@foo | second\n'
305
                             '1.1.1 barry@f | third\n'
306
                             '1.2.1 jerry@f | fourth\n'
307
                             '1.3.1 george@ | fifth\n'
308
                             '              | sixth\n',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
309
                             sio.getvalue())
310
311
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
312
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
313
                               to_file=sio, verbose=False, full=True)
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
314
        self.assertEqualDiff('1     joe@foo | first\n'
315
                             '2     joe@foo | second\n'
316
                             '1.1.1 barry@f | third\n'
317
                             '1.2.1 jerry@f | fourth\n'
318
                             '1.3.1 george@ | fifth\n'
319
                             '1.3.1 george@ | sixth\n',
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
320
                             sio.getvalue())
321
322
        # verbose=True shows everything, the full revno, user id, and date
323
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
324
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
325
                               to_file=sio, verbose=True, full=False)
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
326
        self.assertEqualDiff('1     joe@foo.com    20061213 | first\n'
327
                             '2     joe@foo.com    20061213 | second\n'
328
                             '1.1.1 barry@foo.com  20061213 | third\n'
329
                             '1.2.1 jerry@foo.com  20061213 | fourth\n'
330
                             '1.3.1 george@foo.com 20061213 | fifth\n'
331
                             '                              | sixth\n',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
332
                             sio.getvalue())
333
334
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
335
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
336
                               to_file=sio, verbose=True, full=True)
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
337
        self.assertEqualDiff('1     joe@foo.com    20061213 | first\n'
338
                             '2     joe@foo.com    20061213 | second\n'
339
                             '1.1.1 barry@foo.com  20061213 | third\n'
340
                             '1.2.1 jerry@foo.com  20061213 | fourth\n'
341
                             '1.3.1 george@foo.com 20061213 | fifth\n'
342
                             '1.3.1 george@foo.com 20061213 | sixth\n',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
343
                             sio.getvalue())
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
344
345
    def test_annotate_uses_branch_context(self):
346
        """Dotted revnos should use the Branch context.
347
348
        When annotating a non-mainline revision, the annotation should still
349
        use dotted revnos from the mainline.
350
        """
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
351
        builder = self.create_deeply_merged_trees()
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
352
353
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
354
        annotate.annotate_file(builder.get_branch(), 'rev-1_3_1', 'a-id',
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
355
                               to_file=sio, verbose=False, full=False)
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
356
        self.assertEqualDiff('1     joe@foo | first\n'
357
                             '1.1.1 barry@f | third\n'
358
                             '1.2.1 jerry@f | fourth\n'
359
                             '1.3.1 george@ | fifth\n'
360
                             '              | sixth\n',
2245.3.1 by John Arbash Meinel
bzr annotate should use Branch's dotted revnos.
361
                             sio.getvalue())
362
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
363
    def test_annotate_show_ids(self):
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
364
        builder = self.create_deeply_merged_trees()
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
365
366
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
367
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
368
                               to_file=sio, show_ids=True, full=False)
369
370
        # It looks better with real revision ids :)
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
371
        self.assertEqualDiff('    rev-1 | first\n'
372
                             '    rev-2 | second\n'
373
                             'rev-1_1_1 | third\n'
374
                             'rev-1_2_1 | fourth\n'
375
                             'rev-1_3_1 | fifth\n'
376
                             '          | sixth\n',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
377
                             sio.getvalue())
378
379
        sio = StringIO()
4454.3.24 by John Arbash Meinel
update BranchBuilder to support 'committer'
380
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
2182.3.4 by John Arbash Meinel
add show-ids and test that nearby areas are collapsed without full
381
                               to_file=sio, show_ids=True, full=True)
382
3170.3.4 by John Arbash Meinel
Update the tests for the new revision numbering.
383
        self.assertEqualDiff('    rev-1 | first\n'
384
                             '    rev-2 | second\n'
385
                             'rev-1_1_1 | third\n'
386
                             'rev-1_2_1 | fourth\n'
387
                             'rev-1_3_1 | fifth\n'
388
                             'rev-1_3_1 | sixth\n',
2182.3.3 by John Arbash Meinel
Add tests for annotate with dotted revnos.
389
                             sio.getvalue())
1551.9.19 by Aaron Bentley
Merge from bzr.dev
390
2593.1.1 by Adeodato Simó
Improve annotate to prevent unicode exceptions in certain situations.
391
    def test_annotate_unicode_author(self):
392
        tree1 = self.make_branch_and_tree('tree1')
393
394
        self.build_tree_contents([('tree1/a', 'adi\xc3\xb3s')])
395
        tree1.add(['a'], ['a-id'])
396
        tree1.commit('a', rev_id='rev-1',
397
                     committer=u'Pepe P\xe9rez <pperez@ejemplo.com>',
398
                     timestamp=1166046000.00, timezone=0)
399
400
        self.build_tree_contents([('tree1/b', 'bye')])
401
        tree1.add(['b'], ['b-id'])
402
        tree1.commit('b', rev_id='rev-2',
403
                     committer=u'p\xe9rez',
404
                     timestamp=1166046000.00, timezone=0)
405
3010.1.1 by Robert Collins
Lock the tree's used to test annotate_file, and add a docstring for annotate_file explaining its needs.
406
        tree1.lock_read()
407
        self.addCleanup(tree1.unlock)
2593.1.2 by Adeodato Simó
Improve tests a bit, actually checking for the replace encoding.
408
        # this passes if no exception is raised
409
        to_file = StringIO()
2593.1.1 by Adeodato Simó
Improve annotate to prevent unicode exceptions in certain situations.
410
        annotate.annotate_file(tree1.branch, 'rev-1', 'a-id', to_file=to_file)
411
2593.1.2 by Adeodato Simó
Improve tests a bit, actually checking for the replace encoding.
412
        sio = StringIO()
413
        to_file = codecs.getwriter('ascii')(sio)
2593.1.1 by Adeodato Simó
Improve annotate to prevent unicode exceptions in certain situations.
414
        to_file.encoding = 'ascii' # codecs does not set it
415
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
2593.1.2 by Adeodato Simó
Improve tests a bit, actually checking for the replace encoding.
416
        self.assertEqualDiff('2   p?rez   | bye\n', sio.getvalue())
2593.1.1 by Adeodato Simó
Improve annotate to prevent unicode exceptions in certain situations.
417
2593.1.3 by Adeodato Simó
Cope with to_file.encoding being None or not present.
418
        # test now with to_file.encoding = None
419
        to_file = tests.StringIOWrapper()
420
        to_file.encoding = None
421
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
2593.1.5 by Adeodato Simó
Fix copy&paste bug in test, catched by John.
422
        self.assertContainsRe('2   p.rez   | bye\n', to_file.getvalue())
2593.1.3 by Adeodato Simó
Cope with to_file.encoding being None or not present.
423
424
        # and when it does not exist
425
        to_file = StringIO()
426
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
2593.1.5 by Adeodato Simó
Fix copy&paste bug in test, catched by John.
427
        self.assertContainsRe('2   p.rez   | bye\n', to_file.getvalue())
2593.1.3 by Adeodato Simó
Cope with to_file.encoding being None or not present.
428
2671.5.3 by Lukáš Lalinsky
Use the author name in annotate.
429
    def test_annotate_author_or_committer(self):
430
        tree1 = self.make_branch_and_tree('tree1')
431
432
        self.build_tree_contents([('tree1/a', 'hello')])
433
        tree1.add(['a'], ['a-id'])
434
        tree1.commit('a', rev_id='rev-1',
435
                     committer='Committer <committer@example.com>',
436
                     timestamp=1166046000.00, timezone=0)
437
438
        self.build_tree_contents([('tree1/b', 'bye')])
439
        tree1.add(['b'], ['b-id'])
440
        tree1.commit('b', rev_id='rev-2',
441
                     committer='Committer <committer@example.com>',
4056.2.1 by James Westby
Allow specifying multiple authors for a revision.
442
                     authors=['Author <author@example.com>'],
2671.5.3 by Lukáš Lalinsky
Use the author name in annotate.
443
                     timestamp=1166046000.00, timezone=0)
444
3010.1.1 by Robert Collins
Lock the tree's used to test annotate_file, and add a docstring for annotate_file explaining its needs.
445
        tree1.lock_read()
446
        self.addCleanup(tree1.unlock)
2671.5.3 by Lukáš Lalinsky
Use the author name in annotate.
447
        to_file = StringIO()
448
        annotate.annotate_file(tree1.branch, 'rev-1', 'a-id', to_file=to_file)
449
        self.assertEqual('1   committ | hello\n', to_file.getvalue())
450
451
        to_file = StringIO()
452
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
453
        self.assertEqual('2   author@ | bye\n', to_file.getvalue())
454
1551.9.19 by Aaron Bentley
Merge from bzr.dev
455
456
class TestReannotate(tests.TestCase):
457
2770.1.5 by Aaron Bentley
Clean up docs, test matching blocks for reannotate
458
    def annotateEqual(self, expected, parents, newlines, revision_id,
459
                      blocks=None):
1551.9.19 by Aaron Bentley
Merge from bzr.dev
460
        annotate_list = list(annotate.reannotate(parents, newlines,
2770.1.5 by Aaron Bentley
Clean up docs, test matching blocks for reannotate
461
                             revision_id, blocks))
1551.9.19 by Aaron Bentley
Merge from bzr.dev
462
        self.assertEqual(len(expected), len(annotate_list))
463
        for e, a in zip(expected, annotate_list):
464
            self.assertEqual(e, a)
465
466
    def test_reannotate(self):
467
        self.annotateEqual(parent_1, [parent_1], new_1, 'blahblah')
468
        self.annotateEqual(expected_2_1, [parent_2], new_1, 'blahblah')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
469
        self.annotateEqual(expected_1_2_2, [parent_1, parent_2], new_2,
1551.9.19 by Aaron Bentley
Merge from bzr.dev
470
                           'blahblah')
2770.1.1 by Aaron Bentley
Initial implmentation of plain knit annotation
471
472
    def test_reannotate_no_parents(self):
473
        self.annotateEqual(expected_1, [], new_1, 'blahblah')
2770.1.5 by Aaron Bentley
Clean up docs, test matching blocks for reannotate
474
475
    def test_reannotate_left_matching_blocks(self):
476
        """Ensure that left_matching_blocks has an impact.
477
478
        In this case, the annotation is ambiguous, so the hint isn't actually
479
        lying.
480
        """
481
        parent = [('rev1', 'a\n')]
482
        new_text = ['a\n', 'a\n']
483
        blocks = [(0, 0, 1), (1, 2, 0)]
484
        self.annotateEqual([('rev1', 'a\n'), ('rev2', 'a\n')], [parent],
485
                           new_text, 'rev2', blocks)
486
        blocks = [(0, 1, 1), (1, 2, 0)]
487
        self.annotateEqual([('rev2', 'a\n'), ('rev1', 'a\n')], [parent],
488
                           new_text, 'rev2', blocks)