/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: Martin Albisetti
  • Date: 2008-03-04 18:29:24 UTC
  • mfrom: (423.13.4 nautilus-fix)
  • mto: This revision was merged to the branch mainline in revision 439.
  • Revision ID: beuno@beuno-laptop-20080304182924-yvm7ds9zwpenotg5
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007, 2008 John Arbash Meinel <john@arbash-meinel.com>
 
1
# Copyright (C) 2007 John Arbash Meinel <john@arbash-meinel.com>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Test the Commit functionality."""
18
18
 
19
19
import os
20
 
import subprocess
21
 
from tempfile import NamedTemporaryFile
22
20
 
23
 
from gi.repository import Gtk
 
21
import gtk
24
22
 
25
23
from bzrlib import (
26
 
    branch,
27
24
    tests,
28
 
    uncommit,
 
25
    revision,
29
26
    )
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
 
27
from bzrlib.util import bencode
35
28
 
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
 
29
from bzrlib.plugins.gtk import commit
42
30
 
43
31
 
44
32
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
50
38
        tree = self.make_branch_and_tree('.')
51
39
        tree.commit('one')
52
40
 
53
 
        self.addCleanup(tree.lock_read().unlock)
54
 
        self.assertEquals([], list(commit.pending_revisions(tree)))
 
41
        self.assertIs(None, commit.pending_revisions(tree))
55
42
 
56
43
    def test_pending_revisions_simple(self):
57
44
        tree = self.make_branch_and_tree('tree')
61
48
        tree.merge_from_branch(tree2.branch)
62
49
        self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
63
50
 
64
 
        self.addCleanup(tree.lock_read().unlock)
65
 
        pending_revisions = list(commit.pending_revisions(tree))
 
51
        pending_revisions = commit.pending_revisions(tree)
66
52
        # One primary merge
67
53
        self.assertEqual(1, len(pending_revisions))
68
54
        # Revision == rev_id2
80
66
        tree.merge_from_branch(tree2.branch)
81
67
        self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
82
68
 
83
 
        self.addCleanup(tree.lock_read().unlock)
84
 
        pending_revisions = list(commit.pending_revisions(tree))
 
69
        pending_revisions = commit.pending_revisions(tree)
85
70
        # One primary merge
86
71
        self.assertEqual(1, len(pending_revisions))
87
72
        # Revision == rev_id2
96
81
        rev_id1 = tree.commit('one')
97
82
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
98
83
        rev_id2 = tree2.commit('two')
 
84
        rev_id3 = tree2.commit('three')
99
85
        tree3 = tree2.bzrdir.sprout('tree3').open_workingtree()
100
 
        rev_id3 = tree2.commit('three')
101
86
        rev_id4 = tree3.commit('four')
102
87
        rev_id5 = tree3.commit('five')
103
88
        tree.merge_from_branch(tree2.branch)
104
 
        tree.merge_from_branch(tree3.branch, force=True)
 
89
        tree.merge_from_branch(tree3.branch)
105
90
        self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
106
91
 
107
 
        self.addCleanup(tree.lock_read().unlock)
108
 
        pending_revisions = list(commit.pending_revisions(tree))
 
92
        pending_revisions = commit.pending_revisions(tree)
109
93
        # Two primary merges
110
94
        self.assertEqual(2, len(pending_revisions))
111
95
        # Revision == rev_id2
148
132
 
149
133
class TestCommitDialogSimple(tests.TestCaseWithTransport):
150
134
 
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
 
 
171
135
    def test_setup_parameters_no_pending(self):
172
136
        tree = self.make_branch_and_tree('tree')
173
137
        rev_id = tree.commit('first')
174
138
 
175
139
        dlg = CommitDialogNoWidgets(tree)
176
140
        self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
177
 
        self.assertEquals([], dlg._pending)
 
141
        self.assertIs(None, dlg._pending)
178
142
        self.assertFalse(dlg._is_checkout)
179
143
 
180
144
    def test_setup_parameters_checkout(self):
185
149
 
186
150
        dlg = CommitDialogNoWidgets(tree2)
187
151
        self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
188
 
        self.assertEquals([], dlg._pending)
 
152
        self.assertIs(None, dlg._pending)
189
153
        self.assertTrue(dlg._is_checkout)
190
154
 
191
155
    def test_setup_parameters_pending(self):
216
180
        self.assertEqual([], delta.removed)
217
181
        self.assertEqual([(u'a', 'a-id', 'file')], delta.added)
218
182
 
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
 
 
245
183
 
