/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-05 05:14:11 UTC
  • mto: This revision was merged to the branch mainline in revision 775.
  • Revision ID: sinzui.is@verizon.net-20120205051411-y9ra08wae1wsfv52
Remove unneeded gtksourceview1 support.

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
 
 
53
        self.addCleanup(tree.lock_read().unlock)
41
54
        self.assertIs(None, commit.pending_revisions(tree))
42
55
 
43
56
    def test_pending_revisions_simple(self):
48
61
        tree.merge_from_branch(tree2.branch)
49
62
        self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
50
63
 
 
64
        self.addCleanup(tree.lock_read().unlock)
51
65
        pending_revisions = commit.pending_revisions(tree)
52
66
        # One primary merge
53
67
        self.assertEqual(1, len(pending_revisions))
66
80
        tree.merge_from_branch(tree2.branch)
67
81
        self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
68
82
 
 
83
        self.addCleanup(tree.lock_read().unlock)
69
84
        pending_revisions = commit.pending_revisions(tree)
70
85
        # One primary merge
71
86
        self.assertEqual(1, len(pending_revisions))
81
96
        rev_id1 = tree.commit('one')
82
97
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
83
98
        rev_id2 = tree2.commit('two')
84
 
        rev_id3 = tree2.commit('three')
85
99
        tree3 = tree2.bzrdir.sprout('tree3').open_workingtree()
 
100
        rev_id3 = tree2.commit('three')
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
 
 
107
        self.addCleanup(tree.lock_read().unlock)
92
108
        pending_revisions = commit.pending_revisions(tree)
93
109
        # Two primary merges
94
110
        self.assertEqual(2, len(pending_revisions))
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')
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
 
183
238
 
184
239
class TestCommitDialog(tests.TestCaseWithTransport):
185
240
 
207
262
 
208
263
        commit_col = dlg._treeview_files.get_column(0)
209
264
        self.assertEqual('Commit', commit_col.get_title())
210
 
        renderer = commit_col.get_cell_renderers()[0]
 
265
        renderer = commit_col.get_cells()[0]
211
266
        self.assertTrue(renderer.get_property('activatable'))
212
267
 
213
268
        self.assertEqual('Commit all changes',
232
287
 
233
288
        commit_col = dlg._treeview_files.get_column(0)
234
289
        self.assertEqual('Commit*', commit_col.get_title())
235
 
        renderer = commit_col.get_cell_renderers()[0]
 
290
        renderer = commit_col.get_cells()[0]
236
291
        self.assertFalse(renderer.get_property('activatable'))
237
292
 
238
293
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
266
321
                               committer='Jerry Foo <jerry@foo.com>',
267
322
                               timestamp=1191372278.05,
268
323
                               timezone=+7200)
269
 
        tree.merge_from_branch(tree3.branch)
 
324
        tree.merge_from_branch(tree3.branch, force=True)
270
325
 
271
326
        dlg = commit.CommitDialog(tree)
272
327
        # TODO: assert that the pending box is set to show
284
339
 
285
340
        dlg = commit.CommitDialog(tree)
286
341
        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', ''),
 
