/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
1
# Copyright (C) 2007 John Arbash Meinel <john@arbash-meinel.com>
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
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
21
import gtk
22
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
23
from bzrlib import (
24
    tests,
25
    revision,
26
    )
27
28
from bzrlib.plugins.gtk import commit
29
30
31
# TODO: All we need is basic ancestry code to test this, we shouldn't need a
32
# TestCaseWithTransport, just a TestCaseWithMemoryTransport or somesuch.
33
34
class TestPendingRevisions(tests.TestCaseWithTransport):
35
36
    def test_pending_revisions_none(self):
37
        tree = self.make_branch_and_tree('.')
38
        tree.commit('one')
39
40
        self.assertIs(None, commit.pending_revisions(tree))
41
42
    def test_pending_revisions_simple(self):
43
        tree = self.make_branch_and_tree('tree')
44
        rev_id1 = tree.commit('one')
45
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
46
        rev_id2 = tree2.commit('two')
47
        tree.merge_from_branch(tree2.branch)
48
        self.assertEqual([rev_id1, rev_id2], tree.get_parent_ids())
49
50
        pending_revisions = commit.pending_revisions(tree)
51
        # One primary merge
52
        self.assertEqual(1, len(pending_revisions))
53
        # Revision == rev_id2
54
        self.assertEqual(rev_id2, pending_revisions[0][0].revision_id)
55
        # No children of this revision.
56
        self.assertEqual([], pending_revisions[0][1])
57
58
    def test_pending_revisions_with_children(self):
59
        tree = self.make_branch_and_tree('tree')
60
        rev_id1 = tree.commit('one')
61
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
62
        rev_id2 = tree2.commit('two')
63
        rev_id3 = tree2.commit('three')
64
        rev_id4 = tree2.commit('four')
65
        tree.merge_from_branch(tree2.branch)
66
        self.assertEqual([rev_id1, rev_id4], tree.get_parent_ids())
67
68
        pending_revisions = commit.pending_revisions(tree)
69
        # One primary merge
70
        self.assertEqual(1, len(pending_revisions))
71
        # Revision == rev_id2
72
        self.assertEqual(rev_id4, pending_revisions[0][0].revision_id)
73
        # Two children for this revision
74
        self.assertEqual(2, len(pending_revisions[0][1]))
75
        self.assertEqual(rev_id3, pending_revisions[0][1][0].revision_id)
76
        self.assertEqual(rev_id2, pending_revisions[0][1][1].revision_id)
77
78
    def test_pending_revisions_multi_merge(self):
79
        tree = self.make_branch_and_tree('tree')
80
        rev_id1 = tree.commit('one')
81
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
82
        rev_id2 = tree2.commit('two')
83
        rev_id3 = tree2.commit('three')
84
        tree3 = tree2.bzrdir.sprout('tree3').open_workingtree()
85
        rev_id4 = tree3.commit('four')
86
        rev_id5 = tree3.commit('five')
87
        tree.merge_from_branch(tree2.branch)
88
        tree.merge_from_branch(tree3.branch)
89
        self.assertEqual([rev_id1, rev_id3, rev_id5], tree.get_parent_ids())
90
91
        pending_revisions = commit.pending_revisions(tree)
92
        # Two primary merges
93
        self.assertEqual(2, len(pending_revisions))
94
        # Revision == rev_id2
95
        self.assertEqual(rev_id3, pending_revisions[0][0].revision_id)
96
        self.assertEqual(rev_id5, pending_revisions[1][0].revision_id)
97
        # One child for the first merge
98
        self.assertEqual(1, len(pending_revisions[0][1]))
99
        self.assertEqual(rev_id2, pending_revisions[0][1][0].revision_id)
100
        # One child for the second merge
101
        self.assertEqual(1, len(pending_revisions[1][1]))
102
        self.assertEqual(rev_id4, pending_revisions[1][1][0].revision_id)
