~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_log.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-11-17 03:20:35 UTC
  • mfrom: (4792.4.3 456036)
  • Revision ID: pqm@pqm.ubuntu.com-20091117032035-s3sgtlixj1lrminn
(Gordon Tyler) Fix IndexError during 'bzr ignore /' (#456036)

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
    )
28
28
 
29
29
 
30
 
class TestCaseForLogFormatter(tests.TestCaseWithTransport):
 
30
class TestCaseWithoutPropsHandler(tests.TestCaseWithTransport):
31
31
 
32
32
    def setUp(self):
33
 
        super(TestCaseForLogFormatter, self).setUp()
 
33
        super(TestCaseWithoutPropsHandler, self).setUp()
34
34
        # keep a reference to the "current" custom prop. handler registry
35
35
        self.properties_handler_registry = log.properties_handler_registry
36
36
        # Use a clean registry for log
40
40
            log.properties_handler_registry = self.properties_handler_registry
41
41
        self.addCleanup(restore)
42
42
 
43
 
    def assertFormatterResult(self, result, branch, formatter_class,
44
 
                              formatter_kwargs=None, show_log_kwargs=None,
45
 
                              normalize=False):
46
 
        logfile = self.make_utf8_encoded_stringio()
47
 
        if formatter_kwargs is None:
48
 
            formatter_kwargs = {}
49
 
        formatter = formatter_class(to_file=logfile, **formatter_kwargs)
50
 
        if show_log_kwargs is None:
51
 
            show_log_kwargs = {}
52
 
        log.show_log(branch, formatter, **show_log_kwargs)
53
 
        log_content = logfile.getvalue()
54
 
        if normalize:
55
 
            log_content = normalize_log(log_content)
56
 
        self.assertEqualDiff(result, log_content)
57
 
 
58
 
    def make_standard_commit(self, branch_nick, **kwargs):
59
 
        wt = self.make_branch_and_tree('.')
60
 
        wt.lock_write()
61
 
        self.addCleanup(wt.unlock)
62
 
        self.build_tree(['a'])
63
 
        wt.add(['a'])
64
 
        wt.branch.nick = branch_nick
65
 
        kwargs = dict(kwargs)
66
 
        kwargs.setdefault('message', 'add a')
67
 
        kwargs.setdefault('timestamp', 1132711707)
68
 
        kwargs.setdefault('timezone', 36000)
69
 
        kwargs.setdefault('committer', 'Lorem Ipsum <test@example.com>')
70
 
        kwargs.setdefault('authors', ['John Doe <jdoe@example.com>'])
71
 
        wt.commit(**kwargs)
72
 
        return wt
73
 
 
74
 
    def _prepare_tree_with_merges(self, with_tags=False):
75
 
        wt = self.make_branch_and_memory_tree('.')
76
 
        wt.lock_write()
77
 
        self.addCleanup(wt.unlock)
78
 
        wt.add('')
79
 
        wt.commit('rev-1', rev_id='rev-1',
80
 
                  timestamp=1132586655, timezone=36000,
81
 
                  committer='Joe Foo <joe@foo.com>')
82
 
        wt.commit('rev-merged', rev_id='rev-2a',
83
 
                  timestamp=1132586700, timezone=36000,
84
 
                  committer='Joe Foo <joe@foo.com>')
85
 
        wt.set_parent_ids(['rev-1', 'rev-2a'])
86
 
        wt.branch.set_last_revision_info(1, 'rev-1')
87
 
        wt.commit('rev-2', rev_id='rev-2b',
88
 
                  timestamp=1132586800, timezone=36000,
89
 
                  committer='Joe Foo <joe@foo.com>')
90
 
        if with_tags:
91
 
            branch = wt.branch
92
 
            branch.tags.set_tag('v0.2', 'rev-2b')
93
 
            wt.commit('rev-3', rev_id='rev-3',
94
 
                      timestamp=1132586900, timezone=36000,
95
 
                      committer='Jane Foo <jane@foo.com>')
96
 
            branch.tags.set_tag('v1.0rc1', 'rev-3')
97
 
            branch.tags.set_tag('v1.0', 'rev-3')
98
 
        return wt
99
 
 
100
 
        
101
 
 
102
43
 
103
44
class LogCatcher(log.LogFormatter):
104
45
    """Pull log messages into a list rather than displaying them.
301
242
    return ''.join(lines)
302
243
 
303
244
 
304
 
class TestShortLogFormatter(TestCaseForLogFormatter):
 
245
class TestShortLogFormatter(tests.TestCaseWithTransport):
305
246
 
306
247
    def test_trailing_newlines(self):
307
248
        wt = self.make_branch_and_tree('.')
308
249
        b = make_commits_with_trailing_newlines(wt)
309
 
        self.assertFormatterResult("""\
 
250
        sio = self.make_utf8_encoded_stringio()
 
251
        lf = log.ShortLogFormatter(to_file=sio)
 
252
        log.show_log(b, lf)
 
253
        self.assertEqualDiff("""\
310
254
    3 Joe Foo\t2005-11-21
311
255
      single line with trailing newline
312
256
 
319
263
      simple log message
320
264
 
321
265
""",
322
 
            b, log.ShortLogFormatter)
 
266
                             sio.getvalue())
 
267
 
 
268
    def _prepare_tree_with_merges(self, with_tags=False):
 
269
        wt = self.make_branch_and_memory_tree('.')
 
270
        wt.lock_write()
 
271
        self.addCleanup(wt.unlock)
 
