/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
622.1.2 by John Arbash Meinel
Add tests of RevisionView that it can handle broken file-info properties.
1
# Copyright (C) 2007, 2008 John Arbash Meinel <john@arbash-meinel.com>
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
2
#
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.
7
#
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.
12
#
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
16
17
"""Test the Commit functionality."""
18
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
19
import os
20
734.1.1 by Curtis Hovey
Mechanical changes made by pygi.convert.sh.
21
from gi.repository import Gtk
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
22
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
23
from bzrlib import (
635.2.12 by Vincent Ladeuil
Implement commit message saving without modifying bzrlib.
24
    branch,
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
25
    tests,
635.2.8 by Vincent Ladeuil
Start testing patch behavior.
26
    uncommit,
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
27
    )
645 by Jelmer Vernooij
Fix more bencode imports.
28
try:
737 by Jelmer Vernooij
Support new location of UnicodeFilenameFeature in 2.5.
29
    from bzrlib.tests.features import UnicodeFilenameFeature
30
except ImportError: # bzr < 2.5
31
    from bzrlib.tests import UnicodeFilenameFeature
32
try:
646 by Jelmer Vernooij
Reorder bencode imports, prefer the new location to prevent deprecation warnings.
33
    from bzrlib import bencode
34
except ImportError:
645 by Jelmer Vernooij
Fix more bencode imports.
35
    from bzrlib.util import bencode
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
36
37
from bzrlib.plugins.gtk import commit
38
39
40
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
41
# TestCaseWithTransport, just a TestCaseWithMemoryTransport or somesuch.
42
43
class TestPendingRevisions(tests.TestCaseWithTransport):
44
45
    def test_pending_revisions_none(self):
46
        tree = self.make_branch_and_tree('.')
47
        tree.commit('one')
48
49
        self.assertIs(None, commit.pending_revisions(tree))
50
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())
58
59
        pending_revisions = commit.pending_revisions(tree)
60
        # One primary merge
61
        self.assertEqual(1, len(pending_revisions))
62
        # Revision == rev_id2
63
        self.assertEqual(rev_id2, pending_revisions[0][0].revision_id)
64
        # No children of this revision.
65
        self.assertEqual([], pending_revisions[0][1])
66
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())
76
77
        pending_revisions = commit.pending_revisions(tree)
78
        # One primary merge
79
        self.assertEqual(1, len(pending_revisions))
80
        # Revision == rev_id2
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)
86
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()
500.1.2 by Vincent Ladeuil
Fix third failing test (thanks to jam).
93
        rev_id3 = tree2.commit('three')
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
94
        rev_id4 = tree3.commit('four')
95
        rev_id5 = tree3.commit('five')
96
        tree.merge_from_branch(tree2.branch)
670 by Vincent Ladeuil
Fix regressions in tests about merge being more strict by default.
97
        tree.merge_from_branch(tree3.branch, force=True)
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
98
        self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
99
100
        pending_revisions = commit.pending_revisions(tree)
101
        # Two primary merges
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)
112
113
114
class Test_RevToPendingInfo(tests.TestCaseWithTransport):
115
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,
121
                             timezone=-18000
122
                             )
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',
127
                          'date':'2007-09-28',
128
                          'revision_id':rev_id,
129
                         }, rev_dict)
130
131
132
class CommitDialogNoWidgets(commit.CommitDialog):
133
134
    def construct(self):
135
        pass # Don't create any widgets here
136
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
137
    def fill_in_data(self):
138
        pass # With no widgets, there are no widgets to fill out
139
140
141
class TestCommitDialogSimple(tests.TestCaseWithTransport):
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
142
143
    def test_setup_parameters_no_pending(self):
144
        tree = self.make_branch_and_tree('tree')
145
        rev_id = tree.commit('first')
146
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)
151
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)
157
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)
162
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)
169
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)
175
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'])
180
181
        dlg = CommitDialogNoWidgets(tree)
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
182
        self.assertIs(None, dlg._delta)
183
        dlg._compute_delta()
184
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
185
        delta = 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)
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
190
191
192
class TestCommitDialog(tests.TestCaseWithTransport):
193
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
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)
199
200
        # tree is not a checkout
201
        dlg = commit.CommitDialog(tree)
202
        self.assertFalse(dlg._check_local.get_property('visible'))
203
204
        # tree2 is a checkout
205
        dlg2 = commit.CommitDialog(tree2)
206
        self.assertTrue(dlg2._check_local.get_property('visible'))
207
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
208
    def test_no_pending(self):
209
        tree = self.make_branch_and_tree('tree')
210
        rev_id1 = tree.commit('one')
211
212
        dlg = commit.CommitDialog(tree)
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
213
214
        self.assertFalse(dlg._pending_box.get_property('visible'))
215
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
216
        commit_col = dlg._treeview_files.get_column(0)
217
        self.assertEqual('Commit', commit_col.get_title())
734.1.20 by Curtis Hovey
col.get_cell_renderers => col.get_cells.
218
        renderer = commit_col.get_cells()[0]
278.1.39 by John Arbash Meinel
To disable a checkbox it is set_property('activatable', False),
219
        self.assertTrue(renderer.get_property('activatable'))
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
220
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
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'))
225
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
226
    def test_pending(self):
227
        tree = self.make_branch_and_tree('tree')
228
        rev_id1 = tree.commit('one')
229
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,
234
                               timezone=+7200)
235
        tree.merge_from_branch(tree2.branch)
236
237
        dlg = commit.CommitDialog(tree)
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
238
239
        self.assertTrue(dlg._pending_box.get_property('visible'))
240
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
241
        commit_col = dlg._treeview_files.get_column(0)
242
        self.assertEqual('Commit*', commit_col.get_title())
734.1.20 by Curtis Hovey
col.get_cell_renderers => col.get_cells.
243
        renderer = commit_col.get_cells()[0]
278.1.39 by John Arbash Meinel
To disable a checkbox it is set_property('activatable', False),
244
        self.assertFalse(renderer.get_property('activatable'))
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
245
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
246
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
247
        self.assertEqual([(rev_id2, '2007-10-01', 'Joe Foo', 'two')], values)
248
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
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'))
253
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
254
    def test_pending_multiple(self):
255
        tree = self.make_branch_and_tree('tree')
256
        rev_id1 = tree.commit('one')
257
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,
262
                               timezone=+7200)
263
        rev_id3 = tree2.commit('three',
264
                               committer='Jerry Foo <jerry@foo.com>',
265
                               timestamp=1191264278.05,
266
                               timezone=+7200)
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,
272
                               timezone=+7200)