246
184
class TestCommitDialog(tests.TestCaseWithTransport):
247
185
 
269
207
 
270
208
        commit_col = dlg._treeview_files.get_column(0)
271
209
        self.assertEqual('Commit', commit_col.get_title())
272
 
        renderer = commit_col.get_cells()[0]
 
210
        renderer = commit_col.get_cell_renderers()[0]
273
211
        self.assertTrue(renderer.get_property('activatable'))
274
212
 
275
213
        self.assertEqual('Commit all changes',
294
232
 
295
233
        commit_col = dlg._treeview_files.get_column(0)
296
234
        self.assertEqual('Commit*', commit_col.get_title())
297
 
        renderer = commit_col.get_cells()[0]
 
235
        renderer = commit_col.get_cell_renderers()[0]
298
236
        self.assertFalse(renderer.get_property('activatable'))
299
237
 
300
238
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
328
266
                               committer='Jerry Foo <jerry@foo.com>',
329
267
                               timestamp=1191372278.05,
330
268
                               timezone=+7200)
331
 
        tree.merge_from_branch(tree3.branch, force=True)
 
269
        tree.merge_from_branch(tree3.branch)
332
270
 
333
271
        dlg = commit.CommitDialog(tree)
334
272
        # TODO: assert that the pending box is set to show
346
284
 
347
285
        dlg = commit.CommitDialog(tree)