103
104
105
class Test_RevToPendingInfo(tests.TestCaseWithTransport):
106
107
    def test_basic_info(self):
108
        tree = self.make_branch_and_tree('tree')
109
        rev_id = tree.commit('Multiline\ncommit\nmessage',
110
                             committer='Joe Foo <joe@foo.com>',
111
                             timestamp=1191012408.674,
112
                             timezone=-18000
113
                             )
114
        rev = tree.branch.repository.get_revision(rev_id)
115
        rev_dict = commit.CommitDialog._rev_to_pending_info(rev)
116
        self.assertEqual({'committer':'Joe Foo',
117
                          'summary':'Multiline',
118
                          'date':'2007-09-28',
119
                          'revision_id':rev_id,
120
                         }, rev_dict)
121
122
123
class CommitDialogNoWidgets(commit.CommitDialog):
124
125
    def construct(self):
126
        pass # Don't create any widgets here
127
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
128
    def fill_in_data(self):
129
        pass # With no widgets, there are no widgets to fill out
130
131
132
class TestCommitDialogSimple(tests.TestCaseWithTransport):
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
133
134
    def test_setup_parameters_no_pending(self):
135
        tree = self.make_branch_and_tree('tree')
136
        rev_id = tree.commit('first')
137
138
        dlg = CommitDialogNoWidgets(tree)
139
        self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
140
        self.assertIs(None, dlg._pending)
141
        self.assertFalse(dlg._is_checkout)
142
143
    def test_setup_parameters_checkout(self):
144
        tree = self.make_branch_and_tree('tree')
145
        rev_id = tree.commit('first')
146
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
147
        tree2.branch.bind(tree.branch)
148
149
        dlg = CommitDialogNoWidgets(tree2)
150
        self.assertEqual(rev_id, dlg._basis_tree.get_revision_id())
151
        self.assertIs(None, dlg._pending)
152
        self.assertTrue(dlg._is_checkout)
153
154
    def test_setup_parameters_pending(self):
155
        tree = self.make_branch_and_tree('tree')
156
        rev_id1 = tree.commit('one')
157
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
158
        rev_id2 = tree2.commit('two')
159
        tree.merge_from_branch(tree2.branch)
160
161
        dlg = CommitDialogNoWidgets(tree)
162
        self.assertEqual(rev_id1, dlg._basis_tree.get_revision_id())
163
        self.assertIsNot(None, dlg._pending)
164
        self.assertEqual(1, len(dlg._pending))
165
        self.assertEqual(rev_id2, dlg._pending[0][0].revision_id)
166
167
    def test_setup_parameters_delta(self):
168
        tree = self.make_branch_and_tree('tree')
169
        self.build_tree(['tree/a'])
170
        tree.add(['a'], ['a-id'])
171
172
        dlg = CommitDialogNoWidgets(tree)
278.1.12 by John Arbash Meinel
Delay computing the delta, and clean up some of the diff view names.
173
        self.assertIs(None, dlg._delta)
174
        dlg._compute_delta()
175
278.1.5 by John Arbash Meinel
Starting to flesh out the dialog with actual windows.
176
        delta = dlg._delta
177
        self.assertEqual([], delta.modified)
178
        self.assertEqual([], delta.renamed)
179
        self.assertEqual([], delta.removed)
180
        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.
181
182
183
class TestCommitDialog(tests.TestCaseWithTransport):
184
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
185
    def test_bound(self):
186
        tree = self.make_branch_and_tree('tree')
187
        rev_id = tree.commit('first')
188
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
189
        tree2.branch.bind(tree.branch)
190
191
        # tree is not a checkout
192
        dlg = commit.CommitDialog(tree)
193
        self.assertFalse(dlg._check_local.get_property('visible'))
194
195
        # tree2 is a checkout
196
        dlg2 = commit.CommitDialog(tree2)
197
        self.assertTrue(dlg2._check_local.get_property('visible'))
198
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
199
    def test_no_pending(self):
