1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27
from bzrlib.tests import script
30
# TODO: Test commit with some added, and added-but-missing files
31
# RBC 20060124 is that not tested in test_commit.py ?
33
# The order of 'path' here is important - do not let it
35
# u'\xe5' == a with circle
36
# '\xc3\xae' == u'\xee' == i with hat
37
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
38
example_conflicts = conflicts.ConflictList(
39
[conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
40
conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
41
conflicts.TextConflict(u'p\xe5tha'),
42
conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
43
conflicts.DuplicateID('Unversioned existing file',
44
u'p\xe5thc', u'p\xe5thc2',
45
'\xc3\xaedc', '\xc3\xaedc'),
46
conflicts.DuplicateEntry('Moved existing file to',
47
u'p\xe5thdd.moved', u'p\xe5thd',
49
conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
51
conflicts.UnversionedParent('Versioned directory',
52
u'p\xe5thf', '\xc3\xaedf'),
53
conflicts.NonDirectoryParent('Created directory',
54
u'p\xe5thg', '\xc3\xaedg'),
58
class TestConflicts(tests.TestCaseWithTransport):
60
def test_conflicts(self):
61
"""Conflicts are detected properly"""
62
# Use BzrDirFormat6 so we can fake conflicts
63
tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
64
self.build_tree_contents([('hello', 'hello world4'),
65
('hello.THIS', 'hello world2'),
66
('hello.BASE', 'hello world1'),
67
('hello.OTHER', 'hello world3'),
68
('hello.sploo.BASE', 'yellowworld'),
69
('hello.sploo.OTHER', 'yellowworld2'),
72
self.assertEqual(6, len(list(tree.list_files())))
74
tree_conflicts = tree.conflicts()
75
self.assertEqual(2, len(tree_conflicts))
76
self.assertTrue('hello' in tree_conflicts[0].path)
77
self.assertTrue('hello.sploo' in tree_conflicts[1].path)
78
conflicts.restore('hello')
79
conflicts.restore('hello.sploo')
80
self.assertEqual(0, len(tree.conflicts()))
81
self.assertFileEqual('hello world2', 'hello')
82
self.assertFalse(os.path.lexists('hello.sploo'))
83
self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
84
self.assertRaises(errors.NotConflicted,
85
conflicts.restore, 'hello.sploo')
87
def test_resolve_conflict_dir(self):
88
tree = self.make_branch_and_tree('.')
89
self.build_tree_contents([('hello', 'hello world4'),
90
('hello.THIS', 'hello world2'),
91
('hello.BASE', 'hello world1'),
93
os.mkdir('hello.OTHER')
94
tree.add('hello', 'q')
95
l = conflicts.ConflictList([conflicts.TextConflict('hello')])
98
def test_select_conflicts(self):
99
tree = self.make_branch_and_tree('.')
100
clist = conflicts.ConflictList
102
def check_select(not_selected, selected, paths, **kwargs):
104
(not_selected, selected),
105
tree_conflicts.select_conflicts(tree, paths, **kwargs))
107
foo = conflicts.ContentsConflict('foo')
108
bar = conflicts.ContentsConflict('bar')
109
tree_conflicts = clist([foo, bar])
111
check_select(clist([bar]), clist([foo]), ['foo'])
112
check_select(clist(), tree_conflicts,
113
[''], ignore_misses=True, recurse=True)
115
foobaz = conflicts.ContentsConflict('foo/baz')
116
tree_conflicts = clist([foobaz, bar])
118
check_select(clist([bar]), clist([foobaz]),
119
['foo'], ignore_misses=True, recurse=True)
121
qux = conflicts.PathConflict('qux', 'foo/baz')
122
tree_conflicts = clist([qux])
124
check_select(clist(), tree_conflicts,
125
['foo'], ignore_misses=True, recurse=True)
126
check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
128
def test_resolve_conflicts_recursive(self):
129
tree = self.make_branch_and_tree('.')
130
self.build_tree(['dir/', 'dir/hello'])
131
tree.add(['dir', 'dir/hello'])
133
dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
134
tree.set_conflicts(dirhello)
136
conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
137
self.assertEqual(dirhello, tree.conflicts())
139
conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
140
self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
143
class TestConflictStanzas(tests.TestCase):
145
def test_stanza_roundtrip(self):
146
# write and read our example stanza.
147
stanza_iter = example_conflicts.to_stanzas()
148
processed = conflicts.ConflictList.from_stanzas(stanza_iter)
149
for o, p in zip(processed, example_conflicts):
150
self.assertEqual(o, p)
152
self.assertIsInstance(o.path, unicode)
154
if o.file_id is not None:
155
self.assertIsInstance(o.file_id, str)
157
conflict_path = getattr(o, 'conflict_path', None)
158
if conflict_path is not None:
159
self.assertIsInstance(conflict_path, unicode)
161
conflict_file_id = getattr(o, 'conflict_file_id', None)
162
if conflict_file_id is not None:
163
self.assertIsInstance(conflict_file_id, str)
165
def test_stanzification(self):
166
for stanza in example_conflicts.to_stanzas():
167
if 'file_id' in stanza:
168
# In Stanza form, the file_id has to be unicode.
169
self.assertStartsWith(stanza['file_id'], u'\xeed')
170
self.assertStartsWith(stanza['path'], u'p\xe5th')
171
if 'conflict_path' in stanza:
172
self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
173
if 'conflict_file_id' in stanza:
174
self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')