/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: 2012-07-09 15:23:26 UTC
  • mto: This revision was merged to the branch mainline in revision 794.
  • Revision ID: jelmer@samba.org-20120709152326-dzxb8zoz0btull7n
Remove bzr-notify.

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
17
17
"""Test the Commit functionality."""
18
18
 
19
19
import os
 
20
import subprocess
 
21
from tempfile import NamedTemporaryFile
20
22
 
21
 
import gtk
 
23
from gi.repository import Gtk
22
24
 
23
25
from bzrlib import (
 
26
    branch,
24
27
    tests,
25
 
    revision,
 
28
    uncommit,
26
29
    )
27
 
from bzrlib.util import bencode
 
30
try:
 
31
    from bzrlib.tests.features import UnicodeFilenameFeature
 
32
except ImportError: # bzr < 2.5
 
33
    from bzrlib.tests import UnicodeFilenameFeature
 
34
from bzrlib import bencode
28
35
 
29
 
from bzrlib.plugins.gtk import commit
 
36
from bzrlib.plugins.gtk import (
 
37
    commit,
 
38
    commitmsgs,
 
39
    )
 
40
from bzrlib.plugins.gtk.commitmsgs import SavedCommitMessagesManager
 
41
from bzrlib.plugins.gtk.tests import MockMethod
30
42
 
31
43
 
32
44
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
38
50
        tree = self.make_branch_and_tree('.')
39
51
        tree.commit('one')
40
52
 
41
 
        self.assertIs(None, commit.pending_revisions(tree))
 
53
        self.addCleanup(tree.lock_read().unlock)
 
54
        self.assertEquals([], list(commit.pending_revisions(tree)))
42
55
 
43
56
    def test_pending_revisions_simple(self):
44
57
        tree = self.make_branch_and_tree('tree')
48
61
        tree.merge_from_branch(tree2.branch)
49
62
        self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
50
63
 
51
 
        pending_revisions = commit.pending_revisions(tree)
 
64
        self.addCleanup(tree.lock_read().unlock)
 
65
        pending_revisions = list(commit.pending_revisions(tree))
52
66
        # One primary merge
53
67
        self.assertEqual(1, len(pending_revisions))
54
68
        # Revision == rev_id2
66
80
        tree.merge_from_branch(tree2.branch)
67
81
        self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
68
82
 
69
 
        pending_revisions = commit.pending_revisions(tree)
 
83
        self.addCleanup(tree.lock_read().unlock)
 
84
        pending_revisions = list(commit.pending_revisions(tree))
70
85
        # One primary merge
71
86
        self.assertEqual(1, len(pending_revisions))
72
87
        # Revision == rev_id2
86
101
        rev_id4 = tree3.commit('four')
87
102
        rev_id5 = tree3.commit('five')
88
103
        tree.merge_from_branch(tree2.branch)
89
 
        tree.merge_from_branch(tree3.branch)
 
104
        tree.merge_from_branch(tree3.branch, force=True)
90
105
        self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
91
106
 
92
 
        pending_revisions = commit.pending_revisions(tree)
 
107
        self.addCleanup(tree.lock_read().unlock)
 
108
        pending_revisions = list(commit.pending_revisions(tree))
93
109
        # Two primary merges
94
110
        self.assertEqual(2, len(pending_revisions))
95
111
        # Revision == rev_id2
132
148
 
133
149
class TestCommitDialogSimple(tests.TestCaseWithTransport):
134
150
 
 
151
    def test_init(self):
 
152
        MockMethod.bind(self, CommitDialogNoWidgets, 'setup_params')
 
153
        MockMethod.bind(self, CommitDialogNoWidgets, 'construct')
 
154
        MockMethod.bind(self, CommitDialogNoWidgets, 'fill_in_data')
 
155
 
 
156
        tree = self.make_branch_and_tree('tree')
 
157
        rev_id = tree.commit('first')
 
158
        dlg = CommitDialogNoWidgets(tree)
 
159
        self.assertIs(tree, dlg._wt)
 
160
        self.assertIs(None, dlg._selected)
 
161
        self.assertTrue(dlg._enable_per_file_commits)
 
162
        self.assertTrue(dlg._commit_all_changes)
 
163
        self.assertIs(None, dlg.committed_revision_id)
 
164
        self.assertIs(None, dlg._last_selected_file)
 
