/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to tests/test_commit.py

  • Committer: Jelmer Vernooij
  • Date: 2008-06-29 15:47:30 UTC
  • mto: This revision was merged to the branch mainline in revision 519.
  • Revision ID: jelmer@samba.org-20080629154730-xfsotoxwkiytf0ph
Pass graph object rather than full repository to linegraph.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007, 2008 John Arbash Meinel <john@arbash-meinel.com>
 
1
# Copyright (C) 2007 John Arbash Meinel <john@arbash-meinel.com>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
 
19
19
import os
20
20
 
21
 
from gi.repository import Gtk
 
21
import gtk
22
22
 
23
23
from bzrlib import (
24
 
    branch,
25
24
    tests,
26
 
    uncommit,
 
25
    revision,
27
26
    )
28
 
try:
29
 
    from bzrlib.tests.features import UnicodeFilenameFeature
30
 
except ImportError: # bzr < 2.5
31
 
    from bzrlib.tests import UnicodeFilenameFeature
32
 
from bzrlib import bencode
 
27
from bzrlib.util import bencode
33
28
 
34
 
from bzrlib.plugins.gtk import (
35
 
    commit,
36
 
    commitmsgs,
37
 
    )
38
 
from bzrlib.plugins.gtk.commitmsgs import SavedCommitMessagesManager
 
29
from bzrlib.plugins.gtk import commit
39
30
 
40
31
 
41
32
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
47
38
        tree = self.make_branch_and_tree('.')
48
39
        tree.commit('one')
49
40
 
50
 
        self.addCleanup(tree.lock_read().unlock)
51
41
        self.assertIs(None, commit.pending_revisions(tree))
52
42
 
53
43
    def test_pending_revisions_simple(self):
58
48
        tree.merge_from_branch(tree2.branch)
59
49
        self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
60
50
 
61
 
        self.addCleanup(tree.lock_read().unlock)
62
51
        pending_revisions = commit.pending_revisions(tree)
63
52
        # One primary merge
64
53
        self.assertEqual(1, len(pending_revisions))
77
66
        tree.merge_from_branch(tree2.branch)
78
67
        self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
79
68
 
80
 
        self.addCleanup(tree.lock_read().unlock)
81
69
        pending_revisions = commit.pending_revisions(tree)
82
70
        # One primary merge
83
71
        self.assertEqual(1, len(pending_revisions))
98
86
        rev_id4 = tree3.commit('four')
99
87
        rev_id5 = tree3.commit('five')
100
88
        tree.merge_from_branch(tree2.branch)
101
 
        tree.merge_from_branch(tree3.branch, force=True)
 
89
        tree.merge_from_branch(tree3.branch)
102
90
        self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
103
91
 
104
 
        self.addCleanup(tree.lock_read().unlock)
105
92
        pending_revisions = commit.pending_revisions(tree)
106
93
        # Two primary merges
107
94
        self.assertEqual(2, len(pending_revisions))
143
130
        pass # With no widgets, there are no widgets to fill out
144
131
 
145
132
 
146
 
class MockMethod():
147
 
 
148
 
    @classmethod
149
 
    def bind(klass, test_instance, obj, method_name):
150
 
        original_method = getattr(obj, method_name)
151
 
        test_instance.addCleanup(setattr, obj, method_name, original_method)
152
 
        setattr(obj, method_name, klass())
153
 
 
154
 
    def __init__(self):
155
 
        self.called = False
156
 
        self.args = None
157
 
        self.kwargs = None
158
 
 
159
 
    def __call__(self, *args, **kwargs):
160
 
        self.called = True
161
 
        self.args = args
162
 
        self.kwargs = kwargs
163
 
 
164
 
 
165
133
class TestCommitDialogSimple(tests.TestCaseWithTransport):
166
134
 
167
 
    def test_init(self):
168
 
        MockMethod.bind(self, CommitDialogNoWidgets, 'setup_params')
169
 
        MockMethod.bind(self, CommitDialogNoWidgets, 'construct')
170
 
        MockMethod.bind(self, CommitDialogNoWidgets, 'fill_in_data')
171
 
 
172
 
        tree = self.make_branch_and_tree('tree')
