201
282
self.checkDelta(logentry.delta, added=['file1', 'file2'])
204
def make_commits_with_trailing_newlines(wt):
205
"""Helper method for LogFormatter tests"""
208
open('a', 'wb').write('hello moto\n')
210
wt.commit('simple log message', rev_id='a1',
211
timestamp=1132586655.459960938, timezone=-6*3600,
212
committer='Joe Foo <joe@foo.com>')
213
open('b', 'wb').write('goodbye\n')
215
wt.commit('multiline\nlog\nmessage\n', rev_id='a2',
216
timestamp=1132586842.411175966, timezone=-6*3600,
217
committer='Joe Foo <joe@foo.com>',
218
authors=['Joe Bar <joe@bar.com>'])
220
open('c', 'wb').write('just another manic monday\n')
222
wt.commit('single line with trailing newline\n', rev_id='a3',
223
timestamp=1132587176.835228920, timezone=-6*3600,
224
committer = 'Joe Foo <joe@foo.com>')
228
def normalize_log(log):
229
"""Replaces the variable lines of logs with fixed lines"""
230
author = 'author: Dolor Sit <test@example.com>'
231
committer = 'committer: Lorem Ipsum <test@example.com>'
232
lines = log.splitlines(True)
233
for idx,line in enumerate(lines):
234
stripped_line = line.lstrip()
235
indent = ' ' * (len(line) - len(stripped_line))
236
if stripped_line.startswith('author:'):
237
lines[idx] = indent + author + '\n'
238
elif stripped_line.startswith('committer:'):
239
lines[idx] = indent + committer + '\n'
240
elif stripped_line.startswith('timestamp:'):
241
lines[idx] = indent + 'timestamp: Just now\n'
242
return ''.join(lines)
245
class TestShortLogFormatter(tests.TestCaseWithTransport):
285
class TestShortLogFormatter(TestCaseForLogFormatter):
247
287
def test_trailing_newlines(self):
248
288
wt = self.make_branch_and_tree('.')
249
b = make_commits_with_trailing_newlines(wt)
250
sio = self.make_utf8_encoded_stringio()
251
lf = log.ShortLogFormatter(to_file=sio)
253
self.assertEqualDiff("""\
254
3 Joe Foo\t2005-11-21
289
b = self.make_commits_with_trailing_newlines(wt)
290
self.assertFormatterResult("""\
291
3 Joe Foo\t2005-11-22
255
292
single line with trailing newline
257
2 Joe Bar\t2005-11-21
294
2 Joe Foo\t2005-11-22
262
1 Joe Foo\t2005-11-21
299
1 Joe Foo\t2005-11-22
263
300
simple log message
268
def _prepare_tree_with_merges(self, with_tags=False):
269
wt = self.make_branch_and_memory_tree('.')
271
self.addCleanup(wt.unlock)
273
wt.commit('rev-1', rev_id='rev-1',
274
timestamp=1132586655, timezone=36000,
275
committer='Joe Foo <joe@foo.com>')
276
wt.commit('rev-merged', rev_id='rev-2a',
277
timestamp=1132586700, timezone=36000,
278
committer='Joe Foo <joe@foo.com>')
279
wt.set_parent_ids(['rev-1', 'rev-2a'])
280
wt.branch.set_last_revision_info(1, 'rev-1')
281
wt.commit('rev-2', rev_id='rev-2b',
282
timestamp=1132586800, timezone=36000,
283
committer='Joe Foo <joe@foo.com>')
286
branch.tags.set_tag('v0.2', 'rev-2b')
287
wt.commit('rev-3', rev_id='rev-3',
288
timestamp=1132586900, timezone=36000,
289
committer='Jane Foo <jane@foo.com>')
290
branch.tags.set_tag('v1.0rc1', 'rev-3')
291
branch.tags.set_tag('v1.0', 'rev-3')
303
b, log.ShortLogFormatter)
294
305
def test_short_log_with_merges(self):
295
306
wt = self._prepare_tree_with_merges()
296
logfile = self.make_utf8_encoded_stringio()
297
formatter = log.ShortLogFormatter(to_file=logfile)
298
log.show_log(wt.branch, formatter)
299
self.assertEqualDiff("""\
307
self.assertFormatterResult("""\
300
308
2 Joe Foo\t2005-11-22 [merge]
322
326
Use --include-merges or -n0 to see merged revisions.
328
wt.branch, log.ShortLogFormatter,
329
formatter_kwargs=dict(show_advice=True))
326
331
def test_short_log_with_merges_and_range(self):
327
wt = self.make_branch_and_memory_tree('.')
329
self.addCleanup(wt.unlock)
331
wt.commit('rev-1', rev_id='rev-1',
332
timestamp=1132586655, timezone=36000,
333
committer='Joe Foo <joe@foo.com>')
334
wt.commit('rev-merged', rev_id='rev-2a',
335
timestamp=1132586700, timezone=36000,
336
committer='Joe Foo <joe@foo.com>')
337
wt.branch.set_last_revision_info(1, 'rev-1')
338
wt.set_parent_ids(['rev-1', 'rev-2a'])
339
wt.commit('rev-2b', rev_id='rev-2b',
340
timestamp=1132586800, timezone=36000,
341
committer='Joe Foo <joe@foo.com>')
342
wt.commit('rev-3a', rev_id='rev-3a',
343
timestamp=1132586800, timezone=36000,
344
committer='Joe Foo <joe@foo.com>')
332
wt = self._prepare_tree_with_merges()
333
self.wt_commit(wt, 'rev-3a', rev_id='rev-3a')
345
334
wt.branch.set_last_revision_info(2, 'rev-2b')
346
335
wt.set_parent_ids(['rev-2b', 'rev-3a'])
347
wt.commit('rev-3b', rev_id='rev-3b',
348
timestamp=1132586800, timezone=36000,
349
committer='Joe Foo <joe@foo.com>')
350
logfile = self.make_utf8_encoded_stringio()
351
formatter = log.ShortLogFormatter(to_file=logfile)
352
log.show_log(wt.branch, formatter,
353
start_revision=2, end_revision=3)
354
self.assertEqualDiff("""\
336
self.wt_commit(wt, 'rev-3b', rev_id='rev-3b')
337
self.assertFormatterResult("""\
355
338
3 Joe Foo\t2005-11-22 [merge]
358
341
2 Joe Foo\t2005-11-22 [merge]
345
wt.branch, log.ShortLogFormatter,
346
show_log_kwargs=dict(start_revision=2, end_revision=3))
364
348
def test_short_log_with_tags(self):
365
349
wt = self._prepare_tree_with_merges(with_tags=True)
366
logfile = self.make_utf8_encoded_stringio()
367
formatter = log.ShortLogFormatter(to_file=logfile)
368
log.show_log(wt.branch, formatter)
369
self.assertEqualDiff("""\
370
3 Jane Foo\t2005-11-22 {v1.0, v1.0rc1}
350
self.assertFormatterResult("""\
351
3 Joe Foo\t2005-11-22 {v1.0, v1.0rc1}
373
354
2 Joe Foo\t2005-11-22 {v0.2} [merge]
361
wt.branch, log.ShortLogFormatter)
382
363
def test_short_log_single_merge_revision(self):
383
wt = self.make_branch_and_memory_tree('.')
385
self.addCleanup(wt.unlock)
387
wt.commit('rev-1', rev_id='rev-1',
388
timestamp=1132586655, timezone=36000,
389
committer='Joe Foo <joe@foo.com>')
390
wt.commit('rev-merged', rev_id='rev-2a',
391
timestamp=1132586700, timezone=36000,
392
committer='Joe Foo <joe@foo.com>')
393
wt.set_parent_ids(['rev-1', 'rev-2a'])
394
wt.branch.set_last_revision_info(1, 'rev-1')
395
wt.commit('rev-2', rev_id='rev-2b',
396
timestamp=1132586800, timezone=36000,
397
committer='Joe Foo <joe@foo.com>')
398
logfile = self.make_utf8_encoded_stringio()
399
formatter = log.ShortLogFormatter(to_file=logfile)
364
wt = self._prepare_tree_with_merges()
400
365
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
402
rev = revspec.in_history(wtb)
403
log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
404
self.assertEqualDiff("""\
366
rev = revspec.in_history(wt.branch)
367
self.assertFormatterResult("""\
405
368
1.1.1 Joe Foo\t2005-11-22
412
class TestShortLogFormatterWithMergeRevisions(tests.TestCaseWithTransport):
372
wt.branch, log.ShortLogFormatter,
373
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
375
def test_show_ids(self):
376
wt = self.make_branch_and_tree('parent')
377
self.build_tree(['parent/f1', 'parent/f2'])
379
self.wt_commit(wt, 'first post', rev_id='a')
380
child_wt = wt.bzrdir.sprout('child').open_workingtree()
381
self.wt_commit(child_wt, 'branch 1 changes', rev_id='b')
382
wt.merge_from_branch(child_wt.branch)
383
self.wt_commit(wt, 'merge branch 1', rev_id='c')
384
self.assertFormatterResult("""\
385
2 Joe Foo\t2005-11-22 [merge]
389
1.1.1 Joe Foo\t2005-11-22
393
1 Joe Foo\t2005-11-22
398
wt.branch, log.ShortLogFormatter,
399
formatter_kwargs=dict(levels=0,show_ids=True))
402
class TestShortLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
414
404
def test_short_merge_revs_log_with_merges(self):
415
wt = self.make_branch_and_memory_tree('.')
417
self.addCleanup(wt.unlock)
419
wt.commit('rev-1', rev_id='rev-1',
420
timestamp=1132586655, timezone=36000,
421
committer='Joe Foo <joe@foo.com>')
422
wt.commit('rev-merged', rev_id='rev-2a',
423
timestamp=1132586700, timezone=36000,
424
committer='Joe Foo <joe@foo.com>')
425
wt.set_parent_ids(['rev-1', 'rev-2a'])
426
wt.branch.set_last_revision_info(1, 'rev-1')
427
wt.commit('rev-2', rev_id='rev-2b',
428
timestamp=1132586800, timezone=36000,
429
committer='Joe Foo <joe@foo.com>')
430
logfile = self.make_utf8_encoded_stringio()
431
formatter = log.ShortLogFormatter(to_file=logfile, levels=0)
432
log.show_log(wt.branch, formatter)
405
wt = self._prepare_tree_with_merges()
433
406
# Note that the 1.1.1 indenting is in fact correct given that
434
407
# the revision numbers are right justified within 5 characters
435
408
# for mainline revnos and 9 characters for dotted revnos.
436
self.assertEqualDiff("""\
409
self.assertFormatterResult("""\
437
410
2 Joe Foo\t2005-11-22 [merge]
420
wt.branch, log.ShortLogFormatter,
421
formatter_kwargs=dict(levels=0))
449
423
def test_short_merge_revs_log_single_merge_revision(self):
450
wt = self.make_branch_and_memory_tree('.')
452
self.addCleanup(wt.unlock)
454
wt.commit('rev-1', rev_id='rev-1',
455
timestamp=1132586655, timezone=36000,
456
committer='Joe Foo <joe@foo.com>')
457
wt.commit('rev-merged', rev_id='rev-2a',
458
timestamp=1132586700, timezone=36000,
459
committer='Joe Foo <joe@foo.com>')
460
wt.set_parent_ids(['rev-1', 'rev-2a'])
461
wt.branch.set_last_revision_info(1, 'rev-1')
462
wt.commit('rev-2', rev_id='rev-2b',
463
timestamp=1132586800, timezone=36000,
464
committer='Joe Foo <joe@foo.com>')
465
logfile = self.make_utf8_encoded_stringio()
466
formatter = log.ShortLogFormatter(to_file=logfile, levels=0)
424
wt = self._prepare_tree_with_merges()
467
425
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
469
rev = revspec.in_history(wtb)
470
log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
471
self.assertEqualDiff("""\
426
rev = revspec.in_history(wt.branch)
427
self.assertFormatterResult("""\
472
428
1.1.1 Joe Foo\t2005-11-22
479
class TestLongLogFormatter(TestCaseWithoutPropsHandler):
432
wt.branch, log.ShortLogFormatter,
433
formatter_kwargs=dict(levels=0),
434
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
437
class TestLongLogFormatter(TestCaseForLogFormatter):
481
439
def test_verbose_log(self):
482
440
"""Verbose log includes changed files
486
wt = self.make_branch_and_tree('.')
488
self.build_tree(['a'])
490
# XXX: why does a longer nick show up?
491
b.nick = 'test_verbose_log'
492
wt.commit(message='add a',
493
timestamp=1132711707,
495
committer='Lorem Ipsum <test@example.com>')
496
logfile = file('out.tmp', 'w+')
497
formatter = log.LongLogFormatter(to_file=logfile)
498
log.show_log(b, formatter, verbose=True)
501
log_contents = logfile.read()
502
self.assertEqualDiff('''\
444
wt = self.make_standard_commit('test_verbose_log', authors=[])
445
self.assertFormatterResult('''\
503
446
------------------------------------------------------------
505
448
committer: Lorem Ipsum <test@example.com>
506
449
branch nick: test_verbose_log
507
timestamp: Wed 2005-11-23 12:08:27 +1000
450
timestamp: Tue 2005-11-22 00:00:00 +0000
456
wt.branch, log.LongLogFormatter,
457
show_log_kwargs=dict(verbose=True))
515
459
def test_merges_are_indented_by_level(self):
516
460
wt = self.make_branch_and_tree('parent')
517
wt.commit('first post')
518
self.run_bzr('branch parent child')
519
self.run_bzr(['commit', '-m', 'branch 1', '--unchanged', 'child'])
520
self.run_bzr('branch child smallerchild')
521
self.run_bzr(['commit', '-m', 'branch 2', '--unchanged',
524
self.run_bzr('merge ../smallerchild')
525
self.run_bzr(['commit', '-m', 'merge branch 2'])
526
os.chdir('../parent')
527
self.run_bzr('merge ../child')
528
wt.commit('merge branch 1')
530
sio = self.make_utf8_encoded_stringio()
531
lf = log.LongLogFormatter(to_file=sio, levels=0)
532
log.show_log(b, lf, verbose=True)
533
the_log = normalize_log(sio.getvalue())
534
self.assertEqualDiff("""\
461
self.wt_commit(wt, 'first post')
462
child_wt = wt.bzrdir.sprout('child').open_workingtree()
463
self.wt_commit(child_wt, 'branch 1')
464
smallerchild_wt = wt.bzrdir.sprout('smallerchild').open_workingtree()
465
self.wt_commit(smallerchild_wt, 'branch 2')
466
child_wt.merge_from_branch(smallerchild_wt.branch)
467
self.wt_commit(child_wt, 'merge branch 2')
468
wt.merge_from_branch(child_wt.branch)
469
self.wt_commit(wt, 'merge branch 1')
470
self.assertFormatterResult("""\
535
471
------------------------------------------------------------
537
committer: Lorem Ipsum <test@example.com>
473
committer: Joe Foo <joe@foo.com>
538
474
branch nick: parent
475
timestamp: Tue 2005-11-22 00:00:04 +0000
542
478
------------------------------------------------------------
543
479
revno: 1.1.2 [merge]
544
committer: Lorem Ipsum <test@example.com>
480
committer: Joe Foo <joe@foo.com>
545
481
branch nick: child
482
timestamp: Tue 2005-11-22 00:00:03 +0000
549
485
------------------------------------------------------------
551
committer: Lorem Ipsum <test@example.com>
487
committer: Joe Foo <joe@foo.com>
552
488
branch nick: smallerchild
489
timestamp: Tue 2005-11-22 00:00:02 +0000
556
492
------------------------------------------------------------
558
committer: Lorem Ipsum <test@example.com>
494
committer: Joe Foo <joe@foo.com>
559
495
branch nick: child
496
timestamp: Tue 2005-11-22 00:00:01 +0000
563
499
------------------------------------------------------------
565
committer: Lorem Ipsum <test@example.com>
501
committer: Joe Foo <joe@foo.com>
566
502
branch nick: parent
503
timestamp: Tue 2005-11-22 00:00:00 +0000
507
wt.branch, log.LongLogFormatter,
508
formatter_kwargs=dict(levels=0),
509
show_log_kwargs=dict(verbose=True))
573
511
def test_verbose_merge_revisions_contain_deltas(self):
574
512
wt = self.make_branch_and_tree('parent')
575
513
self.build_tree(['parent/f1', 'parent/f2'])
576
514
wt.add(['f1','f2'])
577
wt.commit('first post')
578
self.run_bzr('branch parent child')
515
self.wt_commit(wt, 'first post')
516
child_wt = wt.bzrdir.sprout('child').open_workingtree()
579
517
os.unlink('child/f1')
580
file('child/f2', 'wb').write('hello\n')
581
self.run_bzr(['commit', '-m', 'removed f1 and modified f2',
584
self.run_bzr('merge ../child')
585
wt.commit('merge branch 1')
587
sio = self.make_utf8_encoded_stringio()
588
lf = log.LongLogFormatter(to_file=sio, levels=0)
589
log.show_log(b, lf, verbose=True)
590
the_log = normalize_log(sio.getvalue())
591
self.assertEqualDiff("""\
518
self.build_tree_contents([('child/f2', 'hello\n')])
519
self.wt_commit(child_wt, 'removed f1 and modified f2')
520
wt.merge_from_branch(child_wt.branch)
521
self.wt_commit(wt, 'merge branch 1')
522
self.assertFormatterResult("""\
592
523
------------------------------------------------------------
594
committer: Lorem Ipsum <test@example.com>
525
committer: Joe Foo <joe@foo.com>
595
526
branch nick: parent
527
timestamp: Tue 2005-11-22 00:00:02 +0000
653
582
committer: Joe Foo <joe@foo.com>
654
583
branch nick: test
655
timestamp: Mon 2005-11-21 09:24:15 -0600
584
timestamp: Tue 2005-11-22 00:00:00 +0000
657
586
simple log message
588
b, log.LongLogFormatter)
661
590
def test_author_in_log(self):
662
591
"""Log includes the author name if it's set in
663
592
the revision properties
665
wt = self.make_branch_and_tree('.')
667
self.build_tree(['a'])
669
b.nick = 'test_author_log'
670
wt.commit(message='add a',
671
timestamp=1132711707,
673
committer='Lorem Ipsum <test@example.com>',
674
authors=['John Doe <jdoe@example.com>',
675
'Jane Rey <jrey@example.com>'])
677
formatter = log.LongLogFormatter(to_file=sio)
678
log.show_log(b, formatter)
679
self.assertEqualDiff('''\
594
wt = self.make_standard_commit('test_author_log',
595
authors=['John Doe <jdoe@example.com>',
596
'Jane Rey <jrey@example.com>'])
597
self.assertFormatterResult("""\
680
598
------------------------------------------------------------
682
600
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
683
601
committer: Lorem Ipsum <test@example.com>
684
602
branch nick: test_author_log
685
timestamp: Wed 2005-11-23 12:08:27 +1000
603
timestamp: Tue 2005-11-22 00:00:00 +0000
607
wt.branch, log.LongLogFormatter)
691
609
def test_properties_in_log(self):
692
610
"""Log includes the custom properties returned by the registered
695
wt = self.make_branch_and_tree('.')
697
self.build_tree(['a'])
699
b.nick = 'test_properties_in_log'
700
wt.commit(message='add a',
701
timestamp=1132711707,
703
committer='Lorem Ipsum <test@example.com>',
704
authors=['John Doe <jdoe@example.com>'])
706
formatter = log.LongLogFormatter(to_file=sio)
708
def trivial_custom_prop_handler(revision):
709
return {'test_prop':'test_value'}
613
wt = self.make_standard_commit('test_properties_in_log')
614
def trivial_custom_prop_handler(revision):
615
return {'test_prop':'test_value'}
711
log.properties_handler_registry.register(
712
'trivial_custom_prop_handler',
713
trivial_custom_prop_handler)
714
log.show_log(b, formatter)
716
log.properties_handler_registry.remove(
717
'trivial_custom_prop_handler')
718
self.assertEqualDiff('''\
617
# Cleaned up in setUp()
618
log.properties_handler_registry.register(
619
'trivial_custom_prop_handler',
620
trivial_custom_prop_handler)
621
self.assertFormatterResult("""\
719
622
------------------------------------------------------------
721
624
test_prop: test_value
722
625
author: John Doe <jdoe@example.com>
723
626
committer: Lorem Ipsum <test@example.com>
724
627
branch nick: test_properties_in_log
725
timestamp: Wed 2005-11-23 12:08:27 +1000
628
timestamp: Tue 2005-11-22 00:00:00 +0000
632
wt.branch, log.LongLogFormatter)
731
634
def test_properties_in_short_log(self):
732
635
"""Log includes the custom properties returned by the registered
735
wt = self.make_branch_and_tree('.')
737
self.build_tree(['a'])
739
b.nick = 'test_properties_in_short_log'
740
wt.commit(message='add a',
741
timestamp=1132711707,
743
committer='Lorem Ipsum <test@example.com>',
744
authors=['John Doe <jdoe@example.com>'])
746
formatter = log.ShortLogFormatter(to_file=sio)
748
def trivial_custom_prop_handler(revision):
749
return {'test_prop':'test_value'}
638
wt = self.make_standard_commit('test_properties_in_short_log')
639
def trivial_custom_prop_handler(revision):
640
return {'test_prop':'test_value'}
751
log.properties_handler_registry.register(
752
'trivial_custom_prop_handler',
753
trivial_custom_prop_handler)
754
log.show_log(b, formatter)
756
log.properties_handler_registry.remove(
757
'trivial_custom_prop_handler')
758
self.assertEqualDiff('''\
759
1 John Doe\t2005-11-23
642
log.properties_handler_registry.register(
643
'trivial_custom_prop_handler',
644
trivial_custom_prop_handler)
645
self.assertFormatterResult("""\
646
1 John Doe\t2005-11-22
760
647
test_prop: test_value
651
wt.branch, log.ShortLogFormatter)
766
653
def test_error_in_properties_handler(self):
767
654
"""Log includes the custom properties returned by the registered
770
wt = self.make_branch_and_tree('.')
772
self.build_tree(['a'])
774
b.nick = 'test_author_log'
775
wt.commit(message='add a',
776
timestamp=1132711707,
778
committer='Lorem Ipsum <test@example.com>',
779
authors=['John Doe <jdoe@example.com>'],
780
revprops={'first_prop':'first_value'})
657
wt = self.make_standard_commit('error_in_properties_handler',
658
revprops={'first_prop':'first_value'})
659
sio = self.make_utf8_encoded_stringio()
782
660
formatter = log.LongLogFormatter(to_file=sio)
784
def trivial_custom_prop_handler(revision):
785
raise StandardError("a test error")
661
def trivial_custom_prop_handler(revision):
662
raise StandardError("a test error")
787
log.properties_handler_registry.register(
788
'trivial_custom_prop_handler',
789
trivial_custom_prop_handler)
790
self.assertRaises(StandardError, log.show_log, b, formatter,)
792
log.properties_handler_registry.remove(
793
'trivial_custom_prop_handler')
664
log.properties_handler_registry.register(
665
'trivial_custom_prop_handler',
666
trivial_custom_prop_handler)
667
self.assertRaises(StandardError, log.show_log, wt.branch, formatter,)
795
669
def test_properties_handler_bad_argument(self):
796
wt = self.make_branch_and_tree('.')
798
self.build_tree(['a'])
800
b.nick = 'test_author_log'
801
wt.commit(message='add a',
802
timestamp=1132711707,
804
committer='Lorem Ipsum <test@example.com>',
805
authors=['John Doe <jdoe@example.com>'],
806
revprops={'a_prop':'test_value'})
670
wt = self.make_standard_commit('bad_argument',
671
revprops={'a_prop':'test_value'})
672
sio = self.make_utf8_encoded_stringio()
808
673
formatter = log.LongLogFormatter(to_file=sio)
810
def bad_argument_prop_handler(revision):
811
return {'custom_prop_name':revision.properties['a_prop']}
813
log.properties_handler_registry.register(
814
'bad_argument_prop_handler',
815
bad_argument_prop_handler)
817
self.assertRaises(AttributeError, formatter.show_properties,
820
revision = b.repository.get_revision(b.last_revision())
821
formatter.show_properties(revision, '')
822
self.assertEqualDiff('''custom_prop_name: test_value\n''',
825
log.properties_handler_registry.remove(
826
'bad_argument_prop_handler')
829
class TestLongLogFormatterWithoutMergeRevisions(TestCaseWithoutPropsHandler):
674
def bad_argument_prop_handler(revision):
675
return {'custom_prop_name':revision.properties['a_prop']}
677
log.properties_handler_registry.register(
678
'bad_argument_prop_handler',
679
bad_argument_prop_handler)
681
self.assertRaises(AttributeError, formatter.show_properties,
684
revision = wt.branch.repository.get_revision(wt.branch.last_revision())
685
formatter.show_properties(revision, '')
686
self.assertEqualDiff('''custom_prop_name: test_value\n''',
689
def test_show_ids(self):
690
wt = self.make_branch_and_tree('parent')
691
self.build_tree(['parent/f1', 'parent/f2'])
693
self.wt_commit(wt, 'first post', rev_id='a')
694
child_wt = wt.bzrdir.sprout('child').open_workingtree()
695
self.wt_commit(child_wt, 'branch 1 changes', rev_id='b')
696
wt.merge_from_branch(child_wt.branch)
697
self.wt_commit(wt, 'merge branch 1', rev_id='c')
698
self.assertFormatterResult("""\
699
------------------------------------------------------------
704
committer: Joe Foo <joe@foo.com>
706
timestamp: Tue 2005-11-22 00:00:02 +0000
709
------------------------------------------------------------
713
committer: Joe Foo <joe@foo.com>
715
timestamp: Tue 2005-11-22 00:00:01 +0000
718
------------------------------------------------------------
721
committer: Joe Foo <joe@foo.com>
723
timestamp: Tue 2005-11-22 00:00:00 +0000
727
wt.branch, log.LongLogFormatter,
728
formatter_kwargs=dict(levels=0,show_ids=True))
731
class TestLongLogFormatterWithoutMergeRevisions(TestCaseForLogFormatter):
831
733
def test_long_verbose_log(self):
832
734
"""Verbose log includes changed files
836
wt = self.make_branch_and_tree('.')
838
self.build_tree(['a'])
840
# XXX: why does a longer nick show up?
841
b.nick = 'test_verbose_log'
842
wt.commit(message='add a',
843
timestamp=1132711707,
845
committer='Lorem Ipsum <test@example.com>')
846
logfile = file('out.tmp', 'w+')
847
formatter = log.LongLogFormatter(to_file=logfile, levels=1)
848
log.show_log(b, formatter, verbose=True)
851
log_contents = logfile.read()
852
self.assertEqualDiff('''\
738
wt = self.make_standard_commit('test_long_verbose_log', authors=[])
739
self.assertFormatterResult("""\
853
740
------------------------------------------------------------
855
742
committer: Lorem Ipsum <test@example.com>
856
branch nick: test_verbose_log
857
timestamp: Wed 2005-11-23 12:08:27 +1000
743
branch nick: test_long_verbose_log
744
timestamp: Tue 2005-11-22 00:00:00 +0000
750
wt.branch, log.LongLogFormatter,
751
formatter_kwargs=dict(levels=1),
752
show_log_kwargs=dict(verbose=True))
865
754
def test_long_verbose_contain_deltas(self):
866
755
wt = self.make_branch_and_tree('parent')
867
756
self.build_tree(['parent/f1', 'parent/f2'])
868
757
wt.add(['f1','f2'])
869
wt.commit('first post')
870
self.run_bzr('branch parent child')
758
self.wt_commit(wt, 'first post')
759
child_wt = wt.bzrdir.sprout('child').open_workingtree()
871
760
os.unlink('child/f1')
872
file('child/f2', 'wb').write('hello\n')
873
self.run_bzr(['commit', '-m', 'removed f1 and modified f2',
876
self.run_bzr('merge ../child')
877
wt.commit('merge branch 1')
879
sio = self.make_utf8_encoded_stringio()
880
lf = log.LongLogFormatter(to_file=sio, levels=1)
881
log.show_log(b, lf, verbose=True)
882
the_log = normalize_log(sio.getvalue())
883
self.assertEqualDiff("""\
761
self.build_tree_contents([('child/f2', 'hello\n')])
762
self.wt_commit(child_wt, 'removed f1 and modified f2')
763
wt.merge_from_branch(child_wt.branch)
764
self.wt_commit(wt, 'merge branch 1')
765
self.assertFormatterResult("""\
884
766
------------------------------------------------------------
886
committer: Lorem Ipsum <test@example.com>
768
committer: Joe Foo <joe@foo.com>
887
769
branch nick: parent
770
timestamp: Tue 2005-11-22 00:00:02 +0000
934
814
committer: Joe Foo <joe@foo.com>
935
815
branch nick: test
936
timestamp: Mon 2005-11-21 09:24:15 -0600
816
timestamp: Tue 2005-11-22 00:00:00 +0000
938
818
simple log message
820
b, log.LongLogFormatter,
821
formatter_kwargs=dict(levels=1))
942
823
def test_long_author_in_log(self):
943
824
"""Log includes the author name if it's set in
944
825
the revision properties
946
wt = self.make_branch_and_tree('.')
948
self.build_tree(['a'])
950
b.nick = 'test_author_log'
951
wt.commit(message='add a',
952
timestamp=1132711707,
954
committer='Lorem Ipsum <test@example.com>',
955
authors=['John Doe <jdoe@example.com>'])
957
formatter = log.LongLogFormatter(to_file=sio, levels=1)
958
log.show_log(b, formatter)
959
self.assertEqualDiff('''\
827
wt = self.make_standard_commit('test_author_log')
828
self.assertFormatterResult("""\
960
829
------------------------------------------------------------
962
831
author: John Doe <jdoe@example.com>
963
832
committer: Lorem Ipsum <test@example.com>
964
833
branch nick: test_author_log
965
timestamp: Wed 2005-11-23 12:08:27 +1000
834
timestamp: Tue 2005-11-22 00:00:00 +0000
838
wt.branch, log.LongLogFormatter,
839
formatter_kwargs=dict(levels=1))
971
841
def test_long_properties_in_log(self):
972
842
"""Log includes the custom properties returned by the registered
975
wt = self.make_branch_and_tree('.')
977
self.build_tree(['a'])
979
b.nick = 'test_properties_in_log'
980
wt.commit(message='add a',
981
timestamp=1132711707,
983
committer='Lorem Ipsum <test@example.com>',
984
authors=['John Doe <jdoe@example.com>'])
986
formatter = log.LongLogFormatter(to_file=sio, levels=1)
988
def trivial_custom_prop_handler(revision):
989
return {'test_prop':'test_value'}
845
wt = self.make_standard_commit('test_properties_in_log')
846
def trivial_custom_prop_handler(revision):
847
return {'test_prop':'test_value'}
991
log.properties_handler_registry.register(
992
'trivial_custom_prop_handler',
993
trivial_custom_prop_handler)
994
log.show_log(b, formatter)
996
log.properties_handler_registry.remove(
997
'trivial_custom_prop_handler')
998
self.assertEqualDiff('''\
849
log.properties_handler_registry.register(
850
'trivial_custom_prop_handler',
851
trivial_custom_prop_handler)
852
self.assertFormatterResult("""\
999
853
------------------------------------------------------------
1001
855
test_prop: test_value
1002
856
author: John Doe <jdoe@example.com>
1003
857
committer: Lorem Ipsum <test@example.com>
1004
858
branch nick: test_properties_in_log
1005
timestamp: Wed 2005-11-23 12:08:27 +1000
859
timestamp: Tue 2005-11-22 00:00:00 +0000
1012
class TestLineLogFormatter(tests.TestCaseWithTransport):
863
wt.branch, log.LongLogFormatter,
864
formatter_kwargs=dict(levels=1))
867
class TestLineLogFormatter(TestCaseForLogFormatter):
1014
869
def test_line_log(self):
1015
870
"""Line log should show revno
1019
wt = self.make_branch_and_tree('.')
1021
self.build_tree(['a'])
1023
b.nick = 'test-line-log'
1024
wt.commit(message='add a',
1025
timestamp=1132711707,
1027
committer='Line-Log-Formatter Tester <test@line.log>')
1028
logfile = file('out.tmp', 'w+')
1029
formatter = log.LineLogFormatter(to_file=logfile)
1030
log.show_log(b, formatter)
1033
log_contents = logfile.read()
1034
self.assertEqualDiff('1: Line-Log-Formatte... 2005-11-23 add a\n',
874
wt = self.make_standard_commit('test-line-log',
875
committer='Line-Log-Formatter Tester <test@line.log>',
877
self.assertFormatterResult("""\
878
1: Line-Log-Formatte... 2005-11-22 add a
880
wt.branch, log.LineLogFormatter)
1037
882
def test_trailing_newlines(self):
1038
883
wt = self.make_branch_and_tree('.')
1039
b = make_commits_with_trailing_newlines(wt)
1040
sio = self.make_utf8_encoded_stringio()
1041
lf = log.LineLogFormatter(to_file=sio)
1043
self.assertEqualDiff("""\
1044
3: Joe Foo 2005-11-21 single line with trailing newline
1045
2: Joe Bar 2005-11-21 multiline
1046
1: Joe Foo 2005-11-21 simple log message
884
b = self.make_commits_with_trailing_newlines(wt)
885
self.assertFormatterResult("""\
886
3: Joe Foo 2005-11-22 single line with trailing newline
887
2: Joe Foo 2005-11-22 multiline
888
1: Joe Foo 2005-11-22 simple log message
1050
def _prepare_tree_with_merges(self, with_tags=False):
1051
wt = self.make_branch_and_memory_tree('.')
1053
self.addCleanup(wt.unlock)
1055
wt.commit('rev-1', rev_id='rev-1',
1056
timestamp=1132586655, timezone=36000,
1057
committer='Joe Foo <joe@foo.com>')
1058
wt.commit('rev-merged', rev_id='rev-2a',
1059
timestamp=1132586700, timezone=36000,
1060
committer='Joe Foo <joe@foo.com>')
1061
wt.set_parent_ids(['rev-1', 'rev-2a'])
1062
wt.branch.set_last_revision_info(1, 'rev-1')
1063
wt.commit('rev-2', rev_id='rev-2b',
1064
timestamp=1132586800, timezone=36000,
1065
committer='Joe Foo <joe@foo.com>')
1068
branch.tags.set_tag('v0.2', 'rev-2b')
1069
wt.commit('rev-3', rev_id='rev-3',
1070
timestamp=1132586900, timezone=36000,
1071
committer='Jane Foo <jane@foo.com>')
1072
branch.tags.set_tag('v1.0rc1', 'rev-3')
1073
branch.tags.set_tag('v1.0', 'rev-3')
890
b, log.LineLogFormatter)
1076
892
def test_line_log_single_merge_revision(self):
1077
893
wt = self._prepare_tree_with_merges()
1078
logfile = self.make_utf8_encoded_stringio()
1079
formatter = log.LineLogFormatter(to_file=logfile)
1080
894
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
1082
rev = revspec.in_history(wtb)
1083
log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
1084
self.assertEqualDiff("""\
895
rev = revspec.in_history(wt.branch)
896
self.assertFormatterResult("""\
1085
897
1.1.1: Joe Foo 2005-11-22 rev-merged
899
wt.branch, log.LineLogFormatter,
900
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
1089
902
def test_line_log_with_tags(self):
1090
903
wt = self._prepare_tree_with_merges(with_tags=True)
1091
logfile = self.make_utf8_encoded_stringio()
1092
formatter = log.LineLogFormatter(to_file=logfile)
1093
log.show_log(wt.branch, formatter)
1094
self.assertEqualDiff("""\
1095
3: Jane Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
904
self.assertFormatterResult("""\
905
3: Joe Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
1096
906
2: Joe Foo 2005-11-22 [merge] {v0.2} rev-2
1097
907
1: Joe Foo 2005-11-22 rev-1
1101
class TestLineLogFormatterWithMergeRevisions(tests.TestCaseWithTransport):
909
wt.branch, log.LineLogFormatter)
912
class TestLineLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
1103
914
def test_line_merge_revs_log(self):
1104
915
"""Line log should show revno
1108
wt = self.make_branch_and_tree('.')
1110
self.build_tree(['a'])
1112
b.nick = 'test-line-log'
1113
wt.commit(message='add a',
1114
timestamp=1132711707,
1116
committer='Line-Log-Formatter Tester <test@line.log>')
1117
logfile = file('out.tmp', 'w+')
1118
formatter = log.LineLogFormatter(to_file=logfile, levels=0)
1119
log.show_log(b, formatter)
1122
log_contents = logfile.read()
1123
self.assertEqualDiff('1: Line-Log-Formatte... 2005-11-23 add a\n',
919
wt = self.make_standard_commit('test-line-log',
920
committer='Line-Log-Formatter Tester <test@line.log>',
922
self.assertFormatterResult("""\
923
1: Line-Log-Formatte... 2005-11-22 add a
925
wt.branch, log.LineLogFormatter)
1126
927
def test_line_merge_revs_log_single_merge_revision(self):
1127
wt = self.make_branch_and_memory_tree('.')
1129
self.addCleanup(wt.unlock)
1131
wt.commit('rev-1', rev_id='rev-1',
1132
timestamp=1132586655, timezone=36000,
1133
committer='Joe Foo <joe@foo.com>')
1134
wt.commit('rev-merged', rev_id='rev-2a',
1135
timestamp=1132586700, timezone=36000,
1136
committer='Joe Foo <joe@foo.com>')
1137
wt.set_parent_ids(['rev-1', 'rev-2a'])
1138
wt.branch.set_last_revision_info(1, 'rev-1')
1139
wt.commit('rev-2', rev_id='rev-2b',
1140
timestamp=1132586800, timezone=36000,
1141
committer='Joe Foo <joe@foo.com>')
1142
logfile = self.make_utf8_encoded_stringio()
1143
formatter = log.LineLogFormatter(to_file=logfile, levels=0)
928
wt = self._prepare_tree_with_merges()
1144
929
revspec = revisionspec.RevisionSpec.from_string('1.1.1')
1146
rev = revspec.in_history(wtb)
1147
log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
1148
self.assertEqualDiff("""\
930
rev = revspec.in_history(wt.branch)
931
self.assertFormatterResult("""\
1149
932
1.1.1: Joe Foo 2005-11-22 rev-merged
934
wt.branch, log.LineLogFormatter,
935
formatter_kwargs=dict(levels=0),
936
show_log_kwargs=dict(start_revision=rev, end_revision=rev))
1153
938
def test_line_merge_revs_log_with_merges(self):
1154
wt = self.make_branch_and_memory_tree('.')
1156
self.addCleanup(wt.unlock)
1158
wt.commit('rev-1', rev_id='rev-1',
1159
timestamp=1132586655, timezone=36000,
1160
committer='Joe Foo <joe@foo.com>')
1161
wt.commit('rev-merged', rev_id='rev-2a',
1162
timestamp=1132586700, timezone=36000,
1163
committer='Joe Foo <joe@foo.com>')
1164
wt.set_parent_ids(['rev-1', 'rev-2a'])
1165
wt.branch.set_last_revision_info(1, 'rev-1')
1166
wt.commit('rev-2', rev_id='rev-2b',
1167
timestamp=1132586800, timezone=36000,
1168
committer='Joe Foo <joe@foo.com>')
1169
logfile = self.make_utf8_encoded_stringio()
1170
formatter = log.LineLogFormatter(to_file=logfile, levels=0)
1171
log.show_log(wt.branch, formatter)
1172
self.assertEqualDiff("""\
939
wt = self._prepare_tree_with_merges()
940
self.assertFormatterResult("""\
1173
941
2: Joe Foo 2005-11-22 [merge] rev-2
1174
942
1.1.1: Joe Foo 2005-11-22 rev-merged
1175
943
1: Joe Foo 2005-11-22 rev-1
1179
class TestGetViewRevisions(tests.TestCaseWithTransport):
945
wt.branch, log.LineLogFormatter,
946
formatter_kwargs=dict(levels=0))
949
class TestGnuChangelogFormatter(TestCaseForLogFormatter):
951
def test_gnu_changelog(self):
952
wt = self.make_standard_commit('nicky', authors=[])
953
self.assertFormatterResult('''\
954
2005-11-22 Lorem Ipsum <test@example.com>
959
wt.branch, log.GnuChangelogLogFormatter)
961
def test_with_authors(self):
962
wt = self.make_standard_commit('nicky',
963
authors=['Fooa Fooz <foo@example.com>',
964
'Bari Baro <bar@example.com>'])
965
self.assertFormatterResult('''\
966
2005-11-22 Fooa Fooz <foo@example.com>
971
wt.branch, log.GnuChangelogLogFormatter)
973
def test_verbose(self):
974
wt = self.make_standard_commit('nicky')
975
self.assertFormatterResult('''\
976
2005-11-22 John Doe <jdoe@example.com>
983
wt.branch, log.GnuChangelogLogFormatter,
984
show_log_kwargs=dict(verbose=True))
986
class TestGetViewRevisions(tests.TestCaseWithTransport, TestLogMixin):
988
def _get_view_revisions(self, *args, **kwargs):
989
return self.applyDeprecated(symbol_versioning.deprecated_in((2, 2, 0)),
990
log.get_view_revisions, *args, **kwargs)
1181
992
def make_tree_with_commits(self):
1182
993
"""Create a tree with well-known revision ids"""
1183
994
wt = self.make_branch_and_tree('tree1')
1184
wt.commit('commit one', rev_id='1')
1185
wt.commit('commit two', rev_id='2')
1186
wt.commit('commit three', rev_id='3')
995
self.wt_commit(wt, 'commit one', rev_id='1')
996
self.wt_commit(wt, 'commit two', rev_id='2')
997
self.wt_commit(wt, 'commit three', rev_id='3')
1187
998
mainline_revs = [None, '1', '2', '3']
1188
999
rev_nos = {'1': 1, '2': 2, '3': 3}
1189
1000
return mainline_revs, rev_nos, wt
1522
1343
class TestLogFormatter(tests.TestCase):
1346
super(TestLogFormatter, self).setUp()
1347
self.rev = revision.Revision('a-id')
1348
self.lf = log.LogFormatter(None)
1524
1350
def test_short_committer(self):
1525
rev = revision.Revision('a-id')
1526
rev.committer = 'John Doe <jdoe@example.com>'
1527
lf = log.LogFormatter(None)
1528
self.assertEqual('John Doe', lf.short_committer(rev))
1529
rev.committer = 'John Smith <jsmith@example.com>'
1530
self.assertEqual('John Smith', lf.short_committer(rev))
1531
rev.committer = 'John Smith'
1532
self.assertEqual('John Smith', lf.short_committer(rev))
1533
rev.committer = 'jsmith@example.com'
1534
self.assertEqual('jsmith@example.com', lf.short_committer(rev))
1535
rev.committer = '<jsmith@example.com>'
1536
self.assertEqual('jsmith@example.com', lf.short_committer(rev))
1537
rev.committer = 'John Smith jsmith@example.com'
1538
self.assertEqual('John Smith', lf.short_committer(rev))
1351
def assertCommitter(expected, committer):
1352
self.rev.committer = committer
1353
self.assertEqual(expected, self.lf.short_committer(self.rev))
1355
assertCommitter('John Doe', 'John Doe <jdoe@example.com>')
1356
assertCommitter('John Smith', 'John Smith <jsmith@example.com>')
1357
assertCommitter('John Smith', 'John Smith')
1358
assertCommitter('jsmith@example.com', 'jsmith@example.com')
1359
assertCommitter('jsmith@example.com', '<jsmith@example.com>')
1360
assertCommitter('John Smith', 'John Smith jsmith@example.com')
1540
1362
def test_short_author(self):
1541
rev = revision.Revision('a-id')
1542
rev.committer = 'John Doe <jdoe@example.com>'
1543
lf = log.LogFormatter(None)
1544
self.assertEqual('John Doe', lf.short_author(rev))
1545
rev.properties['author'] = 'John Smith <jsmith@example.com>'
1546
self.assertEqual('John Smith', lf.short_author(rev))
1547
rev.properties['author'] = 'John Smith'
1548
self.assertEqual('John Smith', lf.short_author(rev))
1549
rev.properties['author'] = 'jsmith@example.com'
1550
self.assertEqual('jsmith@example.com', lf.short_author(rev))
1551
rev.properties['author'] = '<jsmith@example.com>'
1552
self.assertEqual('jsmith@example.com', lf.short_author(rev))
1553
rev.properties['author'] = 'John Smith jsmith@example.com'
1554
self.assertEqual('John Smith', lf.short_author(rev))
1555
del rev.properties['author']
1556
rev.properties['authors'] = ('John Smith <jsmith@example.com>\n'
1557
'Jane Rey <jrey@example.com>')
1558
self.assertEqual('John Smith', lf.short_author(rev))
1363
def assertAuthor(expected, author):
1364
self.rev.properties['author'] = author
1365
self.assertEqual(expected, self.lf.short_author(self.rev))
1367
assertAuthor('John Smith', 'John Smith <jsmith@example.com>')
1368
assertAuthor('John Smith', 'John Smith')
1369
assertAuthor('jsmith@example.com', 'jsmith@example.com')
1370
assertAuthor('jsmith@example.com', '<jsmith@example.com>')
1371
assertAuthor('John Smith', 'John Smith jsmith@example.com')
1373
def test_short_author_from_committer(self):
1374
self.rev.committer = 'John Doe <jdoe@example.com>'
1375
self.assertEqual('John Doe', self.lf.short_author(self.rev))
1377
def test_short_author_from_authors(self):
1378
self.rev.properties['authors'] = ('John Smith <jsmith@example.com>\n'
1379
'Jane Rey <jrey@example.com>')
1380
self.assertEqual('John Smith', self.lf.short_author(self.rev))
1561
1383
class TestReverseByDepth(tests.TestCase):
1707
1529
log.show_branch_change(tree.branch, s, 3, '3b')
1708
1530
self.assertContainsRe(s.getvalue(), 'Removed Revisions:')
1709
1531
self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')
1534
class TestRevisionNotInBranch(TestCaseForLogFormatter):
1536
def setup_a_tree(self):
1537
tree = self.make_branch_and_tree('tree')
1539
self.addCleanup(tree.unlock)
1541
'committer': 'Joe Foo <joe@foo.com>',
1542
'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
1543
'timezone': 0, # UTC
1545
tree.commit('commit 1a', rev_id='1a', **kwargs)
1546
tree.commit('commit 2a', rev_id='2a', **kwargs)
1547
tree.commit('commit 3a', rev_id='3a', **kwargs)
1550
def setup_ab_tree(self):
1551
tree = self.setup_a_tree()
1552
tree.set_last_revision('1a')
1553
tree.branch.set_last_revision_info(1, '1a')
1555
'committer': 'Joe Foo <joe@foo.com>',
1556
'timestamp': 1132617600, # Mon 2005-11-22 00:00:00 +0000
1557
'timezone': 0, # UTC
1559
tree.commit('commit 2b', rev_id='2b', **kwargs)
1560
tree.commit('commit 3b', rev_id='3b', **kwargs)
1563
def test_one_revision(self):
1564
tree = self.setup_ab_tree()
1566
rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1567
log.show_log(tree.branch, lf, verbose=True, start_revision=rev,
1569
self.assertEqual(1, len(lf.revisions))
1570
self.assertEqual(None, lf.revisions[0].revno) # Out-of-branch
1571
self.assertEqual('3a', lf.revisions[0].rev.revision_id)
1573
def test_many_revisions(self):
1574
tree = self.setup_ab_tree()
1576
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1577
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1578
log.show_log(tree.branch, lf, verbose=True, start_revision=start_rev,
1579
end_revision=end_rev)
1580
self.assertEqual(3, len(lf.revisions))
1581
self.assertEqual(None, lf.revisions[0].revno) # Out-of-branch
1582
self.assertEqual('3a', lf.revisions[0].rev.revision_id)
1583
self.assertEqual(None, lf.revisions[1].revno) # Out-of-branch
1584
self.assertEqual('2a', lf.revisions[1].rev.revision_id)
1585
self.assertEqual('1', lf.revisions[2].revno) # In-branch
1587
def test_long_format(self):
1588
tree = self.setup_ab_tree()
1589
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1590
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1591
self.assertFormatterResult("""\
1592
------------------------------------------------------------
1594
committer: Joe Foo <joe@foo.com>
1596
timestamp: Tue 2005-11-22 00:00:00 +0000
1599
------------------------------------------------------------
1601
committer: Joe Foo <joe@foo.com>
1603
timestamp: Tue 2005-11-22 00:00:00 +0000
1606
------------------------------------------------------------
1608
committer: Joe Foo <joe@foo.com>
1610
timestamp: Tue 2005-11-22 00:00:00 +0000
1614
tree.branch, log.LongLogFormatter, show_log_kwargs={
1615
'start_revision': start_rev, 'end_revision': end_rev
1618
def test_short_format(self):
1619
tree = self.setup_ab_tree()
1620
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1621
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1622
self.assertFormatterResult("""\
1631
1 Joe Foo\t2005-11-22
1635
tree.branch, log.ShortLogFormatter, show_log_kwargs={
1636
'start_revision': start_rev, 'end_revision': end_rev
1639
def test_line_format(self):
1640
tree = self.setup_ab_tree()
1641
start_rev = revisionspec.RevisionInfo(tree.branch, None, '1a')
1642
end_rev = revisionspec.RevisionInfo(tree.branch, None, '3a')
1643
self.assertFormatterResult("""\
1644
Joe Foo 2005-11-22 commit 3a
1645
Joe Foo 2005-11-22 commit 2a
1646
1: Joe Foo 2005-11-22 commit 1a
1648
tree.branch, log.LineLogFormatter, show_log_kwargs={
1649
'start_revision': start_rev, 'end_revision': end_rev
1653
class TestLogWithBugs(TestCaseForLogFormatter, TestLogMixin):
1656
TestCaseForLogFormatter.setUp(self)
1657
log.properties_handler_registry.register(
1658
'bugs_properties_handler',
1659
log._bugs_properties_handler)
1661
def make_commits_with_bugs(self):
1662
"""Helper method for LogFormatter tests"""
1663
tree = self.make_branch_and_tree(u'.')
1664
self.build_tree(['a', 'b'])
1666
self.wt_commit(tree, 'simple log message', rev_id='a1',
1667
revprops={'bugs': 'test://bug/id fixed'})
1669
self.wt_commit(tree, 'multiline\nlog\nmessage\n', rev_id='a2',
1670
authors=['Joe Bar <joe@bar.com>'],
1671
revprops={'bugs': 'test://bug/id fixed\n'
1672
'test://bug/2 fixed'})
1676
def test_long_bugs(self):
1677
tree = self.make_commits_with_bugs()
1678
self.assertFormatterResult("""\
1679
------------------------------------------------------------
1681
fixes bug(s): test://bug/id test://bug/2
1682
author: Joe Bar <joe@bar.com>
1683
committer: Joe Foo <joe@foo.com>
1685
timestamp: Tue 2005-11-22 00:00:01 +0000
1690
------------------------------------------------------------
1692
fixes bug(s): test://bug/id
1693
committer: Joe Foo <joe@foo.com>
1695
timestamp: Tue 2005-11-22 00:00:00 +0000
1699
tree.branch, log.LongLogFormatter)
1701
def test_short_bugs(self):
1702
tree = self.make_commits_with_bugs()
1703
self.assertFormatterResult("""\
1704
2 Joe Bar\t2005-11-22
1705
fixes bug(s): test://bug/id test://bug/2
1710
1 Joe Foo\t2005-11-22
1711
fixes bug(s): test://bug/id
1715
tree.branch, log.ShortLogFormatter)
1717
def test_wrong_bugs_property(self):
1718
tree = self.make_branch_and_tree(u'.')
1719
self.build_tree(['foo'])
1720
self.wt_commit(tree, 'simple log message', rev_id='a1',
1721
revprops={'bugs': 'test://bug/id invalid_value'})
1722
self.assertFormatterResult("""\
1723
1 Joe Foo\t2005-11-22
1727
tree.branch, log.ShortLogFormatter)
1729
def test_bugs_handler_present(self):
1730
self.properties_handler_registry.get('bugs_properties_handler')
1733
class TestLogForAuthors(TestCaseForLogFormatter):
1736
TestCaseForLogFormatter.setUp(self)
1737
self.wt = self.make_standard_commit('nicky',
1738
authors=['John Doe <jdoe@example.com>',
1739
'Jane Rey <jrey@example.com>'])
1741
def assertFormatterResult(self, formatter, who, result):
1742
formatter_kwargs = dict()
1744
author_list_handler = log.author_list_registry.get(who)
1745
formatter_kwargs['author_list_handler'] = author_list_handler
1746
TestCaseForLogFormatter.assertFormatterResult(self, result,
1747
self.wt.branch, formatter, formatter_kwargs=formatter_kwargs)
1749
def test_line_default(self):
1750
self.assertFormatterResult(log.LineLogFormatter, None, """\
1751
1: John Doe 2005-11-22 add a
1754
def test_line_committer(self):
1755
self.assertFormatterResult(log.LineLogFormatter, 'committer', """\
1756
1: Lorem Ipsum 2005-11-22 add a
1759
def test_line_first(self):
1760
self.assertFormatterResult(log.LineLogFormatter, 'first', """\
1761
1: John Doe 2005-11-22 add a
1764
def test_line_all(self):
1765
self.assertFormatterResult(log.LineLogFormatter, 'all', """\
1766
1: John Doe, Jane Rey 2005-11-22 add a
1770
def test_short_default(self):
1771
self.assertFormatterResult(log.ShortLogFormatter, None, """\
1772
1 John Doe\t2005-11-22
1777
def test_short_committer(self):
1778
self.assertFormatterResult(log.ShortLogFormatter, 'committer', """\
1779
1 Lorem Ipsum\t2005-11-22
1784
def test_short_first(self):
1785
self.assertFormatterResult(log.ShortLogFormatter, 'first', """\
1786
1 John Doe\t2005-11-22
1791
def test_short_all(self):
1792
self.assertFormatterResult(log.ShortLogFormatter, 'all', """\
1793
1 John Doe, Jane Rey\t2005-11-22
1798
def test_long_default(self):
1799
self.assertFormatterResult(log.LongLogFormatter, None, """\
1800
------------------------------------------------------------
1802
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1803
committer: Lorem Ipsum <test@example.com>
1805
timestamp: Tue 2005-11-22 00:00:00 +0000
1810
def test_long_committer(self):
1811
self.assertFormatterResult(log.LongLogFormatter, 'committer', """\
1812
------------------------------------------------------------
1814
committer: Lorem Ipsum <test@example.com>
1816
timestamp: Tue 2005-11-22 00:00:00 +0000
1821
def test_long_first(self):
1822
self.assertFormatterResult(log.LongLogFormatter, 'first', """\
1823
------------------------------------------------------------
1825
author: John Doe <jdoe@example.com>
1826
committer: Lorem Ipsum <test@example.com>
1828
timestamp: Tue 2005-11-22 00:00:00 +0000
1833
def test_long_all(self):
1834
self.assertFormatterResult(log.LongLogFormatter, 'all', """\
1835
------------------------------------------------------------
1837
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1838
committer: Lorem Ipsum <test@example.com>
1840
timestamp: Tue 2005-11-22 00:00:00 +0000
1845
def test_gnu_changelog_default(self):
1846
self.assertFormatterResult(log.GnuChangelogLogFormatter, None, """\
1847
2005-11-22 John Doe <jdoe@example.com>
1853
def test_gnu_changelog_committer(self):
1854
self.assertFormatterResult(log.GnuChangelogLogFormatter, 'committer', """\
1855
2005-11-22 Lorem Ipsum <test@example.com>
1861
def test_gnu_changelog_first(self):
1862
self.assertFormatterResult(log.GnuChangelogLogFormatter, 'first', """\
1863
2005-11-22 John Doe <jdoe@example.com>
1869
def test_gnu_changelog_all(self):
1870
self.assertFormatterResult(log.GnuChangelogLogFormatter, 'all', """\
1871
2005-11-22 John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
1878
class TestLogExcludeAncestry(tests.TestCaseWithTransport):
1880
def make_branch_with_alternate_ancestries(self, relpath='.'):
1881
# See test_merge_sorted_exclude_ancestry below for the difference with
1882
# bt.per_branch.test_iter_merge_sorted_revision.
1883
# TestIterMergeSortedRevisionsBushyGraph.
1884
# make_branch_with_alternate_ancestries
1885
# and test_merge_sorted_exclude_ancestry
1886
# See the FIXME in assertLogRevnos too.
1887
builder = branchbuilder.BranchBuilder(self.get_transport(relpath))
1899
builder.start_series()
1900
builder.build_snapshot('1', None, [
1901
('add', ('', 'TREE_ROOT', 'directory', '')),])
1902
builder.build_snapshot('1.1.1', ['1'], [])
1903
builder.build_snapshot('2', ['1'], [])
1904
builder.build_snapshot('1.2.1', ['1.1.1'], [])
1905
builder.build_snapshot('1.1.2', ['1.1.1', '1.2.1'], [])
1906
builder.build_snapshot('3', ['2', '1.1.2'], [])
1907
builder.finish_series()
1908
br = builder.get_branch()
1910
self.addCleanup(br.unlock)
1913
def assertLogRevnos(self, expected_revnos, b, start, end,
1914
exclude_common_ancestry, generate_merge_revisions=True):
1915
# FIXME: the layering in log makes it hard to test intermediate levels,
1916
# I wish adding filters with their parameters were easier...
1918
iter_revs = log._calc_view_revisions(
1919
b, start, end, direction='reverse',
1920
generate_merge_revisions=generate_merge_revisions,
1921
exclude_common_ancestry=exclude_common_ancestry)
1922
self.assertEqual(expected_revnos,
1923
[revid for revid, revno, depth in iter_revs])
1925
def test_merge_sorted_exclude_ancestry(self):
1926
b = self.make_branch_with_alternate_ancestries()
1927
self.assertLogRevnos(['3', '1.1.2', '1.2.1', '1.1.1', '2', '1'],
1928
b, '1', '3', exclude_common_ancestry=False)
1929
# '2' is part of the '3' ancestry but not part of '1.1.1' ancestry so
1930
# it should be mentioned even if merge_sort order will make it appear
1932
self.assertLogRevnos(['3', '1.1.2', '1.2.1', '2'],
1933
b, '1.1.1', '3', exclude_common_ancestry=True)
1935
def test_merge_sorted_simple_revnos_exclude_ancestry(self):
1936
b = self.make_branch_with_alternate_ancestries()
1937
self.assertLogRevnos(['3', '2'],
1938
b, '1', '3', exclude_common_ancestry=True,
1939
generate_merge_revisions=False)
1940
self.assertLogRevnos(['3', '1.1.2', '1.2.1', '1.1.1', '2'],
1941
b, '1', '3', exclude_common_ancestry=True,
1942
generate_merge_revisions=True)