348
286
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
349
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
287
        self.assertEqual([(None, None, True, 'All Files', ''),
350
288
                          ('a-id', 'a', True, 'a', 'added'),
351
289
                          ('b-id', 'b', True, 'b/', 'added'),
352
290
                          ('c-id', 'b/c', True, 'b/c', 'added'),
363
301
 
364
302
        dlg = commit.CommitDialog(tree)
365
303
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
366
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
304
        self.assertEqual([(None, None, True, 'All Files', ''),
367
305
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
368
306
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
369
307
                         ], values)
378
316
 
379
317
        dlg = commit.CommitDialog(tree)
380
318
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
381
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
319
        self.assertEqual([(None, None, True, 'All Files', ''),
382
320
                          ('a-id', 'a', True, 'a', 'modified'),
383
321
                         ], values)
384
322
 
398
336
 
399
337
        dlg = commit.CommitDialog(tree)
400
338
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
401
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
339
        self.assertEqual([(None, None, True, 'All Files', ''),
402
340
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
403
341
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
404
342
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
421
359
 
422
360
        dlg = commit.CommitDialog(tree)
423
361
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
424
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
362
        self.assertEqual([(None, None, True, 'All Files', ''),
425
363
                          ('a-id', 'a', True, 'a => a/', 'kind changed'),
426
364
                          # ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
427
365
                         ], values)
437
375
 
438
376
        dlg = commit.CommitDialog(tree)
439
377
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
440
 
        self.assertEqual([("", "", True, 'All Files', ''),
 
378
        self.assertEqual([(None, None, True, 'All Files', ''),
441
379
                          ('a-id', 'a', True, 'a', 'removed'),
442
380
                          ('b-id', 'b', True, 'b/', 'removed'),
443
381
                         ], values)
444
382
        # All Files should be selected
445
 
        self.assertEqual(
446
 
            (Gtk.TreePath(path=0), None), dlg._treeview_files.get_cursor())
 
383
        self.assertEqual(((0,), None), dlg._treeview_files.get_cursor())
447
384
 
448
385
    def test_filelist_with_selected(self):
449
386
        tree = self.make_branch_and_tree('tree')
452
389
 
453
390
        dlg = commit.CommitDialog(tree, selected='a')
454
391
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
455
 
        self.assertEqual([("", "", False, 'All Files', ''),
 
392
        self.assertEqual([(None, None, False, 'All Files', ''),
456
393
                          ('a-id', 'a', True, 'a', 'added'),
457
394
                          ('b-id', 'b', False, 'b/', 'added'),
458
395
                         ], values)
459
396
        # This file should also be selected in the file list, rather than the
460
397
        # 'All Files' selection
461
 
        self.assertEqual(
462
 
            (Gtk.TreePath(path=1), None), dlg._treeview_files.get_cursor())
 
398
        self.assertEqual(((1,), None), dlg._treeview_files.get_cursor())
463
399
 
464
400
    def test_diff_view(self):
465
401
        tree = self.make_branch_and_tree('tree')
473
409
        dlg = commit.CommitDialog(tree)
474
410
        diff_buffer = dlg._diff_view.buffer
475
411
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
476
 
                                    diff_buffer.get_end_iter(),
477
 
                                    True).splitlines(True)
 
412
                                    diff_buffer.get_end_iter()).splitlines(True)
478
413
 
479
 
        self.assertEqual("=== modified file 'a'\n", text[0])
 
414
        self.assertEqual("=== removed file 'b'\n", text[0])
480
415
        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],
481
424
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
482
 
        self.assertContainsRe(text[2],
483
 
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
484
 
        self.assertEqual('@@ -1,1 +1,1 @@\n', text[3])
485
 
        self.assertEqual('-contents of tree/a\n', text[4])
486
 
        self.assertEqual('+new contents for a\n', text[5])
487
 
        self.assertEqual('\n', text[6])
488
 
 
489
 
        self.assertEqual("=== removed file 'b'\n", text[7])
490
425
        self.assertContainsRe(text[8],
491
 
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
492
 
        self.assertEqual('+++ b\t1970-01-01 00:00:00 +0000\n', text[9])
493
 
        self.assertEqual('@@ -1,1 +0,0 @@\n', text[10])
494
 
        self.assertEqual('-contents of tree/b\n', text[11])
 
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])
495
430
        self.assertEqual('\n', text[12])
496
431
 
497
432
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
525
460
        self.assertFalse(dlg._file_message_expander.get_expanded())
526
461
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
527
462
 
528
 
        dlg._treeview_files.set_cursor(
529
 
            Gtk.TreePath(path=1), None, False)
 
463
        dlg._treeview_files.set_cursor((1,))
530
464
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
531
465
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
532
 
                                    diff_buffer.get_end_iter(),
533
 
                                    True).splitlines(True)
 
466
                                    diff_buffer.get_end_iter()).splitlines(True)
534
467
        self.assertEqual("=== added file 'a'\n", text[0])
535
468
        self.assertContainsRe(text[1],
536
469
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
544
477
        self.assertTrue(dlg._file_message_expander.get_expanded())
545
478
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
546
479
 
547
 
        dlg._treeview_files.set_cursor(
548
 
            Gtk.TreePath(path=2), None, False)
 
480
        dlg._treeview_files.set_cursor((2,))
549
481
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
550
482
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
551
 
                                    diff_buffer.get_end_iter(),
552
 
                                    True).splitlines(True)
 
483
                                    diff_buffer.get_end_iter()).splitlines(True)
553
484
        self.assertEqual("=== added file 'b'\n", text[0])
554
485
        self.assertContainsRe(text[1],
555
486
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
563
494
        self.assertTrue(dlg._file_message_expander.get_expanded())
564
495
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
565
496
 
566
 
        dlg._treeview_files.set_cursor(
567
 
            Gtk.TreePath(path=0), None, False)
 
497
        dlg._treeview_files.set_cursor((0,))
568
498
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
569
499
        self.assertEqual('File commit message',
570
500
                         dlg._file_message_expander.get_label())
580
510
 
581
511
        def get_file_text():
582
512
            buf = dlg._file_message_text_view.get_buffer()
583
 
            return buf.get_text(
584
 
                buf.get_start_iter(), buf.get_end_iter(), True)
 
513
            return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
585
514
 
586
515
        def get_saved_text(path):
587
516
            """Get the saved text for a given record."""
594
523
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
595
524
        self.assertEqual('', get_file_text())
596
525
 
597
 
        dlg._treeview_files.set_cursor(
598
 
            Gtk.TreePath(path=1), None, False)
 
526
        dlg._treeview_files.set_cursor((1,))
599
527
        self.assertEqual('Commit message for a',
600
528
                         dlg._file_message_expander.get_label())
601
529
        self.assertTrue(dlg._file_message_expander.get_expanded())
608
536
        # We should have updated the ListStore with the new file commit info
609
537
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
610
538
 
611
 
        dlg._treeview_files.set_cursor(
612
 
            Gtk.TreePath(path=2), None, False)
 
539
        dlg._treeview_files.set_cursor((2,))
613
540
        self.assertEqual('Commit message for b/',
614
541
                         dlg._file_message_expander.get_label())
615
542
        self.assertTrue(dlg._file_message_expander.get_expanded())
620
547
        dlg._set_file_commit_message('More text\nfor b\n')
621
548
        # Now switch back to 'a'. The message should be saved, and the buffer
622
549
        # should be updated with the other text
623
 
        dlg._treeview_files.set_cursor(
624
 
            Gtk.TreePath(path=1), None, False)
 
550
        dlg._treeview_files.set_cursor((1,))
625
551
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
626
552
        self.assertEqual('Commit message for a',
627
553
                         dlg._file_message_expander.get_label())
636
562
        tree.add(['a', 'b'], ['a-id', 'b-id'])
637
563
 
638
564
        dlg = commit.CommitDialog(tree)
639
 
        self.assertEqual([("", "", True),
 
565
        self.assertEqual([(None, None, True),
640
566
                          ('a-id', 'a', True),
641
567
                          ('b-id', 'b', True),
642
568
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
647
573
        #       do with. So instead, we just call toggle directly, and assume
648
574
        #       that toggle is hooked in correctly
649
575
        # column = dlg._treeview_files.get_column(0)
650
 
        # renderer = column.get_cells()[0]
 
576
        # renderer = column.get_cell_renderers()[0]
651
577
 
652
578
        # Toggle a single entry should set just that entry to False
653
579
        dlg._toggle_commit(None, 1, dlg._files_store)
654
 
        self.assertEqual([("", "", True),
 
580
        self.assertEqual([(None, None, True),
655
581
                          ('a-id', 'a', False),
656
582
                          ('b-id', 'b', True),
657
583
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
658
584
 
659
585
        # Toggling the main entry should set all entries
660
586
        dlg._toggle_commit(None, 0, dlg._files_store)
661
 
        self.assertEqual([("", "", False),
 
587
        self.assertEqual([(None, None, False),
662
588
                          ('a-id', 'a', False),
663
589
                          ('b-id', 'b', False),
664
590
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
665
591
 
666
592
        dlg._toggle_commit(None, 2, dlg._files_store)
667
 
        self.assertEqual([("", "", False),
 
593
        self.assertEqual([(None, None, False),
668
594
                          ('a-id', 'a', False),
669
595
                          ('b-id', 'b', True),
670
596
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
671
597
 
672
598
        dlg._toggle_commit(None, 0, dlg._files_store)
673
 
        self.assertEqual([("", "", True),
 
599
        self.assertEqual([(None, None, True),
674
600
                          ('a-id', 'a', True),
675
601
                          ('b-id', 'b', True),
676
602
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
700
626
        dlg._commit_selected_radio.set_active(True)
701
627
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
702
628
 
703
 
        dlg._treeview_files.set_cursor(
704
 
            Gtk.TreePath(path=1), None, False)
 
629
        dlg._treeview_files.set_cursor((1,))
705
630
        dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
706
 
        dlg._treeview_files.set_cursor(
707
 
            Gtk.TreePath(path=2), None, False)
 
631
        dlg._treeview_files.set_cursor((2,))
708
632
        dlg._set_file_commit_message('message\nfor b_dir\n')
709
633
 
710
634
        self.assertEqual((['a_file', 'b_dir'],
720
644
                            'message':'message\nfor b_dir\n'},
721
645
                          ]), dlg._get_specific_files())
722
646
 
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):
 
647
 
 
648
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
 
649
    """Tests on the actual 'commit' button being pushed."""
749
650
 
750
651
    def _set_question_yes(self, dlg):
751
652
        """Set the dialog to answer YES to any questions."""
752
653
        self.questions = []
753
 
        def _question_yes(*args, **kwargs):
 
654
        def _question_yes(*args):
754
655
            self.questions.append(args)
755
656
            self.questions.append('YES')
756
 
            return Gtk.ResponseType.YES
 
657
            return gtk.RESPONSE_YES
757
658
        dlg._question_dialog = _question_yes
758
659
 
759
660
    def _set_question_no(self, dlg):
760
661
        """Set the dialog to answer NO to any questions."""
761
662
        self.questions = []
762
 
        def _question_no(*args, **kwargs):
 
663
        def _question_no(*args):
763
664
            self.questions.append(args)
764
665
            self.questions.append('NO')
765
 
            return Gtk.ResponseType.NO
 
666
            return gtk.RESPONSE_NO
766
667
        dlg._question_dialog = _question_no
767
668
 
768
 
 
769
 
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
770
 
    """Tests on the actual 'commit' button being pushed."""
771
 
 
772
669
    def test_bound_commit_local(self):
773
670
        tree = self.make_branch_and_tree('tree')
774
671
        self.build_tree(['tree/a'])
790
687
        self.assertEqual(last_rev, dlg.committed_revision_id)
791
688
        self.assertEqual(rev_id1, tree.branch.last_revision())
792
689
 
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
 
 
808
690
    def test_bound_commit_both(self):
809
691
        tree = self.make_branch_and_tree('tree')
810
692
        self.build_tree(['tree/a'])
826
708
        self.assertEqual(last_rev, dlg.committed_revision_id)
827
709
        self.assertEqual(last_rev, tree.branch.last_revision())
828
710
 
829
 
    def test_commit_empty_message(self):
 
711
    def test_commit_no_message(self):
830
712
        tree = self.make_branch_and_tree('tree')
831
713
        self.build_tree(['tree/a', 'tree/b'])
832
714
        tree.add(['a'], ['a-id'])
1047
929
 
1048
930
        dlg = commit.CommitDialog(tree)
1049
931
        dlg._commit_selected_radio.set_active(True) # enable partial
1050
 
        dlg._treeview_files.set_cursor(
1051
 
            Gtk.TreePath(path=1), None, False)
 
932
        dlg._treeview_files.set_cursor((1,))
1052
933
        dlg._set_file_commit_message('Message for A\n')
1053
 
        dlg._treeview_files.set_cursor(
1054
 
            Gtk.TreePath(path=2), None, False)
 
934
        dlg._treeview_files.set_cursor((2,))
1055
935
        dlg._set_file_commit_message('Message for B\n')
1056
936
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
1057
937
        dlg._set_global_commit_message('Commit just "a"')
1063
943
        rev = tree.branch.repository.get_revision(rev_id2)
1064
944
        self.assertEqual('Commit just "a"', rev.message)
1065
945
        file_info = rev.properties['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)
 
946
        self.assertEqual('ld7:file_id4:a-id'
 
947
                           '7:message14:Message for A\n'
 
948
                           '4:path1:a'
 
949
                         'ee', file_info)
1071
950
        self.assertEqual([{'path':'a', 'file_id':'a-id',
1072
 
                           'message':'Message for A\n'},],
1073
 
                         bencode.bdecode(file_info.encode('UTF-8')))
 
951
                           'message':'Message for A\n'},
 
952
                         ], bencode.bdecode(file_info))
1074
953
 
1075
954
    def test_commit_messages_after_merge(self):
1076
955
        tree = self.make_branch_and_tree('tree')
1084
963
        tree.merge_from_branch(tree2.branch)
1085
964
 
1086
965
        dlg = commit.CommitDialog(tree)
1087
 
        dlg._treeview_files.set_cursor(
1088
 
            Gtk.TreePath(path=1), None, False) # 'a'
 
966
        dlg._treeview_files.set_cursor((1,)) # 'a'
1089
967
        dlg._set_file_commit_message('Message for A\n')
1090
968
        # No message for 'B'
1091
969
        dlg._set_global_commit_message('Merging from "tree2"\n')
1098
976
        self.assertEqual('Merging from "tree2"\n', rev.message)
1099
977
        self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
1100
978
        file_info = rev.properties['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)
 
979
        self.assertEqual('ld7:file_id4:a-id'
 
980
                           '7:message14:Message for A\n'
 
981
                           '4:path1:a'
 
982
                         'ee', file_info)
1106
983
        self.assertEqual([{'path':'a', 'file_id':'a-id',
1107
 
                           'message':'Message for A\n'},],
1108
 
                         bencode.bdecode(file_info.encode('UTF-8')))
 
984
                           'message':'Message for A\n'},
 
985
                         ], bencode.bdecode(file_info))
1109
986
 
1110
987
    def test_commit_unicode_messages(self):
1111
 
        self.requireFeature(UnicodeFilenameFeature)
 
988
        from bzrlib.tests.test_diff import UnicodeFilename
 
989
        self.requireFeature(UnicodeFilename)
1112
990
 
1113
991
        tree = self.make_branch_and_tree('tree')
1114
992
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
1116
994
        tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
1117
995
 
1118
996
        dlg = commit.CommitDialog(tree)
1119
 
        dlg._treeview_files.set_cursor(
1120
 
            Gtk.TreePath(path=1), None, False) # 'a'
 
997
        dlg._treeview_files.set_cursor((1,)) # 'a'
1121
998
        dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
1122
 
        dlg._treeview_files.set_cursor(
1123
 
            Gtk.TreePath(path=2), None, False) # omega
 
999
        dlg._treeview_files.set_cursor((2,)) # omega
1124
1000
        dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1125
1001
        dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1126
1002
 
1155
1031
                          {'path':u'\u03a9', 'file_id':'omega-id',
1156
1032
                           'message':u'\u03a9 is the end of all things.\n'},
1157
1033
                         ], 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)