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