200
        tree = self.make_branch_and_tree('tree')
201
        rev_id1 = tree.commit('one')
202
203
        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.
204
205
        self.assertFalse(dlg._pending_box.get_property('visible'))
206
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
207
        commit_col = dlg._treeview_files.get_column(0)
208
        self.assertEqual('Commit', commit_col.get_title())
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
209
        renderer = commit_col.get_cell_renderers()[0]
210
        self.assertTrue(renderer.get_active())
278.1.14 by John Arbash Meinel
Tests that we fill out the pending list correctly.
211
212
    def test_pending(self):
213
        tree = self.make_branch_and_tree('tree')
214
        rev_id1 = tree.commit('one')
215
216
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
217
        rev_id2 = tree2.commit('two',
218
                               committer='Joe Foo <joe@foo.com>',
219
                               timestamp=1191264271.05,
220
                               timezone=+7200)
221
        tree.merge_from_branch(tree2.branch)
222
223
        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.
224
225
        self.assertTrue(dlg._pending_box.get_property('visible'))
226
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
227
        commit_col = dlg._treeview_files.get_column(0)
228
        self.assertEqual('Commit*', commit_col.get_title())
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
229
        renderer = commit_col.get_cell_renderers()[0]
230
        self.assertFalse(renderer.get_active())
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
231
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
232
        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.
233
        self.assertEqual([(rev_id2, '2007-10-01', 'Joe Foo', 'two')], values)
234
235
    def test_pending_multiple(self):
236
        tree = self.make_branch_and_tree('tree')
237
        rev_id1 = tree.commit('one')
238
239
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
240
        rev_id2 = tree2.commit('two',
241
                               committer='Joe Foo <joe@foo.com>',
242
                               timestamp=1191264271.05,
243
                               timezone=+7200)
244
        rev_id3 = tree2.commit('three',
245
                               committer='Jerry Foo <jerry@foo.com>',
246
                               timestamp=1191264278.05,
247
                               timezone=+7200)
248
        tree.merge_from_branch(tree2.branch)
249
        tree3 = tree.bzrdir.sprout('tree3').open_workingtree()
250
        rev_id4 = tree3.commit('four',
251
                               committer='Joe Foo <joe@foo.com>',
252
                               timestamp=1191264279.05,
253
                               timezone=+7200)
254
        rev_id5 = tree3.commit('five',
255
                               committer='Jerry Foo <jerry@foo.com>',
256
                               timestamp=1191372278.05,
257
                               timezone=+7200)
258
        tree.merge_from_branch(tree3.branch)
259
260
        dlg = commit.CommitDialog(tree)
261
        # TODO: assert that the pending box is set to show
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
262
        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.
263
        self.assertEqual([(rev_id3, '2007-10-01', 'Jerry Foo', 'three'),
264
                          (rev_id2, '2007-10-01', 'Joe Foo', 'two'),
265
                          (rev_id5, '2007-10-03', 'Jerry Foo', 'five'),
266
                          (rev_id4, '2007-10-01', 'Joe Foo', 'four'),
267
                         ], values)
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
268
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
269
    def test_filelist_added(self):
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
270
        tree = self.make_branch_and_tree('tree')
271
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
272
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
273
274
        dlg = commit.CommitDialog(tree)
275
        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,
276
        self.assertEqual([(None, None, True, 'All Files', ''),
277
                          ('a-id', 'a', True, 'a', 'added'),
278.1.15 by John Arbash Meinel
Hook up the list of modified files.
278
                          ('b-id', 'b', True, 'b/', 'added'),
279
                          ('c-id', 'b/c', True, 'b/c', 'added'),
280
                         ], values)
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
281
282
    def test_filelist_renamed(self):
283
        tree = self.make_branch_and_tree('tree')
284
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
285
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
286
        rev_id1 = tree.commit('one')
287
288
        tree.rename_one('b', 'd')
289
        tree.rename_one('a', 'd/a')
