/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to breezy/tests/test_annotate.py

  • Committer: Jelmer Vernooij
  • Date: 2020-04-05 19:11:34 UTC
  • mto: (7490.7.16 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200405191134-0aebh8ikiwygxma5
Populate the .gitignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Canonical Ltd
 
1
# Copyright (C) 2006-2009, 2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Whitebox tests for annotate functionality."""
18
18
 
19
19
import codecs
20
 
from cStringIO import StringIO
 
20
from io import BytesIO
21
21
 
22
 
from bzrlib import (
 
22
from .. import (
23
23
    annotate,
24
 
    conflicts,
25
 
    errors,
26
24
    tests,
27
 
    trace,
28
 
    )
 
25
    )
 
26
from ..sixish import (
 
27
    StringIO,
 
28
    )
 
29
from .ui_testing import StringIOWithEncoding
29
30
 
30
31
 
31
32
def annotation(text):
32
 
    return [tuple(l.split(' ', 1)) for l in text.splitlines(True)]
33
 
 
34
 
 
35
 
parent_1 = annotation("""\
 
33
    return [tuple(l.split(b' ', 1)) for l in text.splitlines(True)]
 
34
 
 
35
 
 
36
parent_1 = annotation(b"""\
36
37
rev1 a
37
38
rev2 b
38
39
rev3 c
41
42
""")
42
43
 
43
44
 
44
 
parent_2 = annotation("""\
 
45
parent_2 = annotation(b"""\
45
46
rev1 a
46
47
rev3 c
47
48
rev4 d
51
52
""")
52
53
 
53
54
 
54
 
expected_2_1 = annotation("""\
 
55
expected_2_1 = annotation(b"""\
55
56
rev1 a
56
57
blahblah b
57
58
rev3 c
68
69
# f: in 2, but not in new, so ignored
69
70
# g: not in 1 or 2, so it goes to blahblah
70
71
# h: only in parent 2, so 2 gets it
71
 
expected_1_2_2 = annotation("""\
 
72
expected_1_2_2 = annotation(b"""\
72
73
rev1 a
73
74
rev2 b
74
75
rev3 c
79
80
""")
80
81
 
81
82
 
82
 
new_1 = """\
 
83
new_1 = b"""\
83
84
a
84
85
b
85
86
c
87
88
e
88
89
""".splitlines(True)
89
90
 
90
 
expected_1 = annotation("""\
 
91
expected_1 = annotation(b"""\
91
92
blahblah a
92
93
blahblah b
93
94
blahblah c
96
97
""")
97
98
 
98
99
 
99
 
new_2 = """\
 
100
new_2 = b"""\
100
101
a
101
102
b
102
103
c
120
121
#  |/
121
122
#  E    # D should supersede A and stay as D (not become E because C references
122
123
#         A)
123
 
duplicate_base = annotation("""\
 
124
duplicate_base = annotation(b"""\
124
125
rev-base first
125
126
rev-base second
126
127
rev-base third
127
128
rev-base fourth-base
128
129
""")
129
130
 
130
 
duplicate_A = annotation("""\
 
131
duplicate_A = annotation(b"""\
131
132
rev-base first
132
133
rev-A alt-second
133
134
rev-base third
134
135
rev-A fourth-A
135
136
""")
136
137
 
137
 
duplicate_B = annotation("""\
 
138
duplicate_B = annotation(b"""\
138
139
rev-base first
139
140
rev-B alt-second
140
141
rev-base third
141
142
rev-B fourth-B
142
143
""")
143
144
 
144
 
duplicate_C = annotation("""\
 
145
duplicate_C = annotation(b"""\
145
146
rev-base first
146
147
rev-A alt-second
147
148
rev-base third
148
149
rev-C fourth-C
149
150
""")
150
151
 
151
 
duplicate_D = annotation("""\
 
152
duplicate_D = annotation(b"""\
152
153
rev-base first
153
154
rev-A alt-second
154
155
rev-base third
155
156
rev-D fourth-D
156
157
""")
157
158
 
158
 
duplicate_E = annotation("""\
 
159
duplicate_E = annotation(b"""\
159
160
rev-base first
160
161
rev-A alt-second
161
162
rev-base third
179
180
        builder = self.make_branch_builder('branch')
180
181
        builder.start_series()
181
182
        self.addCleanup(builder.finish_series)
182
 
        builder.build_snapshot('rev-1', None, [
183
 
            ('add', ('', 'root-id', 'directory', None)),
184
 
            ('add', ('a', 'a-id', 'file', 'first\n')),
185
 
            ], timestamp=1166046000.00, timezone=0, committer="joe@foo.com")
186
 
        builder.build_snapshot('rev-2', ['rev-1'], [
187
 
            ('modify', ('a-id', 'first\nsecond\n')),
188
 
            ], timestamp=1166046001.00, timezone=0, committer="joe@foo.com")
189
 
        builder.build_snapshot('rev-1_1_1', ['rev-1'], [
190
 
            ('modify', ('a-id', 'first\nthird\n')),
191
 
            ], timestamp=1166046002.00, timezone=0, committer="barry@foo.com")
192
 
        builder.build_snapshot('rev-3', ['rev-2', 'rev-1_1_1'], [
193
 
            ('modify', ('a-id', 'first\nsecond\nthird\n')),
194
 
            ], timestamp=1166046003.00, timezone=0, committer="sal@foo.com")
 
183
        builder.build_snapshot(None, [
 
184
            ('add', ('', b'root-id', 'directory', None)),
 
185
            ('add', ('a', b'a-id', 'file', b'first\n')),
 
186
            ], timestamp=1166046000.00, timezone=0, committer="joe@foo.com",
 
187
            revision_id=b'rev-1')
 
188
        builder.build_snapshot([b'rev-1'], [
 
189
            ('modify', ('a', b'first\nsecond\n')),
 
190
            ], timestamp=1166046001.00, timezone=0, committer="joe@foo.com",
 
191
            revision_id=b'rev-2')
 
192
        builder.build_snapshot([b'rev-1'], [
 
193
            ('modify', ('a', b'first\nthird\n')),
 
194
            ], timestamp=1166046002.00, timezone=0, committer="barry@foo.com",
 
195
            revision_id=b'rev-1_1_1')
 
196
        builder.build_snapshot([b'rev-2', b'rev-1_1_1'], [
 
197
            ('modify', ('a', b'first\nsecond\nthird\n')),
 
198
            ], timestamp=1166046003.00, timezone=0, committer="sal@foo.com",
 
199
            revision_id=b'rev-3')
195
200
        return builder
196
201
 
197
202
    def create_deeply_merged_trees(self):
218
223
        rev-6
219
224
        """
220
225
        builder = self.create_merged_trees()
221
 
        builder.build_snapshot('rev-1_1_2', ['rev-1_1_1'], [])
222
 
        builder.build_snapshot('rev-4', ['rev-3', 'rev-1_1_2'], [])
223
 
        builder.build_snapshot('rev-1_2_1', ['rev-1_1_1'], [
224
 
            ('modify', ('a-id', 'first\nthird\nfourth\n')),
225
 
            ], timestamp=1166046003.00, timezone=0, committer="jerry@foo.com")
226
 
        builder.build_snapshot('rev-1_2_2', ['rev-1_2_1'], [],
227
 
            timestamp=1166046004.00, timezone=0, committer="jerry@foo.com")
228
 
        builder.build_snapshot('rev-5', ['rev-4', 'rev-1_2_2'], [
229
 
            ('modify', ('a-id', 'first\nsecond\nthird\nfourth\n')),
230
 
            ], timestamp=1166046004.00, timezone=0, committer="jerry@foo.com")
231
 
        builder.build_snapshot('rev-1_3_1', ['rev-1_2_1'], [
232
 
            ('modify', ('a-id', 'first\nthird\nfourth\nfifth\nsixth\n')),
233
 
            ], timestamp=1166046005.00, timezone=0, committer="george@foo.com")
234
 
        builder.build_snapshot('rev-6', ['rev-5', 'rev-1_3_1'], [
235
 
            ('modify', ('a-id',
236
 
                        'first\nsecond\nthird\nfourth\nfifth\nsixth\n')),
237
 
            ])
 
226
        builder.build_snapshot([b'rev-1_1_1'], [], revision_id=b'rev-1_1_2')
 
227
        builder.build_snapshot([b'rev-3', b'rev-1_1_2'],
 
228
                               [], revision_id=b'rev-4')
 
229
        builder.build_snapshot([b'rev-1_1_1'], [
 
230
            ('modify', ('a', b'first\nthird\nfourth\n')),
 
231
            ], timestamp=1166046003.00, timezone=0, committer="jerry@foo.com",
 
232
            revision_id=b'rev-1_2_1')
 
233
        builder.build_snapshot([b'rev-1_2_1'], [],
 
234
                               timestamp=1166046004.00, timezone=0, committer="jerry@foo.com",
 
235
                               revision_id=b'rev-1_2_2')
 
236
        builder.build_snapshot([b'rev-4', b'rev-1_2_2'], [
 
237
            ('modify', ('a', b'first\nsecond\nthird\nfourth\n')),
 
238
            ], timestamp=1166046004.00, timezone=0, committer="jerry@foo.com",
 
239
            revision_id=b'rev-5')
 
240
        builder.build_snapshot([b'rev-1_2_1'], [
 
241
            ('modify', ('a', b'first\nthird\nfourth\nfifth\nsixth\n')),
 
242
            ], timestamp=1166046005.00, timezone=0, committer="george@foo.com",
 
243
            revision_id=b'rev-1_3_1')
 
244
        builder.build_snapshot([b'rev-5', b'rev-1_3_1'], [
 
245
            ('modify', ('a',
 
246
                        b'first\nsecond\nthird\nfourth\nfifth\nsixth\n')),
 
247
            ], revision_id=b'rev-6')
238
248
        return builder
239
249
 
240
250
    def create_duplicate_lines_tree(self):
241
251
        builder = self.make_branch_builder('branch')
242
252
        builder.start_series()
243
253
        self.addCleanup(builder.finish_series)
244
 
        base_text = ''.join(l for r, l in duplicate_base)
245
 
        a_text = ''.join(l for r, l in duplicate_A)
246
 
        b_text = ''.join(l for r, l in duplicate_B)
247
 
        c_text = ''.join(l for r, l in duplicate_C)
248
 
        d_text = ''.join(l for r, l in duplicate_D)
249
 
        e_text = ''.join(l for r, l in duplicate_E)
250
 
        builder.build_snapshot('rev-base', None, [
251
 
            ('add', ('', 'root-id', 'directory', None)),
252
 
            ('add', ('file', 'file-id', 'file', base_text)),
253
 
            ])
254
 
        builder.build_snapshot('rev-A', ['rev-base'], [
255
 
            ('modify', ('file-id', a_text))])
256
 
        builder.build_snapshot('rev-B', ['rev-base'], [
257
 
            ('modify', ('file-id', b_text))])
258
 
        builder.build_snapshot('rev-C', ['rev-A'], [
259
 
            ('modify', ('file-id', c_text))])
260
 
        builder.build_snapshot('rev-D', ['rev-B', 'rev-A'], [
261
 
            ('modify', ('file-id', d_text))])
262
 
        builder.build_snapshot('rev-E', ['rev-C', 'rev-D'], [
263
 
            ('modify', ('file-id', e_text))])
 
254
        base_text = b''.join(l for r, l in duplicate_base)
 
255
        a_text = b''.join(l for r, l in duplicate_A)
 
256
        b_text = b''.join(l for r, l in duplicate_B)
 
257
        c_text = b''.join(l for r, l in duplicate_C)
 
258
        d_text = b''.join(l for r, l in duplicate_D)
 
259
        e_text = b''.join(l for r, l in duplicate_E)
 
260
        builder.build_snapshot(None, [
 
261
            ('add', ('', b'root-id', 'directory', None)),
 
262
            ('add', ('file', b'file-id', 'file', base_text)),
 
263
            ], revision_id=b'rev-base')
 
264
        builder.build_snapshot([b'rev-base'], [
 
265
            ('modify', ('file', a_text))],
 
266
            revision_id=b'rev-A')
 
267
        builder.build_snapshot([b'rev-base'], [
 
268
            ('modify', ('file', b_text))],
 
269
            revision_id=b'rev-B')
 
270
        builder.build_snapshot([b'rev-A'], [
 
271
            ('modify', ('file', c_text))],
 
272
            revision_id=b'rev-C')
 
273
        builder.build_snapshot([b'rev-B', b'rev-A'], [
 
274
            ('modify', ('file', d_text))],
 
275
            revision_id=b'rev-D')
 
276
        builder.build_snapshot([b'rev-C', b'rev-D'], [
 
277
            ('modify', ('file', e_text))],
 
278
            revision_id=b'rev-E')
264
279
        return builder
265
280
 
266
 
    def assertRepoAnnotate(self, expected, repo, file_id, revision_id):
267
 
        """Assert that the revision is properly annotated."""
268
 
        actual = list(repo.revision_tree(revision_id).annotate_iter(file_id))
 
281
    def assertAnnotateEqualDiff(self, actual, expected):
269
282
        if actual != expected:
270
283
            # Create an easier to understand diff when the lines don't actually
271
284
            # match
272
285
            self.assertEqualDiff(''.join('\t'.join(l) for l in expected),
273
286
                                 ''.join('\t'.join(l) for l in actual))
274
287
 
 
288
    def assertBranchAnnotate(self, expected, branch, path, revision_id,
 
289
                             verbose=False, full=False, show_ids=False):
 
290
        tree = branch.repository.revision_tree(revision_id)
 
291
        to_file = StringIO()
 
292
        annotate.annotate_file_tree(tree, path, to_file,
 
293
                                    verbose=verbose, full=full, show_ids=show_ids, branch=branch)
 
294
        self.assertAnnotateEqualDiff(to_file.getvalue(), expected)
 
295
 
 
296
    def assertRepoAnnotate(self, expected, repo, path, revision_id):
 
297
        """Assert that the revision is properly annotated."""
 
298
        actual = list(repo.revision_tree(revision_id).annotate_iter(path))
 
299
        self.assertAnnotateEqualDiff(actual, expected)
 
300
 
275
301
    def test_annotate_duplicate_lines(self):
276
302
        # XXX: Should this be a per_repository test?
277
303
        builder = self.create_duplicate_lines_tree()
278
304
        repo = builder.get_branch().repository
279
305
        repo.lock_read()
280
306
        self.addCleanup(repo.unlock)
281
 
        self.assertRepoAnnotate(duplicate_base, repo, 'file-id', 'rev-base')
282
 
        self.assertRepoAnnotate(duplicate_A, repo, 'file-id', 'rev-A')
283
 
        self.assertRepoAnnotate(duplicate_B, repo, 'file-id', 'rev-B')
284
 
        self.assertRepoAnnotate(duplicate_C, repo, 'file-id', 'rev-C')
285
 
        self.assertRepoAnnotate(duplicate_D, repo, 'file-id', 'rev-D')
286
 
        self.assertRepoAnnotate(duplicate_E, repo, 'file-id', 'rev-E')
 
307
        self.assertRepoAnnotate(duplicate_base, repo, 'file', b'rev-base')
 
308
        self.assertRepoAnnotate(duplicate_A, repo, 'file', b'rev-A')
 
309
        self.assertRepoAnnotate(duplicate_B, repo, 'file', b'rev-B')
 
310
        self.assertRepoAnnotate(duplicate_C, repo, 'file', b'rev-C')
 
311
        self.assertRepoAnnotate(duplicate_D, repo, 'file', b'rev-D')
 
312
        self.assertRepoAnnotate(duplicate_E, repo, 'file', b'rev-E')
287
313
 
288
314
    def test_annotate_shows_dotted_revnos(self):
289
315
        builder = self.create_merged_trees()
290
316
 
291
 
        sio = StringIO()
292
 
        annotate.annotate_file(builder.get_branch(), 'rev-3', 'a-id',
293
 
                               to_file=sio)
294
 
        self.assertEqualDiff('1     joe@foo | first\n'
295
 
                             '2     joe@foo | second\n'
296
 
                             '1.1.1 barry@f | third\n',
297
 
                             sio.getvalue())
 
317
        self.assertBranchAnnotate('1     joe@foo | first\n'
 
318
                                  '2     joe@foo | second\n'
 
319
                                  '1.1.1 barry@f | third\n',
 
320
                                  builder.get_branch(), 'a', b'rev-3')
298
321
 
299
322
    def test_annotate_limits_dotted_revnos(self):
300
323
        """Annotate should limit dotted revnos to a depth of 12"""
301
324
        builder = self.create_deeply_merged_trees()
302
325
 
303
 
        sio = StringIO()
304
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
305
 
                               to_file=sio, verbose=False, full=False)
306
 
        self.assertEqualDiff('1     joe@foo | first\n'
307
 
                             '2     joe@foo | second\n'
308
 
                             '1.1.1 barry@f | third\n'
309
 
                             '1.2.1 jerry@f | fourth\n'
310
 
                             '1.3.1 george@ | fifth\n'
311
 
                             '              | sixth\n',
312
 
                             sio.getvalue())
 
326
        self.assertBranchAnnotate('1     joe@foo | first\n'
 
327
                                  '2     joe@foo | second\n'
 
328
                                  '1.1.1 barry@f | third\n'
 
329
                                  '1.2.1 jerry@f | fourth\n'
 
330
                                  '1.3.1 george@ | fifth\n'
 
331
                                  '              | sixth\n',
 
332
                                  builder.get_branch(), 'a', b'rev-6',
 
333
                                  verbose=False, full=False)
313
334
 
314
 
        sio = StringIO()
315
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
316
 
                               to_file=sio, verbose=False, full=True)
317
 
        self.assertEqualDiff('1     joe@foo | first\n'
318
 
                             '2     joe@foo | second\n'
319
 
                             '1.1.1 barry@f | third\n'
320
 
                             '1.2.1 jerry@f | fourth\n'
321
 
                             '1.3.1 george@ | fifth\n'
322
 
                             '1.3.1 george@ | sixth\n',
323
 
                             sio.getvalue())
 
335
        self.assertBranchAnnotate('1     joe@foo | first\n'
 
336
                                  '2     joe@foo | second\n'
 
337
                                  '1.1.1 barry@f | third\n'
 
338
                                  '1.2.1 jerry@f | fourth\n'
 
339
                                  '1.3.1 george@ | fifth\n'
 
340
                                  '1.3.1 george@ | sixth\n',
 
341
                                  builder.get_branch(), 'a', b'rev-6',
 
342
                                  verbose=False, full=True)
324
343
 
325
344
        # verbose=True shows everything, the full revno, user id, and date
326
 
        sio = StringIO()
327
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
328
 
                               to_file=sio, verbose=True, full=False)
329
 
        self.assertEqualDiff('1     joe@foo.com    20061213 | first\n'
330
 
                             '2     joe@foo.com    20061213 | second\n'
331
 
                             '1.1.1 barry@foo.com  20061213 | third\n'
332
 
                             '1.2.1 jerry@foo.com  20061213 | fourth\n'
333
 
                             '1.3.1 george@foo.com 20061213 | fifth\n'
334
 
                             '                              | sixth\n',
335
 
                             sio.getvalue())
 
345
        self.assertBranchAnnotate('1     joe@foo.com    20061213 | first\n'
 
346
                                  '2     joe@foo.com    20061213 | second\n'
 
347
                                  '1.1.1 barry@foo.com  20061213 | third\n'
 
348
                                  '1.2.1 jerry@foo.com  20061213 | fourth\n'
 
349
                                  '1.3.1 george@foo.com 20061213 | fifth\n'
 
350
                                  '                              | sixth\n',
 
351
                                  builder.get_branch(), 'a', b'rev-6',
 
352
                                  verbose=True, full=False)
336
353
 
337
 
        sio = StringIO()
338
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
339
 
                               to_file=sio, verbose=True, full=True)
340
 
        self.assertEqualDiff('1     joe@foo.com    20061213 | first\n'
341
 
                             '2     joe@foo.com    20061213 | second\n'
342
 
                             '1.1.1 barry@foo.com  20061213 | third\n'
343
 
                             '1.2.1 jerry@foo.com  20061213 | fourth\n'
344
 
                             '1.3.1 george@foo.com 20061213 | fifth\n'
345
 
                             '1.3.1 george@foo.com 20061213 | sixth\n',
346
 
                             sio.getvalue())
 
354
        self.assertBranchAnnotate('1     joe@foo.com    20061213 | first\n'
 
355
                                  '2     joe@foo.com    20061213 | second\n'
 
356
                                  '1.1.1 barry@foo.com  20061213 | third\n'
 
357
                                  '1.2.1 jerry@foo.com  20061213 | fourth\n'
 
358
                                  '1.3.1 george@foo.com 20061213 | fifth\n'
 
359
                                  '1.3.1 george@foo.com 20061213 | sixth\n',
 
360
                                  builder.get_branch(), 'a', b'rev-6',
 
361
                                  verbose=True, full=True)
347
362
 
348
363
    def test_annotate_uses_branch_context(self):
349
364
        """Dotted revnos should use the Branch context.
353
368
        """
354
369
        builder = self.create_deeply_merged_trees()
355
370
 
356
 
        sio = StringIO()
357
 
        annotate.annotate_file(builder.get_branch(), 'rev-1_3_1', 'a-id',
358
 
                               to_file=sio, verbose=False, full=False)
359
 
        self.assertEqualDiff('1     joe@foo | first\n'
360
 
                             '1.1.1 barry@f | third\n'
361
 
                             '1.2.1 jerry@f | fourth\n'
362
 
                             '1.3.1 george@ | fifth\n'
363
 
                             '              | sixth\n',
364
 
                             sio.getvalue())
 
371
        self.assertBranchAnnotate('1     joe@foo | first\n'
 
372
                                  '1.1.1 barry@f | third\n'
 
373
                                  '1.2.1 jerry@f | fourth\n'
 
374
                                  '1.3.1 george@ | fifth\n'
 
375
                                  '              | sixth\n',
 
376
                                  builder.get_branch(), 'a', b'rev-1_3_1',
 
377
                                  verbose=False, full=False)
365
378
 
366
379
    def test_annotate_show_ids(self):
367
380
        builder = self.create_deeply_merged_trees()
368
381
 
369
 
        sio = StringIO()
370
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
371
 
                               to_file=sio, show_ids=True, full=False)
372
 
 
373
382
        # It looks better with real revision ids :)
374
 
        self.assertEqualDiff('    rev-1 | first\n'
375
 
                             '    rev-2 | second\n'
376
 
                             'rev-1_1_1 | third\n'
377
 
                             'rev-1_2_1 | fourth\n'
378
 
                             'rev-1_3_1 | fifth\n'
379
 
                             '          | sixth\n',
380
 
                             sio.getvalue())
381
 
 
382
 
        sio = StringIO()
383
 
        annotate.annotate_file(builder.get_branch(), 'rev-6', 'a-id',
384
 
                               to_file=sio, show_ids=True, full=True)
385
 
 
386
 
        self.assertEqualDiff('    rev-1 | first\n'
387
 
                             '    rev-2 | second\n'
388
 
                             'rev-1_1_1 | third\n'
389
 
                             'rev-1_2_1 | fourth\n'
390
 
                             'rev-1_3_1 | fifth\n'
391
 
                             'rev-1_3_1 | sixth\n',
392
 
                             sio.getvalue())
 
383
        self.assertBranchAnnotate('    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
                                  '          | sixth\n',
 
389
                                  builder.get_branch(), 'a', b'rev-6',
 
390
                                  show_ids=True, full=False)
 
391
 
 
392
        self.assertBranchAnnotate('    rev-1 | first\n'
 
393
                                  '    rev-2 | second\n'
 
394
                                  'rev-1_1_1 | third\n'
 
395
                                  'rev-1_2_1 | fourth\n'
 
396
                                  'rev-1_3_1 | fifth\n'
 
397
                                  'rev-1_3_1 | sixth\n',
 
398
                                  builder.get_branch(), 'a', b'rev-6',
 
399
                                  show_ids=True, full=True)
393
400
 
394
401
    def test_annotate_unicode_author(self):
395
402
        tree1 = self.make_branch_and_tree('tree1')
396
403
 
397
 
        self.build_tree_contents([('tree1/a', 'adi\xc3\xb3s')])
398
 
        tree1.add(['a'], ['a-id'])
399
 
        tree1.commit('a', rev_id='rev-1',
 
404
        self.build_tree_contents([('tree1/a', b'adi\xc3\xb3s')])
 
405
        tree1.add(['a'], [b'a-id'])
 
406
        tree1.commit('a', rev_id=b'rev-1',
400
407
                     committer=u'Pepe P\xe9rez <pperez@ejemplo.com>',
401
408
                     timestamp=1166046000.00, timezone=0)
402
409
 
403
 
        self.build_tree_contents([('tree1/b', 'bye')])
404
 
        tree1.add(['b'], ['b-id'])
405
 
        tree1.commit('b', rev_id='rev-2',
 
410
        self.build_tree_contents([('tree1/b', b'bye')])
 
411
        tree1.add(['b'], [b'b-id'])
 
412
        tree1.commit('b', rev_id=b'rev-2',
406
413
                     committer=u'p\xe9rez',
407
414
                     timestamp=1166046000.00, timezone=0)
408
415
 
409
416
        tree1.lock_read()
410
417
        self.addCleanup(tree1.unlock)
 
418
 
 
419
        revtree_1 = tree1.branch.repository.revision_tree(b'rev-1')
 
420
        revtree_2 = tree1.branch.repository.revision_tree(b'rev-2')
 
421
 
411
422
        # this passes if no exception is raised
412
423
        to_file = StringIO()
413
 
        annotate.annotate_file(tree1.branch, 'rev-1', 'a-id', to_file=to_file)
414
 
 
415
 
        sio = StringIO()
416
 
        to_file = codecs.getwriter('ascii')(sio)
417
 
        to_file.encoding = 'ascii' # codecs does not set it
418
 
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
419
 
        self.assertEqualDiff('2   p?rez   | bye\n', sio.getvalue())
420
 
 
421
 
        # test now with to_file.encoding = None
422
 
        to_file = tests.StringIOWrapper()
423
 
        to_file.encoding = None
424
 
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
425
 
        self.assertContainsRe('2   p.rez   | bye\n', to_file.getvalue())
426
 
 
427
 
        # and when it does not exist
428
 
        to_file = StringIO()
429
 
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
430
 
        self.assertContainsRe('2   p.rez   | bye\n', to_file.getvalue())
 
424
        annotate.annotate_file_tree(revtree_1, 'a',
 
425
                                    to_file=to_file, branch=tree1.branch)
 
426
 
 
427
        sio = BytesIO()
 
428
        to_file = codecs.getwriter('ascii')(sio, 'replace')
 
429
        annotate.annotate_file_tree(revtree_2, 'b',
 
430
                                    to_file=to_file, branch=tree1.branch)
 
431
        self.assertEqualDiff(b'2   p?rez   | bye\n', sio.getvalue())
 
432
 
 
433
        # test now with unicode file-like
 
434
        to_file = StringIOWithEncoding()
 
435
        annotate.annotate_file_tree(revtree_2, 'b',
 
436
                                    to_file=to_file, branch=tree1.branch)
 
437
        self.assertContainsRe(u'2   p\xe9rez   | bye\n', to_file.getvalue())
431
438
 
432
439
    def test_annotate_author_or_committer(self):
433
440
        tree1 = self.make_branch_and_tree('tree1')
434
441
 
435
 
        self.build_tree_contents([('tree1/a', 'hello')])
436
 
        tree1.add(['a'], ['a-id'])
437
 
        tree1.commit('a', rev_id='rev-1',
 
442
        self.build_tree_contents([('tree1/a', b'hello')])
 
443
        tree1.add(['a'], [b'a-id'])
 
444
        tree1.commit('a', rev_id=b'rev-1',
438
445
                     committer='Committer <committer@example.com>',
439
446
                     timestamp=1166046000.00, timezone=0)
440
447
 
441
 
        self.build_tree_contents([('tree1/b', 'bye')])
442
 
        tree1.add(['b'], ['b-id'])
443
 
        tree1.commit('b', rev_id='rev-2',
 
448
        self.build_tree_contents([('tree1/b', b'bye')])
 
449
        tree1.add(['b'], [b'b-id'])
 
450
        tree1.commit('b', rev_id=b'rev-2',
444
451
                     committer='Committer <committer@example.com>',
445
452
                     authors=['Author <author@example.com>'],
446
453
                     timestamp=1166046000.00, timezone=0)
447
454
 
448
455
        tree1.lock_read()
449
456
        self.addCleanup(tree1.unlock)
450
 
        to_file = StringIO()
451
 
        annotate.annotate_file(tree1.branch, 'rev-1', 'a-id', to_file=to_file)
452
 
        self.assertEqual('1   committ | hello\n', to_file.getvalue())
453
 
 
454
 
        to_file = StringIO()
455
 
        annotate.annotate_file(tree1.branch, 'rev-2', 'b-id', to_file=to_file)
456
 
        self.assertEqual('2   author@ | bye\n', to_file.getvalue())
 
457
 
 
458
        self.assertBranchAnnotate('1   committ | hello\n', tree1.branch,
 
459
                                  'a', b'rev-1')
 
460
 
 
461
        self.assertBranchAnnotate('2   author@ | bye\n', tree1.branch,
 
462
                                  'b', b'rev-2')
457
463
 
458
464
 
459
465
class TestReannotate(tests.TestCase):
461
467
    def annotateEqual(self, expected, parents, newlines, revision_id,
462
468
                      blocks=None):
463
469
        annotate_list = list(annotate.reannotate(parents, newlines,
464
 
                             revision_id, blocks))
 
470
                                                 revision_id, blocks))
465
471
        self.assertEqual(len(expected), len(annotate_list))
466
472
        for e, a in zip(expected, annotate_list):
467
473
            self.assertEqual(e, a)
468
474
 
469
475
    def test_reannotate(self):
470
 
        self.annotateEqual(parent_1, [parent_1], new_1, 'blahblah')
471
 
        self.annotateEqual(expected_2_1, [parent_2], new_1, 'blahblah')
 
476
        self.annotateEqual(parent_1, [parent_1], new_1, b'blahblah')
 
477
        self.annotateEqual(expected_2_1, [parent_2], new_1, b'blahblah')
472
478
        self.annotateEqual(expected_1_2_2, [parent_1, parent_2], new_2,
473
 
                           'blahblah')
 
479
                           b'blahblah')
474
480
 
475
481
    def test_reannotate_no_parents(self):
476
 
        self.annotateEqual(expected_1, [], new_1, 'blahblah')
 
482
        self.annotateEqual(expected_1, [], new_1, b'blahblah')
477
483
 
478
484
    def test_reannotate_left_matching_blocks(self):
479
485
        """Ensure that left_matching_blocks has an impact.
481
487
        In this case, the annotation is ambiguous, so the hint isn't actually
482
488
        lying.
483
489
        """
484
 
        parent = [('rev1', 'a\n')]
485
 
        new_text = ['a\n', 'a\n']
 
490
        parent = [(b'rev1', b'a\n')]
 
491
        new_text = [b'a\n', b'a\n']
486
492
        blocks = [(0, 0, 1), (1, 2, 0)]
487
 
        self.annotateEqual([('rev1', 'a\n'), ('rev2', 'a\n')], [parent],
488
 
                           new_text, 'rev2', blocks)
 
493
        self.annotateEqual([(b'rev1', b'a\n'), (b'rev2', b'a\n')], [parent],
 
494
                           new_text, b'rev2', blocks)
489
495
        blocks = [(0, 1, 1), (1, 2, 0)]
490
 
        self.annotateEqual([('rev2', 'a\n'), ('rev1', 'a\n')], [parent],
491
 
                           new_text, 'rev2', blocks)
 
496
        self.annotateEqual([(b'rev2', b'a\n'), (b'rev1', b'a\n')], [parent],
 
497
                           new_text, b'rev2', blocks)