272
        wt.add('')
 
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>')
 
284
        if with_tags:
 
285
            branch = wt.branch
 
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')
 
292
        return wt
323
293
 
324
294
    def test_short_log_with_merges(self):
325
295
        wt = self._prepare_tree_with_merges()
326
 
        self.assertFormatterResult("""\
 
296
        logfile = self.make_utf8_encoded_stringio()
 
297
        formatter = log.ShortLogFormatter(to_file=logfile)
 
298
        log.show_log(wt.branch, formatter)
 
299
        self.assertEqualDiff("""\
327
300
    2 Joe Foo\t2005-11-22 [merge]
328
301
      rev-2
329
302
 
331
304
      rev-1
332
305
 
333
306
""",
334
 
            wt.branch, log.ShortLogFormatter)
 
307
                             logfile.getvalue())
335
308
 
336
309
    def test_short_log_with_merges_and_advice(self):
337
310
        wt = self._prepare_tree_with_merges()
338
 
        self.assertFormatterResult("""\
 
311
        logfile = self.make_utf8_encoded_stringio()
 
312
        formatter = log.ShortLogFormatter(to_file=logfile,
 
313
            show_advice=True)
 
314
        log.show_log(wt.branch, formatter)
 
315
        self.assertEqualDiff("""\
339
316
    2 Joe Foo\t2005-11-22 [merge]
340
317
      rev-2
341
318
 
344
321
 
345
322
Use --include-merges or -n0 to see merged revisions.
346
323
""",
347
 
            wt.branch, log.ShortLogFormatter,
348
 
            formatter_kwargs=dict(show_advice=True))
 
324
                             logfile.getvalue())
349
325
 
350
326
    def test_short_log_with_merges_and_range(self):
351
327
        wt = self.make_branch_and_memory_tree('.')
371
347
        wt.commit('rev-3b', rev_id='rev-3b',
372
348
                  timestamp=1132586800, timezone=36000,
373
349
                  committer='Joe Foo <joe@foo.com>')
374
 
        self.assertFormatterResult("""\
 
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("""\
375
355
    3 Joe Foo\t2005-11-22 [merge]
376
356
      rev-3b
377
357
 
379
359
      rev-2b
380
360
 
381
361
""",
382
 
            wt.branch, log.ShortLogFormatter,
383
 
            show_log_kwargs=dict(start_revision=2, end_revision=3))
 
362
                             logfile.getvalue())
384
363
 
385
364
    def test_short_log_with_tags(self):
386
365
        wt = self._prepare_tree_with_merges(with_tags=True)
387
 
        self.assertFormatterResult("""\
 
366
        logfile = self.make_utf8_encoded_stringio()
 
367
        formatter = log.ShortLogFormatter(to_file=logfile)
 
368
        log.show_log(wt.branch, formatter)
 
369
        self.assertEqualDiff("""\
388
370
    3 Jane Foo\t2005-11-22 {v1.0, v1.0rc1}
389
371
      rev-3
390
372
 
395
377
      rev-1
396
378
 
397
379
""",
398
 
            wt.branch, log.ShortLogFormatter)
 
380
                             logfile.getvalue())
399
381
 
400
382
    def test_short_log_single_merge_revision(self):
401
383
        wt = self.make_branch_and_memory_tree('.')
413
395
        wt.commit('rev-2', rev_id='rev-2b',
414
396
                  timestamp=1132586800, timezone=36000,
415
397
                  committer='Joe Foo <joe@foo.com>')
 
398
        logfile = self.make_utf8_encoded_stringio()
 
399
        formatter = log.ShortLogFormatter(to_file=logfile)
416
400
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
417
 
        rev = revspec.in_history(wt.branch)
418
 
        self.assertFormatterResult("""\
 
401
        wtb = wt.branch
 
402
        rev = revspec.in_history(wtb)
 
403
        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
 
404
        self.assertEqualDiff("""\
419
405
      1.1.1 Joe Foo\t2005-11-22
420
406
            rev-merged
421
407
 
422
408
""",
423
 
            wt.branch, log.ShortLogFormatter,
424
 
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
425
 
 
426
 
 
427
 
class TestShortLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
 
409
                             logfile.getvalue())
 
410
 
 
411
 
 
412
class TestShortLogFormatterWithMergeRevisions(tests.TestCaseWithTransport):
428
413
 
429
414
    def test_short_merge_revs_log_with_merges(self):
430
415
        wt = self.make_branch_and_memory_tree('.')
442
427
        wt.commit('rev-2', rev_id='rev-2b',
443
428
                  timestamp=1132586800, timezone=36000,
444
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)
445
433
        # Note that the 1.1.1 indenting is in fact correct given that
446
434
        # the revision numbers are right justified within 5 characters
447
435
        # for mainline revnos and 9 characters for dotted revnos.
448
 
        self.assertFormatterResult("""\
 
436
        self.assertEqualDiff("""\
449
437
    2 Joe Foo\t2005-11-22 [merge]
450
438
      rev-2
451
439
 
456
444
      rev-1
457
445
 
458
446
""",
459
 
            wt.branch, log.ShortLogFormatter,
460
 
            formatter_kwargs=dict(levels=0))
 
447
                             logfile.getvalue())
461
448
 
462
449
    def test_short_merge_revs_log_single_merge_revision(self):
463
450
        wt = self.make_branch_and_memory_tree('.')
475
462
        wt.commit('rev-2', rev_id='rev-2b',
476
463
                  timestamp=1132586800, timezone=36000,
477
464
                  committer='Joe Foo <joe@foo.com>')
 