165
        self.assertIsInstance(
 
166
            dlg._saved_commit_messages_manager, SavedCommitMessagesManager)
 
167
        self.assertTrue(CommitDialogNoWidgets.setup_params.called)
 
168
        self.assertTrue(CommitDialogNoWidgets.construct.called)
 
169
        self.assertTrue(CommitDialogNoWidgets.fill_in_data.called)
 
170
 
135
171
    def test_setup_parameters_no_pending(self):
136
172
        tree = self.make_branch_and_tree('tree')
137
173
        rev_id = tree.commit('first')
138
174
 
139
175
        dlg = CommitDialogNoWidgets(tree)
140
176
        self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
141
 
        self.assertIs(None, dlg._pending)
 
177
        self.assertEquals([], dlg._pending)
142
178
        self.assertFalse(dlg._is_checkout)
143
179
 
144
180
    def test_setup_parameters_checkout(self):
149
185
 
150
186
        dlg = CommitDialogNoWidgets(tree2)
151
187
        self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
152
 
        self.assertIs(None, dlg._pending)
 
188
        self.assertEquals([], dlg._pending)
153
189
        self.assertTrue(dlg._is_checkout)
154
190
 
155
191
    def test_setup_parameters_pending(self):
180
216
        self.assertEqual([], delta.removed)
181
217
        self.assertEqual([(u'a', 'a-id', 'file')], delta.added)
182
218
 
 
219
    def test_on_treeview_files_cursor_changed_no_selection(self):
 
220
        MockMethod.bind(self, CommitDialogNoWidgets, '_update_per_file_info')
 
221
        tree = self.make_branch_and_tree('tree')
 
222
        rev_id = tree.commit('first')
 
223
        dlg = CommitDialogNoWidgets(tree)
 
224
        treeview = Gtk.TreeView()
 
225
        dlg._on_treeview_files_cursor_changed(treeview)
 
226
        self.assertFalse(CommitDialogNoWidgets._update_per_file_info.called)
 
227
 
 
228
    def test_on_treeview_files_cursor_changed_with_destroyed_treeview(self):
 
229
        MockMethod.bind(self, CommitDialogNoWidgets, '_update_per_file_info')
 
230
        tree = self.make_branch_and_tree('tree')
 
231
        rev_id = tree.commit('first')
 
232
        dlg = CommitDialogNoWidgets(tree)
 
233
        treeview = Gtk.TreeView()
 
234
        treeview.destroy()
 
235
        dlg._on_treeview_files_cursor_changed(treeview)
 
236
        self.assertFalse(CommitDialogNoWidgets._update_per_file_info.called)
 
237
 
 
238
    def test_get_line_height(self):
 
239
        tree = self.make_branch_and_tree('tree')
 
240
        dlg = CommitDialogNoWidgets(tree)
 
241
        textview = Gtk.TextView()
 
242
        line_height = dlg.get_line_height(textview)
 
243
        self.assertIsInstance(line_height, int)
 
244
 
183
245
 
184
246
class TestCommitDialog(tests.TestCaseWithTransport):
185
247
 
207
269
 
208
270
        commit_col = dlg._treeview_files.get_column(0)
209
271
        self.assertEqual('Commit', commit_col.get_title())
210
 
        renderer = commit_col.get_cell_renderers()[0]
 
272
        renderer = commit_col.get_cells()[0]
211
273
        self.assertTrue(renderer.get_property('activatable'))
212
274
 
213
275
        self.assertEqual('Commit all changes',
232
294
 
233
295
        commit_col = dlg._treeview_files.get_column(0)
234
296
        self.assertEqual('Commit*', commit_col.get_title())
235
 
        renderer = commit_col.get_cell_renderers()[0]
 
297
        renderer = commit_col.get_cells()[0]
236
298
        self.assertFalse(renderer.get_property('activatable'))
237
299
 
238
300
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
266
328
                               committer='Jerry Foo <jerry@foo.com>',
267
329
                               timestamp=1191372278.05,
268
330
                               timezone=+7200)
269
 
        tree.merge_from_branch(tree3.branch)
 
331
        tree.merge_from_branch(tree3.branch, force=True)
270
332
 
271
333
        dlg = commit.CommitDialog(tree)
272
334
        # TODO: assert that the pending box is set to show
284
346
 
285
347
        dlg = commit.CommitDialog(tree)