273
        rev_id5 = tree3.commit('five',
274
                               committer='Jerry Foo <jerry@foo.com>',
275
                               timestamp=1191372278.05,
276
                               timezone=+7200)
670 by Vincent Ladeuil
Fix regressions in tests about merge being more strict by default.
277
        tree.merge_from_branch(tree3.branch, force=True)
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
278
279
        dlg = commit.CommitDialog(tree)
280
        # TODO: assert that the pending box is set to show
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
281
        values = [(r[0], r[1], r[2], r[3]) for r in dlg._pending_store]
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
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'),
286
                         ], values)
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
287
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
288
    def test_filelist_added(self):
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
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'])
292
293
        dlg = commit.CommitDialog(tree)
294
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
295
        self.assertEqual([(None, None, True, 'All Files', ''),
296
                          ('a-id', 'a', True, 'a', 'added'),
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
297
                          ('b-id', 'b', True, 'b/', 'added'),
298
                          ('c-id', 'b/c', True, 'b/c', 'added'),
299
                         ], values)
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
300
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')
306
307
        tree.rename_one('b', 'd')
308
        tree.rename_one('a', 'd/a')
309
310
        dlg = commit.CommitDialog(tree)
311
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
312
        self.assertEqual([(None, None, True, 'All Files', ''),
313
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
314
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
315
                         ], values)
316
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')
322
323
        self.build_tree_contents([('tree/a', 'new contents for a\n')])
324
325
        dlg = commit.CommitDialog(tree)
326
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
327
        self.assertEqual([(None, None, True, 'All Files', ''),
328
                          ('a-id', 'a', True, 'a', 'modified'),
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
329
                         ], values)
330
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')
336
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'),
341
                                 ])
342
        # 'c' is not considered renamed, because only its parent was moved, it
343
        # stayed in the same directory
344
345
        dlg = commit.CommitDialog(tree)
346
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
347
        self.assertEqual([(None, None, True, 'All Files', ''),
348
                          ('b-id', 'd', True, 'b/ => d/', 'renamed'),
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
349
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
350
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
351
                         ], values)
352
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'])
357
        tree.commit('one')
358
359
        os.remove('tree/a')
360
        self.build_tree(['tree/a/'])
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
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
363
        #       test for now.
364
        # tree.rename_one('b', 'c')
365
        # os.remove('tree/c')
366
        # self.build_tree(['tree/c/'])
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
367
368
        dlg = commit.CommitDialog(tree)
369
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
370
        self.assertEqual([(None, None, True, 'All Files', ''),
371
                          ('a-id', 'a', True, 'a => a/', 'kind changed'),
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
372
                          # ('b-id', 'c', True, 'b => c/', 'renamed and modified'),
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
373
                         ], values)
374
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'])
379
        tree.commit('one')
380
381
        os.remove('tree/a')
382
        tree.remove('b', force=True)
383
384
        dlg = commit.CommitDialog(tree)
385
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
386
        self.assertEqual([(None, None, True, 'All Files', ''),
387
                          ('a-id', 'a', True, 'a', 'removed'),
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
388
                          ('b-id', 'b', True, 'b/', 'removed'),
389
                         ], values)
278.1.35 by John Arbash Meinel
Make use of the 'selected' parameter to CommitDialog.
390
        # All Files should be selected
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
391
        self.assertEqual(
392
            (Gtk.TreePath(path=0), None), dlg._treeview_files.get_cursor())
278.1.35 by John Arbash Meinel
Make use of the 'selected' parameter to CommitDialog.
393
394
    def test_filelist_with_selected(self):
395
        tree = self.make_branch_and_tree('tree')
396
        self.build_tree(['tree/a', 'tree/b/'])
397
        tree.add(['a', 'b'], ['a-id', 'b-id'])
398
399
        dlg = commit.CommitDialog(tree, selected='a')
400
        values = [(r[0], r[1], r[2], r[3], r[4]) for r in dlg._files_store]
401
        self.assertEqual([(None, None, False, 'All Files', ''),
402
                          ('a-id', 'a', True, 'a', 'added'),
403
                          ('b-id', 'b', False, 'b/', 'added'),
404
                         ], values)
405
        # This file should also be selected in the file list, rather than the
406
        # 'All Files' selection
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
407
        self.assertEqual(
408
            (Gtk.TreePath(path=1), None), dlg._treeview_files.get_cursor())
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
409
410
    def test_diff_view(self):
411
        tree = self.make_branch_and_tree('tree')
412
        self.build_tree(['tree/a', 'tree/b'])
413
        tree.add(['a', 'b'], ['a-id', 'b-id'])
414
        tree.commit('one')
415
416
        self.build_tree_contents([('tree/a', 'new contents for a\n')])
417
        tree.remove('b')
418
419
        dlg = commit.CommitDialog(tree)
420
        diff_buffer = dlg._diff_view.buffer
421
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
734.1.7 by Curtis Hovey
Updated buffer.getText() calls and ModifierType enums.
422
                                    diff_buffer.get_end_iter(),