465
        logfile = self.make_utf8_encoded_stringio()
 
466
        formatter = log.ShortLogFormatter(to_file=logfile, levels=0)
478
467
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
479
 
        rev = revspec.in_history(wt.branch)
480
 
        self.assertFormatterResult("""\
 
468
        wtb = wt.branch
 
469
        rev = revspec.in_history(wtb)
 
470
        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
 
471
        self.assertEqualDiff("""\
481
472
      1.1.1 Joe Foo\t2005-11-22
482
473
            rev-merged
483
474
 
484
475
""",
485
 
            wt.branch, log.ShortLogFormatter,
486
 
            formatter_kwargs=dict(levels=0),
487
 
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
488
 
 
489
 
 
490
 
class TestLongLogFormatter(TestCaseForLogFormatter):
 
476
                             logfile.getvalue())
 
477
 
 
478
 
 
479
class TestLongLogFormatter(TestCaseWithoutPropsHandler):
491
480
 
492
481
    def test_verbose_log(self):
493
482
        """Verbose log includes changed files
494
483
 
495
484
        bug #4676
496
485
        """
497
 
        wt = self.make_standard_commit('test_verbose_log', authors=[])
498
 
        self.assertFormatterResult('''\
 
486
        wt = self.make_branch_and_tree('.')
 
487
        b = wt.branch
 
488
        self.build_tree(['a'])
 
489
        wt.add('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,
 
494
                  timezone=36000,
 
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)
 
499
        logfile.flush()
 
500
        logfile.seek(0)
 
501
        log_contents = logfile.read()
 
502
        self.assertEqualDiff('''\
499
503
------------------------------------------------------------
500
504
revno: 1
501
505
committer: Lorem Ipsum <test@example.com>
506
510
added:
507
511
  a
508
512
''',
509
 
            wt.branch, log.LongLogFormatter,
510
 
            show_log_kwargs=dict(verbose=True))
 
513
                             log_contents)
511
514
 
512
515
    def test_merges_are_indented_by_level(self):
513
516
        wt = self.make_branch_and_tree('parent')
523
526
        os.chdir('../parent')
524
527
        self.run_bzr('merge ../child')
525
528
        wt.commit('merge branch 1')
526
 
        self.assertFormatterResult("""\
 
529
        b = wt.branch
 
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("""\
527
535
------------------------------------------------------------
528
536
revno: 2 [merge]
529
537
committer: Lorem Ipsum <test@example.com>
560
568
message:
561
569
  first post
562
570
""",
563
 
            wt.branch, log.LongLogFormatter,
564
 
            formatter_kwargs=dict(levels=0),
565
 
            show_log_kwargs=dict(verbose=True),
566
 
            normalize=True)
 
571
                             the_log)
567
572
 
568
573
    def test_verbose_merge_revisions_contain_deltas(self):
569
574
        wt = self.make_branch_and_tree('parent')
578
583
        os.chdir('parent')
579
584
        self.run_bzr('merge ../child')
580
585
        wt.commit('merge branch 1')
581
 
        self.assertFormatterResult("""\
 
586
        b = wt.branch
 
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("""\
582
592
------------------------------------------------------------
583
593
revno: 2 [merge]
584
594
committer: Lorem Ipsum <test@example.com>
612
622
  f1
613
623
  f2
614
624
""",
615
 
            wt.branch, log.LongLogFormatter,
616
 
            formatter_kwargs=dict(levels=0),
617
 
            show_log_kwargs=dict(verbose=True),
618
 
            normalize=True)
 
625
                             the_log)
619
626
 
620
627
    def test_trailing_newlines(self):
621
628
        wt = self.make_branch_and_tree('.')
622
629
        b = make_commits_with_trailing_newlines(wt)
623
 
        self.assertFormatterResult("""\
 
630
        sio = self.make_utf8_encoded_stringio()
 
631
        lf = log.LongLogFormatter(to_file=sio)
 
632
        log.show_log(b, lf)
 
633
        self.assertEqualDiff("""\
624
634
------------------------------------------------------------
625
635
revno: 3
626
636
committer: Joe Foo <joe@foo.com>
646
656
message:
647
657
  simple log message
648
658
""",
649
 
        b, log.LongLogFormatter)
 
659
                             sio.getvalue())
650
660
 
651
661
    def test_author_in_log(self):
652
662
        """Log includes the author name if it's set in
653
663
        the revision properties
654
664
        """
655
 
        wt = self.make_standard_commit('test_author_log',
656
 
            authors=['John Doe <jdoe@example.com>',
657
 
                     'Jane Rey <jrey@example.com>'])
658
 
        self.assertFormatterResult("""\
 
665
        wt = self.make_branch_and_tree('.')
 
666
        b = wt.branch
 
667
        self.build_tree(['a'])
 
668
        wt.add('a')
 
669
        b.nick = 'test_author_log'
 
670
        wt.commit(message='add a',
 
671
                  timestamp=1132711707,
 
672
                  timezone=36000,
 
673
                  committer='Lorem Ipsum <test@example.com>',
 
674
                  authors=['John Doe <jdoe@example.com>',
 
675
                           'Jane Rey <jrey@example.com>'])
 
676
        sio = StringIO()
 
677
        formatter = log.LongLogFormatter(to_file=sio)
 
678
        log.show_log(b, formatter)
 
679
        self.assertEqualDiff('''\
659
680
------------------------------------------------------------
660
681
revno: 1
661
682
author: John Doe <jdoe@example.com>, Jane Rey <jrey@example.com>
664
685
timestamp: Wed 2005-11-23 12:08:27 +1000
665
686
message:
666
687
  add a
667
 
""",
668
 
        wt.branch, log.LongLogFormatter)
 