286
348
        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', ''),
 
349
        self.assertEqual([("", "", True, 'All Files', ''),
288
350
                          ('a-id', 'a', True, 'a', 'added'),
289
351
                          ('b-id', 'b', True, 'b/', 'added'),
290
352
                          ('c-id', 'b/c', True, 'b/c', 'added'),
301
363
 
302
364
        dlg = commit.CommitDialog(tree)
303
365
        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', ''),
 
366
        self.assertEqual([("", "", True, 'All Files', ''),
305
367
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
306
368
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
307
369
                         ], values)
316
378
 
317
379
        dlg = commit.CommitDialog(tree)
318
380
        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', ''),
 
381
        self.assertEqual([("", "", True, 'All Files', ''),
320
382
                          ('a-id', 'a', True, 'a', 'modified'),
321
383
                         ], values)
322
384
 
336
398
 
337
399
        dlg = commit.CommitDialog(tree)
338
400
        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', ''),
 
401
        self.assertEqual([("", "", True, 'All Files', ''),
340
402
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
341
403
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
342
404
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
359
421
 
360
422
        dlg = commit.CommitDialog(tree)
361
423
        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', ''),
 
424
        self.assertEqual([("", "", True, 'All Files', ''),
363
425
                          ('a-id', 'a', True, 'a => a/', 'kind changed'),
364
426
                          # ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
365
427
                         ], values)
375
437
 
376
438
        dlg = commit.CommitDialog(tree)
377
439
        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', ''),
 
440
        self.assertEqual([("", "", True, 'All Files', ''),
379
441
                          ('a-id', 'a', True, 'a', 'removed'),
380
442
                          ('b-id', 'b', True, 'b/', 'removed'),
381
443
                         ], values)
382
444
        # All Files should be selected
383
 
        self.assertEqual(((0,), None), dlg._treeview_files.get_cursor())
 
445
        self.assertEqual(
 
446
            (Gtk.TreePath(path=0), None), dlg._treeview_files.get_cursor())
384
447
 
385
448
    def test_filelist_with_selected(self):
386
449
        tree = self.make_branch_and_tree('tree')
389
452
 
390
453
        dlg = commit.CommitDialog(tree, selected='a')
391
454
        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', ''),
 
455
        self.assertEqual([("", "", False, 'All Files', ''),
393
456
                          ('a-id', 'a', True, 'a', 'added'),
394
457
                          ('b-id', 'b', False, 'b/', 'added'),
395
458
                         ], values)
396
459
        # This file should also be selected in the file list, rather than the
397
460
        # 'All Files' selection
398
 
        self.assertEqual(((1,), None), dlg._treeview_files.get_cursor())
 
461
        self.assertEqual(
 
462
            (Gtk.TreePath(path=1), None), dlg._treeview_files.get_cursor())
399
463
 
400
464
    def test_diff_view(self):
401
465
        tree = self.make_branch_and_tree('tree')
409
473
        dlg = commit.CommitDialog(tree)
410
474
        diff_buffer = dlg._diff_view.buffer
411
475
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
412
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
476
                                    diff_buffer.get_end_iter(),
 
477
                                    True).splitlines(True)
413
478
 
414
479
        self.assertEqual("=== modified file 'a'\n", text[0])
415
480
        self.assertContainsRe(text[1],
460
525
        self.assertFalse(dlg._file_message_expander.get_expanded())
461
526
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
462
527
 
463
 
        dlg._treeview_files.set_cursor((1,))
 
528
        dlg._treeview_files.set_cursor(
 
529
            Gtk.TreePath(path=1), None, False)
464
530
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
465
531
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
466
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
532
                                    diff_buffer.get_end_iter(),
 
533
                                    True).splitlines(True)
467
534
        self.assertEqual("=== added file 'a'\n", text[0])
468
535
        self.assertContainsRe(text[1],
469
536
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
477
544
        self.assertTrue(dlg._file_message_expander.get_expanded())
478
545
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
479
546
 
480
 
        dlg._treeview_files.set_cursor((2,))
 
547
        dlg._treeview_files.set_cursor(
 
548
            Gtk.TreePath(path=2), None, False)
481
549
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
482
550
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
483
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
551
                                    diff_buffer.get_end_iter(),
 
552
                                    True).splitlines(True)
484
553
        self.assertEqual("=== added file 'b'\n", text[0])
485
554
        self.assertContainsRe(text[1],
486
555
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
494
563
        self.assertTrue(dlg._file_message_expander.get_expanded())
495
564
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
496
565
 
497
 
        dlg._treeview_files.set_cursor((0,))
 
566
        dlg._treeview_files.set_cursor(
 
567
            Gtk.TreePath(path=0), None, False)
498
568
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
499
569
        self.assertEqual('File commit message',
500
570
                         dlg._file_message_expander.get_label())
510
580
 
511
581
        def get_file_text():
512
582
            buf = dlg._file_message_text_view.get_buffer()
513
 
            return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
 
583
            return buf.get_text(
 
584
                buf.get_start_iter(), buf.get_end_iter(), True)
514
585
 
515
586
        def get_saved_text(path):
516
587
            """Get the saved text for a given record."""
523
594
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
524
595
        self.assertEqual('', get_file_text())
525
596
 
526
 
        dlg._treeview_files.set_cursor((1,))
 
597
        dlg._treeview_files.set_cursor(
 
598
            Gtk.TreePath(path=1), None, False)
527
599
        self.assertEqual('Commit message for a',
528
600
                         dlg._file_message_expander.get_label())
529
601
        self.assertTrue(dlg._file_message_expander.get_expanded())
536
608
        # We should have updated the ListStore with the new file commit info
537
609
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
538
610
 
539
 
        dlg._treeview_files.set_cursor((2,))
 
611
        dlg._treeview_files.set_cursor(
 
612
            Gtk.TreePath(path=2), None, False)
540
613
        self.assertEqual('Commit message for b/',
541
614
                         dlg._file_message_expander.get_label())
542
615
        self.assertTrue(dlg._file_message_expander.get_expanded())
547
620
        dlg._set_file_commit_message('More text\nfor b\n')
548
621
        # Now switch back to 'a'. The message should be saved, and the buffer
549
622
        # should be updated with the other text
550
 
        dlg._treeview_files.set_cursor((1,))
 
623
        dlg._treeview_files.set_cursor(
 
624
            Gtk.TreePath(path=1), None, False)
551
625
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
552
626
        self.assertEqual('Commit message for a',
553
627
                         dlg._file_message_expander.get_label())
562
636
        tree.add(['a', 'b'], ['a-id', 'b-id'])
563
637
 
564
638
        dlg = commit.CommitDialog(tree)
565
 
        self.assertEqual([(None, None, True),
 
639
        self.assertEqual([("", "", True),
566
640
                          ('a-id', 'a', True),
567
641
                          ('b-id', 'b', True),
568
642
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
573
647
        #       do with. So instead, we just call toggle directly, and assume
574
648
        #       that toggle is hooked in correctly
575
649
        # column = dlg._treeview_files.get_column(0)
576
 
        # renderer = column.get_cell_renderers()[0]
 
650
        # renderer = column.get_cells()[0]
577
651
 
578
652
        # Toggle a single entry should set just that entry to False
579
653
        dlg._toggle_commit(None, 1, dlg._files_store)
580
 
        self.assertEqual([(None, None, True),
 
654
        self.assertEqual([("", "", True),
581
655
                          ('a-id', 'a', False),
582
656
                          ('b-id', 'b', True),
583
657
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
584
658
 
585
659
        # Toggling the main entry should set all entries
586
660
        dlg._toggle_commit(None, 0, dlg._files_store)
587
 
        self.assertEqual([(None, None, False),
 
661
        self.assertEqual([("", "", False),
588
662
                          ('a-id', 'a', False),
589
663
                          ('b-id', 'b', False),
590
664
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
591
665
 
592
666
        dlg._toggle_commit(None, 2, dlg._files_store)
593
 
        self.assertEqual([(None, None, False),
 
667
        self.assertEqual([("", "", False),
594
668
                          ('a-id', 'a', False),
595
669
                          ('b-id', 'b', True),
596
670
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
597
671
 
598
672
        dlg._toggle_commit(None, 0, dlg._files_store)
599
 
        self.assertEqual([(None, None, True),
 
673
        self.assertEqual([("", "", True),
600
674
                          ('a-id', 'a', True),
601
675
                          ('b-id', 'b', True),
602
676
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
626
700
        dlg._commit_selected_radio.set_active(True)
627
701
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
628
702
 
629
 
        dlg._treeview_files.set_cursor((1,))
 
703
        dlg._treeview_files.set_cursor(
 
704
            Gtk.TreePath(path=1), None, False)
630
705
        dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
631
 
        dlg._treeview_files.set_cursor((2,))
 
706
        dlg._treeview_files.set_cursor(
 
707
            Gtk.TreePath(path=2), None, False)
632
708
        dlg._set_file_commit_message('message\nfor b_dir\n')
633
709
 
634
710
        self.assertEqual((['a_file', 'b_dir'],
644
720
                            'message':'message\nfor b_dir\n'},
645
721
                          ]), dlg._get_specific_files())
646
722
 
647
 
 
648
 
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
649
 
    """Tests on the actual 'commit' button being pushed."""
 
723
    def test_specific_files_sanitizes_messages(self):
 
724
        tree = self.make_branch_and_tree('tree')
 
725
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
 
726
        self.build_tree(['tree/a_file', 'tree/b_dir/'])
 
727
        tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
 
728
 
 
729
        dlg = commit.CommitDialog(tree)
 
730
        dlg._commit_selected_radio.set_active(True)
 
731
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
 
732
 
 
733
        dlg._treeview_files.set_cursor(
 
734
            Gtk.TreePath(path=1), None, False)
 
735
        dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
 
736
        dlg._treeview_files.set_cursor(
 
737
            Gtk.TreePath(path=2), None, False)
 
738
        dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
 
739
 
 
740
        self.assertEqual((['a_file', 'b_dir'],
 
741
                          [{'path':'a_file', 'file_id':'1a-id',
 
742
                            'message':'Test\nmessage\nfor a_file\n'},
 
743
                           {'path':'b_dir', 'file_id':'0b-id',
 
744
                            'message':'message\nfor\nb_dir\n'},
 
745
                          ]), dlg._get_specific_files())
 
746
 
 
747
 
 
748
class QuestionHelpers(object):
650
749
 
651
750
    def _set_question_yes(self, dlg):
652
751
        """Set the dialog to answer YES to any questions."""
653
752
        self.questions = []
654
 
        def _question_yes(*args):
 
753
        def _question_yes(*args, **kwargs):
655
754
            self.questions.append(args)
656
755
            self.questions.append('YES')
657
 
            return gtk.RESPONSE_YES
 
756
            return Gtk.ResponseType.YES
658
757
        dlg._question_dialog = _question_yes
659
758
 
660
759
    def _set_question_no(self, dlg):
661
760
        """Set the dialog to answer NO to any questions."""
662
761
        self.questions = []
663
 
        def _question_no(*args):
 
762
        def _question_no(*args, **kwargs):
664
763
            self.questions.append(args)
665
764
            self.questions.append('NO')
666
 
            return gtk.RESPONSE_NO
 
765
            return Gtk.ResponseType.NO
667
766
        dlg._question_dialog = _question_no
668
767
 
 
768
 
 
769
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
 
770
    """Tests on the actual 'commit' button being pushed."""
 
771
 
669
772
    def test_bound_commit_local(self):
670
773
        tree = self.make_branch_and_tree('tree')
671
774
        self.build_tree(['tree/a'])
687
790
        self.assertEqual(last_rev, dlg.committed_revision_id)
688
791
        self.assertEqual(rev_id1, tree.branch.last_revision())
689
792
 
 
793
    def test_commit_global_sanitizes_message(self):
 
794
        tree = self.make_branch_and_tree('tree')
 
795
        self.build_tree(['tree/a'])
 
796
        tree.add(['a'], ['a-id'])
 
797
        rev_id1 = tree.commit('one')
 
798
 
 
799
        self.build_tree(['tree/b'])
 
800
        tree.add(['b'], ['b-id'])
 
801
        dlg = commit.CommitDialog(tree)
 
802
        # With the check box set, it should only effect the local branch
 
803
        dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
 
804
        dlg._do_commit()
 
805
        rev = tree.branch.repository.get_revision(tree.last_revision())
 
806
        self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
 
807
 
690
808
    def test_bound_commit_both(self):
691
809
        tree = self.make_branch_and_tree('tree')
692
810
        self.build_tree(['tree/a'])
708
826
        self.assertEqual(last_rev, dlg.committed_revision_id)
709
827
        self.assertEqual(last_rev, tree.branch.last_revision())
710
828
 
711
 
    def test_commit_no_message(self):
 
829
    def test_commit_empty_message(self):
712
830
        tree = self.make_branch_and_tree('tree')
713
831
        self.build_tree(['tree/a', 'tree/b'])
714
832
        tree.add(['a'], ['a-id'])
929
1047
 
930
1048
        dlg = commit.CommitDialog(tree)
931
1049
        dlg._commit_selected_radio.set_active(True) # enable partial
932
 
        dlg._treeview_files.set_cursor((1,))
 
1050
        dlg._treeview_files.set_cursor(
 
1051
            Gtk.TreePath(path=1), None, False)
933
1052
        dlg._set_file_commit_message('Message for A\n')
934
 
        dlg._treeview_files.set_cursor((2,))
 
1053
        dlg._treeview_files.set_cursor(
 
1054
            Gtk.TreePath(path=2), None, False)
935
1055
        dlg._set_file_commit_message('Message for B\n')
936
1056
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
937
1057
        dlg._set_global_commit_message('Commit just "a"')
943
1063
        rev = tree.branch.repository.get_revision(rev_id2)
944
1064
        self.assertEqual('Commit just "a"', rev.message)
945
1065
        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)
 
1066
        self.assertEqual(u'ld7:file_id4:a-id'
 
1067
                         '7:message14:Message for A\n'
 
1068
                         '4:path1:a'
 
1069
                         'ee',
 
1070
                         file_info)
950
1071
        self.assertEqual([{'path':'a', 'file_id':'a-id',
951
 
                           'message':'Message for A\n'},
952
 
                         ], bencode.bdecode(file_info))
 
1072
                           'message':'Message for A\n'},],
 
1073
                         bencode.bdecode(file_info.encode('UTF-8')))
953
1074
 
954
1075
    def test_commit_messages_after_merge(self):
955
1076
        tree = self.make_branch_and_tree('tree')
963
1084
        tree.merge_from_branch(tree2.branch)
964
1085
 
965
1086
        dlg = commit.CommitDialog(tree)
966
 
        dlg._treeview_files.set_cursor((1,)) # 'a'
 
1087
        dlg._treeview_files.set_cursor(
 
1088
            Gtk.TreePath(path=1), None, False) # 'a'
967
1089
        dlg._set_file_commit_message('Message for A\n')
968
1090
        # No message for 'B'
969
1091
        dlg._set_global_commit_message('Merging from "tree2"\n')
976
1098
        self.assertEqual('Merging from "tree2"\n', rev.message)
977
1099
        self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
978
1100
        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)
 
1101
        self.assertEqual(u'ld7:file_id4:a-id'
 
1102
                         '7:message14:Message for A\n'
 
1103
                         '4:path1:a'
 
1104
                         'ee',
 
1105
                         file_info)
983
1106
        self.assertEqual([{'path':'a', 'file_id':'a-id',
984
 
                           'message':'Message for A\n'},
985
 
                         ], bencode.bdecode(file_info))
 
1107
                           'message':'Message for A\n'},],
 
1108
                         bencode.bdecode(file_info.encode('UTF-8')))
986
1109
 
987
1110
    def test_commit_unicode_messages(self):
988
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
1111
        self.requireFeature(UnicodeFilenameFeature)
989
1112
 
990
1113
        tree = self.make_branch_and_tree('tree')
991
1114
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
993
1116
        tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
994
1117
 
995
1118
        dlg = commit.CommitDialog(tree)
996
 
        dlg._treeview_files.set_cursor((1,)) # 'a'
 
1119
        dlg._treeview_files.set_cursor(
 
1120
            Gtk.TreePath(path=1), None, False) # 'a'
997
1121
        dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
998
 
        dlg._treeview_files.set_cursor((2,)) # omega
 
1122
        dlg._treeview_files.set_cursor(
 
1123
            Gtk.TreePath(path=2), None, False) # omega
999
1124
        dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1000
1125
        dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1001
1126
 
1030
1155
                          {'path':u'\u03a9', 'file_id':'omega-id',
1031
1156
                           'message':u'\u03a9 is the end of all things.\n'},
1032
1157
                         ], file_info_decoded)
 
1158
 
 
1159
 
 
1160
class TestSanitizeMessage(tests.TestCase):
 
1161
 
 
1162
    def assertSanitize(self, expected, original):
 
1163
        self.assertEqual(expected,
 
1164
                         commit._sanitize_and_decode_message(original))
 
1165
 
 
1166
    def test_untouched(self):
 
1167
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
 
1168
 
 
1169
    def test_converts_cr_to_lf(self):
 
1170
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
 
1171
 
 
1172
    def test_converts_crlf_to_lf(self):
 
1173
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
 
1174
 
 
1175
    def test_converts_mixed_to_lf(self):
 
1176
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
 
1177
 
 
1178
 
 
1179
class TestSavedCommitMessages(tests.TestCaseWithTransport):
 
1180
 
 
1181
    def setUp(self):
 
1182
        super(TestSavedCommitMessages, self).setUp()
 
1183
        # Install our hook
 
1184
        branch.Branch.hooks.install_named_hook(
 
1185
            'post_uncommit', commitmsgs.save_commit_messages, None)
 
1186
 
 
1187
    def _get_file_info_dict(self, rank):
 
1188
        file_info = [dict(path='a', file_id='a-id', message='a msg %d' % rank),
 
1189
                     dict(path='b', file_id='b-id', message='b msg %d' % rank)]
 
1190
        return file_info
 
1191
 
 
1192
    def _get_file_info_revprops(self, rank):
 
1193
        file_info_prop = self._get_file_info_dict(rank)
 
1194
        return {'file-info': bencode.bencode(file_info_prop).decode('UTF-8')}
 
1195
 
 
1196
    def _get_commit_message(self):
 
1197
        return self.config.get_user_option('gtk_global_commit_message')
 
1198
 
 
1199
    def _get_file_commit_messages(self):
 
1200
        return self.config.get_user_option('gtk_file_commit_messages')
 
1201
 
 
1202
 
 
1203
class TestUncommitHook(TestSavedCommitMessages):
 
1204
 
 
1205
    def setUp(self):
 
1206
        super(TestUncommitHook, self).setUp()
 
1207
        self.tree = self.make_branch_and_tree('tree')
 
1208
        self.config = self.tree.branch.get_config()
 
1209
        self.build_tree(['tree/a', 'tree/b'])
 
1210
        self.tree.add(['a'], ['a-id'])
 
1211
        self.tree.add(['b'], ['b-id'])
 
1212
        rev1 = self.tree.commit('one', rev_id='one-id',
 
1213
                                revprops=self._get_file_info_revprops(1))
 
1214
        rev2 = self.tree.commit('two', rev_id='two-id',
 
1215
                                revprops=self._get_file_info_revprops(2))
 
1216
        rev3 = self.tree.commit('three', rev_id='three-id',
 
1217
                                revprops=self._get_file_info_revprops(3))
 
1218
 
 
1219
    def test_uncommit_one_by_one(self):
 
1220
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1221
        self.assertEquals(u'three', self._get_commit_message())
 
1222
        self.assertEquals(u'd4:a-id7:a msg 34:b-id7:b msg 3e',
 
1223
                          self._get_file_commit_messages())
 
1224
 
 
1225
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1226
        self.assertEquals(u'two\n******\nthree', self._get_commit_message())
 
1227
        self.assertEquals(u'd4:a-id22:a msg 2\n******\na msg 3'
 
1228
                          '4:b-id22:b msg 2\n******\nb msg 3e',
 
1229
                          self._get_file_commit_messages())
 
1230
 
 
1231
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1232
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
 
1233
                          self._get_commit_message())
 
1234
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
 
1235
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
 
1236
                          self._get_file_commit_messages())
 
1237
 
 
1238
    def test_uncommit_all_at_once(self):
 
1239
        uncommit.uncommit(self.tree.branch, tree=self.tree, revno=1)
 
1240
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
 
1241
                          self._get_commit_message())
 
1242
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
 
1243
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
 
1244
                          self._get_file_commit_messages())
 
1245
 
 
1246
 
 
1247
class TestReusingSavedCommitMessages(TestSavedCommitMessages, QuestionHelpers):
 
1248
 
 
1249
    def setUp(self):
 
1250
        super(TestReusingSavedCommitMessages, self).setUp()
 
1251
        self.tree = self.make_branch_and_tree('tree')
 
1252
        self.config = self.tree.branch.get_config()
 
1253
        self.config.set_user_option('per_file_commits', 'true')
 
1254
        self.build_tree(['tree/a', 'tree/b'])
 
1255
        self.tree.add(['a'], ['a-id'])
 
1256
        self.tree.add(['b'], ['b-id'])
 
1257
        rev1 = self.tree.commit('one', revprops=self._get_file_info_revprops(1))
 
1258
        rev2 = self.tree.commit('two', revprops=self._get_file_info_revprops(2))
 
1259
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1260
        self.build_tree_contents([('tree/a', 'new a content\n'),
 
1261
                                  ('tree/b', 'new b content'),])
 
1262
 
 
1263
    def _get_commit_dialog(self, tree):
 
1264
        # Ensure we will never use a dialog that can actually prompt the user
 
1265
        # during the test suite. Test *can* and *should* override with the
 
1266
        # correct question dialog type.
 
1267
        dlg = commit.CommitDialog(tree)
 
1268
        self._set_question_no(dlg)
 
1269
        return dlg
 
1270
 
 
1271
    def test_setup_saved_messages(self):
 
1272
        # Check the initial setup
 
1273
        self.assertEquals(u'two', self._get_commit_message())
 
1274
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
 
1275
                          self._get_file_commit_messages())
 
1276
 
 
1277
    def test_messages_are_reloaded(self):
 
1278
        dlg = self._get_commit_dialog(self.tree)
 
1279
        self.assertEquals(u'two', dlg._get_global_commit_message())
 
1280
        self.assertEquals(([u'a', u'b'],
 
1281
                           [{ 'path': 'a',
 
1282
                             'file_id': 'a-id', 'message': 'a msg 2',},
 
1283
                           {'path': 'b',
 
1284
                            'file_id': 'b-id', 'message': 'b msg 2',}],),
 
1285
                          dlg._get_specific_files())
 
1286
 
 
1287
    def test_messages_are_consumed(self):
 
1288
        dlg = self._get_commit_dialog(self.tree)
 
1289
        dlg._do_commit()
 
1290
        self.assertEquals(u'', self._get_commit_message())
 
1291
        self.assertEquals(u'de', self._get_file_commit_messages())
 
1292
 
 
1293
    def test_messages_are_saved_on_cancel_if_required(self):
 
1294
        dlg = self._get_commit_dialog(self.tree)
 
1295
        self._set_question_yes(dlg) # Save messages
 
1296
        dlg._do_cancel()
 
1297
        self.assertEquals(u'two', self._get_commit_message())
 
1298
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
 
1299
                          self._get_file_commit_messages())
 
1300
 
 
1301
    def test_messages_are_cleared_on_cancel_if_required(self):
 
1302
        dlg = self._get_commit_dialog(self.tree)
 
1303
        self._set_question_no(dlg) # Don't save messages
 
1304
        dlg._do_cancel()
 
1305
        self.assertEquals(u'', self._get_commit_message())
 
1306
        self.assertEquals(u'de',
 
1307
                          self._get_file_commit_messages())
 
1308
 
 
1309
 
 
1310
class BzrHandlePatchTestCase(tests.TestCase):
 
1311
 
 
1312
    def setUp(self):
 
1313
        top = os.path.abspath(os.path.join(
 
1314
            os.path.dirname(__file__), os.pardir))
 
1315
        self.script = os.path.join(top, 'bzr-handle-patch')
 
1316
        self.env = dict(os.environ)
 
1317
        self.env['BZR_PLUGINS_AT'] = 'gtk@%s' % top
 
1318
        self.patch = NamedTemporaryFile()
 
1319
        self.patch.write('\n'.join([
 
1320
            "=== added file '_test.txt'",
 
1321
            "--- _test.txt      1970-01-01 00:00:00 +0000",
 
1322
            "+++ _test.txt      2012-02-03 20:00:34 +0000",
 
1323
            "@@ -0,0 +1,1 @@",
 
1324
            "+hello",
 
1325
            ]))
 
1326
        self.patch.flush()
 
1327
        super(BzrHandlePatchTestCase, self).setUp()
 
1328
 
 
1329
    def test_smoketest(self):
 
1330
        # This is a smoke test to verify the process starts.
 
1331
        bzr_notify = subprocess.Popen(
 
1332
            [self.script, self.patch.name, 'test'],
 
1333
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env)
 
1334
        stdout, stderr = bzr_notify.communicate()
 
1335
        self.assertEqual('', stdout)
 
1336
        self.assertEqual('', stderr)