342
        self.assertEqual([("", "", True, 'All Files', ''),
288
343
                          ('a-id', 'a', True, 'a', 'added'),
289
344
                          ('b-id', 'b', True, 'b/', 'added'),
290
345
                          ('c-id', 'b/c', True, 'b/c', 'added'),
301
356
 
302
357
        dlg = commit.CommitDialog(tree)
303
358
        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', ''),
 
359
        self.assertEqual([("", "", True, 'All Files', ''),
305
360
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
306
361
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
307
362
                         ], values)
316
371
 
317
372
        dlg = commit.CommitDialog(tree)
318
373
        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', ''),
 
374
        self.assertEqual([("", "", True, 'All Files', ''),
320
375
                          ('a-id', 'a', True, 'a', 'modified'),
321
376
                         ], values)
322
377
 
336
391
 
337
392
        dlg = commit.CommitDialog(tree)
338
393
        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', ''),
 
394
        self.assertEqual([("", "", True, 'All Files', ''),
340
395
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
341
396
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
342
397
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
359
414
 
360
415
        dlg = commit.CommitDialog(tree)
361
416
        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', ''),
 
417
        self.assertEqual([("", "", True, 'All Files', ''),
363
418
                          ('a-id', 'a', True, 'a => a/', 'kind changed'),
364
419
                          # ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
365
420
                         ], values)
375
430
 
376
431
        dlg = commit.CommitDialog(tree)
377
432
        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', ''),
 
433
        self.assertEqual([("", "", True, 'All Files', ''),
379
434
                          ('a-id', 'a', True, 'a', 'removed'),
380
435
                          ('b-id', 'b', True, 'b/', 'removed'),
381
436
                         ], values)
382
437
        # All Files should be selected
383
 
        self.assertEqual(((0,), None), dlg._treeview_files.get_cursor())
 
438
        self.assertEqual(
 
439
            (Gtk.TreePath(path=0), None), dlg._treeview_files.get_cursor())
384
440
 
385
441
    def test_filelist_with_selected(self):
386
442
        tree = self.make_branch_and_tree('tree')
389
445
 
390
446
        dlg = commit.CommitDialog(tree, selected='a')
391
447
        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', ''),
 
448
        self.assertEqual([("", "", False, 'All Files', ''),
393
449
                          ('a-id', 'a', True, 'a', 'added'),
394
450
                          ('b-id', 'b', False, 'b/', 'added'),
395
451
                         ], values)
396
452
        # This file should also be selected in the file list, rather than the
397
453
        # 'All Files' selection
398
 
        self.assertEqual(((1,), None), dlg._treeview_files.get_cursor())
 
454
        self.assertEqual(
 
455
            (Gtk.TreePath(path=1), None), dlg._treeview_files.get_cursor())
399
456
 
400
457
    def test_diff_view(self):
401
458
        tree = self.make_branch_and_tree('tree')
409
466
        dlg = commit.CommitDialog(tree)
410
467
        diff_buffer = dlg._diff_view.buffer
411
468
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
412
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
469
                                    diff_buffer.get_end_iter(),
 
470
                                    True).splitlines(True)
413
471
 
414
 
        self.assertEqual("=== removed file 'b'\n", text[0])
 
472
        self.assertEqual("=== modified file 'a'\n", text[0])
415
473
        self.assertContainsRe(text[1],
416
 
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
417
 
        self.assertEqual('+++ b\t1970-01-01 00:00:00 +0000\n', text[2])
418
 
        self.assertEqual('@@ -1,1 +0,0 @@\n', text[3])
419
 
        self.assertEqual('-contents of tree/b\n', text[4])
420
 
        self.assertEqual('\n', text[5])
421
 
 
422
 
        self.assertEqual("=== modified file 'a'\n", text[6])
423
 
        self.assertContainsRe(text[7],
424
474
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
 
475
        self.assertContainsRe(text[2],
 
476
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
 
477
        self.assertEqual('@@ -1,1 +1,1 @@\n', text[3])
 
478
        self.assertEqual('-contents of tree/a\n', text[4])
 
479
        self.assertEqual('+new contents for a\n', text[5])
 
480
        self.assertEqual('\n', text[6])
 
481
 
 
482
        self.assertEqual("=== removed file 'b'\n", text[7])
425
483
        self.assertContainsRe(text[8],
426
 
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
427
 
        self.assertEqual('@@ -1,1 +1,1 @@\n', text[9])
428
 
        self.assertEqual('-contents of tree/a\n', text[10])
429
 
        self.assertEqual('+new contents for a\n', text[11])
 
484
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
 
485
        self.assertEqual('+++ b\t1970-01-01 00:00:00 +0000\n', text[9])
 
486
        self.assertEqual('@@ -1,1 +0,0 @@\n', text[10])
 
487
        self.assertEqual('-contents of tree/b\n', text[11])
430
488
        self.assertEqual('\n', text[12])
431
489
 
432
490
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
460
518
        self.assertFalse(dlg._file_message_expander.get_expanded())
461
519
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
462
520
 
463
 
        dlg._treeview_files.set_cursor((1,))
 
521
        dlg._treeview_files.set_cursor(
 
522
            Gtk.TreePath(path=1), None, False)
464
523
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
465
524
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
466
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
525
                                    diff_buffer.get_end_iter(),
 
526
                                    True).splitlines(True)
467
527
        self.assertEqual("=== added file 'a'\n", text[0])
468
528
        self.assertContainsRe(text[1],
469
529
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
477
537
        self.assertTrue(dlg._file_message_expander.get_expanded())
478
538
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
479
539
 
480
 
        dlg._treeview_files.set_cursor((2,))
 
540
        dlg._treeview_files.set_cursor(
 
541
            Gtk.TreePath(path=2), None, False)
481
542
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
482
543
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
483
 
                                    diff_buffer.get_end_iter()).splitlines(True)
 
544
                                    diff_buffer.get_end_iter(),
 
545
                                    True).splitlines(True)
484
546
        self.assertEqual("=== added file 'b'\n", text[0])
485
547
        self.assertContainsRe(text[1],
486
548
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
494
556
        self.assertTrue(dlg._file_message_expander.get_expanded())
495
557
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
496
558
 
497
 
        dlg._treeview_files.set_cursor((0,))
 
559
        dlg._treeview_files.set_cursor(
 
560
            Gtk.TreePath(path=0), None, False)
498
561
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
499
562
        self.assertEqual('File commit message',
500
563
                         dlg._file_message_expander.get_label())
510
573
 
511
574
        def get_file_text():
512
575
            buf = dlg._file_message_text_view.get_buffer()
513
 
            return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
 
576
            return buf.get_text(
 
577
                buf.get_start_iter(), buf.get_end_iter(), True)
514
578
 
515
579
        def get_saved_text(path):
516
580
            """Get the saved text for a given record."""
523
587
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
524
588
        self.assertEqual('', get_file_text())
525
589
 
526
 
        dlg._treeview_files.set_cursor((1,))
 
590
        dlg._treeview_files.set_cursor(
 
591
            Gtk.TreePath(path=1), None, False)
527
592
        self.assertEqual('Commit message for a',
528
593
                         dlg._file_message_expander.get_label())
529
594
        self.assertTrue(dlg._file_message_expander.get_expanded())
536
601
        # We should have updated the ListStore with the new file commit info
537
602
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
538
603
 
539
 
        dlg._treeview_files.set_cursor((2,))
 
604
        dlg._treeview_files.set_cursor(
 
605
            Gtk.TreePath(path=2), None, False)
540
606
        self.assertEqual('Commit message for b/',
541
607
                         dlg._file_message_expander.get_label())
542
608
        self.assertTrue(dlg._file_message_expander.get_expanded())
547
613
        dlg._set_file_commit_message('More text\nfor b\n')
548
614
        # Now switch back to 'a'. The message should be saved, and the buffer
549
615
        # should be updated with the other text
550
 
        dlg._treeview_files.set_cursor((1,))
 
616
        dlg._treeview_files.set_cursor(
 
617
            Gtk.TreePath(path=1), None, False)
551
618
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
552
619
        self.assertEqual('Commit message for a',
553
620
                         dlg._file_message_expander.get_label())
562
629
        tree.add(['a', 'b'], ['a-id', 'b-id'])
563
630
 
564
631
        dlg = commit.CommitDialog(tree)
565
 
        self.assertEqual([(None, None, True),
 
632
        self.assertEqual([("", "", True),
566
633
                          ('a-id', 'a', True),
567
634
                          ('b-id', 'b', True),
568
635
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
573
640
        #       do with. So instead, we just call toggle directly, and assume
574
641
        #       that toggle is hooked in correctly
575
642
        # column = dlg._treeview_files.get_column(0)
576
 
        # renderer = column.get_cell_renderers()[0]
 
643
        # renderer = column.get_cells()[0]
577
644
 
578
645
        # Toggle a single entry should set just that entry to False
579
646
        dlg._toggle_commit(None, 1, dlg._files_store)
580
 
        self.assertEqual([(None, None, True),
 
647
        self.assertEqual([("", "", True),
581
648
                          ('a-id', 'a', False),
582
649
                          ('b-id', 'b', True),
583
650
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
584
651
 
585
652
        # Toggling the main entry should set all entries
586
653
        dlg._toggle_commit(None, 0, dlg._files_store)
587
 
        self.assertEqual([(None, None, False),
 
654
        self.assertEqual([("", "", False),
588
655
                          ('a-id', 'a', False),
589
656
                          ('b-id', 'b', False),
590
657
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
591
658
 
592
659
        dlg._toggle_commit(None, 2, dlg._files_store)
593
 
        self.assertEqual([(None, None, False),
 
660
        self.assertEqual([("", "", False),
594
661
                          ('a-id', 'a', False),
595
662
                          ('b-id', 'b', True),
596
663
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
597
664
 
598
665
        dlg._toggle_commit(None, 0, dlg._files_store)
599
 
        self.assertEqual([(None, None, True),
 
666
        self.assertEqual([("", "", True),
600
667
                          ('a-id', 'a', True),
601
668
                          ('b-id', 'b', True),
602
669
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
626
693
        dlg._commit_selected_radio.set_active(True)
627
694
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
628
695
 
629
 
        dlg._treeview_files.set_cursor((1,))
 
696
        dlg._treeview_files.set_cursor(
 
697
            Gtk.TreePath(path=1), None, False)
630
698
        dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
631
 
        dlg._treeview_files.set_cursor((2,))
 
699
        dlg._treeview_files.set_cursor(
 
700
            Gtk.TreePath(path=2), None, False)
632
701
        dlg._set_file_commit_message('message\nfor b_dir\n')
633
702
 
634
703
        self.assertEqual((['a_file', 'b_dir'],
644
713
                            'message':'message\nfor b_dir\n'},
645
714
                          ]), dlg._get_specific_files())
646
715
 
647
 
 
648
 
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
649
 
    """Tests on the actual 'commit' button being pushed."""
 
716
    def test_specific_files_sanitizes_messages(self):
 
717
        tree = self.make_branch_and_tree('tree')
 
718
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
 
719
        self.build_tree(['tree/a_file', 'tree/b_dir/'])
 
720
        tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
 
721
 
 
722
        dlg = commit.CommitDialog(tree)
 
723
        dlg._commit_selected_radio.set_active(True)
 
724
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
 
725
 
 
726
        dlg._treeview_files.set_cursor(
 
727
            Gtk.TreePath(path=1), None, False)
 
728
        dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
 
729
        dlg._treeview_files.set_cursor(
 
730
            Gtk.TreePath(path=2), None, False)
 
731
        dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
 
732
 
 
733
        self.assertEqual((['a_file', 'b_dir'],
 
734
                          [{'path':'a_file', 'file_id':'1a-id',
 
735
                            'message':'Test\nmessage\nfor a_file\n'},
 
736
                           {'path':'b_dir', 'file_id':'0b-id',
 
737
                            'message':'message\nfor\nb_dir\n'},
 
738
                          ]), dlg._get_specific_files())
 
739
 
 
740
 
 
741
class QuestionHelpers(object):
650
742
 
651
743
    def _set_question_yes(self, dlg):
652
744
        """Set the dialog to answer YES to any questions."""
653
745
        self.questions = []
654
 
        def _question_yes(*args):
 
746
        def _question_yes(*args, **kwargs):
655
747
            self.questions.append(args)
656
748
            self.questions.append('YES')
657
 
            return gtk.RESPONSE_YES
 
749
            return Gtk.ResponseType.YES
658
750
        dlg._question_dialog = _question_yes
659
751
 
660
752
    def _set_question_no(self, dlg):
661
753
        """Set the dialog to answer NO to any questions."""
662
754
        self.questions = []
663
 
        def _question_no(*args):
 
755
        def _question_no(*args, **kwargs):
664
756
            self.questions.append(args)
665
757
            self.questions.append('NO')
666
 
            return gtk.RESPONSE_NO
 
758
            return Gtk.ResponseType.NO
667
759
        dlg._question_dialog = _question_no
668
760
 
 
761
 
 
762
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
 
763
    """Tests on the actual 'commit' button being pushed."""
 
764
 
669
765
    def test_bound_commit_local(self):
670
766
        tree = self.make_branch_and_tree('tree')
671
767
        self.build_tree(['tree/a'])
687
783
        self.assertEqual(last_rev, dlg.committed_revision_id)
688
784
        self.assertEqual(rev_id1, tree.branch.last_revision())
689
785
 
 
786
    def test_commit_global_sanitizes_message(self):
 
787
        tree = self.make_branch_and_tree('tree')
 
788
        self.build_tree(['tree/a'])
 
789
        tree.add(['a'], ['a-id'])
 
790
        rev_id1 = tree.commit('one')
 
791
 
 
792
        self.build_tree(['tree/b'])
 
793
        tree.add(['b'], ['b-id'])
 
794
        dlg = commit.CommitDialog(tree)
 
795
        # With the check box set, it should only effect the local branch
 
796
        dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
 
797
        dlg._do_commit()
 
798
        rev = tree.branch.repository.get_revision(tree.last_revision())
 
799
        self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
 
800
 
690
801
    def test_bound_commit_both(self):
691
802
        tree = self.make_branch_and_tree('tree')
692
803
        self.build_tree(['tree/a'])
708
819
        self.assertEqual(last_rev, dlg.committed_revision_id)
709
820
        self.assertEqual(last_rev, tree.branch.last_revision())
710
821
 
711
 
    def test_commit_no_message(self):
 
822
    def test_commit_empty_message(self):
712
823
        tree = self.make_branch_and_tree('tree')
713
824
        self.build_tree(['tree/a', 'tree/b'])
714
825
        tree.add(['a'], ['a-id'])
929
1040
 
930
1041
        dlg = commit.CommitDialog(tree)
931
1042
        dlg._commit_selected_radio.set_active(True) # enable partial
932
 
        dlg._treeview_files.set_cursor((1,))
 
1043
        dlg._treeview_files.set_cursor(
 
1044
            Gtk.TreePath(path=1), None, False)
933
1045
        dlg._set_file_commit_message('Message for A\n')
934
 
        dlg._treeview_files.set_cursor((2,))
 
1046
        dlg._treeview_files.set_cursor(
 
1047
            Gtk.TreePath(path=2), None, False)
935
1048
        dlg._set_file_commit_message('Message for B\n')
936
1049
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
937
1050
        dlg._set_global_commit_message('Commit just "a"')
943
1056
        rev = tree.branch.repository.get_revision(rev_id2)
944
1057
        self.assertEqual('Commit just "a"', rev.message)
945
1058
        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)
 
1059
        self.assertEqual(u'ld7:file_id4:a-id'
 
1060
                         '7:message14:Message for A\n'
 
1061
                         '4:path1:a'
 
1062
                         'ee',
 
1063
                         file_info)
950
1064
        self.assertEqual([{'path':'a', 'file_id':'a-id',
951
 
                           'message':'Message for A\n'},
952
 
                         ], bencode.bdecode(file_info))
 
1065
                           'message':'Message for A\n'},],
 
1066
                         bencode.bdecode(file_info.encode('UTF-8')))
953
1067
 
954
1068
    def test_commit_messages_after_merge(self):
955
1069
        tree = self.make_branch_and_tree('tree')
963
1077
        tree.merge_from_branch(tree2.branch)
964
1078
 
965
1079
        dlg = commit.CommitDialog(tree)
966
 
        dlg._treeview_files.set_cursor((1,)) # 'a'
 
1080
        dlg._treeview_files.set_cursor(
 
1081
            Gtk.TreePath(path=1), None, False) # 'a'
967
1082
        dlg._set_file_commit_message('Message for A\n')
968
1083
        # No message for 'B'
969
1084
        dlg._set_global_commit_message('Merging from "tree2"\n')
976
1091
        self.assertEqual('Merging from "tree2"\n', rev.message)
977
1092
        self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
978
1093
        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)
 
1094
        self.assertEqual(u'ld7:file_id4:a-id'
 
1095
                         '7:message14:Message for A\n'
 
1096
                         '4:path1:a'
 
1097
                         'ee',
 
1098
                         file_info)
983
1099
        self.assertEqual([{'path':'a', 'file_id':'a-id',
984
 
                           'message':'Message for A\n'},
985
 
                         ], bencode.bdecode(file_info))
 
1100
                           'message':'Message for A\n'},],
 
1101
                         bencode.bdecode(file_info.encode('UTF-8')))
986
1102
 
987
1103
    def test_commit_unicode_messages(self):
988
 
        from bzrlib.tests.test_diff import UnicodeFilename
989
 
        self.requireFeature(UnicodeFilename)
 
1104
        self.requireFeature(UnicodeFilenameFeature)
990
1105
 
991
1106
        tree = self.make_branch_and_tree('tree')
992
1107
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
994
1109
        tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
995
1110
 
996
1111
        dlg = commit.CommitDialog(tree)
997
 
        dlg._treeview_files.set_cursor((1,)) # 'a'
 
1112
        dlg._treeview_files.set_cursor(
 
1113
            Gtk.TreePath(path=1), None, False) # 'a'
998
1114
        dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
999
 
        dlg._treeview_files.set_cursor((2,)) # omega
 
1115
        dlg._treeview_files.set_cursor(
 
1116
            Gtk.TreePath(path=2), None, False) # omega
1000
1117
        dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1001
1118
        dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1002
1119
 
1031
1148
                          {'path':u'\u03a9', 'file_id':'omega-id',
1032
1149
                           'message':u'\u03a9 is the end of all things.\n'},
1033
1150
                         ], file_info_decoded)
 
1151
 
 
1152
 
 
1153
class TestSanitizeMessage(tests.TestCase):
 
1154
 
 
1155
    def assertSanitize(self, expected, original):
 
1156
        self.assertEqual(expected,
 
1157
                         commit._sanitize_and_decode_message(original))
 
1158
 
 
1159
    def test_untouched(self):
 
1160
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
 
1161
 
 
1162
    def test_converts_cr_to_lf(self):
 
1163
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
 
1164
 
 
1165
    def test_converts_crlf_to_lf(self):
 
1166
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
 
1167
 
 
1168
    def test_converts_mixed_to_lf(self):
 
1169
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
 
1170
 
 
1171
 
 
1172
class TestSavedCommitMessages(tests.TestCaseWithTransport):
 
1173
 
 
1174
    def setUp(self):
 
1175
        super(TestSavedCommitMessages, self).setUp()
 
1176
        # Install our hook
 
1177
        branch.Branch.hooks.install_named_hook(
 
1178
            'post_uncommit', commitmsgs.save_commit_messages, None)
 
1179
 
 
1180
    def _get_file_info_dict(self, rank):
 
1181
        file_info = [dict(path='a', file_id='a-id', message='a msg %d' % rank),
 
1182
                     dict(path='b', file_id='b-id', message='b msg %d' % rank)]
 
1183
        return file_info
 
1184
 
 
1185
    def _get_file_info_revprops(self, rank):
 
1186
        file_info_prop = self._get_file_info_dict(rank)
 
1187
        return {'file-info': bencode.bencode(file_info_prop).decode('UTF-8')}
 
1188
 
 
1189
    def _get_commit_message(self):
 
1190
        return self.config.get_user_option('gtk_global_commit_message')
 
1191
 
 
1192
    def _get_file_commit_messages(self):
 
1193
        return self.config.get_user_option('gtk_file_commit_messages')
 
1194
 
 
1195
 
 
1196
class TestUncommitHook(TestSavedCommitMessages):
 
1197
 
 
1198
    def setUp(self):
 
1199
        super(TestUncommitHook, self).setUp()
 
1200
        self.tree = self.make_branch_and_tree('tree')
 
1201
        self.config = self.tree.branch.get_config()
 
1202
        self.build_tree(['tree/a', 'tree/b'])
 
1203
        self.tree.add(['a'], ['a-id'])
 
1204
        self.tree.add(['b'], ['b-id'])
 
1205
        rev1 = self.tree.commit('one', rev_id='one-id',
 
1206
                                revprops=self._get_file_info_revprops(1))
 
1207
        rev2 = self.tree.commit('two', rev_id='two-id',
 
1208
                                revprops=self._get_file_info_revprops(2))
 
1209
        rev3 = self.tree.commit('three', rev_id='three-id',
 
1210
                                revprops=self._get_file_info_revprops(3))
 
1211
 
 
1212
    def test_uncommit_one_by_one(self):
 
1213
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1214
        self.assertEquals(u'three', self._get_commit_message())
 
1215
        self.assertEquals(u'd4:a-id7:a msg 34:b-id7:b msg 3e',
 
1216
                          self._get_file_commit_messages())
 
1217
 
 
1218
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1219
        self.assertEquals(u'two\n******\nthree', self._get_commit_message())
 
1220
        self.assertEquals(u'd4:a-id22:a msg 2\n******\na msg 3'
 
1221
                          '4:b-id22:b msg 2\n******\nb msg 3e',
 
1222
                          self._get_file_commit_messages())
 
1223
 
 
1224
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1225
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
 
1226
                          self._get_commit_message())
 
1227
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
 
1228
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
 
1229
                          self._get_file_commit_messages())
 
1230
 
 
1231
    def test_uncommit_all_at_once(self):
 
1232
        uncommit.uncommit(self.tree.branch, tree=self.tree, revno=1)
 
1233
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
 
1234
                          self._get_commit_message())
 
1235
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
 
1236
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
 
1237
                          self._get_file_commit_messages())
 
1238
 
 
1239
 
 
1240
class TestReusingSavedCommitMessages(TestSavedCommitMessages, QuestionHelpers):
 
1241
 
 
1242
    def setUp(self):
 
1243
        super(TestReusingSavedCommitMessages, self).setUp()
 
1244
        self.tree = self.make_branch_and_tree('tree')
 
1245
        self.config = self.tree.branch.get_config()
 
1246
        self.config.set_user_option('per_file_commits', 'true')
 
1247
        self.build_tree(['tree/a', 'tree/b'])
 
1248
        self.tree.add(['a'], ['a-id'])
 
1249
        self.tree.add(['b'], ['b-id'])
 
1250
        rev1 = self.tree.commit('one', revprops=self._get_file_info_revprops(1))
 
1251
        rev2 = self.tree.commit('two', revprops=self._get_file_info_revprops(2))
 
1252
        uncommit.uncommit(self.tree.branch, tree=self.tree)
 
1253
        self.build_tree_contents([('tree/a', 'new a content\n'),
 
1254
                                  ('tree/b', 'new b content'),])
 
1255
 
 
1256
    def _get_commit_dialog(self, tree):
 
1257
        # Ensure we will never use a dialog that can actually prompt the user
 
1258
        # during the test suite. Test *can* and *should* override with the
 
1259
        # correct question dialog type.
 
1260
        dlg = commit.CommitDialog(tree)
 
1261
        self._set_question_no(dlg)
 
1262
        return dlg
 
1263
 
 
1264
    def test_setup_saved_messages(self):
 
1265
        # Check the initial setup
 
1266
        self.assertEquals(u'two', self._get_commit_message())
 
1267
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
 
1268
                          self._get_file_commit_messages())
 
1269
 
 
1270
    def test_messages_are_reloaded(self):
 
1271
        dlg = self._get_commit_dialog(self.tree)
 
1272
        self.assertEquals(u'two', dlg._get_global_commit_message())
 
1273
        self.assertEquals(([u'a', u'b'],
 
1274
                           [{ 'path': 'a',
 
1275
                             'file_id': 'a-id', 'message': 'a msg 2',},
 
1276
                           {'path': 'b',
 
1277
                            'file_id': 'b-id', 'message': 'b msg 2',}],),
 
1278
                          dlg._get_specific_files())
 
1279
 
 
1280
    def test_messages_are_consumed(self):
 
1281
        dlg = self._get_commit_dialog(self.tree)
 
1282
        dlg._do_commit()
 
1283
        self.assertEquals(u'', self._get_commit_message())
 
1284
        self.assertEquals(u'de', self._get_file_commit_messages())
 
1285
 
 
1286
    def test_messages_are_saved_on_cancel_if_required(self):
 
1287
        dlg = self._get_commit_dialog(self.tree)
 
1288
        self._set_question_yes(dlg) # Save messages
 
1289
        dlg._do_cancel()
 
1290
        self.assertEquals(u'two', self._get_commit_message())
 
1291
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
 
1292
                          self._get_file_commit_messages())
 
1293
 
 
1294
    def test_messages_are_cleared_on_cancel_if_required(self):
 
1295
        dlg = self._get_commit_dialog(self.tree)
 
1296
        self._set_question_no(dlg) # Don't save messages
 
1297
        dlg._do_cancel()
 
1298
        self.assertEquals(u'', self._get_commit_message())
 
1299
        self.assertEquals(u'de',
 
1300
                          self._get_file_commit_messages())
 
1301
 
 
1302
 
 
1303
class BzrHandlePatchTestCase(tests.TestCase):
 
1304
 
 
1305
    def setUp(self):
 
1306
        top = os.path.abspath(os.path.join(
 
1307
            os.path.dirname(__file__), os.pardir))
 
1308
        self.script = os.path.join(top, 'bzr-handle-patch')
 
1309
        self.env = dict(os.environ)
 
1310
        self.env['BZR_PLUGINS_AT'] = 'gtk@%s' % top
 
1311
        self.patch = NamedTemporaryFile()
 
1312
        self.patch.write('\n'.join([
 
1313
            "=== added file '_test.txt'",
 
1314
            "--- _test.txt      1970-01-01 00:00:00 +0000",
 
1315
            "+++ _test.txt      2012-02-03 20:00:34 +0000",
 
1316
            "@@ -0,0 +1,1 @@",
 
1317
            "+hello",
 
1318
            ]))
 
1319
        self.patch.flush()
 
1320
        super(BzrHandlePatchTestCase, self).setUp()
 
1321
 
 
1322
    def test_smoketest(self):
 
1323
        # This is a smoke test to verify the process starts.
 
1324
        bzr_notify = subprocess.Popen(
 
1325
            [self.script, self.patch.name, 'test'],
 
1326
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env)
 
1327
        stdout, stderr = bzr_notify.communicate()
 
1328
        self.assertEqual('', stdout)
 
1329
        self.assertEqual('', stderr)