688
''',
 
689
                             sio.getvalue())
669
690
 
670
691
    def test_properties_in_log(self):
671
692
        """Log includes the custom properties returned by the registered
672
693
        handlers.
673
694
        """
674
 
        wt = self.make_standard_commit('test_properties_in_log')
675
 
        def trivial_custom_prop_handler(revision):
676
 
            return {'test_prop':'test_value'}
 
695
        wt = self.make_branch_and_tree('.')
 
696
        b = wt.branch
 
697
        self.build_tree(['a'])
 
698
        wt.add('a')
 
699
        b.nick = 'test_properties_in_log'
 
700
        wt.commit(message='add a',
 
701
                  timestamp=1132711707,
 
702
                  timezone=36000,
 
703
                  committer='Lorem Ipsum <test@example.com>',
 
704
                  authors=['John Doe <jdoe@example.com>'])
 
705
        sio = StringIO()
 
706
        formatter = log.LongLogFormatter(to_file=sio)
 
707
        try:
 
708
            def trivial_custom_prop_handler(revision):
 
709
                return {'test_prop':'test_value'}
677
710
 
678
 
        # Cleaned up in setUp()
679
 
        log.properties_handler_registry.register(
680
 
            'trivial_custom_prop_handler',
681
 
            trivial_custom_prop_handler)
682
 
        self.assertFormatterResult("""\
 
711
            log.properties_handler_registry.register(
 
712
                'trivial_custom_prop_handler',
 
713
                trivial_custom_prop_handler)
 
714
            log.show_log(b, formatter)
 
715
        finally:
 
716
            log.properties_handler_registry.remove(
 
717
                'trivial_custom_prop_handler')
 
718
            self.assertEqualDiff('''\
683
719
------------------------------------------------------------
684
720
revno: 1
685
721
test_prop: test_value
689
725
timestamp: Wed 2005-11-23 12:08:27 +1000
690
726
message:
691
727
  add a
692
 
""",
693
 
            wt.branch, log.LongLogFormatter)
 
728
''',
 
729
                                 sio.getvalue())
694
730
 
695
731
    def test_properties_in_short_log(self):
696
732
        """Log includes the custom properties returned by the registered
697
733
        handlers.
698
734
        """
699
 
        wt = self.make_standard_commit('test_properties_in_short_log')
700
 
        def trivial_custom_prop_handler(revision):
701
 
            return {'test_prop':'test_value'}
 
735
        wt = self.make_branch_and_tree('.')
 
736
        b = wt.branch
 
737
        self.build_tree(['a'])
 
738
        wt.add('a')
 
739
        b.nick = 'test_properties_in_short_log'
 
740
        wt.commit(message='add a',
 
741
                  timestamp=1132711707,
 
742
                  timezone=36000,
 
743
                  committer='Lorem Ipsum <test@example.com>',
 
744
                  authors=['John Doe <jdoe@example.com>'])
 
745
        sio = StringIO()
 
746
        formatter = log.ShortLogFormatter(to_file=sio)
 
747
        try:
 
748
            def trivial_custom_prop_handler(revision):
 
749
                return {'test_prop':'test_value'}
702
750
 
703
 
        log.properties_handler_registry.register(
704
 
            'trivial_custom_prop_handler',
705
 
            trivial_custom_prop_handler)
706
 
        self.assertFormatterResult("""\
 
751
            log.properties_handler_registry.register(
 
752
                'trivial_custom_prop_handler',
 
753
                trivial_custom_prop_handler)
 
754
            log.show_log(b, formatter)
 
755
        finally:
 
756
            log.properties_handler_registry.remove(
 
757
                'trivial_custom_prop_handler')
 
758
            self.assertEqualDiff('''\
707
759
    1 John Doe\t2005-11-23
708
760
      test_prop: test_value
709
761
      add a
710
762
 
711
 
""",
712
 
            wt.branch, log.ShortLogFormatter)
 
763
''',
 
764
                                 sio.getvalue())
713
765
 
714
766
    def test_error_in_properties_handler(self):
715
767
        """Log includes the custom properties returned by the registered
716
768
        handlers.
717
769
        """
718
 
        wt = self.make_standard_commit('error_in_properties_handler',
719
 
            revprops={'first_prop':'first_value'})
720
 
        sio = self.make_utf8_encoded_stringio()
 
770
        wt = self.make_branch_and_tree('.')
 
771
        b = wt.branch
 
772
        self.build_tree(['a'])
 
773
        wt.add('a')
 
774
        b.nick = 'test_author_log'
 
775
        wt.commit(message='add a',
 
776
                  timestamp=1132711707,
 
777
                  timezone=36000,
 
778
                  committer='Lorem Ipsum <test@example.com>',
 
779
                  authors=['John Doe <jdoe@example.com>'],
 
780
                  revprops={'first_prop':'first_value'})
 
781
        sio = StringIO()
721
782
        formatter = log.LongLogFormatter(to_file=sio)
722
 
        def trivial_custom_prop_handler(revision):
723
 
            raise StandardError("a test error")
 
783
        try:
 
784
            def trivial_custom_prop_handler(revision):
 
785
                raise StandardError("a test error")
724
786
 
