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
28
# TODO: Test commit with some added, and added-but-missing files
29
# RBC 20060124 is that not tested in test_commit.py ?
31
# The order of 'path' here is important - do not let it
33
# u'\xe5' == a with circle
34
# '\xc3\xae' == u'\xee' == i with hat
35
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
36
example_conflicts = conflicts.ConflictList(
37
[conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
38
conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
39
conflicts.TextConflict(u'p\xe5tha'),
40
conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
41
conflicts.DuplicateID('Unversioned existing file',
42
u'p\xe5thc', u'p\xe5thc2',
43
'\xc3\xaedc', '\xc3\xaedc'),
44
conflicts.DuplicateEntry('Moved existing file to',
45
u'p\xe5thdd.moved', u'p\xe5thd',
47
conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
49
conflicts.UnversionedParent('Versioned directory',
50
u'p\xe5thf', '\xc3\xaedf'),
51
conflicts.NonDirectoryParent('Created directory',
52
u'p\xe5thg', '\xc3\xaedg'),
56
class TestConflicts(tests.TestCaseWithTransport):
58
def test_conflicts(self):
59
"""Conflicts are detected properly"""
60
# Use BzrDirFormat6 so we can fake conflicts
61
tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
62
self.build_tree_contents([('hello', 'hello world4'),
63
('hello.THIS', 'hello world2'),
64
('hello.BASE', 'hello world1'),
65
('hello.OTHER', 'hello world3'),
66
('hello.sploo.BASE', 'yellowworld'),
67
('hello.sploo.OTHER', 'yellowworld2'),
70
self.assertEqual(6, len(list(tree.list_files())))
72
tree_conflicts = tree.conflicts()
73
self.assertEqual(2, len(tree_conflicts))
74
self.assertTrue('hello' in tree_conflicts[0].path)
75
self.assertTrue('hello.sploo' in tree_conflicts[1].path)
76
conflicts.restore('hello')
77
conflicts.restore('hello.sploo')
78
self.assertEqual(0, len(tree.conflicts()))
79
self.assertFileEqual('hello world2', 'hello')
80
self.assertFalse(os.path.lexists('hello.sploo'))
81
self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
82
self.assertRaises(errors.NotConflicted,
83
conflicts.restore, 'hello.sploo')
85
def test_resolve_conflict_dir(self):
86
tree = self.make_branch_and_tree('.')
87
self.build_tree_contents([('hello', 'hello world4'),
88
('hello.THIS', 'hello world2'),
89
('hello.BASE', 'hello world1'),
91
os.mkdir('hello.OTHER')
92
tree.add('hello', 'q')
93
l = conflicts.ConflictList([conflicts.TextConflict('hello')])
96
def test_select_conflicts(self):
97
tree = self.make_branch_and_tree('.')
98
clist = conflicts.ConflictList
100
def check_select(not_selected, selected, paths, **kwargs):
102
(not_selected, selected),
103
tree_conflicts.select_conflicts(tree, paths, **kwargs))
105
foo = conflicts.ContentsConflict('foo')
106
bar = conflicts.ContentsConflict('bar')
107
tree_conflicts = clist([foo, bar])
109
check_select(clist([bar]), clist([foo]), ['foo'])
110
check_select(clist(), tree_conflicts,
111
[''], ignore_misses=True, recurse=True)
113
foobaz = conflicts.ContentsConflict('foo/baz')
114
tree_conflicts = clist([foobaz, bar])
116
check_select(clist([bar]), clist([foobaz]),
117
['foo'], ignore_misses=True, recurse=True)
119
qux = conflicts.PathConflict('qux', 'foo/baz')
120
tree_conflicts = clist([qux])
122
check_select(clist(), tree_conflicts,
123
['foo'], ignore_misses=True, recurse=True)
124
check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
126
def test_resolve_conflicts_recursive(self):
127
tree = self.make_branch_and_tree('.')
128
self.build_tree(['dir/', 'dir/hello'])
129
tree.add(['dir', 'dir/hello'])
131
dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
132
tree.set_conflicts(dirhello)
134
conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
135
self.assertEqual(dirhello, tree.conflicts())
137
conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
138
self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
141
class TestConflictStanzas(tests.TestCase):
143
def test_stanza_roundtrip(self):
144
# write and read our example stanza.
145
stanza_iter = example_conflicts.to_stanzas()
146
processed = conflicts.ConflictList.from_stanzas(stanza_iter)
147
for o, p in zip(processed, example_conflicts):
148
self.assertEqual(o, p)
150
self.assertIsInstance(o.path, unicode)
152
if o.file_id is not None:
153
self.assertIsInstance(o.file_id, str)
155
conflict_path = getattr(o, 'conflict_path', None)
156
if conflict_path is not None:
157
self.assertIsInstance(conflict_path, unicode)
159
conflict_file_id = getattr(o, 'conflict_file_id', None)
160
if conflict_file_id is not None:
161
self.assertIsInstance(conflict_file_id, str)
163
def test_stanzification(self):
164
for stanza in example_conflicts.to_stanzas():
165
if 'file_id' in stanza:
166
# In Stanza form, the file_id has to be unicode.
167
self.assertStartsWith(stanza['file_id'], u'\xeed')
168
self.assertStartsWith(stanza['path'], u'p\xe5th')
169
if 'conflict_path' in stanza:
170
self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
171
if 'conflict_file_id' in stanza:
172
self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')