173
 
        rev_id = tree.commit('first')
174
 
        dlg = CommitDialogNoWidgets(tree)
175
 
        self.assertIs(tree, dlg._wt)
176
 
        self.assertIs(None, dlg._selected)
177
 
        self.assertTrue(dlg._enable_per_file_commits)
178
 
        self.assertTrue(dlg._commit_all_changes)
179
 
        self.assertIs(None, dlg.committed_revision_id)
180
 
        self.assertIs(None, dlg._last_selected_file)
181
 
        self.assertIsInstance(
182
 
            dlg._saved_commit_messages_manager, SavedCommitMessagesManager)
183
 
        self.assertTrue(CommitDialogNoWidgets.setup_params.called)
184
 
        self.assertTrue(CommitDialogNoWidgets.construct.called)
185
 
        self.assertTrue(CommitDialogNoWidgets.fill_in_data.called)
186
 
 
187
135
    def test_setup_parameters_no_pending(self):
188
136
        tree = self.make_branch_and_tree('tree')
189
137
        rev_id = tree.commit('first')
232
180
        self.assertEqual([], delta.removed)
233
181
        self.assertEqual([(u'a', 'a-id', 'file')], delta.added)
234
182
 
235
 
    def test_on_treeview_files_cursor_changed_no_selection(self):
236
 
        MockMethod.bind(self, CommitDialogNoWidgets, '_update_per_file_info')
237
 
        tree = self.make_branch_and_tree('tree')
238
 
        rev_id = tree.commit('first')
239
 
        dlg = CommitDialogNoWidgets(tree)
240
 
        treeview = Gtk.TreeView()
241
 
        dlg._on_treeview_files_cursor_changed(treeview)
242
 
        self.assertFalse(CommitDialogNoWidgets._update_per_file_info.called)
243
 
 
244
 
    def test_on_treeview_files_cursor_changed_with_destroyed_treeview(self):
245
 
        MockMethod.bind(self, CommitDialogNoWidgets, '_update_per_file_info')
246
 
        tree = self.make_branch_and_tree('tree')
247
 
        rev_id = tree.commit('first')
248
 
        dlg = CommitDialogNoWidgets(tree)
249
 
        treeview = Gtk.TreeView()
250
 
        treeview.destroy()
251
 
        dlg._on_treeview_files_cursor_changed(treeview)
252
 
        self.assertFalse(CommitDialogNoWidgets._update_per_file_info.called)
253
 
 
254
183
 
255
184
class TestCommitDialog(tests.TestCaseWithTransport):
256
185
 
278
207
 
279
208
        commit_col = dlg._treeview_files.get_column(0)
280
209
        self.assertEqual('Commit', commit_col.get_title())
281
 
        renderer = commit_col.get_cells()[0]
 
210
        renderer = commit_col.get_cell_renderers()[0]
282
211
        self.assertTrue(renderer.get_property('activatable'))
283
212
 
284
213
        self.assertEqual('Commit all changes',
303
232
 
304
233
        commit_col = dlg._treeview_files.get_column(0)
305
234
        self.assertEqual('Commit*', commit_col.get_title())
306
 
        renderer = commit_col.get_cells()[0]
 
235
        renderer = commit_col.get_cell_renderers()[0]
307
236
        self.assertFalse(renderer.get_property('activatable'))
308
237
 
309
238
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
337
266
                               committer='Jerry Foo <jerry@foo.com>',
338
267
                               timestamp=1191372278.05,
339
268
                               timezone=+7200)
340
 
        tree.merge_from_branch(tree3.branch, force=True)
 
269
        tree.merge_from_branch(tree3.branch)
341
270
 
342
271
        dlg = commit.CommitDialog(tree)
343
272
        # TODO: assert that the pending box is set to show
355
284
 
356
285
        dlg = commit.CommitDialog(tree)