725
 
        log.properties_handler_registry.register(
726
 
            'trivial_custom_prop_handler',
727
 
            trivial_custom_prop_handler)
728
 
        self.assertRaises(StandardError, log.show_log, wt.branch, formatter,)
 
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,)
 
791
        finally:
 
792
            log.properties_handler_registry.remove(
 
793
                'trivial_custom_prop_handler')
729
794
 
730
795
    def test_properties_handler_bad_argument(self):
731
 
        wt = self.make_standard_commit('bad_argument',
732
 
              revprops={'a_prop':'test_value'})
733
 
        sio = self.make_utf8_encoded_stringio()
 
796
        wt = self.make_branch_and_tree('.')
 
797
        b = wt.branch
 
798
        self.build_tree(['a'])
 
799
        wt.add('a')
 
800
        b.nick = 'test_author_log'
 
801
        wt.commit(message='add a',
 
802
                  timestamp=1132711707,
 
803
                  timezone=36000,
 
804
                  committer='Lorem Ipsum <test@example.com>',
 
805
                  authors=['John Doe <jdoe@example.com>'],
 
806
                  revprops={'a_prop':'test_value'})
 
807
        sio = StringIO()
734
808
        formatter = log.LongLogFormatter(to_file=sio)
735
 
        def bad_argument_prop_handler(revision):
736
 
            return {'custom_prop_name':revision.properties['a_prop']}
737
 
 
738
 
        log.properties_handler_registry.register(
739
 
            'bad_argument_prop_handler',
740
 
            bad_argument_prop_handler)
741
 
 
742
 
        self.assertRaises(AttributeError, formatter.show_properties,
743
 
                          'a revision', '')
744
 
 
745
 
        revision = wt.branch.repository.get_revision(wt.branch.last_revision())
746
 
        formatter.show_properties(revision, '')
747
 
        self.assertEqualDiff('''custom_prop_name: test_value\n''',
748
 
                             sio.getvalue())
749
 
 
750
 
 
751
 
class TestLongLogFormatterWithoutMergeRevisions(TestCaseForLogFormatter):
 
809
        try:
 
810
            def bad_argument_prop_handler(revision):
 
811
                return {'custom_prop_name':revision.properties['a_prop']}
 
812
 
 
813
            log.properties_handler_registry.register(
 
814
                'bad_argument_prop_handler',
 
815
                bad_argument_prop_handler)
 
816
 
 
817
            self.assertRaises(AttributeError, formatter.show_properties,
 
818
                              'a revision', '')
 
819
 
 
820
            revision = b.repository.get_revision(b.last_revision())
 
821
            formatter.show_properties(revision, '')
 
822
            self.assertEqualDiff('''custom_prop_name: test_value\n''',
 
823
                                 sio.getvalue())
 
824
        finally:
 
825
            log.properties_handler_registry.remove(
 
826
                'bad_argument_prop_handler')
 
827
 
 
828
 
 
829
class TestLongLogFormatterWithoutMergeRevisions(TestCaseWithoutPropsHandler):
752
830
 
753
831
    def test_long_verbose_log(self):
754
832
        """Verbose log includes changed files
755
833
 
756
834
        bug #4676
757
835
        """
758
 
        wt = self.make_standard_commit('test_long_verbose_log', authors=[])
759
 
        self.assertFormatterResult("""\
 
836
        wt = self.make_branch_and_tree('.')
 
837
        b = wt.branch
 
838
        self.build_tree(['a'])
 
839
        wt.add('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,
 
844
                  timezone=36000,
 
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)
 
849
        logfile.flush()
 
850
        logfile.seek(0)
 
851
        log_contents = logfile.read()
 
852
        self.assertEqualDiff('''\
760
853
------------------------------------------------------------
761
854
revno: 1
762
855
committer: Lorem Ipsum <test@example.com>
763
 
branch nick: test_long_verbose_log
 
856
branch nick: test_verbose_log
764
857
timestamp: Wed 2005-11-23 12:08:27 +1000
765
858
message:
766
859
  add a
767
860
added:
768
861
  a
769
 
""",
770
 
            wt.branch, log.LongLogFormatter,
771
 
            formatter_kwargs=dict(levels=1),
772
 
            show_log_kwargs=dict(verbose=True))
 
