/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: Curtis Hovey
  • Date: 2012-02-03 18:08:07 UTC
  • mto: This revision was merged to the branch mainline in revision 773.
  • Revision ID: sinzui.is@verizon.net-20120203180807-jwo9vrbafie4a730
Return early if the widget is being destroyed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 John Arbash Meinel <john@arbash-meinel.com>
 
1
# Copyright (C) 2007, 2008 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
 
import gtk
 
21
from gi.repository import Gtk
22
22
 
23
23
from bzrlib import (
 
24
    branch,
24
25
    tests,
25
 
    revision,
 
26
    uncommit,
26
27
    )
27
 
from bzrlib.util import bencode
 
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
28
33
 
29
 
from bzrlib.plugins.gtk import commit
 
34
from bzrlib.plugins.gtk import (
 
35
    commit,
 
36
    commitmsgs,
 
37
    )
 
38
from bzrlib.plugins.gtk.commitmsgs import SavedCommitMessagesManager
 
39
from bzrlib.plugins.gtk.tests import MockMethod
30
40
 
31
41
 
32
42
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
38
48
        tree = self.make_branch_and_tree('.')
39
49
        tree.commit('one')
40
50
 
 
51
        self.addCleanup(tree.lock_read().unlock)
41
52
        self.assertIs(None, commit.pending_revisions(tree))
42
53
 
43
54
    def test_pending_revisions_simple(self):
48
59
        tree.merge_from_branch(tree2.branch)
49
60
        self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
50
61
 
 
62
        self.addCleanup(tree.lock_read().unlock)
51
63
        pending_revisions = commit.pending_revisions(tree)
52
64
        # One primary merge
53
65
        self.assertEqual(1, len(pending_revisions))
66
78
        tree.merge_from_branch(tree2.branch)
67
79
        self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
68
80
 
 
81
        self.addCleanup(tree.lock_read().unlock)
69
82
        pending_revisions = commit.pending_revisions(tree)
70
83
        # One primary merge
71
84
        self.assertEqual(1, len(pending_revisions))
86
99
        rev_id4 = tree3.commit('four')
87
100
        rev_id5 = tree3.commit('five')
88
101
        tree.merge_from_branch(tree2.branch)
89
 
        tree.merge_from_branch(tree3.branch)
 
102
        tree.merge_from_branch(tree3.branch, force=True)
90
103
        self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
91
104
 
 
105
        self.addCleanup(tree.lock_read().unlock)
92
106
        pending_revisions = commit.pending_revisions(tree)
93
107
        # Two primary merges
94
108
        self.assertEqual(2, len(pending_revisions))
132
146
 
133
147
class TestCommitDialogSimple(tests.TestCaseWithTransport):
134
148
 
 
149
    def test_init(self):
 
150
        MockMethod.bind(self, CommitDialogNoWidgets, 'setup_params')
 
151
        MockMethod.bind(self, CommitDialogNoWidgets, 'construct')
 
152
        MockMethod.bind(self, CommitDialogNoWidgets, 'fill_in_data')
 
153
 
 
154
        tree = self.make_branch_and_tree('tree')
 
155
        rev_id = tree.commit('first')
 
156
        dlg = CommitDialogNoWidgets(tree)
 
157
        self.assertIs(tree, dlg._wt)
 
158
        self.assertIs(None, dlg._selected)
 
159
        self.assertTrue(dlg._enable_per_file_commits)
 
160
        self.assertTrue(dlg._commit_all_changes)
 
161
        self.assertIs(None, dlg.committed_revision_id)
 
162
        self.assertIs(None, dlg._last_selected_file)
 
163
        self.assertIsInstance(
 
164
            dlg._saved_commit_messages_manager, SavedCommitMessagesManager)
 
165
        self.assertTrue(CommitDialogNoWidgets.setup_params.called)
 
166
        self.assertTrue(CommitDialogNoWidgets.construct.called)
 
167
        self.assertTrue(CommitDialogNoWidgets.fill_in_data.called)
 
168
 
