1
# Copyright (C) 2007, 2008 John Arbash Meinel <john@arbash-meinel.com>
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Test the Commit functionality."""
29
from bzrlib.tests.features import UnicodeFilenameFeature
30
except ImportError: # bzr < 2.5
31
from bzrlib.tests import UnicodeFilenameFeature
33
from bzrlib import bencode
35
from bzrlib.util import bencode
37
from bzrlib.plugins.gtk import commit
40
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
41
# TestCaseWithTransport, just a TestCaseWithMemoryTransport or somesuch.
43
class TestPendingRevisions(tests.TestCaseWithTransport):
45
def test_pending_revisions_none(self):
46
tree = self.make_branch_and_tree('.')
49
self.assertIs(None, commit.pending_revisions(tree))
51
def test_pending_revisions_simple(self):
52
tree = self.make_branch_and_tree('tree')
53
rev_id1 = tree.commit('one')
54
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
55
rev_id2 = tree2.commit('two')
56
tree.merge_from_branch(tree2.branch)
57
self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
59
pending_revisions = commit.pending_revisions(tree)
61
self.assertEqual(1, len(pending_revisions))
63
self.assertEqual(rev_id2, pending_revisions[0][0].revision_id)
64
# No children of this revision.
65
self.assertEqual([], pending_revisions[0][1])
67
def test_pending_revisions_with_children(self):
68
tree = self.make_branch_and_tree('tree')
69
rev_id1 = tree.commit('one')
70
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
71
rev_id2 = tree2.commit('two')
72
rev_id3 = tree2.commit('three')
73
rev_id4 = tree2.commit('four')
74
tree.merge_from_branch(tree2.branch)
75
self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
77
pending_revisions = commit.pending_revisions(tree)
79
self.assertEqual(1, len(pending_revisions))
81
self.assertEqual(rev_id4, pending_revisions[0][0].revision_id)
82
# Two children for this revision
83
self.assertEqual(2, len(pending_revisions[0][1]))
84
self.assertEqual(rev_id3, pending_revisions[0][1][0].revision_id)
85
self.assertEqual(rev_id2, pending_revisions[0][1][1].revision_id)
87
def test_pending_revisions_multi_merge(self):
88
tree = self.make_branch_and_tree('tree')
89
rev_id1 = tree.commit('one')
90
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
91
rev_id2 = tree2.commit('two')
92
tree3 = tree2.bzrdir.sprout('tree3').open_workingtree()
93
rev_id3 = tree2.commit('three')
94
rev_id4 = tree3.commit('four')
95
rev_id5 = tree3.commit('five')
96
tree.merge_from_branch(tree2.branch)
97
tree.merge_from_branch(tree3.branch, force=True)
98
self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
100
pending_revisions = commit.pending_revisions(tree)
102
self.assertEqual(2, len(pending_revisions))
103
# Revision == rev_id2
104
self.assertEqual(rev_id3, pending_revisions[0][0].revision_id)
105
self.assertEqual(rev_id5, pending_revisions[1][0].revision_id)
106
# One child for the first merge
107
self.assertEqual(1, len(pending_revisions[0][1]))
108
self.assertEqual(rev_id2, pending_revisions[0][1][0].revision_id)
109
# One child for the second merge
110
self.assertEqual(1, len(pending_revisions[1][1]))
111
self.assertEqual(rev_id4, pending_revisions[1][1][0].revision_id)
114
class Test_RevToPendingInfo(tests.TestCaseWithTransport):
116
def test_basic_info(self):
117
tree = self.make_branch_and_tree('tree')
118
rev_id = tree.commit('Multiline\ncommit\nmessage',
119
committer='Joe Foo <joe@foo.com>',
120
timestamp=1191012408.674,
123
rev = tree.branch.repository.get_revision(rev_id)
124
rev_dict = commit.CommitDialog._rev_to_pending_info(rev)
125
self.assertEqual({'committer':'Joe Foo',
126
'summary':'Multiline',
128
'revision_id':rev_id,
132
class CommitDialogNoWidgets(commit.CommitDialog):
135
pass # Don't create any widgets here
137
def fill_in_data(self):
138
pass # With no widgets, there are no widgets to fill out
141
class TestCommitDialogSimple(tests.TestCaseWithTransport):
143
def test_setup_parameters_no_pending(self):
144
tree = self.make_branch_and_tree('tree')
145
rev_id = tree.commit('first')
147
dlg = CommitDialogNoWidgets(tree)
148
self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
149
self.assertIs(None, dlg._pending)
150
self.assertFalse(dlg._is_checkout)
152
def test_setup_parameters_checkout(self):
153
tree = self.make_branch_and_tree('tree')
154
rev_id = tree.commit('first')
155
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
156
tree2.branch.bind(tree.branch)
158
dlg = CommitDialogNoWidgets(tree2)
159
self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
160
self.assertIs(None, dlg._pending)
161
self.assertTrue(dlg._is_checkout)
163
def test_setup_parameters_pending(self):
164
tree = self.make_branch_and_tree('tree')
165
rev_id1 = tree.commit('one')
166
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
167
rev_id2 = tree2.commit('two')
168
tree.merge_from_branch(tree2.branch)
170
dlg = CommitDialogNoWidgets(tree)
171
self.assertEqual(rev_id1, dlg._basis_tree.get_revision_id())
172
self.assertIsNot(None, dlg._pending)
173
self.assertEqual(1, len(dlg._pending))
174
self.assertEqual(rev_id2, dlg._pending[0][0].revision_id)
176
def test_setup_parameters_delta(self):
177
tree = self.make_branch_and_tree('tree')
178
self.build_tree(['tree/a'])
179
tree.add(['a'], ['a-id'])
181
dlg = CommitDialogNoWidgets(tree)
182
self.assertIs(None, dlg._delta)
186
self.assertEqual([], delta.modified)
187
self.assertEqual([], delta.renamed)
188
self.assertEqual([], delta.removed)
189
self.assertEqual([(u'a', 'a-id', 'file')], delta.added)
192
class TestCommitDialog(tests.TestCaseWithTransport):
194
def test_bound(self):
195
tree = self.make_branch_and_tree('tree')
196
rev_id = tree.commit('first')
197
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
198
tree2.branch.bind(tree.branch)
200
# tree is not a checkout
201
dlg = commit.CommitDialog(tree)
202
self.assertFalse(dlg._check_local.get_property('visible'))
204
# tree2 is a checkout
205
dlg2 = commit.CommitDialog(tree2)
206
self.assertTrue(dlg2._check_local.get_property('visible'))
208
def test_no_pending(self):
209
tree = self.make_branch_and_tree('tree')
210
rev_id1 = tree.commit('one')
212
dlg = commit.CommitDialog(tree)
214
self.assertFalse(dlg._pending_box.get_property('visible'))
216
commit_col = dlg._treeview_files.get_column(0)
217
self.assertEqual('Commit', commit_col.get_title())
218
renderer = commit_col.get_cell_renderers()[0]
219
self.assertTrue(renderer.get_property('activatable'))
221
self.assertEqual('Commit all changes',
222
dlg._commit_all_files_radio.get_label())
223
self.assertTrue(dlg._commit_all_files_radio.get_property('sensitive'))
224
self.assertTrue(dlg._commit_selected_radio.get_property('sensitive'))
226
def test_pending(self):
227
tree = self.make_branch_and_tree('tree')
228
rev_id1 = tree.commit('one')
230
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
231
rev_id2 = tree2.commit('two',
232
committer='Joe Foo <joe@foo.com>',
233
timestamp=1191264271.05,
235
tree.merge_from_branch(tree2.branch)
237
dlg = commit.CommitDialog(tree)
239
self.assertTrue(dlg._pending_box.get_property('visible'))
241
commit_col = dlg._treeview_files.get_column(0)
242
self.assertEqual('Commit*', commit_col.get_title())
243
renderer = commit_col.get_cell_renderers()[0]
244
self.assertFalse(renderer.get_property('activatable'))
246
values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
247
self.assertEqual([(rev_id2, '2007-10-01', 'Joe Foo', 'two')], values)
249
self.assertEqual('Commit all changes*',
250
dlg._commit_all_files_radio.get_label())
251
self.assertFalse(dlg._commit_all_files_radio.get_property('sensitive'))
252
self.assertFalse(dlg._commit_selected_radio.get_property('sensitive'))
254
def test_pending_multiple(self):
255
tree = self.make_branch_and_tree('tree')
256
rev_id1 = tree.commit('one')
258
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
259
rev_id2 = tree2.commit('two',
260
committer='Joe Foo <joe@foo.com>',
261
timestamp=1191264271.05,
263
rev_id3 = tree2.commit('three',
264
committer='Jerry Foo <jerry@foo.com>',
265
timestamp=1191264278.05,
267
tree.merge_from_branch(tree2.branch)
268
tree3 = tree.bzrdir.sprout('tree3').open_workingtree()
269
rev_id4 = tree3.commit('four',
270
committer='Joe Foo <joe@foo.com>',
271
timestamp=1191264279.05,
273
rev_id5 = tree3.commit('five',
274
committer='Jerry Foo <jerry@foo.com>',
275
timestamp=1191372278.05,
277
tree.merge_from_branch(tree3.branch, force=True)
279
dlg = commit.CommitDialog(tree)
280
# TODO: assert that the pending box is set to show
281
values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
282
self.assertEqual([(rev_id3, '2007-10-01', 'Jerry Foo', 'three'),
283
(rev_id2, '2007-10-01', 'Joe Foo', 'two'),
284
(rev_id5, '2007-10-03', 'Jerry Foo', 'five'),
285
(rev_id4, '2007-10-01', 'Joe Foo', 'four'),
288
def test_filelist_added(self):
289
tree = self.make_branch_and_tree('tree')
290
self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
291
tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
293
dlg = commit.CommitDialog(tree)
294
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
295
self.assertEqual([(None, None, True, 'All Files', ''),
296
('a-id', 'a', True, 'a', 'added'),
297
('b-id', 'b', True, 'b/', 'added'),
298
('c-id', 'b/c', True, 'b/c', 'added'),
301
def test_filelist_renamed(self):
302
tree = self.make_branch_and_tree('tree')
303
self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
304
tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
305
rev_id1 = tree.commit('one')
307
tree.rename_one('b', 'd')
308
tree.rename_one('a', 'd/a')
310
dlg = commit.CommitDialog(tree)
311
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
312
self.assertEqual([(None, None, True, 'All Files', ''),
313
('b-id', 'd', True, 'b/ => d/', 'renamed'),
314
('a-id', 'd/a', True, 'a => d/a', 'renamed'),
317
def test_filelist_modified(self):
318
tree = self.make_branch_and_tree('tree')
319
self.build_tree(['tree/a'])
320
tree.add(['a'], ['a-id'])
321
rev_id1 = tree.commit('one')
323
self.build_tree_contents([('tree/a', 'new contents for a\n')])
325
dlg = commit.CommitDialog(tree)
326
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
327
self.assertEqual([(None, None, True, 'All Files', ''),
328
('a-id', 'a', True, 'a', 'modified'),
331
def test_filelist_renamed_and_modified(self):
332
tree = self.make_branch_and_tree('tree')
333
self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
334
tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
335
rev_id1 = tree.commit('one')
337
tree.rename_one('b', 'd')
338
tree.rename_one('a', 'd/a')
339
self.build_tree_contents([('tree/d/a', 'new contents for a\n'),
340
('tree/d/c', 'new contents for c\n'),
342
# 'c' is not considered renamed, because only its parent was moved, it
343
# stayed in the same directory
345
dlg = commit.CommitDialog(tree)
346
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
347
self.assertEqual([(None, None, True, 'All Files', ''),
348
('b-id', 'd', True, 'b/ => d/', 'renamed'),
349
('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
350
('c-id', 'd/c', True, 'd/c', 'modified'),
353
def test_filelist_kind_changed(self):
354
tree = self.make_branch_and_tree('tree')
355
self.build_tree(['tree/a', 'tree/b'])
356
tree.add(['a', 'b'], ['a-id', 'b-id'])
360
self.build_tree(['tree/a/'])
361
# XXX: This is technically valid, and the file list handles it fine,
362
# but 'show_diff_trees()' does not, so we skip this part of the
364
# tree.rename_one('b', 'c')
365
# os.remove('tree/c')
366
# self.build_tree(['tree/c/'])
368
dlg = commit.CommitDialog(tree)
369
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
370
self.assertEqual([(None, None, True, 'All Files', ''),
371
('a-id', 'a', True, 'a => a/', 'kind changed'),
372
# ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
375
def test_filelist_removed(self):
376
tree = self.make_branch_and_tree('tree')
377
self.build_tree(['tree/a', 'tree/b/'])
378
tree.add(['a', 'b'], ['a-id', 'b-id'])
382
tree.remove('b', force=True)
384
dlg = commit.CommitDialog(tree)
385
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
386
self.assertEqual([(None, None, True, 'All Files', ''),
387
('a-id', 'a', True, 'a', 'removed'),
388
('b-id', 'b', True, 'b/', 'removed'),
390
# All Files should be selected
391
self.assertEqual(((0,), None), dlg._treeview_files.get_cursor())
393
def test_filelist_with_selected(self):
394
tree = self.make_branch_and_tree('tree')
395
self.build_tree(['tree/a', 'tree/b/'])
396
tree.add(['a', 'b'], ['a-id', 'b-id'])
398
dlg = commit.CommitDialog(tree, selected='a')
399
values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
400
self.assertEqual([(None, None, False, 'All Files', ''),
401
('a-id', 'a', True, 'a', 'added'),
402
('b-id', 'b', False, 'b/', 'added'),
404
# This file should also be selected in the file list, rather than the
405
# 'All Files' selection
406
self.assertEqual(((1,), None), dlg._treeview_files.get_cursor())
408
def test_diff_view(self):
409
tree = self.make_branch_and_tree('tree')
410
self.build_tree(['tree/a', 'tree/b'])
411
tree.add(['a', 'b'], ['a-id', 'b-id'])
414
self.build_tree_contents([('tree/a', 'new contents for a\n')])
417
dlg = commit.CommitDialog(tree)
418
diff_buffer = dlg._diff_view.buffer
419
text = diff_buffer.get_text(diff_buffer.get_start_iter(),
420
diff_buffer.get_end_iter()).splitlines(True)
422
self.assertEqual("=== modified file 'a'\n", text[0])
423
self.assertContainsRe(text[1],
424
r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
425
self.assertContainsRe(text[2],
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[3])
428
self.assertEqual('-contents of tree/a\n', text[4])
429
self.assertEqual('+new contents for a\n', text[5])
430
self.assertEqual('\n', text[6])
432
self.assertEqual("=== removed file 'b'\n", text[7])
433
self.assertContainsRe(text[8],
434
r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
435
self.assertEqual('+++ b\t1970-01-01 00:00:00 +0000\n', text[9])
436
self.assertEqual('@@ -1,1 +0,0 @@\n', text[10])
437
self.assertEqual('-contents of tree/b\n', text[11])
438
self.assertEqual('\n', text[12])
440
self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
442
def test_commit_partial_toggle(self):
443
tree = self.make_branch_and_tree('tree')
444
self.build_tree(['tree/a', 'tree/b'])
445
tree.add(['a', 'b'], ['a-id', 'b-id'])
447
dlg = commit.CommitDialog(tree)
448
checked_col = dlg._treeview_files.get_column(0)
449
self.assertFalse(checked_col.get_property('visible'))
450
self.assertTrue(dlg._commit_all_changes)
452
dlg._commit_selected_radio.set_active(True)
453
self.assertTrue(checked_col.get_property('visible'))
454
self.assertFalse(dlg._commit_all_changes)
456
def test_file_selection(self):
457
"""Several things should happen when a file has been selected."""
458
tree = self.make_branch_and_tree('tree')
459
tree.branch.get_config().set_user_option('per_file_commits', 'true')
460
self.build_tree(['tree/a', 'tree/b'])
461
tree.add(['a', 'b'], ['a-id', 'b-id'])
463
dlg = commit.CommitDialog(tree)
464
diff_buffer = dlg._diff_view.buffer
465
self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
466
self.assertEqual('File commit message',
467
dlg._file_message_expander.get_label())
468
self.assertFalse(dlg._file_message_expander.get_expanded())
469
self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
471
dlg._treeview_files.set_cursor((1,))
472
self.assertEqual('Diff for a', dlg._diff_label.get_text())
473
text = diff_buffer.get_text(diff_buffer.get_start_iter(),
474
diff_buffer.get_end_iter()).splitlines(True)
475
self.assertEqual("=== added file 'a'\n", text[0])
476
self.assertContainsRe(text[1],
477
r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
478
self.assertContainsRe(text[2],
479
r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
480
self.assertEqual('@@ -0,0 +1,1 @@\n', text[3])
481
self.assertEqual('+contents of tree/a\n', text[4])
482
self.assertEqual('\n', text[5])
483
self.assertEqual('Commit message for a',
484
dlg._file_message_expander.get_label())
485
self.assertTrue(dlg._file_message_expander.get_expanded())
486
self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
488
dlg._treeview_files.set_cursor((2,))
489
self.assertEqual('Diff for b', dlg._diff_label.get_text())
490
text = diff_buffer.get_text(diff_buffer.get_start_iter(),
491
diff_buffer.get_end_iter()).splitlines(True)
492
self.assertEqual("=== added file 'b'\n", text[0])
493
self.assertContainsRe(text[1],
494
r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
495
self.assertContainsRe(text[2],
496
r"\+\+\+ b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
497
self.assertEqual('@@ -0,0 +1,1 @@\n', text[3])
498
self.assertEqual('+contents of tree/b\n', text[4])
499
self.assertEqual('\n', text[5])
500
self.assertEqual('Commit message for b',
501
dlg._file_message_expander.get_label())
502
self.assertTrue(dlg._file_message_expander.get_expanded())
503
self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
505
dlg._treeview_files.set_cursor((0,))
506
self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
507
self.assertEqual('File commit message',
508
dlg._file_message_expander.get_label())
509
self.assertFalse(dlg._file_message_expander.get_expanded())
510
self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
512
def test_file_selection_message(self):
513
"""Selecting a file should bring up its commit message."""
514
tree = self.make_branch_and_tree('tree')
515
tree.branch.get_config().set_user_option('per_file_commits', 'true')
516
self.build_tree(['tree/a', 'tree/b/'])
517
tree.add(['a', 'b'], ['a-id', 'b-id'])
520
buf = dlg._file_message_text_view.get_buffer()
521
return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
523
def get_saved_text(path):
524
"""Get the saved text for a given record."""
525
return dlg._files_store.get_value(dlg._files_store.get_iter(path), 5)
527
dlg = commit.CommitDialog(tree)
528
self.assertEqual('File commit message',
529
dlg._file_message_expander.get_label())
530
self.assertFalse(dlg._file_message_expander.get_expanded())
531
self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
532
self.assertEqual('', get_file_text())
534
dlg._treeview_files.set_cursor((1,))
535
self.assertEqual('Commit message for a',
536
dlg._file_message_expander.get_label())
537
self.assertTrue(dlg._file_message_expander.get_expanded())
538
self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
539
self.assertEqual('', get_file_text())
541
self.assertEqual('', get_saved_text(1))
542
dlg._set_file_commit_message('Some text\nfor a\n')
543
dlg._save_current_file_message()
544
# We should have updated the ListStore with the new file commit info
545
self.assertEqual('Some text\nfor a\n', get_saved_text(1))
547
dlg._treeview_files.set_cursor((2,))
548
self.assertEqual('Commit message for b/',
549
dlg._file_message_expander.get_label())
550
self.assertTrue(dlg._file_message_expander.get_expanded())
551
self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
552
self.assertEqual('', get_file_text())
554
self.assertEqual('', get_saved_text(2))
555
dlg._set_file_commit_message('More text\nfor b\n')
556
# Now switch back to 'a'. The message should be saved, and the buffer
557
# should be updated with the other text
558
dlg._treeview_files.set_cursor((1,))
559
self.assertEqual('More text\nfor b\n', get_saved_text(2))
560
self.assertEqual('Commit message for a',
561
dlg._file_message_expander.get_label())
562
self.assertTrue(dlg._file_message_expander.get_expanded())
563
self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
564
self.assertEqual('Some text\nfor a\n', get_file_text())
566
def test_toggle_all_files(self):
567
"""When checking the All Files entry, it should toggle all fields"""
568
tree = self.make_branch_and_tree('tree')
569
self.build_tree(['tree/a', 'tree/b/'])
570
tree.add(['a', 'b'], ['a-id', 'b-id'])
572
dlg = commit.CommitDialog(tree)
573
self.assertEqual([(None, None, True),
576
], [(r[0], r[1], r[2]) for r in dlg._files_store])
578
# TODO: jam 20071002 I'm not sure how to exactly trigger a toggle, it
579
# looks like we need to call renderer.activate() and pass an
580
# event and widget, and lots of other stuff I'm not sure what to
581
# do with. So instead, we just call toggle directly, and assume
582
# that toggle is hooked in correctly
583
# column = dlg._treeview_files.get_column(0)
584
# renderer = column.get_cell_renderers()[0]
586
# Toggle a single entry should set just that entry to False
587
dlg._toggle_commit(None, 1, dlg._files_store)
588
self.assertEqual([(None, None, True),
589
('a-id', 'a', False),
591
], [(r[0], r[1], r[2]) for r in dlg._files_store])
593
# Toggling the main entry should set all entries
594
dlg._toggle_commit(None, 0, dlg._files_store)
595
self.assertEqual([(None, None, False),
596
('a-id', 'a', False),
597
('b-id', 'b', False),
598
], [(r[0], r[1], r[2]) for r in dlg._files_store])
600
dlg._toggle_commit(None, 2, dlg._files_store)
601
self.assertEqual([(None, None, False),
602
('a-id', 'a', False),
604
], [(r[0], r[1], r[2]) for r in dlg._files_store])
606
dlg._toggle_commit(None, 0, dlg._files_store)
607
self.assertEqual([(None, None, True),
610
], [(r[0], r[1], r[2]) for r in dlg._files_store])
612
def test_specific_files(self):
613
tree = self.make_branch_and_tree('tree')
614
self.build_tree(['tree/a', 'tree/b/'])
615
tree.add(['a', 'b'], ['a-id', 'b-id'])
617
dlg = commit.CommitDialog(tree)
618
self.assertEqual((['a', 'b'], []), dlg._get_specific_files())
620
dlg._commit_selected_radio.set_active(True)
621
dlg._toggle_commit(None, 0, dlg._files_store)
622
self.assertEqual(([], []), dlg._get_specific_files())
624
dlg._toggle_commit(None, 1, dlg._files_store)
625
self.assertEqual((['a'], []), dlg._get_specific_files())
627
def test_specific_files_with_messages(self):
628
tree = self.make_branch_and_tree('tree')
629
tree.branch.get_config().set_user_option('per_file_commits', 'true')
630
self.build_tree(['tree/a_file', 'tree/b_dir/'])
631
tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
633
dlg = commit.CommitDialog(tree)
634
dlg._commit_selected_radio.set_active(True)
635
self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
637
dlg._treeview_files.set_cursor((1,))
638
dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
639
dlg._treeview_files.set_cursor((2,))
640
dlg._set_file_commit_message('message\nfor b_dir\n')
642
self.assertEqual((['a_file', 'b_dir'],
643
[{'path':'a_file', 'file_id':'1a-id',
644
'message':'Test\nmessage\nfor a_file\n'},
645
{'path':'b_dir', 'file_id':'0b-id',
646
'message':'message\nfor b_dir\n'},
647
]), dlg._get_specific_files())
649
dlg._toggle_commit(None, 1, dlg._files_store)
650
self.assertEqual((['b_dir'],
651
[{'path':'b_dir', 'file_id':'0b-id',
652
'message':'message\nfor b_dir\n'},
653
]), dlg._get_specific_files())
655
def test_specific_files_sanitizes_messages(self):
656
tree = self.make_branch_and_tree('tree')
657
tree.branch.get_config().set_user_option('per_file_commits', 'true')
658
self.build_tree(['tree/a_file', 'tree/b_dir/'])
659
tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
661
dlg = commit.CommitDialog(tree)
662
dlg._commit_selected_radio.set_active(True)
663
self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
665
dlg._treeview_files.set_cursor((1,))
666
dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
667
dlg._treeview_files.set_cursor((2,))
668
dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
670
self.assertEqual((['a_file', 'b_dir'],
671
[{'path':'a_file', 'file_id':'1a-id',
672
'message':'Test\nmessage\nfor a_file\n'},
673
{'path':'b_dir', 'file_id':'0b-id',
674
'message':'message\nfor\nb_dir\n'},
675
]), dlg._get_specific_files())
678
class QuestionHelpers(object):
680
def _set_question_yes(self, dlg):
681
"""Set the dialog to answer YES to any questions."""
683
def _question_yes(*args, **kwargs):
684
self.questions.append(args)
685
self.questions.append('YES')
686
return gtk.RESPONSE_YES
687
dlg._question_dialog = _question_yes
689
def _set_question_no(self, dlg):
690
"""Set the dialog to answer NO to any questions."""
692
def _question_no(*args, **kwargs):
693
self.questions.append(args)
694
self.questions.append('NO')
695
return gtk.RESPONSE_NO
696
dlg._question_dialog = _question_no
699
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
700
"""Tests on the actual 'commit' button being pushed."""
702
def test_bound_commit_local(self):
703
tree = self.make_branch_and_tree('tree')
704
self.build_tree(['tree/a'])
705
tree.add(['a'], ['a-id'])
706
rev_id1 = tree.commit('one')
708
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
709
self.build_tree(['tree2/b'])
710
tree2.add(['b'], ['b-id'])
711
tree2.branch.bind(tree.branch)
713
dlg = commit.CommitDialog(tree2)
714
# With the check box set, it should only effect the local branch
715
dlg._check_local.set_active(True)
716
dlg._set_global_commit_message('Commit message\n')
719
last_rev = tree2.last_revision()
720
self.assertEqual(last_rev, dlg.committed_revision_id)
721
self.assertEqual(rev_id1, tree.branch.last_revision())
723
def test_commit_global_sanitizes_message(self):
724
tree = self.make_branch_and_tree('tree')
725
self.build_tree(['tree/a'])
726
tree.add(['a'], ['a-id'])
727
rev_id1 = tree.commit('one')
729
self.build_tree(['tree/b'])
730
tree.add(['b'], ['b-id'])
731
dlg = commit.CommitDialog(tree)
732
# With the check box set, it should only effect the local branch
733
dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
735
rev = tree.branch.repository.get_revision(tree.last_revision())
736
self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
738
def test_bound_commit_both(self):
739
tree = self.make_branch_and_tree('tree')
740
self.build_tree(['tree/a'])
741
tree.add(['a'], ['a-id'])
742
rev_id1 = tree.commit('one')
744
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
745
self.build_tree(['tree2/b'])
746
tree2.add(['b'], ['b-id'])
747
tree2.branch.bind(tree.branch)
749
dlg = commit.CommitDialog(tree2)
750
# With the check box set, it should only effect the local branch
751
dlg._check_local.set_active(False)
752
dlg._set_global_commit_message('Commit message\n')
755
last_rev = tree2.last_revision()
756
self.assertEqual(last_rev, dlg.committed_revision_id)
757
self.assertEqual(last_rev, tree.branch.last_revision())
759
def test_commit_empty_message(self):
760
tree = self.make_branch_and_tree('tree')
761
self.build_tree(['tree/a', 'tree/b'])
762
tree.add(['a'], ['a-id'])
763
rev_id = tree.commit('one')
765
tree.add(['b'], ['b-id'])
767
dlg = commit.CommitDialog(tree)
768
self._set_question_no(dlg)
771
[('Commit with an empty message?',
772
'You can describe your commit intent in the message.'),
775
# By saying NO, nothing should be committed.
776
self.assertEqual(rev_id, tree.last_revision())
777
self.assertIs(None, dlg.committed_revision_id)
778
self.assertTrue(dlg._global_message_text_view.get_property('is-focus'))
780
self._set_question_yes(dlg)
784
[('Commit with an empty message?',
785
'You can describe your commit intent in the message.'),
788
committed = tree.last_revision()
789
self.assertNotEqual(rev_id, committed)
790
self.assertEqual(committed, dlg.committed_revision_id)
792
def test_initial_commit(self):
793
tree = self.make_branch_and_tree('tree')
794
self.build_tree(['tree/a'])
795
tree.add(['a'], ['a-id'])
797
dlg = commit.CommitDialog(tree)
798
dlg._set_global_commit_message('Some text\n')
801
last_rev = tree.last_revision()
802
self.assertEqual(last_rev, dlg.committed_revision_id)
803
rev = tree.branch.repository.get_revision(last_rev)
804
self.assertEqual(last_rev, rev.revision_id)
805
self.assertEqual('Some text\n', rev.message)
807
def test_pointless_commit(self):
808
tree = self.make_branch_and_tree('tree')
809
self.build_tree(['tree/a'])
810
tree.add(['a'], ['a-id'])
811
rev_id1 = tree.commit('one')
813
dlg = commit.CommitDialog(tree)
814
dlg._set_global_commit_message('Some text\n')
816
self._set_question_no(dlg)
819
self.assertIs(None, dlg.committed_revision_id)
820
self.assertEqual(rev_id1, tree.last_revision())
822
[('Commit with no changes?',
823
'There are no changes in the working tree.'
824
' Do you want to commit anyway?'),
828
self._set_question_yes(dlg)
831
rev_id2 = tree.last_revision()
832
self.assertEqual(rev_id2, dlg.committed_revision_id)
833
self.assertNotEqual(rev_id1, rev_id2)
835
[('Commit with no changes?',
836
'There are no changes in the working tree.'
837
' Do you want to commit anyway?'),
841
def test_unknowns(self):
842
"""We should check if there are unknown files."""
843
tree = self.make_branch_and_tree('tree')
844
rev_id1 = tree.commit('one')
845
self.build_tree(['tree/a', 'tree/b'])
846
tree.add(['a'], ['a-id'])
848
dlg = commit.CommitDialog(tree)
849
dlg._set_global_commit_message('Some text\n')
850
self._set_question_no(dlg)
854
self.assertIs(None, dlg.committed_revision_id)
855
self.assertEqual(rev_id1, tree.last_revision())
857
[("Commit with unknowns?",
858
"Unknown files exist in the working tree. Commit anyway?"),
862
self._set_question_yes(dlg)
865
rev_id2 = tree.last_revision()
866
self.assertNotEqual(rev_id1, rev_id2)
867
self.assertEqual(rev_id2, dlg.committed_revision_id)
869
[("Commit with unknowns?",
870
"Unknown files exist in the working tree. Commit anyway?"),
874
def test_commit_specific_files(self):
875
tree = self.make_branch_and_tree('tree')
876
rev_id1 = tree.commit('one')
877
self.build_tree(['tree/a', 'tree/b'])
878
tree.add(['a', 'b'], ['a-id', 'b-id'])
880
dlg = commit.CommitDialog(tree)
881
dlg._commit_selected_radio.set_active(True) # enable partial
882
dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
884
dlg._set_global_commit_message('Committing just "a"\n')
887
rev_id2 = dlg.committed_revision_id
888
self.assertIsNot(None, rev_id2)
889
self.assertEqual(rev_id2, tree.last_revision())
891
rt = tree.branch.repository.revision_tree(rev_id2)
892
entries = [(path, ie.file_id) for path, ie in rt.iter_entries_by_dir()
893
if path] # Ignore the root entry
894
self.assertEqual([('a', 'a-id')], entries)
896
def test_commit_partial_no_partial(self):
897
"""Ignore the checkboxes if committing all files."""
898
tree = self.make_branch_and_tree('tree')
899
rev_id1 = tree.commit('one')
900
self.build_tree(['tree/a', 'tree/b'])
901
tree.add(['a', 'b'], ['a-id', 'b-id'])
903
dlg = commit.CommitDialog(tree)
904
dlg._commit_selected_radio.set_active(True) # enable partial
905
dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
907
# Switch back to committing all changes
908
dlg._commit_all_files_radio.set_active(True)
910
dlg._set_global_commit_message('Committing everything\n')
913
rev_id2 = dlg.committed_revision_id
914
self.assertIsNot(None, rev_id2)
915
self.assertEqual(rev_id2, tree.last_revision())
917
rt = tree.branch.repository.revision_tree(rev_id2)
918
entries = [(path, ie.file_id) for path, ie in rt.iter_entries_by_dir()
919
if path] # Ignore the root entry
920
self.assertEqual([('a', 'a-id'), ('b', 'b-id')], entries)
922
def test_commit_no_messages(self):
923
tree = self.make_branch_and_tree('tree')
924
rev_id1 = tree.commit('one')
925
self.build_tree(['tree/a', 'tree/b'])
926
tree.add(['a', 'b'], ['a-id', 'b-id'])
928
dlg = commit.CommitDialog(tree)
929
dlg._set_global_commit_message('Simple commit\n')
932
rev = tree.branch.repository.get_revision(dlg.committed_revision_id)
933
self.failIf('file-info' in rev.properties)
935
def test_commit_disabled_messages(self):
936
tree = self.make_branch_and_tree('tree')
937
rev_id1 = tree.commit('one')
939
self.build_tree(['tree/a', 'tree/b'])
940
tree.add(['a', 'b'], ['a-id', 'b-id'])
942
dlg = commit.CommitDialog(tree)
943
self.assertFalse(dlg._file_message_expander.get_property('visible'))
944
self.assertEqual('Commit Message',
945
dlg._global_message_label.get_text())
947
tree.branch.get_config().set_user_option('per_file_commits', 'true')
948
dlg = commit.CommitDialog(tree)
949
self.assertTrue(dlg._file_message_expander.get_property('visible'))
950
self.assertEqual('Global Commit Message',
951
dlg._global_message_label.get_text())
953
tree.branch.get_config().set_user_option('per_file_commits', 'on')
954
dlg = commit.CommitDialog(tree)
955
self.assertTrue(dlg._file_message_expander.get_property('visible'))
956
self.assertEqual('Global Commit Message',
957
dlg._global_message_label.get_text())
959
tree.branch.get_config().set_user_option('per_file_commits', 'y')
960
dlg = commit.CommitDialog(tree)
961
self.assertTrue(dlg._file_message_expander.get_property('visible'))
962
self.assertEqual('Global Commit Message',
963
dlg._global_message_label.get_text())
965
tree.branch.get_config().set_user_option('per_file_commits', 'n')
966
dlg = commit.CommitDialog(tree)
967
self.assertFalse(dlg._file_message_expander.get_property('visible'))
968
self.assertEqual('Commit Message',
969
dlg._global_message_label.get_text())
971
def test_commit_specific_files_with_messages(self):
972
tree = self.make_branch_and_tree('tree')
973
tree.branch.get_config().set_user_option('per_file_commits', 'true')
974
rev_id1 = tree.commit('one')
975
self.build_tree(['tree/a', 'tree/b'])
976
tree.add(['a', 'b'], ['a-id', 'b-id'])
978
dlg = commit.CommitDialog(tree)
979
dlg._commit_selected_radio.set_active(True) # enable partial
980
dlg._treeview_files.set_cursor((1,))
981
dlg._set_file_commit_message('Message for A\n')
982
dlg._treeview_files.set_cursor((2,))
983
dlg._set_file_commit_message('Message for B\n')
984
dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
985
dlg._set_global_commit_message('Commit just "a"')
989
rev_id2 = dlg.committed_revision_id
990
self.assertEqual(rev_id2, tree.last_revision())
991
rev = tree.branch.repository.get_revision(rev_id2)
992
self.assertEqual('Commit just "a"', rev.message)
993
file_info = rev.properties['file-info']
994
self.assertEqual(u'ld7:file_id4:a-id'
995
'7:message14:Message for A\n'
999
self.assertEqual([{'path':'a', 'file_id':'a-id',
1000
'message':'Message for A\n'},],
1001
bencode.bdecode(file_info.encode('UTF-8')))
1003
def test_commit_messages_after_merge(self):
1004
tree = self.make_branch_and_tree('tree')
1005
tree.branch.get_config().set_user_option('per_file_commits', 'true')
1006
rev_id1 = tree.commit('one')
1007
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
1008
self.build_tree(['tree2/a', 'tree2/b'])
1009
tree2.add(['a', 'b'], ['a-id', 'b-id'])
1010
rev_id2 = tree2.commit('two')
1012
tree.merge_from_branch(tree2.branch)
1014
dlg = commit.CommitDialog(tree)
1015
dlg._treeview_files.set_cursor((1,)) # 'a'
1016
dlg._set_file_commit_message('Message for A\n')
1017
# No message for 'B'
1018
dlg._set_global_commit_message('Merging from "tree2"\n')
1022
rev_id3 = dlg.committed_revision_id
1023
self.assertEqual(rev_id3, tree.last_revision())
1024
rev = tree.branch.repository.get_revision(rev_id3)
1025
self.assertEqual('Merging from "tree2"\n', rev.message)
1026
self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
1027
file_info = rev.properties['file-info']
1028
self.assertEqual(u'ld7:file_id4:a-id'
1029
'7:message14:Message for A\n'
1033
self.assertEqual([{'path':'a', 'file_id':'a-id',
1034
'message':'Message for A\n'},],
1035
bencode.bdecode(file_info.encode('UTF-8')))
1037
def test_commit_unicode_messages(self):
1038
self.requireFeature(UnicodeFilenameFeature)
1040
tree = self.make_branch_and_tree('tree')
1041
tree.branch.get_config().set_user_option('per_file_commits', 'true')
1042
self.build_tree(['tree/a', u'tree/\u03a9'])
1043
tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
1045
dlg = commit.CommitDialog(tree)
1046
dlg._treeview_files.set_cursor((1,)) # 'a'
1047
dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
1048
dlg._treeview_files.set_cursor((2,)) # omega
1049
dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1050
dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1052
self.assertEqual(([u'a', u'\u03a9'],
1053
[{'path':'a', 'file_id':'a-id',
1054
'message':'Test \xc3\xban\xc3\xacc\xc3\xb6de\n'},
1055
{'path':'\xce\xa9', 'file_id':'omega-id',
1056
'message':'\xce\xa9 is the end of all things.\n'},
1057
]), dlg._get_specific_files())
1061
rev = tree.branch.repository.get_revision(dlg.committed_revision_id)
1062
file_info = rev.properties['file-info'].encode('UTF-8')
1063
value = ('ld7:file_id4:a-id'
1064
'7:message16:Test \xc3\xban\xc3\xacc\xc3\xb6de\n'
1067
'd7:file_id8:omega-id'
1068
'7:message29:\xce\xa9 is the end of all things.\n'
1072
self.assertEqual(value, file_info)
1073
file_info_decoded = bencode.bdecode(file_info)
1074
for d in file_info_decoded:
1075
d['path'] = d['path'].decode('UTF-8')
1076
d['message'] = d['message'].decode('UTF-8')
1078
self.assertEqual([{'path':u'a', 'file_id':'a-id',
1079
'message':u'Test \xfan\xecc\xf6de\n'},
1080
{'path':u'\u03a9', 'file_id':'omega-id',
1081
'message':u'\u03a9 is the end of all things.\n'},
1082
], file_info_decoded)
1085
class TestSanitizeMessage(tests.TestCase):
1087
def assertSanitize(self, expected, original):
1088
self.assertEqual(expected,
1089
commit._sanitize_and_decode_message(original))
1091
def test_untouched(self):
1092
self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
1094
def test_converts_cr_to_lf(self):
1095
self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
1097
def test_converts_crlf_to_lf(self):
1098
self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
1100
def test_converts_mixed_to_lf(self):
1101
self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
1104
class TestSavedCommitMessages(tests.TestCaseWithTransport):
1107
super(TestSavedCommitMessages, self).setUp()
1109
branch.Branch.hooks.install_named_hook(
1110
'post_uncommit', commit.save_commit_messages, None)
1112
def _get_file_info_dict(self, rank):
1113
file_info = [dict(path='a', file_id='a-id', message='a msg %d' % rank),
1114
dict(path='b', file_id='b-id', message='b msg %d' % rank)]
1117
def _get_file_info_revprops(self, rank):
1118
file_info_prop = self._get_file_info_dict(rank)
1119
return {'file-info': bencode.bencode(file_info_prop).decode('UTF-8')}
1121
def _get_commit_message(self):
1122
return self.config.get_user_option('gtk_global_commit_message')
1124
def _get_file_commit_messages(self):
1125
return self.config.get_user_option('gtk_file_commit_messages')
1128
class TestUncommitHook(TestSavedCommitMessages):
1131
super(TestUncommitHook, self).setUp()
1132
self.tree = self.make_branch_and_tree('tree')
1133
self.config = self.tree.branch.get_config()
1134
self.build_tree(['tree/a', 'tree/b'])
1135
self.tree.add(['a'], ['a-id'])
1136
self.tree.add(['b'], ['b-id'])
1137
rev1 = self.tree.commit('one', rev_id='one-id',
1138
revprops=self._get_file_info_revprops(1))
1139
rev2 = self.tree.commit('two', rev_id='two-id',
1140
revprops=self._get_file_info_revprops(2))
1141
rev3 = self.tree.commit('three', rev_id='three-id',
1142
revprops=self._get_file_info_revprops(3))
1144
def test_uncommit_one_by_one(self):
1145
uncommit.uncommit(self.tree.branch, tree=self.tree)
1146
self.assertEquals(u'three', self._get_commit_message())
1147
self.assertEquals(u'd4:a-id7:a msg 34:b-id7:b msg 3e',
1148
self._get_file_commit_messages())
1150
uncommit.uncommit(self.tree.branch, tree=self.tree)
1151
self.assertEquals(u'two\n******\nthree', self._get_commit_message())
1152
self.assertEquals(u'd4:a-id22:a msg 2\n******\na msg 3'
1153
'4:b-id22:b msg 2\n******\nb msg 3e',
1154
self._get_file_commit_messages())
1156
uncommit.uncommit(self.tree.branch, tree=self.tree)
1157
self.assertEquals(u'one\n******\ntwo\n******\nthree',
1158
self._get_commit_message())
1159
self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
1160
'4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
1161
self._get_file_commit_messages())
1163
def test_uncommit_all_at_once(self):
1164
uncommit.uncommit(self.tree.branch, tree=self.tree, revno=1)
1165
self.assertEquals(u'one\n******\ntwo\n******\nthree',
1166
self._get_commit_message())
1167
self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
1168
'4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
1169
self._get_file_commit_messages())
1172
class TestReusingSavedCommitMessages(TestSavedCommitMessages, QuestionHelpers):
1175
super(TestReusingSavedCommitMessages, self).setUp()
1176
self.tree = self.make_branch_and_tree('tree')
1177
self.config = self.tree.branch.get_config()
1178
self.config.set_user_option('per_file_commits', 'true')
1179
self.build_tree(['tree/a', 'tree/b'])
1180
self.tree.add(['a'], ['a-id'])
1181
self.tree.add(['b'], ['b-id'])
1182
rev1 = self.tree.commit('one', revprops=self._get_file_info_revprops(1))
1183
rev2 = self.tree.commit('two', revprops=self._get_file_info_revprops(2))
1184
uncommit.uncommit(self.tree.branch, tree=self.tree)
1185
self.build_tree_contents([('tree/a', 'new a content\n'),
1186
('tree/b', 'new b content'),])
1188
def _get_commit_dialog(self, tree):
1189
# Ensure we will never use a dialog that can actually prompt the user
1190
# during the test suite. Test *can* and *should* override with the
1191
# correct question dialog type.
1192
dlg = commit.CommitDialog(tree)
1193
self._set_question_no(dlg)
1196
def test_setup_saved_messages(self):
1197
# Check the initial setup
1198
self.assertEquals(u'two', self._get_commit_message())
1199
self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
1200
self._get_file_commit_messages())
1202
def test_messages_are_reloaded(self):
1203
dlg = self._get_commit_dialog(self.tree)
1204
self.assertEquals(u'two', dlg._get_global_commit_message())
1205
self.assertEquals(([u'a', u'b'],
1207
'file_id': 'a-id', 'message': 'a msg 2',},
1209
'file_id': 'b-id', 'message': 'b msg 2',}],),
1210
dlg._get_specific_files())
1212
def test_messages_are_consumed(self):
1213
dlg = self._get_commit_dialog(self.tree)
1215
self.assertEquals(u'', self._get_commit_message())
1216
self.assertEquals(u'de', self._get_file_commit_messages())
1218
def test_messages_are_saved_on_cancel_if_required(self):
1219
dlg = self._get_commit_dialog(self.tree)
1220
self._set_question_yes(dlg) # Save messages
1222
self.assertEquals(u'two', self._get_commit_message())
1223
self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
1224
self._get_file_commit_messages())
1226
def test_messages_are_cleared_on_cancel_if_required(self):
1227
dlg = self._get_commit_dialog(self.tree)
1228
self._set_question_no(dlg) # Don't save messages
1230
self.assertEquals(u'', self._get_commit_message())
1231
self.assertEquals(u'de',
1232
self._get_file_commit_messages())