862
''',
 
863
                             log_contents)
773
864
 
774
865
    def test_long_verbose_contain_deltas(self):
775
866
        wt = self.make_branch_and_tree('parent')
776
867
        self.build_tree(['parent/f1', 'parent/f2'])
777
868
        wt.add(['f1','f2'])
778
869
        wt.commit('first post')
779
 
        child_wt = wt.bzrdir.sprout('child').open_workingtree()
 
870
        self.run_bzr('branch parent child')
780
871
        os.unlink('child/f1')
781
 
        self.build_tree_contents([('child/f2', 'hello\n')])
782
 
        child_wt.commit('removed f1 and modified f2')
783
 
        wt.merge_from_branch(child_wt.branch)
 
872
        file('child/f2', 'wb').write('hello\n')
 
873
        self.run_bzr(['commit', '-m', 'removed f1 and modified f2',
 
874
            'child'])
 
875
        os.chdir('parent')
 
876
        self.run_bzr('merge ../child')
784
877
        wt.commit('merge branch 1')
785
 
        self.assertFormatterResult("""\
 
878
        b = wt.branch
 
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("""\
786
884
------------------------------------------------------------
787
885
revno: 2 [merge]
788
886
committer: Lorem Ipsum <test@example.com>
805
903
  f1
806
904
  f2
807
905
""",
808
 
            wt.branch, log.LongLogFormatter,
809
 
            formatter_kwargs=dict(levels=1),
810
 
            show_log_kwargs=dict(verbose=True),
811
 
            normalize=True)
 
906
                             the_log)
812
907
 
813
908
    def test_long_trailing_newlines(self):
814
909
        wt = self.make_branch_and_tree('.')
815
910
        b = make_commits_with_trailing_newlines(wt)
816
 
        self.assertFormatterResult("""\
 
911
        sio = self.make_utf8_encoded_stringio()
 
912
        lf = log.LongLogFormatter(to_file=sio, levels=1)
 
913
        log.show_log(b, lf)
 
914
        self.assertEqualDiff("""\
817
915
------------------------------------------------------------
818
916
revno: 3
819
917
committer: Joe Foo <joe@foo.com>
839
937
message:
840
938
  simple log message
841
939
""",
842
 
        b, log.LongLogFormatter,
843
 
        formatter_kwargs=dict(levels=1))
 
940
                             sio.getvalue())
844
941
 
845
942
    def test_long_author_in_log(self):
846
943
        """Log includes the author name if it's set in
847
944
        the revision properties
848
945
        """
849
 
        wt = self.make_standard_commit('test_author_log')
850
 
        self.assertFormatterResult("""\
 
946
        wt = self.make_branch_and_tree('.')
 
947
        b = wt.branch
 
948
        self.build_tree(['a'])
 
949
        wt.add('a')
 
950
        b.nick = 'test_author_log'
 
951
        wt.commit(message='add a',
 
952
                  timestamp=1132711707,
 
953
                  timezone=36000,
 
954
                  committer='Lorem Ipsum <test@example.com>',
 
955
                  authors=['John Doe <jdoe@example.com>'])
 
956
        sio = StringIO()
 
957
        formatter = log.LongLogFormatter(to_file=sio, levels=1)
 
958
        log.show_log(b, formatter)
 
959
        self.assertEqualDiff('''\
851
960
------------------------------------------------------------
852
961
revno: 1
853
962
author: John Doe <jdoe@example.com>
856
965
timestamp: Wed 2005-11-23 12:08:27 +1000
857
966
message:
858
967
  add a
859
 
""",
860
 
            wt.branch, log.LongLogFormatter,
861
 
            formatter_kwargs=dict(levels=1))
 
968
''',
 
969
                             sio.getvalue())
862
970
 
863
971
    def test_long_properties_in_log(self):
864
972
        """Log includes the custom properties returned by the registered
865
973
        handlers.
866
974
        """
867
 
        wt = self.make_standard_commit('test_properties_in_log')
868
 
        def trivial_custom_prop_handler(revision):
869
 
            return {'test_prop':'test_value'}
 
975
        wt = self.make_branch_and_tree('.')
 
976
        b = wt.branch
 
977
        self.build_tree(['a'])
 
978
        wt.add('a')
 
979
        b.nick = 'test_properties_in_log'
 
980
        wt.commit(message='add a',
 
981
                  timestamp=1132711707,
 
982
                  timezone=36000,
 
983
                  committer='Lorem Ipsum <test@example.com>',
 
984
                  authors=['John Doe <jdoe@example.com>'])
 
985
        sio = StringIO()
 
986
        formatter = log.LongLogFormatter(to_file=sio, levels=1)
 
987
        try:
 
988
            def trivial_custom_prop_handler(revision):
 
989
                return {'test_prop':'test_value'}
870
990
 
871
 
        log.properties_handler_registry.register(
872
 
            'trivial_custom_prop_handler',
873
 
            trivial_custom_prop_handler)
874
 
        self.assertFormatterResult("""\
 
991
            log.properties_handler_registry.register(
 
992
                'trivial_custom_prop_handler',
 
993
                trivial_custom_prop_handler)
 
994
            log.show_log(b, formatter)
 
995
        finally:
 
996
            log.properties_handler_registry.remove(
 
997
                'trivial_custom_prop_handler')
 
998
            self.assertEqualDiff('''\
875
999
------------------------------------------------------------
876
1000
revno: 1
877
1001
test_prop: test_value
881
1005
timestamp: Wed 2005-11-23 12:08:27 +1000
882
1006
message:
883
1007
  add a
884
 
""",
885
 
            wt.branch, log.LongLogFormatter,
886
 
            formatter_kwargs=dict(levels=1))
887
 
 
888
 
 
889
 
class TestLineLogFormatter(TestCaseForLogFormatter):
 
1008
''',
 
1009
                                 sio.getvalue())
 
1010
 
 
1011
 
 
1012
class TestLineLogFormatter(tests.TestCaseWithTransport):
890
1013
 
891
1014
    def test_line_log(self):
892
1015
        """Line log should show revno
893
1016
 
894
1017
        bug #5162
895
1018
        """
896
 
        wt = self.make_standard_commit('test-line-log',
897
 
                committer='Line-Log-Formatter Tester <test@line.log>',
898
 
                authors=[])
899
 
        self.assertFormatterResult("""\
900
 
1: Line-Log-Formatte... 2005-11-23 add a
901
 
""",
902
 
            wt.branch, log.LineLogFormatter)
 
1019
        wt = self.make_branch_and_tree('.')
 
1020
        b = wt.branch
 
1021
        self.build_tree(['a'])
 
1022
        wt.add('a')
 
1023
        b.nick = 'test-line-log'
 