423
                                    True).splitlines(True)
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
424
483 by Jelmer Vernooij
Fix diff test.
425
        self.assertEqual("=== modified file 'a'\n", text[0])
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
426
        self.assertContainsRe(text[1],
427
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
483 by Jelmer Vernooij
Fix diff test.
428
        self.assertContainsRe(text[2],
429
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
430
        self.assertEqual('@@ -1,1 +1,1 @@\n', text[3])
431
        self.assertEqual('-contents of tree/a\n', text[4])
432
        self.assertEqual('+new contents for a\n', text[5])
433
        self.assertEqual('\n', text[6])
434
435
        self.assertEqual("=== removed file 'b'\n", text[7])
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
436
        self.assertContainsRe(text[8],
483 by Jelmer Vernooij
Fix diff test.
437
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
438
        self.assertEqual('+++ b\t1970-01-01 00:00:00 +0000\n', text[9])
439
        self.assertEqual('@@ -1,1 +0,0 @@\n', text[10])
440
        self.assertEqual('-contents of tree/b\n', text[11])
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
441
        self.assertEqual('\n', text[12])
442
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
443
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
444
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
445
    def test_commit_partial_toggle(self):
446
        tree = self.make_branch_and_tree('tree')
447
        self.build_tree(['tree/a', 'tree/b'])
448
        tree.add(['a', 'b'], ['a-id', 'b-id'])
449
450
        dlg = commit.CommitDialog(tree)
451
        checked_col = dlg._treeview_files.get_column(0)
452
        self.assertFalse(checked_col.get_property('visible'))
453
        self.assertTrue(dlg._commit_all_changes)
454
455
        dlg._commit_selected_radio.set_active(True)
456
        self.assertTrue(checked_col.get_property('visible'))
457
        self.assertFalse(dlg._commit_all_changes)
458
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
459
    def test_file_selection(self):
460
        """Several things should happen when a file has been selected."""
461
        tree = self.make_branch_and_tree('tree')
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
462
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
463
        self.build_tree(['tree/a', 'tree/b'])
464
        tree.add(['a', 'b'], ['a-id', 'b-id'])
465
466
        dlg = commit.CommitDialog(tree)
467
        diff_buffer = dlg._diff_view.buffer
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
468
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
469
        self.assertEqual('File commit message',
470
                         dlg._file_message_expander.get_label())
471
        self.assertFalse(dlg._file_message_expander.get_expanded())
472
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
473
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
474
        dlg._treeview_files.set_cursor(
475
            Gtk.TreePath(path=1), None, False)
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
476
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
477
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
734.1.7 by Curtis Hovey
Updated buffer.getText() calls and ModifierType enums.
478
                                    diff_buffer.get_end_iter(),
479
                                    True).splitlines(True)
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
480
        self.assertEqual("=== added file 'a'\n", text[0])
481
        self.assertContainsRe(text[1],
482
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
483
        self.assertContainsRe(text[2],
484
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
485
        self.assertEqual('@@ -0,0 +1,1 @@\n', text[3])
486
        self.assertEqual('+contents of tree/a\n', text[4])
487
        self.assertEqual('\n', text[5])
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
488
        self.assertEqual('Commit message for a',
489
                         dlg._file_message_expander.get_label())
490
        self.assertTrue(dlg._file_message_expander.get_expanded())
491
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
492
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
493
        dlg._treeview_files.set_cursor(
494
            Gtk.TreePath(path=2), None, False)
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
495
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
496
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
734.1.7 by Curtis Hovey
Updated buffer.getText() calls and ModifierType enums.
497
                                    diff_buffer.get_end_iter(),
498
                                    True).splitlines(True)
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
499
        self.assertEqual("=== added file 'b'\n", text[0])
500
        self.assertContainsRe(text[1],
501
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
502
        self.assertContainsRe(text[2],
503
            r"\+\+\+ b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
504
        self.assertEqual('@@ -0,0 +1,1 @@\n', text[3])
505
        self.assertEqual('+contents of tree/b\n', text[4])
506
        self.assertEqual('\n', text[5])
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
507
        self.assertEqual('Commit message for b',
508
                         dlg._file_message_expander.get_label())
509
        self.assertTrue(dlg._file_message_expander.get_expanded())
510
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
511
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
512
        dlg._treeview_files.set_cursor(
513
            Gtk.TreePath(path=0), None, False)
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
514
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
515
        self.assertEqual('File commit message',
516
                         dlg._file_message_expander.get_label())
517
        self.assertFalse(dlg._file_message_expander.get_expanded())
518
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
519
520
    def test_file_selection_message(self):
521
        """Selecting a file should bring up its commit message."""
522
        tree = self.make_branch_and_tree('tree')
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
523
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
524
        self.build_tree(['tree/a', 'tree/b/'])
525
        tree.add(['a', 'b'], ['a-id', 'b-id'])
526
527
        def get_file_text():
528
            buf = dlg._file_message_text_view.get_buffer()
734.1.7 by Curtis Hovey
Updated buffer.getText() calls and ModifierType enums.
529
            return buf.get_text(
530
                buf.get_start_iter(), buf.get_end_iter(), True)
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
531
532
        def get_saved_text(path):
533
            """Get the saved text for a given record."""
534
            return dlg._files_store.get_value(dlg._files_store.get_iter(path), 5)
535
536
        dlg = commit.CommitDialog(tree)
537
        self.assertEqual('File commit message',
538
                         dlg._file_message_expander.get_label())
539
        self.assertFalse(dlg._file_message_expander.get_expanded())
540
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
541
        self.assertEqual('', get_file_text())
542
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
543
        dlg._treeview_files.set_cursor(
544
            Gtk.TreePath(path=1), None, False)
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
545
        self.assertEqual('Commit message for a',
546
                         dlg._file_message_expander.get_label())
547
        self.assertTrue(dlg._file_message_expander.get_expanded())
548
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
549
        self.assertEqual('', get_file_text())
550
551
        self.assertEqual('', get_saved_text(1))
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
552
        dlg._set_file_commit_message('Some text\nfor a\n')
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
553
        dlg._save_current_file_message()
554
        # We should have updated the ListStore with the new file commit info
555
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
556
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
557
        dlg._treeview_files.set_cursor(
558
            Gtk.TreePath(path=2), None, False)
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
559
        self.assertEqual('Commit message for b/',
560
                         dlg._file_message_expander.get_label())
561
        self.assertTrue(dlg._file_message_expander.get_expanded())
562
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
563
        self.assertEqual('', get_file_text())
564
565
        self.assertEqual('', get_saved_text(2))
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
566
        dlg._set_file_commit_message('More text\nfor b\n')
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
567
        # Now switch back to 'a'. The message should be saved, and the buffer
568
        # should be updated with the other text
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
569
        dlg._treeview_files.set_cursor(
570
            Gtk.TreePath(path=1), None, False)
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
571
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
572
        self.assertEqual('Commit message for a',
573
                         dlg._file_message_expander.get_label())
574
        self.assertTrue(dlg._file_message_expander.get_expanded())
575
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
576
        self.assertEqual('Some text\nfor a\n', get_file_text())
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
577
578
    def test_toggle_all_files(self):
579
        """When checking the All Files entry, it should toggle all fields"""
580
        tree = self.make_branch_and_tree('tree')
581
        self.build_tree(['tree/a', 'tree/b/'])
582
        tree.add(['a', 'b'], ['a-id', 'b-id'])
583
584
        dlg = commit.CommitDialog(tree)
585
        self.assertEqual([(None, None, True),
586
                          ('a-id', 'a', True),
587
                          ('b-id', 'b', True),
588
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
589
590
        # TODO: jam 20071002 I'm not sure how to exactly trigger a toggle, it
591
        #       looks like we need to call renderer.activate() and pass an
592
        #       event and widget, and lots of other stuff I'm not sure what to
593
        #       do with. So instead, we just call toggle directly, and assume
594
        #       that toggle is hooked in correctly
595
        # column = dlg._treeview_files.get_column(0)
734.1.20 by Curtis Hovey
col.get_cell_renderers => col.get_cells.
596
        # renderer = column.get_cells()[0]
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
597
598
        # Toggle a single entry should set just that entry to False
599
        dlg._toggle_commit(None, 1, dlg._files_store)
600
        self.assertEqual([(None, None, True),
601
                          ('a-id', 'a', False),
602
                          ('b-id', 'b', True),
603
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
604
605
        # Toggling the main entry should set all entries
606
        dlg._toggle_commit(None, 0, dlg._files_store)
607
        self.assertEqual([(None, None, False),
608
                          ('a-id', 'a', False),
609
                          ('b-id', 'b', False),
610
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
611
612
        dlg._toggle_commit(None, 2, dlg._files_store)
613
        self.assertEqual([(None, None, False),
614
                          ('a-id', 'a', False),
615
                          ('b-id', 'b', True),
616
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
617
618
        dlg._toggle_commit(None, 0, dlg._files_store)
619
        self.assertEqual([(None, None, True),
620
                          ('a-id', 'a', True),
621
                          ('b-id', 'b', True),
622
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
623
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
624
    def test_specific_files(self):
625
        tree = self.make_branch_and_tree('tree')
626
        self.build_tree(['tree/a', 'tree/b/'])
627
        tree.add(['a', 'b'], ['a-id', 'b-id'])
628
629
        dlg = commit.CommitDialog(tree)
630
        self.assertEqual((['a', 'b'], []), dlg._get_specific_files())
631
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
632
        dlg._commit_selected_radio.set_active(True)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
633
        dlg._toggle_commit(None, 0, dlg._files_store)
634
        self.assertEqual(([], []), dlg._get_specific_files())
635
636
        dlg._toggle_commit(None, 1, dlg._files_store)
637
        self.assertEqual((['a'], []), dlg._get_specific_files())
638
639
    def test_specific_files_with_messages(self):
640
        tree = self.make_branch_and_tree('tree')
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
641
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
642
        self.build_tree(['tree/a_file', 'tree/b_dir/'])
643
        tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
644
645
        dlg = commit.CommitDialog(tree)
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
646
        dlg._commit_selected_radio.set_active(True)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
647
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
648
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
649
        dlg._treeview_files.set_cursor(
650
            Gtk.TreePath(path=1), None, False)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
651
        dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
652
        dlg._treeview_files.set_cursor(
653
            Gtk.TreePath(path=2), None, False)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
654
        dlg._set_file_commit_message('message\nfor b_dir\n')
655
656
        self.assertEqual((['a_file', 'b_dir'],
657
                          [{'path':'a_file', 'file_id':'1a-id',
658
                            'message':'Test\nmessage\nfor a_file\n'},
659
                           {'path':'b_dir', 'file_id':'0b-id',
660
                            'message':'message\nfor b_dir\n'},
661
                          ]), dlg._get_specific_files())
662
663
        dlg._toggle_commit(None, 1, dlg._files_store)
664
        self.assertEqual((['b_dir'],
665
                          [{'path':'b_dir', 'file_id':'0b-id',
666
                            'message':'message\nfor b_dir\n'},
667
                          ]), dlg._get_specific_files())
668
622.1.1 by John Arbash Meinel
Ensure that per-file commit messages and global commit messages get sanitized.
669
    def test_specific_files_sanitizes_messages(self):
670
        tree = self.make_branch_and_tree('tree')
671
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
672
        self.build_tree(['tree/a_file', 'tree/b_dir/'])
673
        tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
674
675
        dlg = commit.CommitDialog(tree)
676
        dlg._commit_selected_radio.set_active(True)
677
        self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
678
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
679
        dlg._treeview_files.set_cursor(
680
            Gtk.TreePath(path=1), None, False)
622.1.1 by John Arbash Meinel
Ensure that per-file commit messages and global commit messages get sanitized.
681
        dlg._set_file_commit_message('Test\r\nmessage\rfor a_file\n')
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
682
        dlg._treeview_files.set_cursor(
683
            Gtk.TreePath(path=2), None, False)
622.1.1 by John Arbash Meinel
Ensure that per-file commit messages and global commit messages get sanitized.
684
        dlg._set_file_commit_message('message\r\nfor\nb_dir\r')
685
686
        self.assertEqual((['a_file', 'b_dir'],
687
                          [{'path':'a_file', 'file_id':'1a-id',
688
                            'message':'Test\nmessage\nfor a_file\n'},
689
                           {'path':'b_dir', 'file_id':'0b-id',
690
                            'message':'message\nfor\nb_dir\n'},
691
                          ]), dlg._get_specific_files())
692
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
693
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
694
class QuestionHelpers(object):
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
695
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
696
    def _set_question_yes(self, dlg):
697
        """Set the dialog to answer YES to any questions."""
698
        self.questions = []
606 by Vincent Ladeuil
Fix gtk dialogs popping up and asking for input during selftest.
699
        def _question_yes(*args, **kwargs):
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
700
            self.questions.append(args)
701
            self.questions.append('YES')
734.1.1 by Curtis Hovey
Mechanical changes made by pygi.convert.sh.
702
            return Gtk.ResponseType.YES
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
703
        dlg._question_dialog = _question_yes
704
705
    def _set_question_no(self, dlg):
706
        """Set the dialog to answer NO to any questions."""
707
        self.questions = []
606 by Vincent Ladeuil
Fix gtk dialogs popping up and asking for input during selftest.
708
        def _question_no(*args, **kwargs):
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
709
            self.questions.append(args)
710
            self.questions.append('NO')
734.1.1 by Curtis Hovey
Mechanical changes made by pygi.convert.sh.
711
            return Gtk.ResponseType.NO
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
712
        dlg._question_dialog = _question_no
713
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
714
715
class TestCommitDialog_Commit(tests.TestCaseWithTransport, QuestionHelpers):
716
    """Tests on the actual 'commit' button being pushed."""
717
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
718
    def test_bound_commit_local(self):
719
        tree = self.make_branch_and_tree('tree')
720
        self.build_tree(['tree/a'])
721
        tree.add(['a'], ['a-id'])
722
        rev_id1 = tree.commit('one')
723
724
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
725
        self.build_tree(['tree2/b'])
726
        tree2.add(['b'], ['b-id'])
727
        tree2.branch.bind(tree.branch)
728
729
        dlg = commit.CommitDialog(tree2)
730
        # With the check box set, it should only effect the local branch
731
        dlg._check_local.set_active(True)
732
        dlg._set_global_commit_message('Commit message\n')
733
        dlg._do_commit()
734
735
        last_rev = tree2.last_revision()
736
        self.assertEqual(last_rev, dlg.committed_revision_id)
737
        self.assertEqual(rev_id1, tree.branch.last_revision())
738
622.1.1 by John Arbash Meinel
Ensure that per-file commit messages and global commit messages get sanitized.
739
    def test_commit_global_sanitizes_message(self):
740
        tree = self.make_branch_and_tree('tree')
741
        self.build_tree(['tree/a'])
742
        tree.add(['a'], ['a-id'])
743
        rev_id1 = tree.commit('one')
744
745
        self.build_tree(['tree/b'])
746
        tree.add(['b'], ['b-id'])
747
        dlg = commit.CommitDialog(tree)
748
        # With the check box set, it should only effect the local branch
749
        dlg._set_global_commit_message('Commit\r\nmessage\rfoo\n')
750
        dlg._do_commit()
751
        rev = tree.branch.repository.get_revision(tree.last_revision())
752
        self.assertEqual('Commit\nmessage\nfoo\n', rev.message)
753
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
754
    def test_bound_commit_both(self):
755
        tree = self.make_branch_and_tree('tree')
756
        self.build_tree(['tree/a'])
757
        tree.add(['a'], ['a-id'])
758
        rev_id1 = tree.commit('one')
759
760
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
761
        self.build_tree(['tree2/b'])
762
        tree2.add(['b'], ['b-id'])
763
        tree2.branch.bind(tree.branch)
764
765
        dlg = commit.CommitDialog(tree2)
766
        # With the check box set, it should only effect the local branch
767
        dlg._check_local.set_active(False)
768
        dlg._set_global_commit_message('Commit message\n')
769
        dlg._do_commit()
770
771
        last_rev = tree2.last_revision()
772
        self.assertEqual(last_rev, dlg.committed_revision_id)
773
        self.assertEqual(last_rev, tree.branch.last_revision())
774
606 by Vincent Ladeuil
Fix gtk dialogs popping up and asking for input during selftest.
775
    def test_commit_empty_message(self):
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
776
        tree = self.make_branch_and_tree('tree')
777
        self.build_tree(['tree/a', 'tree/b'])
778
        tree.add(['a'], ['a-id'])
779
        rev_id = tree.commit('one')
780
781
        tree.add(['b'], ['b-id'])
782
783
        dlg = commit.CommitDialog(tree)
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
784
        self._set_question_no(dlg)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
785
        dlg._do_commit()
786
        self.assertEqual(
787
            [('Commit with an empty message?',
788
              'You can describe your commit intent in the message.'),
789
              'NO',
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
790
            ], self.questions)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
791
        # By saying NO, nothing should be committed.
792
        self.assertEqual(rev_id, tree.last_revision())
793
        self.assertIs(None, dlg.committed_revision_id)
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
794
        self.assertTrue(dlg._global_message_text_view.get_property('is-focus'))
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
795
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
796
        self._set_question_yes(dlg)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
797
798
        dlg._do_commit()
799
        self.assertEqual(
800
            [('Commit with an empty message?',
801
              'You can describe your commit intent in the message.'),
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
802
              'YES',
803
            ], self.questions)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
804
        committed = tree.last_revision()
805
        self.assertNotEqual(rev_id, committed)
806
        self.assertEqual(committed, dlg.committed_revision_id)
807
808
    def test_initial_commit(self):
809
        tree = self.make_branch_and_tree('tree')
810
        self.build_tree(['tree/a'])
811
        tree.add(['a'], ['a-id'])
812
813
        dlg = commit.CommitDialog(tree)
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
814
        dlg._set_global_commit_message('Some text\n')
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
815
        dlg._do_commit()
816
817
        last_rev = tree.last_revision()
818
        self.assertEqual(last_rev, dlg.committed_revision_id)
819
        rev = tree.branch.repository.get_revision(last_rev)
820
        self.assertEqual(last_rev, rev.revision_id)
821
        self.assertEqual('Some text\n', rev.message)
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
822
823
    def test_pointless_commit(self):
824
        tree = self.make_branch_and_tree('tree')
825
        self.build_tree(['tree/a'])
826
        tree.add(['a'], ['a-id'])
827
        rev_id1 = tree.commit('one')
828
829
        dlg = commit.CommitDialog(tree)
830
        dlg._set_global_commit_message('Some text\n')
831
832
        self._set_question_no(dlg)
833
        dlg._do_commit()
834
835
        self.assertIs(None, dlg.committed_revision_id)
836
        self.assertEqual(rev_id1, tree.last_revision())
837
        self.assertEqual(
838
            [('Commit with no changes?',
839
              'There are no changes in the working tree.'
840
              ' Do you want to commit anyway?'),
841
              'NO',
842
            ], self.questions)
843
844
        self._set_question_yes(dlg)
845
        dlg._do_commit()
846
847
        rev_id2 = tree.last_revision()
848
        self.assertEqual(rev_id2, dlg.committed_revision_id)
849
        self.assertNotEqual(rev_id1, rev_id2)
850
        self.assertEqual(
851
            [('Commit with no changes?',
852
              'There are no changes in the working tree.'
853
              ' Do you want to commit anyway?'),
854
              'YES',
855
            ], self.questions)
856
857
    def test_unknowns(self):
858
        """We should check if there are unknown files."""
859
        tree = self.make_branch_and_tree('tree')
860
        rev_id1 = tree.commit('one')
861
        self.build_tree(['tree/a', 'tree/b'])
862
        tree.add(['a'], ['a-id'])
863
864
        dlg = commit.CommitDialog(tree)
865
        dlg._set_global_commit_message('Some text\n')
866
        self._set_question_no(dlg)
867
868
        dlg._do_commit()
869
870
        self.assertIs(None, dlg.committed_revision_id)
871
        self.assertEqual(rev_id1, tree.last_revision())
872
        self.assertEqual(
873
            [("Commit with unknowns?",
874
              "Unknown files exist in the working tree. Commit anyway?"),
875
              "NO",
876
            ], self.questions)
877
878
        self._set_question_yes(dlg)
879
        dlg._do_commit()
880
881
        rev_id2 = tree.last_revision()
882
        self.assertNotEqual(rev_id1, rev_id2)
883
        self.assertEqual(rev_id2, dlg.committed_revision_id)
884
        self.assertEqual(
885
            [("Commit with unknowns?",
886
              "Unknown files exist in the working tree. Commit anyway?"),
887
              "YES",
888
            ], self.questions)
889
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
890
    def test_commit_specific_files(self):
891
        tree = self.make_branch_and_tree('tree')
892
        rev_id1 = tree.commit('one')
893
        self.build_tree(['tree/a', 'tree/b'])
894
        tree.add(['a', 'b'], ['a-id', 'b-id'])
895
896
        dlg = commit.CommitDialog(tree)
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
897
        dlg._commit_selected_radio.set_active(True) # enable partial
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
898
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
899
900
        dlg._set_global_commit_message('Committing just "a"\n')
901
        dlg._do_commit()
902
903
        rev_id2 = dlg.committed_revision_id
904
        self.assertIsNot(None, rev_id2)
905
        self.assertEqual(rev_id2, tree.last_revision())
906
907
        rt = tree.branch.repository.revision_tree(rev_id2)
908
        entries = [(path, ie.file_id) for path, ie in rt.iter_entries_by_dir()
909
                                       if path] # Ignore the root entry
910
        self.assertEqual([('a', 'a-id')], entries)
911
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
912
    def test_commit_partial_no_partial(self):
913
        """Ignore the checkboxes if committing all files."""
914
        tree = self.make_branch_and_tree('tree')
915
        rev_id1 = tree.commit('one')
916
        self.build_tree(['tree/a', 'tree/b'])
917
        tree.add(['a', 'b'], ['a-id', 'b-id'])
918
919
        dlg = commit.CommitDialog(tree)
920
        dlg._commit_selected_radio.set_active(True) # enable partial
921
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
922
923
        # Switch back to committing all changes
924
        dlg._commit_all_files_radio.set_active(True)
925
926
        dlg._set_global_commit_message('Committing everything\n')
927
        dlg._do_commit()
928
929
        rev_id2 = dlg.committed_revision_id
930
        self.assertIsNot(None, rev_id2)
931
        self.assertEqual(rev_id2, tree.last_revision())
932
933
        rt = tree.branch.repository.revision_tree(rev_id2)
934
        entries = [(path, ie.file_id) for path, ie in rt.iter_entries_by_dir()
935
                                       if path] # Ignore the root entry
936
        self.assertEqual([('a', 'a-id'), ('b', 'b-id')], entries)
937
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
938
    def test_commit_no_messages(self):
939
        tree = self.make_branch_and_tree('tree')
940
        rev_id1 = tree.commit('one')
941
        self.build_tree(['tree/a', 'tree/b'])
942
        tree.add(['a', 'b'], ['a-id', 'b-id'])
943
944
        dlg = commit.CommitDialog(tree)
945
        dlg._set_global_commit_message('Simple commit\n')
946
        dlg._do_commit()
947
948
        rev = tree.branch.repository.get_revision(dlg.committed_revision_id)
949
        self.failIf('file-info' in rev.properties)
950
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
951
    def test_commit_disabled_messages(self):
952
        tree = self.make_branch_and_tree('tree')
953
        rev_id1 = tree.commit('one')
954
955
        self.build_tree(['tree/a', 'tree/b'])
956
        tree.add(['a', 'b'], ['a-id', 'b-id'])
957
958
        dlg = commit.CommitDialog(tree)
959
        self.assertFalse(dlg._file_message_expander.get_property('visible'))
278.1.38 by John Arbash Meinel
Add tests that when per-file messages are disabled
960
        self.assertEqual('Commit Message',
961
                         dlg._global_message_label.get_text())
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
962
963
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
964
        dlg = commit.CommitDialog(tree)
965
        self.assertTrue(dlg._file_message_expander.get_property('visible'))
278.1.38 by John Arbash Meinel
Add tests that when per-file messages are disabled
966
        self.assertEqual('Global Commit Message',
967
                         dlg._global_message_label.get_text())
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
968
969
        tree.branch.get_config().set_user_option('per_file_commits', 'on')
970
        dlg = commit.CommitDialog(tree)
971
        self.assertTrue(dlg._file_message_expander.get_property('visible'))
278.1.38 by John Arbash Meinel
Add tests that when per-file messages are disabled
972
        self.assertEqual('Global Commit Message',
973
                         dlg._global_message_label.get_text())
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
974
975
        tree.branch.get_config().set_user_option('per_file_commits', 'y')
976
        dlg = commit.CommitDialog(tree)
977
        self.assertTrue(dlg._file_message_expander.get_property('visible'))
278.1.38 by John Arbash Meinel
Add tests that when per-file messages are disabled
978
        self.assertEqual('Global Commit Message',
979
                         dlg._global_message_label.get_text())
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
980
981
        tree.branch.get_config().set_user_option('per_file_commits', 'n')
982
        dlg = commit.CommitDialog(tree)
983
        self.assertFalse(dlg._file_message_expander.get_property('visible'))
278.1.38 by John Arbash Meinel
Add tests that when per-file messages are disabled
984
        self.assertEqual('Commit Message',
985
                         dlg._global_message_label.get_text())
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
986
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
987
    def test_commit_specific_files_with_messages(self):
988
        tree = self.make_branch_and_tree('tree')
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
989
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
990
        rev_id1 = tree.commit('one')
991
        self.build_tree(['tree/a', 'tree/b'])
992
        tree.add(['a', 'b'], ['a-id', 'b-id'])
993
994
        dlg = commit.CommitDialog(tree)
278.1.43 by John Arbash Meinel
Finish connecting the 'Commit all changes' radio buttons.
995
        dlg._commit_selected_radio.set_active(True) # enable partial
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
996
        dlg._treeview_files.set_cursor(
997
            Gtk.TreePath(path=1), None, False)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
998
        dlg._set_file_commit_message('Message for A\n')
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
999
        dlg._treeview_files.set_cursor(
1000
            Gtk.TreePath(path=2), None, False)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
1001
        dlg._set_file_commit_message('Message for B\n')
1002
        dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
1003
        dlg._set_global_commit_message('Commit just "a"')
1004
1005
        dlg._do_commit()
1006
1007
        rev_id2 = dlg.committed_revision_id
1008
        self.assertEqual(rev_id2, tree.last_revision())
1009
        rev = tree.branch.repository.get_revision(rev_id2)
1010
        self.assertEqual('Commit just "a"', rev.message)
1011
        file_info = rev.properties['file-info']
662 by Vincent Ladeuil
Fix test failures.
1012
        self.assertEqual(u'ld7:file_id4:a-id'
1013
                         '7:message14:Message for A\n'
1014
                         '4:path1:a'
1015
                         'ee',
1016
                         file_info)
278.1.27 by John Arbash Meinel
Add the ability to commit just specific files.
1017
        self.assertEqual([{'path':'a', 'file_id':'a-id',
662 by Vincent Ladeuil
Fix test failures.
1018
                           'message':'Message for A\n'},],
1019
                         bencode.bdecode(file_info.encode('UTF-8')))
278.1.28 by John Arbash Meinel
Ensure that we can set per-file messages even during a merge.
1020
1021
    def test_commit_messages_after_merge(self):
1022
        tree = self.make_branch_and_tree('tree')
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
1023
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
278.1.28 by John Arbash Meinel
Ensure that we can set per-file messages even during a merge.
1024
        rev_id1 = tree.commit('one')
1025
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
1026
        self.build_tree(['tree2/a', 'tree2/b'])
1027
        tree2.add(['a', 'b'], ['a-id', 'b-id'])
1028
        rev_id2 = tree2.commit('two')
1029
1030
        tree.merge_from_branch(tree2.branch)
1031
1032
        dlg = commit.CommitDialog(tree)
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
1033
        dlg._treeview_files.set_cursor(
1034
            Gtk.TreePath(path=1), None, False) # 'a'
278.1.28 by John Arbash Meinel
Ensure that we can set per-file messages even during a merge.
1035
        dlg._set_file_commit_message('Message for A\n')
1036
        # No message for 'B'
1037
        dlg._set_global_commit_message('Merging from "tree2"\n')
1038
1039
        dlg._do_commit()
1040
1041
        rev_id3 = dlg.committed_revision_id
1042
        self.assertEqual(rev_id3, tree.last_revision())
1043
        rev = tree.branch.repository.get_revision(rev_id3)
1044
        self.assertEqual('Merging from "tree2"\n', rev.message)
1045
        self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
1046
        file_info = rev.properties['file-info']
662 by Vincent Ladeuil
Fix test failures.
1047
        self.assertEqual(u'ld7:file_id4:a-id'
1048
                         '7:message14:Message for A\n'
1049
                         '4:path1:a'
1050
                         'ee',
1051
                         file_info)
278.1.28 by John Arbash Meinel
Ensure that we can set per-file messages even during a merge.
1052
        self.assertEqual([{'path':'a', 'file_id':'a-id',
662 by Vincent Ladeuil
Fix test failures.
1053
                           'message':'Message for A\n'},],
1054
                         bencode.bdecode(file_info.encode('UTF-8')))
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1055
1056
    def test_commit_unicode_messages(self):
737 by Jelmer Vernooij
Support new location of UnicodeFilenameFeature in 2.5.
1057
        self.requireFeature(UnicodeFilenameFeature)
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1058
1059
        tree = self.make_branch_and_tree('tree')
278.1.33 by John Arbash Meinel
Only enable the per-file dialog if 'per_file_commits' is enabled in the config.
1060
        tree.branch.get_config().set_user_option('per_file_commits', 'true')
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1061
        self.build_tree(['tree/a', u'tree/\u03a9'])
1062
        tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
1063
1064
        dlg = commit.CommitDialog(tree)
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
1065
        dlg._treeview_files.set_cursor(
1066
            Gtk.TreePath(path=1), None, False) # 'a'
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1067
        dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
734.1.23 by Curtis Hovey
Always pass a Gtk.TreePath instead of an int or tuple.
1068
        dlg._treeview_files.set_cursor(
1069
            Gtk.TreePath(path=2), None, False) # omega
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1070
        dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1071
        dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1072
1073
        self.assertEqual(([u'a', u'\u03a9'],
1074
                          [{'path':'a', 'file_id':'a-id',
1075
                            'message':'Test \xc3\xban\xc3\xacc\xc3\xb6de\n'},
1076
                           {'path':'\xce\xa9', 'file_id':'omega-id',
1077
                            'message':'\xce\xa9 is the end of all things.\n'},
1078
                          ]), dlg._get_specific_files())
1079
1080
        dlg._do_commit()
1081
1082
        rev = tree.branch.repository.get_revision(dlg.committed_revision_id)
278.1.31 by John Arbash Meinel
We can make bencode work again by a simple decode/encode step.
1083
        file_info = rev.properties['file-info'].encode('UTF-8')
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1084
        value = ('ld7:file_id4:a-id'
1085
                   '7:message16:Test \xc3\xban\xc3\xacc\xc3\xb6de\n'
1086
                   '4:path1:a'
1087
                  'e'
1088
                  'd7:file_id8:omega-id'
1089
                   '7:message29:\xce\xa9 is the end of all things.\n'
1090
                   '4:path2:\xce\xa9'
1091
                  'e'
1092
                 'e')
1093
        self.assertEqual(value, file_info)
1094
        file_info_decoded = bencode.bdecode(file_info)
1095
        for d in file_info_decoded:
278.1.31 by John Arbash Meinel
We can make bencode work again by a simple decode/encode step.
1096
            d['path'] = d['path'].decode('UTF-8')
1097
            d['message'] = d['message'].decode('UTF-8')
278.1.29 by John Arbash Meinel
Start testing with Unicode data.
1098
1099
        self.assertEqual([{'path':u'a', 'file_id':'a-id',
1100
                           'message':u'Test \xfan\xecc\xf6de\n'},
1101
                          {'path':u'\u03a9', 'file_id':'omega-id',
1102
                           'message':u'\u03a9 is the end of all things.\n'},
1103
                         ], file_info_decoded)
622.1.1 by John Arbash Meinel
Ensure that per-file commit messages and global commit messages get sanitized.
1104
1105
1106
class TestSanitizeMessage(tests.TestCase):
1107
1108
    def assertSanitize(self, expected, original):
1109
        self.assertEqual(expected,
1110
                         commit._sanitize_and_decode_message(original))
1111
1112
    def test_untouched(self):
1113
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\nbar\nbaz\n')
1114
1115
    def test_converts_cr_to_lf(self):
1116
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\rbar\rbaz\r')
1117
1118
    def test_converts_crlf_to_lf(self):
1119
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\r\nbaz\r\n')
1120
1121
    def test_converts_mixed_to_lf(self):
1122
        self.assertSanitize('foo\nbar\nbaz\n', 'foo\r\nbar\rbaz\n')
635.2.8 by Vincent Ladeuil
Start testing patch behavior.
1123
1124
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1125
class TestSavedCommitMessages(tests.TestCaseWithTransport):
635.2.9 by Vincent Ladeuil
Tests completed for uncommit.
1126
635.2.12 by Vincent Ladeuil
Implement commit message saving without modifying bzrlib.
1127
    def setUp(self):
1128
        super(TestSavedCommitMessages, self).setUp()
1129
        # Install our hook
1130
        branch.Branch.hooks.install_named_hook(
1131
            'post_uncommit', commit.save_commit_messages, None)
1132
635.2.9 by Vincent Ladeuil
Tests completed for uncommit.
1133
    def _get_file_info_dict(self, rank):
1134
        file_info = [dict(path='a', file_id='a-id', message='a msg %d' % rank),
1135
                     dict(path='b', file_id='b-id', message='b msg %d' % rank)]
1136
        return file_info
1137
1138
    def _get_file_info_revprops(self, rank):
1139
        file_info_prop = self._get_file_info_dict(rank)
1140
        return {'file-info': bencode.bencode(file_info_prop).decode('UTF-8')}
1141
1142
    def _get_commit_message(self):
1143
        return self.config.get_user_option('gtk_global_commit_message')
1144
1145
    def _get_file_commit_messages(self):
1146
        return self.config.get_user_option('gtk_file_commit_messages')
1147
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1148
1149
class TestUncommitHook(TestSavedCommitMessages):
1150
1151
    def setUp(self):
1152
        super(TestUncommitHook, self).setUp()
1153
        self.tree = self.make_branch_and_tree('tree')
1154
        self.config = self.tree.branch.get_config()
1155
        self.build_tree(['tree/a', 'tree/b'])
1156
        self.tree.add(['a'], ['a-id'])
1157
        self.tree.add(['b'], ['b-id'])
635.2.12 by Vincent Ladeuil
Implement commit message saving without modifying bzrlib.
1158
        rev1 = self.tree.commit('one', rev_id='one-id',
1159
                                revprops=self._get_file_info_revprops(1))
1160
        rev2 = self.tree.commit('two', rev_id='two-id',
1161
                                revprops=self._get_file_info_revprops(2))
1162
        rev3 = self.tree.commit('three', rev_id='three-id',
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1163
                                revprops=self._get_file_info_revprops(3))
1164
635.2.9 by Vincent Ladeuil
Tests completed for uncommit.
1165
    def test_uncommit_one_by_one(self):
1166
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1167
        self.assertEquals(u'three', self._get_commit_message())
1168
        self.assertEquals(u'd4:a-id7:a msg 34:b-id7:b msg 3e',
1169
                          self._get_file_commit_messages())
1170
1171
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1172
        self.assertEquals(u'two\n******\nthree', self._get_commit_message())
1173
        self.assertEquals(u'd4:a-id22:a msg 2\n******\na msg 3'
1174
                          '4:b-id22:b msg 2\n******\nb msg 3e',
1175
                          self._get_file_commit_messages())
1176
1177
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1178
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
1179
                          self._get_commit_message())
1180
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
1181
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
1182
                          self._get_file_commit_messages())
1183
1184
    def test_uncommit_all_at_once(self):
1185
        uncommit.uncommit(self.tree.branch, tree=self.tree, revno=1)
1186
        self.assertEquals(u'one\n******\ntwo\n******\nthree',
1187
                          self._get_commit_message())
1188
        self.assertEquals(u'd4:a-id37:a msg 1\n******\na msg 2\n******\na msg 3'
1189
                          '4:b-id37:b msg 1\n******\nb msg 2\n******\nb msg 3e',
1190
                          self._get_file_commit_messages())
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1191
1192
1193
class TestReusingSavedCommitMessages(TestSavedCommitMessages, QuestionHelpers):
1194
1195
    def setUp(self):
1196
        super(TestReusingSavedCommitMessages, self).setUp()
1197
        self.tree = self.make_branch_and_tree('tree')
1198
        self.config = self.tree.branch.get_config()
1199
        self.config.set_user_option('per_file_commits', 'true')
1200
        self.build_tree(['tree/a', 'tree/b'])
1201
        self.tree.add(['a'], ['a-id'])
1202
        self.tree.add(['b'], ['b-id'])
1203
        rev1 = self.tree.commit('one', revprops=self._get_file_info_revprops(1))
1204
        rev2 = self.tree.commit('two', revprops=self._get_file_info_revprops(2))
1205
        uncommit.uncommit(self.tree.branch, tree=self.tree)
1206
        self.build_tree_contents([('tree/a', 'new a content\n'),
1207
                                  ('tree/b', 'new b content'),])
1208
635.2.11 by Vincent Ladeuil
Fix a leaking dialog windows appearing during the test suite.
1209
    def _get_commit_dialog(self, tree):
1210
        # Ensure we will never use a dialog that can actually prompt the user
1211
        # during the test suite. Test *can* and *should* override with the
1212
        # correct question dialog type.
1213
        dlg = commit.CommitDialog(tree)
1214
        self._set_question_no(dlg)
1215
        return dlg
1216
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1217
    def test_setup_saved_messages(self):
1218
        # Check the initial setup
1219
        self.assertEquals(u'two', self._get_commit_message())
1220
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
1221
                          self._get_file_commit_messages())
1222
1223
    def test_messages_are_reloaded(self):
635.2.11 by Vincent Ladeuil
Fix a leaking dialog windows appearing during the test suite.
1224
        dlg = self._get_commit_dialog(self.tree)
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1225
        self.assertEquals(u'two', dlg._get_global_commit_message())
1226
        self.assertEquals(([u'a', u'b'],
1227
                           [{ 'path': 'a',
1228
                             'file_id': 'a-id', 'message': 'a msg 2',},
1229
                           {'path': 'b',
1230
                            'file_id': 'b-id', 'message': 'b msg 2',}],),
1231
                          dlg._get_specific_files())
1232
1233
    def test_messages_are_consumed(self):
635.2.11 by Vincent Ladeuil
Fix a leaking dialog windows appearing during the test suite.
1234
        dlg = self._get_commit_dialog(self.tree)
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1235
        dlg._do_commit()
1236
        self.assertEquals(u'', self._get_commit_message())
1237
        self.assertEquals(u'de', self._get_file_commit_messages())
1238
1239
    def test_messages_are_saved_on_cancel_if_required(self):
635.2.11 by Vincent Ladeuil
Fix a leaking dialog windows appearing during the test suite.
1240
        dlg = self._get_commit_dialog(self.tree)
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1241
        self._set_question_yes(dlg) # Save messages
1242
        dlg._do_cancel()
1243
        self.assertEquals(u'two', self._get_commit_message())
1244
        self.assertEquals(u'd4:a-id7:a msg 24:b-id7:b msg 2e',
1245
                          self._get_file_commit_messages())
1246
1247
    def test_messages_are_cleared_on_cancel_if_required(self):
635.2.11 by Vincent Ladeuil
Fix a leaking dialog windows appearing during the test suite.
1248
        dlg = self._get_commit_dialog(self.tree)
635.2.10 by Vincent Ladeuil
Complete tests around saved commit messages.
1249
        self._set_question_no(dlg) # Don't save messages
1250
        dlg._do_cancel()
1251
        self.assertEquals(u'', self._get_commit_message())
1252
        self.assertEquals(u'de',
1253
                          self._get_file_commit_messages())