~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_conflicts.py

  • Committer: John Arbash Meinel
  • Date: 2009-12-18 17:58:10 UTC
  • mto: This revision was merged to the branch mainline in revision 4934.
  • Revision ID: john@arbash-meinel.com-20091218175810-07kjs6e20i30acob
Include the KiB/s for the transfer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
import os
 
19
 
 
20
from bzrlib import (
 
21
    bzrdir,
 
22
    conflicts,
 
23
    errors,
 
24
    tests,
 
25
    workingtree,
 
26
    )
 
27
from bzrlib.tests import script
 
28
 
 
29
 
 
30
# TODO: Test commit with some added, and added-but-missing files
 
31
# RBC 20060124 is that not tested in test_commit.py ?
 
32
 
 
33
# The order of 'path' here is important - do not let it
 
34
# be a sorted list.
 
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',
 
48
                             '\xc3\xaedd', None),
 
49
    conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
 
50
                         None, '\xc3\xaed2e'),
 
51
    conflicts.UnversionedParent('Versioned directory',
 
52
                                u'p\xe5thf', '\xc3\xaedf'),
 
53
    conflicts.NonDirectoryParent('Created directory',
 
54
                                 u'p\xe5thg', '\xc3\xaedg'),
 
55
])
 
56
 
 
57
 
 
58
class TestConflicts(tests.TestCaseWithTransport):
 
59
 
 
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'),
 
70
                                  ])
 
71
        tree.lock_read()
 
72
        self.assertEqual(6, len(list(tree.list_files())))
 
73
        tree.unlock()
 
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')
 
86
 
 
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'),
 
92
                                  ])
 
93
        os.mkdir('hello.OTHER')
 
94
        tree.add('hello', 'q')
 
95
        l = conflicts.ConflictList([conflicts.TextConflict('hello')])
 
96
        l.remove_files(tree)
 
97
 
 
98
    def test_select_conflicts(self):
 
99
        tree = self.make_branch_and_tree('.')
 
100
        clist = conflicts.ConflictList
 
101
 
 
102
        def check_select(not_selected, selected, paths, **kwargs):
 
103
            self.assertEqual(
 
104
                (not_selected, selected),
 
105
                tree_conflicts.select_conflicts(tree, paths, **kwargs))
 
106
 
 
107
        foo = conflicts.ContentsConflict('foo')
 
108
        bar = conflicts.ContentsConflict('bar')
 
109
        tree_conflicts = clist([foo, bar])
 
110
 
 
111
        check_select(clist([bar]), clist([foo]), ['foo'])
 
112
        check_select(clist(), tree_conflicts,
 
113
                     [''], ignore_misses=True, recurse=True)
 
114
 
 
115
        foobaz  = conflicts.ContentsConflict('foo/baz')
 
116
        tree_conflicts = clist([foobaz, bar])
 
117
 
 
118
        check_select(clist([bar]), clist([foobaz]),
 
119
                     ['foo'], ignore_misses=True, recurse=True)
 
120
 
 
121
        qux = conflicts.PathConflict('qux', 'foo/baz')
 
122
        tree_conflicts = clist([qux])
 
123
 
 
124
        check_select(clist(), tree_conflicts,
 
125
                     ['foo'], ignore_misses=True, recurse=True)
 
126
        check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
 
127
 
 
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'])
 
132
 
 
133
        dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
 
134
        tree.set_conflicts(dirhello)
 
135
 
 
136
        conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
 
137
        self.assertEqual(dirhello, tree.conflicts())
 
138
 
 
139
        conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
 
140
        self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
 
141
 
 
142
 
 
143
class TestConflictStanzas(tests.TestCase):
 
144
 
 
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)
 
151
 
 
152
            self.assertIsInstance(o.path, unicode)
 
153
 
 
154
            if o.file_id is not None:
 
155
                self.assertIsInstance(o.file_id, str)
 
156
 
 
157
            conflict_path = getattr(o, 'conflict_path', None)
 
158
            if conflict_path is not None:
 
159
                self.assertIsInstance(conflict_path, unicode)
 
160
 
 
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)
 
164
 
 
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')
 
175