1024
        wt.commit(message='add a',
 
1025
                  timestamp=1132711707,
 
1026
                  timezone=36000,
 
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)
 
1031
        logfile.flush()
 
1032
        logfile.seek(0)
 
1033
        log_contents = logfile.read()
 
1034
        self.assertEqualDiff('1: Line-Log-Formatte... 2005-11-23 add a\n',
 
1035
                             log_contents)
903
1036
 
904
1037
    def test_trailing_newlines(self):
905
1038
        wt = self.make_branch_and_tree('.')
906
1039
        b = make_commits_with_trailing_newlines(wt)
907
 
        self.assertFormatterResult("""\
 
1040
        sio = self.make_utf8_encoded_stringio()
 
1041
        lf = log.LineLogFormatter(to_file=sio)
 
1042
        log.show_log(b, lf)
 
1043
        self.assertEqualDiff("""\
908
1044
3: Joe Foo 2005-11-21 single line with trailing newline
909
1045
2: Joe Bar 2005-11-21 multiline
910
1046
1: Joe Foo 2005-11-21 simple log message
911
1047
""",
912
 
            b, log.LineLogFormatter)
 
1048
                             sio.getvalue())
 
1049
 
 
1050
    def _prepare_tree_with_merges(self, with_tags=False):
 
1051
        wt = self.make_branch_and_memory_tree('.')
 
1052
        wt.lock_write()
 
1053
        self.addCleanup(wt.unlock)
 
1054
        wt.add('')
 
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>')
 
1066
        if with_tags:
 
1067
            branch = wt.branch
 
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')
 
1074
        return wt
913
1075
 
914
1076
    def test_line_log_single_merge_revision(self):
915
1077
        wt = self._prepare_tree_with_merges()
 
1078
        logfile = self.make_utf8_encoded_stringio()
 
1079
        formatter = log.LineLogFormatter(to_file=logfile)
916
1080
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
917
 
        rev = revspec.in_history(wt.branch)
918
 
        self.assertFormatterResult("""\
 
1081
        wtb = wt.branch
 
1082
        rev = revspec.in_history(wtb)
 
1083
        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
 
1084
        self.assertEqualDiff("""\
919
1085
1.1.1: Joe Foo 2005-11-22 rev-merged
920
1086
""",
921
 
            wt.branch, log.LineLogFormatter,
922
 
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
 
1087
                             logfile.getvalue())
923
1088
 
924
1089
    def test_line_log_with_tags(self):
925
1090
        wt = self._prepare_tree_with_merges(with_tags=True)
926
 
        self.assertFormatterResult("""\
 
1091
        logfile = self.make_utf8_encoded_stringio()
 
1092
        formatter = log.LineLogFormatter(to_file=logfile)
 
1093
        log.show_log(wt.branch, formatter)
 
1094
        self.assertEqualDiff("""\
927
1095
3: Jane Foo 2005-11-22 {v1.0, v1.0rc1} rev-3
928
1096
2: Joe Foo 2005-11-22 [merge] {v0.2} rev-2
929
1097
1: Joe Foo 2005-11-22 rev-1
930
1098
""",
931
 
            wt.branch, log.LineLogFormatter)
932
 
 
933
 
 
934
 
class TestLineLogFormatterWithMergeRevisions(TestCaseForLogFormatter):
 
1099
                             logfile.getvalue())
 
1100
 
 
1101
class TestLineLogFormatterWithMergeRevisions(tests.TestCaseWithTransport):
935
1102
 
936
1103
    def test_line_merge_revs_log(self):
937
1104
        """Line log should show revno
938
1105
 
939
1106
        bug #5162
940
1107
        """
941
 
        wt = self.make_standard_commit('test-line-log',
942
 
                committer='Line-Log-Formatter Tester <test@line.log>',
943
 
                authors=[])
944
 
        self.assertFormatterResult("""\
945
 
1: Line-Log-Formatte... 2005-11-23 add a
946
 
""",
947
 
            wt.branch, log.LineLogFormatter)
 
1108
        wt = self.make_branch_and_tree('.')
 
1109
        b = wt.branch
 
1110
        self.build_tree(['a'])
 
1111
        wt.add('a')
 
1112
        b.nick = 'test-line-log'
 
1113
        wt.commit(message='add a',
 
1114
                  timestamp=1132711707,
 
1115
                  timezone=36000,
 
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)
 
1120
        logfile.flush()
 
1121
        logfile.seek(0)
 
1122
        log_contents = logfile.read()
 
1123
        self.assertEqualDiff('1: Line-Log-Formatte... 2005-11-23 add a\n',
 
1124
                             log_contents)
948
1125
 
949
1126
    def test_line_merge_revs_log_single_merge_revision(self):
950
1127
        wt = self.make_branch_and_memory_tree('.')
962
1139
        wt.commit('rev-2', rev_id='rev-2b',
963
1140
                  timestamp=1132586800, timezone=36000,
964
1141
                  committer='Joe Foo <joe@foo.com>')
 
1142
        logfile = self.make_utf8_encoded_stringio()
 
1143
        formatter = log.LineLogFormatter(to_file=logfile, levels=0)
965
1144
        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
966
 
        rev = revspec.in_history(wt.branch)
967
 
        self.assertFormatterResult("""\
 
1145
        wtb = wt.branch
 
1146
        rev = revspec.in_history(wtb)
 
1147
        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
 
1148
        self.assertEqualDiff("""\
968
1149
1.1.1: Joe Foo 2005-11-22 rev-merged
969
1150
""",
970
 
            wt.branch, log.LineLogFormatter,
971
 
            formatter_kwargs=dict(levels=0),
972
 
            show_log_kwargs=dict(start_revision=rev, end_revision=rev))
 
1151
                             logfile.getvalue())
973
1152
 
974
1153
    def test_line_merge_revs_log_with_merges(self):
975
1154
        wt = self.make_branch_and_memory_tree('.')
987
1166
        wt.commit('rev-2', rev_id='rev-2b',
988
1167
                  timestamp=1132586800, timezone=36000,
989
1168
                  committer='Joe Foo <joe@foo.com>')
990
 
        self.assertFormatterResult("""\
 
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("""\
991
1173
2: Joe Foo 2005-11-22 [merge] rev-2
992
1174
  1.1.1: Joe Foo 2005-11-22 rev-merged
993
1175
1: Joe Foo 2005-11-22 rev-1
994
1176
""",
995
 
            wt.branch, log.LineLogFormatter,
996
 
            formatter_kwargs=dict(levels=0))
997
 
 
 
1177
                             logfile.getvalue())
998
1178
 
999
1179
class TestGetViewRevisions(tests.TestCaseWithTransport):
1000
1180
 
1527
1707
        log.show_branch_change(tree.branch, s, 3, '3b')
1528
1708
        self.assertContainsRe(s.getvalue(), 'Removed Revisions:')
1529
1709
        self.assertNotContainsRe(s.getvalue(), 'Added Revisions:')
1530
 
 
1531
 
 
1532
 
 
1533
 
class TestLogWithBugs(TestCaseForLogFormatter):
1534
 
 
1535
 
    def setUp(self):
1536
 
        TestCaseForLogFormatter.setUp(self)
1537
 
        log.properties_handler_registry.register(
1538
 
            'bugs_properties_handler',
1539
 
            log._bugs_properties_handler)
1540
 
 
1541
 
    def make_commits_with_bugs(self):
1542
 
        """Helper method for LogFormatter tests"""
1543
 
        tree = self.make_branch_and_tree(u'.')
1544
 
        self.build_tree(['a', 'b'])
1545
 
        tree.add('a')
1546
 
        tree.commit('simple log message', rev_id='a1',
1547
 
                    timestamp=1132586655.459960938, timezone=-6*3600,
1548
 
                    committer='Joe Foo <joe@foo.com>',
1549
 
                    revprops={'bugs': 'test://bug/id fixed'})
1550
 
        tree.add('b')
1551
 
        tree.commit('multiline\nlog\nmessage\n', rev_id='a2',
1552
 
                    timestamp=1132586842.411175966, timezone=-6*3600,
1553
 
                    committer='Joe Foo <joe@foo.com>',
1554
 
                    authors=['Joe Bar <joe@bar.com>'],
1555
 
                    revprops={'bugs': 'test://bug/id fixed\n'
1556
 
                                      'test://bug/2 fixed'})
1557
 
        return tree
1558
 
 
1559
 
 
1560
 
    def test_long_bugs(self):
1561
 
        tree = self.make_commits_with_bugs()
1562
 
        self.assertFormatterResult("""\
1563
 
------------------------------------------------------------
1564
 
revno: 2
1565
 
fixes bug(s): test://bug/id test://bug/2
1566
 
author: Joe Bar <joe@bar.com>
1567
 
committer: Joe Foo <joe@foo.com>
1568
 
branch nick: work
1569
 
timestamp: Mon 2005-11-21 09:27:22 -0600
1570
 
message:
1571
 
  multiline
1572
 
  log
1573
 
  message
1574
 
------------------------------------------------------------
1575
 
revno: 1
1576
 
fixes bug(s): test://bug/id
1577
 
committer: Joe Foo <joe@foo.com>
1578
 
branch nick: work
1579
 
timestamp: Mon 2005-11-21 09:24:15 -0600
1580
 
message:
1581
 
  simple log message
1582
 
""",
1583
 
            tree.branch, log.LongLogFormatter)
1584
 
 
1585
 
    def test_short_bugs(self):
1586
 
        tree = self.make_commits_with_bugs()
1587
 
        self.assertFormatterResult("""\
1588
 
    2 Joe Bar\t2005-11-21
1589
 
      fixes bug(s): test://bug/id test://bug/2
1590
 
      multiline
1591
 
      log
1592
 
      message
1593
 
 
1594
 
    1 Joe Foo\t2005-11-21
1595
 
      fixes bug(s): test://bug/id
1596
 
      simple log message
1597
 
 
1598
 
""",
1599
 
            tree.branch, log.ShortLogFormatter)
1600
 
 
1601
 
    def test_wrong_bugs_property(self):
1602
 
        tree = self.make_branch_and_tree(u'.')
1603
 
        self.build_tree(['foo'])
1604
 
        tree.commit('simple log message', rev_id='a1',
1605
 
              timestamp=1132586655.459960938, timezone=-6*3600,
1606
 
              committer='Joe Foo <joe@foo.com>',
1607
 
              revprops={'bugs': 'test://bug/id invalid_value'})
1608
 
        self.assertFormatterResult("""\
1609
 
    1 Joe Foo\t2005-11-21
1610
 
      simple log message
1611
 
 
1612
 
""",
1613
 
            tree.branch, log.ShortLogFormatter)
1614
 
 
1615
 
    def test_bugs_handler_present(self):
1616
 
        self.properties_handler_registry.get('bugs_properties_handler')