135
169
    def test_setup_parameters_no_pending(self):
136
170
        tree = self.make_branch_and_tree('tree')
137
171
        rev_id = tree.commit('first')
180
214
        self.assertEqual([], delta.removed)
181
215
        self.assertEqual([(u'a', 'a-id', 'file')], delta.added)
182
216
 
 
217
    def test_on_treeview_files_cursor_changed_no_selection(self):
 
218
        MockMethod.bind(self, CommitDialogNoWidgets, '_update_per_file_info')
 
219
        tree = self.make_branch_and_tree('tree')
 
220
        rev_id = tree.commit('first')
 
221
        dlg = CommitDialogNoWidgets(tree)
 
222
        treeview = Gtk.TreeView()
 
223
        dlg._on_treeview_files_cursor_changed(treeview)
 
224
        self.assertFalse(CommitDialogNoWidgets._update_per_file_info.called)
 
225
 
 
226
    def test_on_treeview_files_cursor_changed_with_destroyed_treeview(self):
 
227
        MockMethod.bind(self, CommitDialogNoWidgets, '_update_per_file_info')
 
228
        tree = self.make_branch_and_tree('tree')
 
229
        rev_id = tree.commit('first')
 
230
        dlg = CommitDialogNoWidgets(tree)
 
231
        treeview = Gtk.TreeView()
 
232
        treeview.destroy()
 
233
        dlg._on_treeview_files_cursor_changed(treeview)
 
234
        self.assertFalse(CommitDialogNoWidgets._update_per_file_info.called)
 
235
 
183
236
 
184
237
class TestCommitDialog(tests.TestCaseWithTransport):
185
238
 
207
260
 
208
261
        commit_col = dlg._treeview_files.get_column(0)
209
262
        self.assertEqual('Commit', commit_col.get_title())
210
 
        renderer = commit_col.get_cell_renderers()[0]
 
263
        renderer = commit_col.get_cells()[0]
211
264
        self.assertTrue(renderer.get_property('activatable'))
212
265
 
213
266
        self.assertEqual('Commit all changes',
232
285
 
233
286
        commit_col = dlg._treeview_files.get_column(0)
234
287
        self.assertEqual('Commit*', commit_col.get_title())
235
 
        renderer = commit_col.get_cell_renderers()[0]
 
288
        renderer = commit_col.get_cells()[0]
236
289
        self.assertFalse(renderer.get_property('activatable'))
237
290
 
238
291
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
266
319
                               committer='Jerry Foo <jerry@foo.com>',
267
320
                               timestamp=1191372278.05,
268
321
                               timezone=+7200)
269
 
        tree.merge_from_branch(tree3.branch)
 
322
        tree.merge_from_branch(tree3.branch, force=True)
270
323
 
271
324
        dlg = commit.CommitDialog(tree)
272
325
        # TODO: assert that the pending box is set to show
284
337
 
285
338
        dlg = commit.CommitDialog(tree)