357
286
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
358
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
287
        self.assertEqual([(None, None, True, 'All Files', ''),
359
288
                          ('a-id', 'a', True, 'a', 'added'),
360
289
                          ('b-id', 'b', True, 'b/', 'added'),
361
290
                          ('c-id', 'b/c', True, 'b/c', 'added'),
372
301
 
373
302
        dlg = commit.CommitDialog(tree)
374
303
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
375
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
304
        self.assertEqual([(None, None, True, 'All Files', ''),
376
305
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
377
306
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
378
307
                         ], values)
387
316
 
388
317
        dlg = commit.CommitDialog(tree)
389
318
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
390
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
319
        self.assertEqual([(None, None, True, 'All Files', ''),
391
320
                          ('a-id', 'a', True, 'a', 'modified'),
392
321
                         ], values)
393
322
 
407
336
 
408
337
        dlg = commit.CommitDialog(tree)
409
338
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
410
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
339
        self.assertEqual([(None, None, True, 'All Files', ''),
411
340
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
412
341
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
413
342
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
430
359
 
431
360
        dlg = commit.CommitDialog(tree)
432
361
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
433
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
362
        self.assertEqual([(None, None, True, 'All Files', ''),
434
363
                          ('a-id', 'a', True, 'a => a/', 'kind changed'),
435
364
                          # ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
436
365
                         ], values)
446
375
 
447
376
        dlg = commit.CommitDialog(tree)
448
377
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
449
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
378
        self.assertEqual([(None, None, True, 'All Files', ''),
450
379
                          ('a-id', 'a', True, 'a', 'removed'),
451
380
                          ('b-id', 'b', True, 'b/', 'removed'),
452
381
                         ], values)
453
382
        # All Files should be selected
454
 
        self.assertEqual(
455
 
            (Gtk.TreePath(path=0), None), dlg._treeview_files.get_cursor())
 
383
        self.assertEqual(((0,), None), dlg._treeview_files.get_cursor())
456
384
 
457
385
    def test_filelist_with_selected(self):
458
386
        tree = self.make_branch_and_tree('tree')
461
389
 
462
390
        dlg = commit.CommitDialog(tree, selected='a')
463
391
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
464
 
        self.assertEqual([("", "", False, 'All Files', ''),
 
392
        self.assertEqual([(None, None, False, 'All Files', ''),
465
393
                          ('a-id', 'a', True, 'a', 'added'),
466
394
                          ('b-id', 'b', False, 'b/', 'added'),
467
395
                         ], values)
468
396
        # This file should also be selected in the file list, rather than the
469
397
        # 'All Files' selection
470
 
        self.assertEqual(
471
 
            (Gtk.TreePath(path=1), None), dlg._treeview_files.get_cursor())
 
398
        self.assertEqual(((1,), None), dlg._treeview_files.get_cursor())
472
399
 
473
400
    def test_diff_view(self):
474
401
        tree = self.make_branch_and_tree('tree')
482
409
        dlg = commit.CommitDialog(tree)
483
410
        diff_buffer = dlg._diff_view.buffer
484
411
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
485
 
                                    diff_buffer.get_end_iter(),
486
 
                                    True).splitlines(True)
 
412
                                    diff_buffer.get_end_iter()).splitlines(True)
487
413
 
488
414
        self.assertEqual("=== modified file 'a'\n", text[0])
489
415
        self.assertContainsRe(text[1],
534
460
        self.assertFalse(dlg._file_message_expander.get_expanded())
535
461
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
536
462
 
537
 
        dlg._treeview_files.set_cursor(
538
 
            Gtk.TreePath(path=1), None, False)
 
463
        dlg._treeview_files.set_cursor((1,))
539
464
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
540
465
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
541
 
                                    diff_buffer.get_end_iter(),
542
 
                                    True).splitlines(True)
 
466
                                    diff_buffer.get_end_iter()).splitlines(True)
543
467
        self.assertEqual("=== added file 'a'\n", text[0])
544
468
        self.assertContainsRe(text[1],
545
469
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
553
477
        self.assertTrue(dlg._file_message_expander.get_expanded())
554
478
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
555
479
 
556
 
        dlg._treeview_files.set_cursor(
557
 
            Gtk.TreePath(path=2), None, False)
 
480
        dlg._treeview_files.set_cursor((2,))
558
481
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
559
482
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
560
 
                                    diff_buffer.get_end_iter(),
561
 
                                    True).splitlines(True)
 
483
                                    diff_buffer.get_end_iter()).splitlines(True)
562
484
        self.assertEqual("=== added file 'b'\n", text[0])
563
485
        self.assertContainsRe(text[1],
564
486
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
572
494
        self.assertTrue(dlg._file_message_expander.get_expanded())
573
495
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
574
496
 
575
 
        dlg._treeview_files.set_cursor(
576
 
            Gtk.TreePath(path=0), None, False)
 
497
        dlg._treeview_files.set_cursor((0,))
577
498
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
578
499
        self.assertEqual('File commit message',
579
500
                         dlg._file_message_expander.get_label())
589
510
 
590
511
        def get_file_text():
591
512
            buf = dlg._file_message_text_view.get_buffer()
592
 
            return buf.get_text(
593
 
                buf.get_start_iter(), buf.get_end_iter(), True)
 
513
            return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
594
514
 
595
515
        def get_saved_text(path):
596
516
            """Get the saved text for a given record."""
603
523
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
604
524
        self.assertEqual('', get_file_text())
605
525
 
606
 
        dlg._treeview_files.set_cursor(
607
 
            Gtk.TreePath(path=1), None, False)
 
526
        dlg._treeview_files.set_cursor((1,))
608
527
        self.assertEqual('Commit message for a',
609
528
                         dlg._file_message_expander.get_label())
610
529
        self.assertTrue(dlg._file_message_expander.get_expanded())
617
536
        # We should have updated the ListStore with the new file commit info
618
537
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
619
538
 
620
 
        dlg._treeview_files.set_cursor(
621
 
            Gtk.TreePath(path=2), None, False)
 
539
        dlg._treeview_files.set_cursor((2,))
622
540
        self.assertEqual('Commit message for b/',
623
541
                         dlg._file_message_expander.get_label())
624
542
        self.assertTrue(dlg._file_message_expander.get_expanded())
629
547
        dlg._set_file_commit_message('More text\nfor b\n')
630
548
        # Now switch back to 'a'. The message should be saved, and the buffer
631
549
        # should be updated with the other text
632
 
        dlg._treeview_files.set_cursor(
633
 
            Gtk.TreePath(path=1), None, False)
 
550
        dlg._treeview_files.set_cursor((1,))
634
551
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
635
552
        self.assertEqual('Commit message for a',
636
553
                         dlg._file_message_expander.get_label())
645
562
        tree.add(['a', 'b'], ['a-id', 'b-id'])
646
563
 
647
564
        dlg = commit.CommitDialog(tree)
648
 
        self.assertEqual([("", "", True),
 
565
        self.assertEqual([(None, None, True),
649
566
                          ('a-id', 'a', True),
650
567
                          ('b-id', 'b', True),
651
568
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
656
573
        #       do with. So instead, we just call toggle directly, and assume
657
574
        #       that toggle is hooked in correctly
658
575
        # column = dlg._treeview_files.get_column(0)
659
 
        # renderer = column.get_cells()[0]
 
576
        # renderer = column.get_cell_renderers()[0]
660
577
 
661
578
        # Toggle a single entry should set just that entry to False
662
579
        dlg._toggle_commit(None, 1, dlg._files_store)
663
 
        self.assertEqual([("", "", True),
 
580
        self.assertEqual([(None, None, True),
664
581
                          ('a-id', 'a', False),
665
582
                          ('b-id', 'b', True),
666
583
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
667
584
 
668
585
        # Toggling the main entry should set all entries
669
586
        dlg._toggle_commit(None, 0, dlg._files_store)
670
 
        self.assertEqual([("", "", False),
 
587
        self.assertEqual([(None, None, False),
671
588
                          ('a-id', 'a', False),
672
589
                          ('b-id', 'b', False),
673
590
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
674
591
 
675
592
        dlg._toggle_commit(None, 2, dlg._files_store)
676
 
        self.assertEqual([("", "", False),
 
593
        self.assertEqual([(None, None, False),
677
594
                          ('a-id', 'a', False),
678
595
                          ('b-id', 'b', True),
679
596
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
680
597
 
681
598
        dlg._toggle_commit(None, 0, dlg._files_store)
682
 
        self.assertEqual([("", "", True),
 
599
        self.assertEqual([(None, None, True),
683
600
                          ('a-id', 'a', True),
684
601
                          ('b-id', 'b', True),
685
602
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
709
626
        dlg._commit_selected_radio.set_active(True)
710
627
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
711
628
 
712
 
        dlg._treeview_files.set_cursor(
713
 
            Gtk.TreePath(path=1), None, False)
 
629
        dlg._treeview_files.set_cursor((1,))
714
630
        dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
715
 
        dlg._treeview_files.set_cursor(
716
 
            Gtk.TreePath(path=2), None, False)
 
631
        dlg._treeview_files.set_cursor((2,))
717
632
        dlg._set_file_commit_message('message\nfor b_dir\n')
718
633
 
719
634
        self.assertEqual((['a_file', 'b_dir'],
729
644
                            'message':'message\nfor b_dir\n'},
730
645
                          ]), dlg._get_specific_files())
731
646
 
732
 
    def test_specific_files_sanitizes_messages(self):
733
 
        tree = self.make_branch_and_tree('tree')
734
 
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
735
 
        self.build_tree(['tree/a_file', 'tree/b_dir/'])
736
 
        tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
737
 
 
738
 
        dlg = commit.CommitDialog(tree)
739
 
        dlg._commit_selected_radio.set_active(True)
740
 
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
741
 
 
742
 
        dlg._treeview_files.set_cursor(
743
 
            Gtk.TreePath(path=1), None, False)
744
 
        dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
745
 
        dlg._treeview_files.set_cursor(
746
 
            Gtk.TreePath(path=2), None, False)
747
 
        dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
748
 
 
749
 
        self.assertEqual((['a_file', 'b_dir'],
750
 
                          [{'path':'a_file', 'file_id':'1a-id',
751
 
                            'message':'Test\nmessage\nfor a_file\n'},
752
 
                           {'path':'b_dir', 'file_id':'0b-id',
753
 
                            'message':'message\nfor\nb_dir\n'},
754
 
                          ]), dlg._get_specific_files())
755
 
 
756
 
 
757
 
class QuestionHelpers(object):
 
647
 
 
648
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
 
649
    """Tests on the actual 'commit' button being pushed."""
758
650
 
759
651
    def _set_question_yes(self, dlg):
760
652
        """Set the dialog to answer YES to any questions."""
761
653
        self.questions = []
762
 
        def _question_yes(*args, **kwargs):
 
654
        def _question_yes(*args):
763
655
            self.questions.append(args)
764
656
            self.questions.append('YES')
765
 
            return Gtk.ResponseType.YES
 
657
            return gtk.RESPONSE_YES
766
658
        dlg._question_dialog = _question_yes
767
659
 
768
660
    def _set_question_no(self, dlg):
769
661
        """Set the dialog to answer NO to any questions."""
770
662
        self.questions = []
771
 
        def _question_no(*args, **kwargs):
 
663
        def _question_no(*args):
772
664
            self.questions.append(args)
773
665
            self.questions.append('NO')
774
 
            return Gtk.ResponseType.NO
 
666
            return gtk.RESPONSE_NO
775
667
        dlg._question_dialog = _question_no
776
668
 
777
 
 
778
 
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
779
 
    """Tests on the actual 'commit' button being pushed."""
780
 
 
781
669
    def test_bound_commit_local(self):
782
670
        tree = self.make_branch_and_tree('tree')
783
671
        self.build_tree(['tree/a'])
799
687
        self.assertEqual(last_rev, dlg.committed_revision_id)
800
688
        self.assertEqual(rev_id1, tree.branch.last_revision())
801
689
 
802
 
    def test_commit_global_sanitizes_message(self):
803
 
        tree = self.make_branch_and_tree('tree')
804
 
        self.build_tree(['tree/a'])
805
 
        tree.add(['a'], ['a-id'])
806
 
        rev_id1 = tree.commit('one')
807
 
 
808
 
        self.build_tree(['tree/b'])
809
 
        tree.add(['b'], ['b-id'])
810
 
        dlg = commit.CommitDialog(tree)
811
 
        # With the check box set, it should only effect the local branch
812
 
        dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
813
 
        dlg._do_commit()
814
 
        rev = tree.branch.repository.get_revision(tree.last_revision())
815
 
        self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
816
 
 
817
690
    def test_bound_commit_both(self):
818
691
        tree = self.make_branch_and_tree('tree')
819
692
        self.build_tree(['tree/a'])
835
708
        self.assertEqual(last_rev, dlg.committed_revision_id)
836
709
        self.assertEqual(last_rev, tree.branch.last_revision())
837
710
 
838
 
    def test_commit_empty_message(self):
 
711
    def test_commit_no_message(self):
839
712
        tree = self.make_branch_and_tree('tree')
840
713
        self.build_tree(['tree/a', 'tree/b'])
841
714
        tree.add(['a'], ['a-id'])
1056
929
 
1057
930
        dlg = commit.CommitDialog(tree)
1058
931
        dlg._commit_selected_radio.set_active(True) # enable partial
1059
 
        dlg._treeview_files.set_cursor(
1060
 
            Gtk.TreePath(path=1), None, False)
 
932
        dlg._treeview_files.set_cursor((1,))
1061
933
        dlg._set_file_commit_message('Message for A\n')
1062
 
        dlg._treeview_files.set_cursor(
1063
 
            Gtk.TreePath(path=2), None, False)
 
934
        dlg._treeview_files.set_cursor((2,))
1064
935
        dlg._set_file_commit_message('Message for B\n')
1065
936
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
1066
937
        dlg._set_global_commit_message('Commit just "a"')
1072
943
        rev = tree.branch.repository.get_revision(rev_id2)
1073
944
        self.assertEqual('Commit just "a"', rev.message)
1074
945
        file_info = rev.properties['file-info']
1075
 
        self.assertEqual(u'ld7:file_id4:a-id'
1076
 
                         '7:message14:Message for A\n'
1077
 
                         '4:path1:a'
1078
 
                         'ee',
1079
 
                         file_info)
 
946
        self.assertEqual('ld7:file_id4:a-id'
 
947
                           '7:message14:Message for A\n'
 
948
                           '4:path1:a'
 
949
                         'ee', file_info)
1080
950
        self.assertEqual([{'path':'a', 'file_id':'a-id',
1081
 
                           'message':'Message for A\n'},],
1082
 
                         bencode.bdecode(file_info.encode('UTF-8')))
 
951
                           'message':'Message for A\n'},
 
952
                         ], bencode.bdecode(file_info))
1083
953
 
1084
954
    def test_commit_messages_after_merge(self):
1085
955
        tree = self.make_branch_and_tree('tree')
1093
963
        tree.merge_from_branch(tree2.branch)
1094
964
 
1095
965
        dlg = commit.CommitDialog(tree)
1096
 
        dlg._treeview_files.set_cursor(
1097
 
            Gtk.TreePath(path=1), None, False) # 'a'
 
966
        dlg._treeview_files.set_cursor((1,)) # 'a'
1098
967
        dlg._set_file_commit_message('Message for A\n')
1099
968
        # No message for 'B'
1100
969
        dlg._set_global_commit_message('Merging from "tree2"\n')
1107
976
        self.assertEqual('Merging from "tree2"\n', rev.message)
1108
977
        self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
1109
978
        file_info = rev.properties['file-info']
1110
 
        self.assertEqual(u'ld7:file_id4:a-id'
1111
 
                         '7:message14:Message for A\n'
1112
 
                         '4:path1:a'
1113
 
                         'ee',
1114
 
                         file_info)
 
979
        self.assertEqual('ld7:file_id4:a-id'
 
980
                           '7:message14:Message for A\n'
 
981
                           '4:path1:a'
 
982
                         'ee', file_info)
1115
983
        self.assertEqual([{'path':'a', 'file_id':'a-id',
1116
 
                           'message':'Message for A\n'},],
1117
 
                         bencode.bdecode(file_info.encode('UTF-8')))
 
984
                           'message':'Message for A\n'},
 
985
                         ], bencode.bdecode(file_info))
1118
986
 
1119
987
    def test_commit_unicode_messages(self):
1120
 
        self.requireFeature(UnicodeFilenameFeature)
 
988
        self.requireFeature(tests.UnicodeFilenameFeature)
1121
989
 
1122
990
        tree = self.make_branch_and_tree('tree')
1123
991
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
1125
993
        tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
1126
994
 
1127
995
        dlg = commit.CommitDialog(tree)
1128
 
        dlg._treeview_files.set_cursor(
1129
 
            Gtk.TreePath(path=1), None, False) # 'a'
 
996
        dlg._treeview_files.set_cursor((1,)) # 'a'
1130
997
        dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
1131
 
        dlg._treeview_files.set_cursor(
1132
 
            Gtk.TreePath(path=2), None, False) # omega
 
998
        dlg._treeview_files.set_cursor((2,)) # omega
1133
999
        dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1134
1000
        dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1135
1001
 
1164
1030
                          {'path':u'\u03a9', 'file_id':'omega-id',
1165
1031
                           'message':u'\u03a9 is the end of all things.\n'},
1166
1032
                         ], file_info_decoded)
1167
 
 
1168
 
 
1169
 
class TestSanitizeMessage(tests.TestCase):
1170
 
 
1171
 
    def assertSanitize(self, expected, original):
1172
 
        self.assertEqual(expected,
1173
 
                         commit._sanitize_and_decode_message(original))
1174
 
 
1175
 
    def test_untouched(self):
1176
 
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
1177
 
 
1178
 
    def test_converts_cr_to_lf(self):
1179
 
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
1180
 
 
1181
 
    def test_converts_crlf_to_lf(self):
1182
 
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
1183
 
 
1184
 
    def test_converts_mixed_to_lf(self):
1185
 
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
1186
 
 
1187
 
 
1188
 
class TestSavedCommitMessages(tests.TestCaseWithTransport):
1189
 
 
1190
 
    def setUp(self):
1191
 
        super(TestSavedCommitMessages, self).setUp()
1192
 
        # Install our hook
1193
 
        branch.Branch.hooks.install_named_hook(
1194
 
            'post_uncommit', commitmsgs.save_commit_messages, None)
1195
 
 
1196
 
    def _get_file_info_dict(self, rank):
1197
 
        file_info = [dict(path='a', file_id='a-id', message='a msg %d' % rank),
1198
 
                     dict(path='b', file_id='b-id', message='b msg %d' % rank)]
1199
 
        return file_info
1200
 
 
1201
 
    def _get_file_info_revprops(self, rank):
1202
 
        file_info_prop = self._get_file_info_dict(rank)
1203
 
        return {'file-info': bencode.bencode(file_info_prop).decode('UTF-8')}
1204
 
 
1205
 
    def _get_commit_message(self):
1206
 
        return self.config.get_user_option('gtk_global_commit_message')
1207
 
 
1208
 
    def _get_file_commit_messages(self):
1209
 
        return self.config.get_user_option('gtk_file_commit_messages')
1210
 
 
1211
 
 
1212
 
class TestUncommitHook(TestSavedCommitMessages):
1213
 
 
1214
 
    def setUp(self):
1215
 
        super(TestUncommitHook, self).setUp()
1216
 
        self.tree = self.make_branch_and_tree('tree')
1217
 
        self.config = self.tree.branch.get_config()
1218
 
        self.build_tree(['tree/a', 'tree/b'])
1219
 
        self.tree.add(['a'], ['a-id'])
1220
 
        self.tree.add(['b'], ['b-id'])
1221
 
        rev1 = self.tree.commit('one', rev_id='one-id',
1222
 
                                revprops=self._get_file_info_revprops(1))
1223
 
        rev2 = self.tree.commit('two', rev_id='two-id',
1224
 
                                revprops=self._get_file_info_revprops(2))
1225
 
        rev3 = self.tree.commit('three', rev_id='three-id',
1226
 
                                revprops=self._get_file_info_revprops(3))
1227
 
 
1228
 
    def test_uncommit_one_by_one(self):
1229
 
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1230
 
        self.assertEquals(u'three', self._get_commit_message())
1231
 
        self.assertEquals(u'd4:a-id7:a msg 34:b-id7:b msg 3e',
1232
 
                          self._get_file_commit_messages())
1233
 
 
1234
 
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1235
 
        self.assertEquals(u'two\n******\nthree', self._get_commit_message())
1236
 
        self.assertEquals(u'd4:a-id22:a msg 2\n******\na msg 3'
1237
 
                          '4:b-id22:b msg 2\n******\nb msg 3e',
1238
 
                          self._get_file_commit_messages())
1239
 
 
1240
 
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1241
 
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
1242
 
                          self._get_commit_message())
1243
 
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
1244
 
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
1245
 
                          self._get_file_commit_messages())
1246
 
 
1247
 
    def test_uncommit_all_at_once(self):
1248
 
        uncommit.uncommit(self.tree.branch, tree=self.tree, revno=1)
1249
 
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
1250
 
                          self._get_commit_message())
1251
 
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
1252
 
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
1253
 
                          self._get_file_commit_messages())
1254
 
 
1255
 
 
1256
 
class TestReusingSavedCommitMessages(TestSavedCommitMessages, QuestionHelpers):
1257
 
 
1258
 
    def setUp(self):
1259
 
        super(TestReusingSavedCommitMessages, self).setUp()
1260
 
        self.tree = self.make_branch_and_tree('tree')
1261
 
        self.config = self.tree.branch.get_config()
1262
 
        self.config.set_user_option('per_file_commits', 'true')
1263
 
        self.build_tree(['tree/a', 'tree/b'])
1264
 
        self.tree.add(['a'], ['a-id'])
1265
 
        self.tree.add(['b'], ['b-id'])
1266
 
        rev1 = self.tree.commit('one', revprops=self._get_file_info_revprops(1))
1267
 
        rev2 = self.tree.commit('two', revprops=self._get_file_info_revprops(2))
1268
 
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1269
 
        self.build_tree_contents([('tree/a', 'new a content\n'),
1270
 
                                  ('tree/b', 'new b content'),])
1271
 
 
1272
 
    def _get_commit_dialog(self, tree):
1273
 
        # Ensure we will never use a dialog that can actually prompt the user
1274
 
        # during the test suite. Test *can* and *should* override with the
1275
 
        # correct question dialog type.
1276
 
        dlg = commit.CommitDialog(tree)
1277
 
        self._set_question_no(dlg)
1278
 
        return dlg
1279
 
 
1280
 
    def test_setup_saved_messages(self):
1281
 
        # Check the initial setup
1282
 
        self.assertEquals(u'two', self._get_commit_message())
1283
 
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
1284
 
                          self._get_file_commit_messages())
1285
 
 
1286
 
    def test_messages_are_reloaded(self):
1287
 
        dlg = self._get_commit_dialog(self.tree)
1288
 
        self.assertEquals(u'two', dlg._get_global_commit_message())
1289
 
        self.assertEquals(([u'a', u'b'],
1290
 
                           [{ 'path': 'a',
1291
 
                             'file_id': 'a-id', 'message': 'a msg 2',},
1292
 
                           {'path': 'b',
1293
 
                            'file_id': 'b-id', 'message': 'b msg 2',}],),
1294
 
                          dlg._get_specific_files())
1295
 
 
1296
 
    def test_messages_are_consumed(self):
1297
 
        dlg = self._get_commit_dialog(self.tree)
1298
 
        dlg._do_commit()
1299
 
        self.assertEquals(u'', self._get_commit_message())
1300
 
        self.assertEquals(u'de', self._get_file_commit_messages())
1301
 
 
1302
 
    def test_messages_are_saved_on_cancel_if_required(self):
1303
 
        dlg = self._get_commit_dialog(self.tree)
1304
 
        self._set_question_yes(dlg) # Save messages
1305
 
        dlg._do_cancel()
1306
 
        self.assertEquals(u'two', self._get_commit_message())
1307
 
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
1308
 
                          self._get_file_commit_messages())
1309
 
 
1310
 
    def test_messages_are_cleared_on_cancel_if_required(self):
1311
 
        dlg = self._get_commit_dialog(self.tree)
1312
 
        self._set_question_no(dlg) # Don't save messages
1313
 
        dlg._do_cancel()
1314
 
        self.assertEquals(u'', self._get_commit_message())
1315
 
        self.assertEquals(u'de',
1316
 
                          self._get_file_commit_messages())