290
291
        dlg = commit.CommitDialog(tree)
292
        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,
293
        self.assertEqual([(None, None, True, 'All Files', ''),
294
                          ('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
295
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed'),
296
                         ], values)
297
298
    def test_filelist_modified(self):
299
        tree = self.make_branch_and_tree('tree')
300
        self.build_tree(['tree/a'])
301
        tree.add(['a'], ['a-id'])
302
        rev_id1 = tree.commit('one')
303
304
        self.build_tree_contents([('tree/a', 'new contents for a\n')])
305
306
        dlg = commit.CommitDialog(tree)
307
        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,
308
        self.assertEqual([(None, None, True, 'All Files', ''),
309
                          ('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
310
                         ], values)
311
312
    def test_filelist_renamed_and_modified(self):
313
        tree = self.make_branch_and_tree('tree')
314
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
315
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
316
        rev_id1 = tree.commit('one')
317
318
        tree.rename_one('b', 'd')
319
        tree.rename_one('a', 'd/a')
320
        self.build_tree_contents([('tree/d/a', 'new contents for a\n'),
321
                                  ('tree/d/c', 'new contents for c\n'),
322
                                 ])
323
        # 'c' is not considered renamed, because only its parent was moved, it
324
        # stayed in the same directory
325
326
        dlg = commit.CommitDialog(tree)
327
        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,
328
        self.assertEqual([(None, None, True, 'All Files', ''),
329
                          ('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
330
                          ('a-id', 'd/a', True, 'a => d/a', 'renamed and modified'),
331
                          ('c-id', 'd/c', True, 'd/c', 'modified'),
332
                         ], values)
333
334
    def test_filelist_kind_changed(self):
335
        tree = self.make_branch_and_tree('tree')
336
        self.build_tree(['tree/a', 'tree/b'])
337
        tree.add(['a', 'b'], ['a-id', 'b-id'])
338
        tree.commit('one')
339
340
        os.remove('tree/a')
341
        self.build_tree(['tree/a/'])
278.1.17 by John Arbash Meinel
Add a * reference for why you can't change the commit selection.
342
        # XXX:  This is technically valid, and the file list handles it fine,
343
        #       but 'show_diff_trees()' does not, so we skip this part of the
344
        #       test for now.
345
        # tree.rename_one('b', 'c')
346
        # os.remove('tree/c')
347
        # self.build_tree(['tree/c/'])
278.1.16 by John Arbash Meinel
Implement the file changes list on top of _iter_changes rather than
348
349
        dlg = commit.CommitDialog(tree)
350
        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,
351
        self.assertEqual([(None, None, True, 'All Files', ''),
352
                          ('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.
353
                          # ('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
354
                         ], values)
355
356
    def test_filelist_removed(self):
357
        tree = self.make_branch_and_tree('tree')
358
        self.build_tree(['tree/a', 'tree/b/'])
359
        tree.add(['a', 'b'], ['a-id', 'b-id'])
360
        tree.commit('one')
361
362
        os.remove('tree/a')
363
        tree.remove('b', force=True)
364
365
        dlg = commit.CommitDialog(tree)
366
        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,
367
        self.assertEqual([(None, None, True, 'All Files', ''),
368
                          ('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
369
                          ('b-id', 'b', True, 'b/', 'removed'),
370
                         ], values)
278.1.18 by John Arbash Meinel
Start checking the diff view is correct.
371
372
    def test_diff_view(self):
373
        tree = self.make_branch_and_tree('tree')
374
        self.build_tree(['tree/a', 'tree/b'])
375
        tree.add(['a', 'b'], ['a-id', 'b-id'])
376
        tree.commit('one')
377
378
        self.build_tree_contents([('tree/a', 'new contents for a\n')])
379
        tree.remove('b')
380
381
        dlg = commit.CommitDialog(tree)
382
        diff_buffer = dlg._diff_view.buffer
383
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
384
                                    diff_buffer.get_end_iter()).splitlines(True)
385
386
        self.assertEqual("=== removed file 'b'\n", text[0])
387
        self.assertContainsRe(text[1],
388
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
389
        self.assertEqual('+++ b\t1970-01-01 00:00:00 +0000\n', text[2])
390
        self.assertEqual('@@ -1,1 +0,0 @@\n', text[3])
391
        self.assertEqual('-contents of tree/b\n', text[4])
392
        self.assertEqual('\n', text[5])
393
394
        self.assertEqual("=== modified file 'a'\n", text[6])
395
        self.assertContainsRe(text[7],
396
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
397
        self.assertContainsRe(text[8],
398
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
399
        self.assertEqual('@@ -1,1 +1,1 @@\n', text[9])
400
        self.assertEqual('-contents of tree/a\n', text[10])
401
        self.assertEqual('+new contents for a\n', text[11])
402
        self.assertEqual('\n', text[12])
403
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
404
        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.
405
406
    def test_file_selection(self):
407
        """Several things should happen when a file has been selected."""
408
        tree = self.make_branch_and_tree('tree')
409
        self.build_tree(['tree/a', 'tree/b'])
410
        tree.add(['a', 'b'], ['a-id', 'b-id'])
411
412
        dlg = commit.CommitDialog(tree)
413
        diff_buffer = dlg._diff_view.buffer
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
414
        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.
415
        self.assertEqual('File commit message',
416
                         dlg._file_message_expander.get_label())
417
        self.assertFalse(dlg._file_message_expander.get_expanded())
418
        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.
419
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
420
        dlg._treeview_files.set_cursor((1,))
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
421
        self.assertEqual('Diff for a', dlg._diff_label.get_text())
422
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
423
                                    diff_buffer.get_end_iter()).splitlines(True)
424
        self.assertEqual("=== added file 'a'\n", text[0])
425
        self.assertContainsRe(text[1],
426
            r"--- a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
427
        self.assertContainsRe(text[2],
428
            r"\+\+\+ a\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
429
        self.assertEqual('@@ -0,0 +1,1 @@\n', text[3])
430
        self.assertEqual('+contents of tree/a\n', text[4])
431
        self.assertEqual('\n', text[5])
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
432
        self.assertEqual('Commit message for a',
433
                         dlg._file_message_expander.get_label())
434
        self.assertTrue(dlg._file_message_expander.get_expanded())
435
        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.
436
278.1.20 by John Arbash Meinel
We always select the All Files record in the files view,
437
        dlg._treeview_files.set_cursor((2,))
278.1.19 by John Arbash Meinel
Test what happens when a specific file is selected.
438
        self.assertEqual('Diff for b', dlg._diff_label.get_text())
439
        text = diff_buffer.get_text(diff_buffer.get_start_iter(),
440
                                    diff_buffer.get_end_iter()).splitlines(True)
441
        self.assertEqual("=== added file 'b'\n", text[0])
442
        self.assertContainsRe(text[1],
443
            r"--- b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
444
        self.assertContainsRe(text[2],
445
            r"\+\+\+ b\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d")
446
        self.assertEqual('@@ -0,0 +1,1 @@\n', text[3])
447
        self.assertEqual('+contents of tree/b\n', text[4])
448
        self.assertEqual('\n', text[5])
278.1.21 by John Arbash Meinel
Start tracking the per-file commit messages.
449
        self.assertEqual('Commit message for b',
450
                         dlg._file_message_expander.get_label())
451
        self.assertTrue(dlg._file_message_expander.get_expanded())
452
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
453
454
        dlg._treeview_files.set_cursor((0,))
455
        self.assertEqual('Diff for All Files', dlg._diff_label.get_text())
456
        self.assertEqual('File commit message',
457
                         dlg._file_message_expander.get_label())
458
        self.assertFalse(dlg._file_message_expander.get_expanded())
459
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
460
461
    def test_file_selection_message(self):
462
        """Selecting a file should bring up its commit message."""
463
        tree = self.make_branch_and_tree('tree')
464
        self.build_tree(['tree/a', 'tree/b/'])
465
        tree.add(['a', 'b'], ['a-id', 'b-id'])
466
467
        def get_file_text():
468
            buf = dlg._file_message_text_view.get_buffer()
469
            return buf.get_text(buf.get_start_iter(), buf.get_end_iter())
470
471
        def get_saved_text(path):
472
            """Get the saved text for a given record."""
473
            return dlg._files_store.get_value(dlg._files_store.get_iter(path), 5)
474
475
        dlg = commit.CommitDialog(tree)
476
        self.assertEqual('File commit message',
477
                         dlg._file_message_expander.get_label())
478
        self.assertFalse(dlg._file_message_expander.get_expanded())
479
        self.assertFalse(dlg._file_message_expander.get_property('sensitive'))
480
        self.assertEqual('', get_file_text())
481
482
        dlg._treeview_files.set_cursor((1,))
483
        self.assertEqual('Commit message for a',
484
                         dlg._file_message_expander.get_label())
485
        self.assertTrue(dlg._file_message_expander.get_expanded())
486
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
487
        self.assertEqual('', get_file_text())
488
489
        self.assertEqual('', get_saved_text(1))
490
        dlg._file_message_text_view.get_buffer().set_text('Some text\nfor a\n')
491
        dlg._save_current_file_message()
492
        # We should have updated the ListStore with the new file commit info
493
        self.assertEqual('Some text\nfor a\n', get_saved_text(1))
494
495
        dlg._treeview_files.set_cursor((2,))
496
        self.assertEqual('Commit message for b/',
497
                         dlg._file_message_expander.get_label())
498
        self.assertTrue(dlg._file_message_expander.get_expanded())
499
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
500
        self.assertEqual('', get_file_text())
501
502
        self.assertEqual('', get_saved_text(2))
503
        dlg._file_message_text_view.get_buffer().set_text('More text\nfor b\n')
504
        # Now switch back to 'a'. The message should be saved, and the buffer
505
        # should be updated with the other text
506
        dlg._treeview_files.set_cursor((1,))
507
        self.assertEqual('More text\nfor b\n', get_saved_text(2))
508
        self.assertEqual('Commit message for a',
509
                         dlg._file_message_expander.get_label())
510
        self.assertTrue(dlg._file_message_expander.get_expanded())
511
        self.assertTrue(dlg._file_message_expander.get_property('sensitive'))
512
        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,
513
514
    def test_toggle_all_files(self):
515
        """When checking the All Files entry, it should toggle all fields"""
516
        tree = self.make_branch_and_tree('tree')
517
        self.build_tree(['tree/a', 'tree/b/'])
518
        tree.add(['a', 'b'], ['a-id', 'b-id'])
519
520
        dlg = commit.CommitDialog(tree)
521
        self.assertEqual([(None, None, True),
522
                          ('a-id', 'a', True),
523
                          ('b-id', 'b', True),
524
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
525
526
        # TODO: jam 20071002 I'm not sure how to exactly trigger a toggle, it
527
        #       looks like we need to call renderer.activate() and pass an
528
        #       event and widget, and lots of other stuff I'm not sure what to
529
        #       do with. So instead, we just call toggle directly, and assume
530
        #       that toggle is hooked in correctly
531
        # column = dlg._treeview_files.get_column(0)
532
        # renderer = column.get_cell_renderers()[0]
533
534
        # Toggle a single entry should set just that entry to False
535
        dlg._toggle_commit(None, 1, dlg._files_store)
536
        self.assertEqual([(None, None, True),
537
                          ('a-id', 'a', False),
538
                          ('b-id', 'b', True),
539
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
540
541
        # Toggling the main entry should set all entries
542
        dlg._toggle_commit(None, 0, dlg._files_store)
543
        self.assertEqual([(None, None, False),
544
                          ('a-id', 'a', False),
545
                          ('b-id', 'b', False),
546
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
547
548
        dlg._toggle_commit(None, 2, dlg._files_store)
549
        self.assertEqual([(None, None, False),
550
                          ('a-id', 'a', False),
551
                          ('b-id', 'b', True),
552
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
553
554
        dlg._toggle_commit(None, 0, dlg._files_store)
555
        self.assertEqual([(None, None, True),
556
                          ('a-id', 'a', True),
557
                          ('b-id', 'b', True),
558
                         ], [(r[0], r[1], r[2]) for r in dlg._files_store])
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
559
560
561
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
562
    """Tests on the actual 'commit' button being pushed."""
563
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
564
    def _set_question_yes(self, dlg):
565
        """Set the dialog to answer YES to any questions."""
566
        self.questions = []
567
        def _question_yes(*args):
568
            self.questions.append(args)
569
            self.questions.append('YES')
570
            return gtk.RESPONSE_YES
571
        dlg._question_dialog = _question_yes
572
573
    def _set_question_no(self, dlg):
574
        """Set the dialog to answer NO to any questions."""
575
        self.questions = []
576
        def _question_no(*args):
577
            self.questions.append(args)
578
            self.questions.append('NO')
579
            return gtk.RESPONSE_NO
580
        dlg._question_dialog = _question_no
581
278.1.25 by John Arbash Meinel
Add the 'Only Commit Locally' checkbox, we may want to put it elsewhere, though.
582
    def test_bound_commit_local(self):
583
        tree = self.make_branch_and_tree('tree')
584
        self.build_tree(['tree/a'])
585
        tree.add(['a'], ['a-id'])
586
        rev_id1 = tree.commit('one')
587
588
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
589
        self.build_tree(['tree2/b'])
590
        tree2.add(['b'], ['b-id'])
591
        tree2.branch.bind(tree.branch)
592
593
        dlg = commit.CommitDialog(tree2)
594
        # With the check box set, it should only effect the local branch
595
        dlg._check_local.set_active(True)
596
        dlg._set_global_commit_message('Commit message\n')
597
        dlg._do_commit()
598
599
        last_rev = tree2.last_revision()
600
        self.assertEqual(last_rev, dlg.committed_revision_id)
601
        self.assertEqual(rev_id1, tree.branch.last_revision())
602
603
    def test_bound_commit_both(self):
604
        tree = self.make_branch_and_tree('tree')
605
        self.build_tree(['tree/a'])
606
        tree.add(['a'], ['a-id'])
607
        rev_id1 = tree.commit('one')
608
609
        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
610
        self.build_tree(['tree2/b'])
611
        tree2.add(['b'], ['b-id'])
612
        tree2.branch.bind(tree.branch)
613
614
        dlg = commit.CommitDialog(tree2)
615
        # With the check box set, it should only effect the local branch
616
        dlg._check_local.set_active(False)
617
        dlg._set_global_commit_message('Commit message\n')
618
        dlg._do_commit()
619
620
        last_rev = tree2.last_revision()
621
        self.assertEqual(last_rev, dlg.committed_revision_id)
622
        self.assertEqual(last_rev, tree.branch.last_revision())
623
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
624
    def test_commit_no_message(self):
625
        tree = self.make_branch_and_tree('tree')
626
        self.build_tree(['tree/a', 'tree/b'])
627
        tree.add(['a'], ['a-id'])
628
        rev_id = tree.commit('one')
629
630
        tree.add(['b'], ['b-id'])
631
632
        dlg = commit.CommitDialog(tree)
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
633
        self._set_question_no(dlg)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
634
        dlg._do_commit()
635
        self.assertEqual(
636
            [('Commit with an empty message?',
637
              'You can describe your commit intent in the message.'),
638
              'NO',
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
639
            ], self.questions)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
640
        # By saying NO, nothing should be committed.
641
        self.assertEqual(rev_id, tree.last_revision())
642
        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.
643
        self.assertTrue(dlg._global_message_text_view.get_property('is-focus'))
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
644
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
645
        self._set_question_yes(dlg)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
646
647
        dlg._do_commit()
648
        self.assertEqual(
649
            [('Commit with an empty message?',
650
              'You can describe your commit intent in the message.'),
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
651
              'YES',
652
            ], self.questions)
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
653
        committed = tree.last_revision()
654
        self.assertNotEqual(rev_id, committed)
655
        self.assertEqual(committed, dlg.committed_revision_id)
656
657
    def test_initial_commit(self):
658
        tree = self.make_branch_and_tree('tree')
659
        self.build_tree(['tree/a'])
660
        tree.add(['a'], ['a-id'])
661
662
        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.
663
        dlg._set_global_commit_message('Some text\n')
278.1.23 by John Arbash Meinel
Beginning to support actual commit.
664
        dlg._do_commit()
665
666
        last_rev = tree.last_revision()
667
        self.assertEqual(last_rev, dlg.committed_revision_id)
668
        rev = tree.branch.repository.get_revision(last_rev)
669
        self.assertEqual(last_rev, rev.revision_id)
670
        self.assertEqual('Some text\n', rev.message)
278.1.26 by John Arbash Meinel
Handle pointless commits and trees with unknown files.
671
672
    def test_pointless_commit(self):
673
        tree = self.make_branch_and_tree('tree')
674
        self.build_tree(['tree/a'])
675
        tree.add(['a'], ['a-id'])
676
        rev_id1 = tree.commit('one')
677
678
        dlg = commit.CommitDialog(tree)
679
        dlg._set_global_commit_message('Some text\n')
680
681
        self._set_question_no(dlg)
682
        dlg._do_commit()
683
684
        self.assertIs(None, dlg.committed_revision_id)
685
        self.assertEqual(rev_id1, tree.last_revision())
686
        self.assertEqual(
687
            [('Commit with no changes?',
688
              'There are no changes in the working tree.'
689
              ' Do you want to commit anyway?'),
690
              'NO',
691
            ], self.questions)
692
693
        self._set_question_yes(dlg)
694
        dlg._do_commit()
695
696
        rev_id2 = tree.last_revision()
697
        self.assertEqual(rev_id2, dlg.committed_revision_id)
698
        self.assertNotEqual(rev_id1, rev_id2)
699
        self.assertEqual(
700
            [('Commit with no changes?',
701
              'There are no changes in the working tree.'
702
              ' Do you want to commit anyway?'),
703
              'YES',
704
            ], self.questions)
705
706
    def test_unknowns(self):
707
        """We should check if there are unknown files."""
708
        tree = self.make_branch_and_tree('tree')
709
        rev_id1 = tree.commit('one')
710
        self.build_tree(['tree/a', 'tree/b'])
711
        tree.add(['a'], ['a-id'])
712
713
        dlg = commit.CommitDialog(tree)
714
        dlg._set_global_commit_message('Some text\n')
715
        self._set_question_no(dlg)
716
717
        dlg._do_commit()
718
719
        self.assertIs(None, dlg.committed_revision_id)
720
        self.assertEqual(rev_id1, tree.last_revision())
721
        self.assertEqual(
722
            [("Commit with unknowns?",
723
              "Unknown files exist in the working tree. Commit anyway?"),
724
              "NO",
725
            ], self.questions)
726
727
        self._set_question_yes(dlg)
728
        dlg._do_commit()
729
730
        rev_id2 = tree.last_revision()
731
        self.assertNotEqual(rev_id1, rev_id2)
732
        self.assertEqual(rev_id2, dlg.committed_revision_id)
733
        self.assertEqual(
734
            [("Commit with unknowns?",
735
              "Unknown files exist in the working tree. Commit anyway?"),
736
              "YES",
737
            ], self.questions)
738