286
339
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
287
 
        self.assertEqual([(None, None, True, 'All Files', ''),
 
340
        self.assertEqual([("", "", True, 'All Files', ''),
288
341
                          ('a-id', 'a', True, 'a', 'added'),
289
342
                          ('b-id', 'b', True, 'b/', 'added'),
290
343
                          ('c-id', 'b/c', True, 'b/c', 'added'),
301
354
 
302
355
        dlg = commit.CommitDialog(tree)
303
356
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
304
 
        self.assertEqual([(None, None, True, 'All Files', ''),
 
357
        self.assertEqual([("", "", True, 'All Files', ''),
305
358
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
306
359
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
307
360
                         ], values)
316
369
 
317
370
        dlg = commit.CommitDialog(tree)
318
371
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
319
 
        self.assertEqual([(None, None, True, 'All Files', ''),
 
372
        self.assertEqual([("", "", True, 'All Files', ''),
320
373
                          ('a-id', 'a', True, 'a', 'modified'),
321
374
                         ], values)
322
375
 
336
389
 
337
390
        dlg = commit.CommitDialog(tree)
338
391
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
339
 
        self.assertEqual([(None, None, True, 'All Files', ''),
 
392
        self.assertEqual([("", "", True, 'All Files', ''),
340
393
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
341
394
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
342
395
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
359
412
 
360
413
        dlg = commit.CommitDialog(tree)
361
414
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
362
 
        self.assertEqual([(None, None, True, 'All Files', ''),
 
415
        self.assertEqual([("", "", True, 'All Files', ''),
363
416
                          ('a-id', 'a', True, 'a => a/', 'kind changed'),
364
417
                          # ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
365
418
                         ], values)
375
428
 
376
429
        dlg = commit.CommitDialog(tree)
377
430
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
378
 
        self.assertEqual([(None, None, True, 'All Files', ''),
 
431
        self.assertEqual([("", "", True, 'All Files', ''),
379
432
                          ('a-id', 'a', True, 'a', 'removed'),
380
433
                          ('b-id', 'b', True, 'b/', 'removed'),
381
434
                         ], values)
382
435
        # All Files should be selected
383
 
        self.assertEqual(((0,), None), dlg._treeview_files.get_cursor())
 
436
        self.assertEqual(
 
437
            (Gtk.TreePath(path=0), None), dlg._treeview_files.get_cursor())
384
438
 
385
439
    def test_filelist_with_selected(self):
386
440
        tree = self.make_branch_and_tree('tree')
389
443
 
390
444
        dlg = commit.CommitDialog(tree, selected='a')
391
445
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
392
 
        self.assertEqual([(None, None, False, 'All Files', ''),
 
446
        self.assertEqual([("", "", False, 'All Files', ''),
393
447
                          ('a-id', 'a', True, 'a', 'added'),
394
448
                          ('b-id', 'b', False, 'b/', 'added'),
395
449
                         ], values)
396
450
        # This file should also be selected in the file list, rather than the
397
451
        # 'All Files' selection
398
 
        self.assertEqual(((1,), None), dlg._treeview_files.get_cursor())
 
452
        self.assertEqual(
 
453
            (Gtk.TreePath(path=1), None), dlg._treeview_files.get_cursor())
399
454
 
400
455
    def test_diff_view(self):
401
456
        tree = self.make_branch_and_tree('tree')
409
464
        dlg = commit.CommitDialog(tree)
410
465
        diff_buffer = dlg._diff_view.buffer
411
466
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
412
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
467
                                    diff_buffer.get_end_iter(),
 
468
                                    True).splitlines(True)
413
469
 
414
470
        self.assertEqual("=== modified file 'a'\n", text[0])
415
471
        self.assertContainsRe(text[1],
460
516
        self.assertFalse(dlg._file_message_expander.get_expanded())
461
517
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
462
518
 
463
 
        dlg._treeview_files.set_cursor((1,))
 
519
        dlg._treeview_files.set_cursor(
 
520
            Gtk.TreePath(path=1), None, False)
464
521
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
465
522
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
466
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
523
                                    diff_buffer.get_end_iter(),
 
524
                                    True).splitlines(True)
467
525
        self.assertEqual("=== added file 'a'\n", text[0])
468
526
        self.assertContainsRe(text[1],
469
527
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
477
535
        self.assertTrue(dlg._file_message_expander.get_expanded())
478
536
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
479
537
 
480
 
        dlg._treeview_files.set_cursor((2,))
 
538
        dlg._treeview_files.set_cursor(
 
539
            Gtk.TreePath(path=2), None, False)
481
540
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
482
541
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
483
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
542
                                    diff_buffer.get_end_iter(),
 
543
                                    True).splitlines(True)
484
544
        self.assertEqual("=== added file 'b'\n", text[0])
485
545
        self.assertContainsRe(text[1],
486
546
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
494
554
        self.assertTrue(dlg._file_message_expander.get_expanded())
495
555
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
496
556
 
497
 
        dlg._treeview_files.set_cursor((0,))
 
557
        dlg._treeview_files.set_cursor(
 
558
            Gtk.TreePath(path=0), None, False)
498
559
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
499
560
        self.assertEqual('File commit message',
500
561
                         dlg._file_message_expander.get_label())
510
571
 
511
572
        def get_file_text():
512
573
            buf = dlg._file_message_text_view.get_buffer()
513
 
            return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
 
574
            return buf.get_text(
 
575
                buf.get_start_iter(), buf.get_end_iter(), True)
514
576
 
515
577
        def get_saved_text(path):
516
578
            """Get the saved text for a given record."""
523
585
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
524
586
        self.assertEqual('', get_file_text())
525
587
 
526
 
        dlg._treeview_files.set_cursor((1,))
 
588
        dlg._treeview_files.set_cursor(
 
589
            Gtk.TreePath(path=1), None, False)
527
590
        self.assertEqual('Commit message for a',
528
591
                         dlg._file_message_expander.get_label())
529
592
        self.assertTrue(dlg._file_message_expander.get_expanded())
536
599
        # We should have updated the ListStore with the new file commit info
537
600
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
538
601
 
539
 
        dlg._treeview_files.set_cursor((2,))
 
602
        dlg._treeview_files.set_cursor(
 
603
            Gtk.TreePath(path=2), None, False)
540
604
        self.assertEqual('Commit message for b/',
541
605
                         dlg._file_message_expander.get_label())
542
606
        self.assertTrue(dlg._file_message_expander.get_expanded())
547
611
        dlg._set_file_commit_message('More text\nfor b\n')
548
612
        # Now switch back to 'a'. The message should be saved, and the buffer
549
613
        # should be updated with the other text
550
 
        dlg._treeview_files.set_cursor((1,))
 
614
        dlg._treeview_files.set_cursor(
 
615
            Gtk.TreePath(path=1), None, False)
551
616
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
552
617
        self.assertEqual('Commit message for a',
553
618
                         dlg._file_message_expander.get_label())
562
627
        tree.add(['a', 'b'], ['a-id', 'b-id'])
563
628
 
564
629
        dlg = commit.CommitDialog(tree)
565
 
        self.assertEqual([(None, None, True),
 
630
        self.assertEqual([("", "", True),
566
631
                          ('a-id', 'a', True),
567
632
                          ('b-id', 'b', True),
568
633
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
573
638
        #       do with. So instead, we just call toggle directly, and assume
574
639
        #       that toggle is hooked in correctly
575
640
        # column = dlg._treeview_files.get_column(0)
576
 
        # renderer = column.get_cell_renderers()[0]
 
641
        # renderer = column.get_cells()[0]
577
642
 
578
643
        # Toggle a single entry should set just that entry to False
579
644
        dlg._toggle_commit(None, 1, dlg._files_store)
580
 
        self.assertEqual([(None, None, True),
 
645
        self.assertEqual([("", "", True),
581
646
                          ('a-id', 'a', False),
582
647
                          ('b-id', 'b', True),
583
648
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
584
649
 
585
650
        # Toggling the main entry should set all entries
586
651
        dlg._toggle_commit(None, 0, dlg._files_store)
587
 
        self.assertEqual([(None, None, False),
 
652
        self.assertEqual([("", "", False),
588
653
                          ('a-id', 'a', False),
589
654
                          ('b-id', 'b', False),
590
655
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
591
656
 
592
657
        dlg._toggle_commit(None, 2, dlg._files_store)
593
 
        self.assertEqual([(None, None, False),
 
658
        self.assertEqual([("", "", False),
594
659
                          ('a-id', 'a', False),
595
660
                          ('b-id', 'b', True),
596
661
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
597
662
 
598
663
        dlg._toggle_commit(None, 0, dlg._files_store)
599
 
        self.assertEqual([(None, None, True),
 
664
        self.assertEqual([("", "", True),
600
665
                          ('a-id', 'a', True),
601
666
                          ('b-id', 'b', True),
602
667
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
626
691
        dlg._commit_selected_radio.set_active(True)
627
692
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
628
693
 
629
 
        dlg._treeview_files.set_cursor((1,))
 
694
        dlg._treeview_files.set_cursor(
 
695
            Gtk.TreePath(path=1), None, False)
630
696
        dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
631
 
        dlg._treeview_files.set_cursor((2,))
 
697
        dlg._treeview_files.set_cursor(
 
698
            Gtk.TreePath(path=2), None, False)
632
699
        dlg._set_file_commit_message('message\nfor b_dir\n')
633
700
 
634
701
        self.assertEqual((['a_file', 'b_dir'],
644
711
                            'message':'message\nfor b_dir\n'},
645
712
                          ]), dlg._get_specific_files())
646
713
 
647
 
 
648
 
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
649
 
    """Tests on the actual 'commit' button being pushed."""
 
714
    def test_specific_files_sanitizes_messages(self):
 
715
        tree = self.make_branch_and_tree('tree')
 
716
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
 
717
        self.build_tree(['tree/a_file', 'tree/b_dir/'])
 
718
        tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
 
719
 
 
720
        dlg = commit.CommitDialog(tree)
 
721
        dlg._commit_selected_radio.set_active(True)
 
722
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
 
723
 
 
724
        dlg._treeview_files.set_cursor(
 
725
            Gtk.TreePath(path=1), None, False)
 
726
        dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
 
727
        dlg._treeview_files.set_cursor(
 
728
            Gtk.TreePath(path=2), None, False)
 
729
        dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
 
730
 
 
731
        self.assertEqual((['a_file', 'b_dir'],
 
732
                          [{'path':'a_file', 'file_id':'1a-id',
 
733
                            'message':'Test\nmessage\nfor a_file\n'},
 
734
                           {'path':'b_dir', 'file_id':'0b-id',
 
735
                            'message':'message\nfor\nb_dir\n'},
 
736
                          ]), dlg._get_specific_files())
 
737
 
 
738
 
 
739
class QuestionHelpers(object):
650
740
 
651
741
    def _set_question_yes(self, dlg):
652
742
        """Set the dialog to answer YES to any questions."""
653
743
        self.questions = []
654
 
        def _question_yes(*args):
 
744
        def _question_yes(*args, **kwargs):
655
745
            self.questions.append(args)
656
746
            self.questions.append('YES')
657
 
            return gtk.RESPONSE_YES
 
747
            return Gtk.ResponseType.YES
658
748
        dlg._question_dialog = _question_yes
659
749
 
660
750
    def _set_question_no(self, dlg):
661
751
        """Set the dialog to answer NO to any questions."""
662
752
        self.questions = []
663
 
        def _question_no(*args):
 
753
        def _question_no(*args, **kwargs):
664
754
            self.questions.append(args)
665
755
            self.questions.append('NO')
666
 
            return gtk.RESPONSE_NO
 
756
            return Gtk.ResponseType.NO
667
757
        dlg._question_dialog = _question_no
668
758
 
 
759
 
 
760
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
 
761
    """Tests on the actual 'commit' button being pushed."""
 
762
 
669
763
    def test_bound_commit_local(self):
670
764
        tree = self.make_branch_and_tree('tree')
671
765
        self.build_tree(['tree/a'])
687
781
        self.assertEqual(last_rev, dlg.committed_revision_id)
688
782
        self.assertEqual(rev_id1, tree.branch.last_revision())
689
783
 
 
784
    def test_commit_global_sanitizes_message(self):
 
785
        tree = self.make_branch_and_tree('tree')
 
786
        self.build_tree(['tree/a'])
 
787
        tree.add(['a'], ['a-id'])
 
788
        rev_id1 = tree.commit('one')
 
789
 
 
790
        self.build_tree(['tree/b'])
 
791
        tree.add(['b'], ['b-id'])
 
792
        dlg = commit.CommitDialog(tree)
 
793
        # With the check box set, it should only effect the local branch
 
794
        dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
 
795
        dlg._do_commit()
 
796
        rev = tree.branch.repository.get_revision(tree.last_revision())
 
797
        self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
 
798
 
690
799
    def test_bound_commit_both(self):
691
800
        tree = self.make_branch_and_tree('tree')
692
801
        self.build_tree(['tree/a'])
708
817
        self.assertEqual(last_rev, dlg.committed_revision_id)
709
818
        self.assertEqual(last_rev, tree.branch.last_revision())
710
819
 
711
 
    def test_commit_no_message(self):
 
820
    def test_commit_empty_message(self):
712
821
        tree = self.make_branch_and_tree('tree')
713
822
        self.build_tree(['tree/a', 'tree/b'])
714
823
        tree.add(['a'], ['a-id'])
929
1038
 
930
1039
        dlg = commit.CommitDialog(tree)
931
1040
        dlg._commit_selected_radio.set_active(True) # enable partial
932
 
        dlg._treeview_files.set_cursor((1,))
 
1041
        dlg._treeview_files.set_cursor(
 
1042
            Gtk.TreePath(path=1), None, False)
933
1043
        dlg._set_file_commit_message('Message for A\n')
934
 
        dlg._treeview_files.set_cursor((2,))
 
1044
        dlg._treeview_files.set_cursor(
 
1045
            Gtk.TreePath(path=2), None, False)
935
1046
        dlg._set_file_commit_message('Message for B\n')
936
1047
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
937
1048
        dlg._set_global_commit_message('Commit just "a"')
943
1054
        rev = tree.branch.repository.get_revision(rev_id2)
944
1055
        self.assertEqual('Commit just "a"', rev.message)
945
1056
        file_info = rev.properties['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)
 
1057
        self.assertEqual(u'ld7:file_id4:a-id'
 
1058
                         '7:message14:Message for A\n'
 
1059
                         '4:path1:a'
 
1060
                         'ee',
 
1061
                         file_info)
950
1062
        self.assertEqual([{'path':'a', 'file_id':'a-id',
951
 
                           'message':'Message for A\n'},
952
 
                         ], bencode.bdecode(file_info))
 
1063
                           'message':'Message for A\n'},],
 
1064
                         bencode.bdecode(file_info.encode('UTF-8')))
953
1065
 
954
1066
    def test_commit_messages_after_merge(self):
955
1067
        tree = self.make_branch_and_tree('tree')
963
1075
        tree.merge_from_branch(tree2.branch)
964
1076
 
965
1077
        dlg = commit.CommitDialog(tree)
966
 
        dlg._treeview_files.set_cursor((1,)) # 'a'
 
1078
        dlg._treeview_files.set_cursor(
 
1079
            Gtk.TreePath(path=1), None, False) # 'a'
967
1080
        dlg._set_file_commit_message('Message for A\n')
968
1081
        # No message for 'B'
969
1082
        dlg._set_global_commit_message('Merging from "tree2"\n')
976
1089
        self.assertEqual('Merging from "tree2"\n', rev.message)
977
1090
        self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
978
1091
        file_info = rev.properties['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)
 
1092
        self.assertEqual(u'ld7:file_id4:a-id'
 
1093
                         '7:message14:Message for A\n'
 
1094
                         '4:path1:a'
 
1095
                         'ee',
 
1096
                         file_info)
983
1097
        self.assertEqual([{'path':'a', 'file_id':'a-id',
984
 
                           'message':'Message for A\n'},
985
 
                         ], bencode.bdecode(file_info))
 
1098
                           'message':'Message for A\n'},],
 
1099
                         bencode.bdecode(file_info.encode('UTF-8')))
986
1100
 
987
1101
    def test_commit_unicode_messages(self):
988
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1102
        self.requireFeature(UnicodeFilenameFeature)
989
1103
 
990
1104
        tree = self.make_branch_and_tree('tree')
991
1105
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
993
1107
        tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
994
1108
 
995
1109
        dlg = commit.CommitDialog(tree)
996
 
        dlg._treeview_files.set_cursor((1,)) # 'a'
 
1110
        dlg._treeview_files.set_cursor(
 
1111
            Gtk.TreePath(path=1), None, False) # 'a'
997
1112
        dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
998
 
        dlg._treeview_files.set_cursor((2,)) # omega
 
1113
        dlg._treeview_files.set_cursor(
 
1114
            Gtk.TreePath(path=2), None, False) # omega
999
1115
        dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1000
1116
        dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1001
1117
 
1030
1146
                          {'path':u'\u03a9', 'file_id':'omega-id',
1031
1147
                           'message':u'\u03a9 is the end of all things.\n'},
1032
1148
                         ], file_info_decoded)
 
1149
 
 
1150
 
 
1151
class TestSanitizeMessage(tests.TestCase):
 
1152
 
 
1153
    def assertSanitize(self, expected, original):
 
1154
        self.assertEqual(expected,
 
1155
                         commit._sanitize_and_decode_message(original))
 
1156
 
 
1157
    def test_untouched(self):
 
1158
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
 
1159
 
 
1160
    def test_converts_cr_to_lf(self):
 
1161
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
 
1162
 
 
1163
    def test_converts_crlf_to_lf(self):
 
1164
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
 
1165
 
 
1166
    def test_converts_mixed_to_lf(self):
 
1167
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
 
1168
 
 
1169
 
 
1170
class TestSavedCommitMessages(tests.TestCaseWithTransport):
 
1171
 
 
1172
    def setUp(self):
 
1173
        super(TestSavedCommitMessages, self).setUp()
 
1174
        # Install our hook
 
1175
        branch.Branch.hooks.install_named_hook(
 
1176
            'post_uncommit', commitmsgs.save_commit_messages, None)
 
1177
 
 
1178
    def _get_file_info_dict(self, rank):
 
1179
        file_info = [dict(path='a', file_id='a-id', message='a msg %d' % rank),
 
1180
                     dict(path='b', file_id='b-id', message='b msg %d' % rank)]
 
1181
        return file_info
 
1182
 
 
1183
    def _get_file_info_revprops(self, rank):
 
1184
        file_info_prop = self._get_file_info_dict(rank)
 
1185
        return {'file-info': bencode.bencode(file_info_prop).decode('UTF-8')}
 
1186
 
 
1187
    def _get_commit_message(self):
 
1188
        return self.config.get_user_option('gtk_global_commit_message')
 
1189
 
 
1190
    def _get_file_commit_messages(self):
 
1191
        return self.config.get_user_option('gtk_file_commit_messages')
 
1192
 
 
1193
 
 
1194
class TestUncommitHook(TestSavedCommitMessages):
 
1195
 
 
1196
    def setUp(self):
 
1197
        super(TestUncommitHook, self).setUp()
 
1198
        self.tree = self.make_branch_and_tree('tree')
 
1199
        self.config = self.tree.branch.get_config()
 
1200
        self.build_tree(['tree/a', 'tree/b'])
 
1201
        self.tree.add(['a'], ['a-id'])
 
1202
        self.tree.add(['b'], ['b-id'])
 
1203
        rev1 = self.tree.commit('one', rev_id='one-id',
 
1204
                                revprops=self._get_file_info_revprops(1))
 
1205
        rev2 = self.tree.commit('two', rev_id='two-id',
 
1206
                                revprops=self._get_file_info_revprops(2))
 
1207
        rev3 = self.tree.commit('three', rev_id='three-id',
 
1208
                                revprops=self._get_file_info_revprops(3))
 
1209
 
 
1210
    def test_uncommit_one_by_one(self):
 
1211
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1212
        self.assertEquals(u'three', self._get_commit_message())
 
1213
        self.assertEquals(u'd4:a-id7:a msg 34:b-id7:b msg 3e',
 
1214
                          self._get_file_commit_messages())
 
1215
 
 
1216
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1217
        self.assertEquals(u'two\n******\nthree', self._get_commit_message())
 
1218
        self.assertEquals(u'd4:a-id22:a msg 2\n******\na msg 3'
 
1219
                          '4:b-id22:b msg 2\n******\nb msg 3e',
 
1220
                          self._get_file_commit_messages())
 
1221
 
 
1222
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1223
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
 
1224
                          self._get_commit_message())
 
1225
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
 
1226
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
 
1227
                          self._get_file_commit_messages())
 
1228
 
 
1229
    def test_uncommit_all_at_once(self):
 
1230
        uncommit.uncommit(self.tree.branch, tree=self.tree, revno=1)
 
1231
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
 
1232
                          self._get_commit_message())
 
1233
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
 
1234
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
 
1235
                          self._get_file_commit_messages())
 
1236
 
 
1237
 
 
1238
class TestReusingSavedCommitMessages(TestSavedCommitMessages, QuestionHelpers):
 
1239
 
 
1240
    def setUp(self):
 
1241
        super(TestReusingSavedCommitMessages, self).setUp()
 
1242
        self.tree = self.make_branch_and_tree('tree')
 
1243
        self.config = self.tree.branch.get_config()
 
1244
        self.config.set_user_option('per_file_commits', 'true')
 
1245
        self.build_tree(['tree/a', 'tree/b'])
 
1246
        self.tree.add(['a'], ['a-id'])
 
1247
        self.tree.add(['b'], ['b-id'])
 
1248
        rev1 = self.tree.commit('one', revprops=self._get_file_info_revprops(1))
 
1249
        rev2 = self.tree.commit('two', revprops=self._get_file_info_revprops(2))
 
1250
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1251
        self.build_tree_contents([('tree/a', 'new a content\n'),
 
1252
                                  ('tree/b', 'new b content'),])
 
1253
 
 
1254
    def _get_commit_dialog(self, tree):
 
1255
        # Ensure we will never use a dialog that can actually prompt the user
 
1256
        # during the test suite. Test *can* and *should* override with the
 
1257
        # correct question dialog type.
 
1258
        dlg = commit.CommitDialog(tree)
 
1259
        self._set_question_no(dlg)
 
1260
        return dlg
 
1261
 
 
1262
    def test_setup_saved_messages(self):
 
1263
        # Check the initial setup
 
1264
        self.assertEquals(u'two', self._get_commit_message())
 
1265
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
 
1266
                          self._get_file_commit_messages())
 
1267
 
 
1268
    def test_messages_are_reloaded(self):
 
1269
        dlg = self._get_commit_dialog(self.tree)
 
1270
        self.assertEquals(u'two', dlg._get_global_commit_message())
 
1271
        self.assertEquals(([u'a', u'b'],
 
1272
                           [{ 'path': 'a',
 
1273
                             'file_id': 'a-id', 'message': 'a msg 2',},
 
1274
                           {'path': 'b',
 
1275
                            'file_id': 'b-id', 'message': 'b msg 2',}],),
 
1276
                          dlg._get_specific_files())
 
1277
 
 
1278
    def test_messages_are_consumed(self):
 
1279
        dlg = self._get_commit_dialog(self.tree)
 
1280
        dlg._do_commit()
 
1281
        self.assertEquals(u'', self._get_commit_message())
 
1282
        self.assertEquals(u'de', self._get_file_commit_messages())
 
1283
 
 
1284
    def test_messages_are_saved_on_cancel_if_required(self):
 
1285
        dlg = self._get_commit_dialog(self.tree)
 
1286
        self._set_question_yes(dlg) # Save messages
 
1287
        dlg._do_cancel()
 
1288
        self.assertEquals(u'two', self._get_commit_message())
 
1289
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
 
1290
                          self._get_file_commit_messages())
 
1291
 
 
1292
    def test_messages_are_cleared_on_cancel_if_required(self):
 
1293
        dlg = self._get_commit_dialog(self.tree)
 
1294
        self._set_question_no(dlg) # Don't save messages
 
1295
        dlg._do_cancel()
 
1296
        self.assertEquals(u'', self._get_commit_message())
 
1297
        self.assertEquals(u'de',
 
1298
                          self._get_file_commit_messages())