~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_conflicts.py

  • Committer: Aaron Bentley
  • Date: 2007-12-20 20:44:45 UTC
  • mto: This revision was merged to the branch mainline in revision 3235.
  • Revision ID: abentley@panoramicfeedback.com-20071220204445-9o2f10gvvd8e4rks
Implement hard-link support for branch and checkout

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
 
 
18
import os
 
19
 
 
20
from bzrlib import bzrdir
 
21
from bzrlib.tests import TestCaseWithTransport, TestCase
 
22
from bzrlib.branch import Branch
 
23
from bzrlib.conflicts import (
 
24
    ConflictList,
 
25
    ContentsConflict,
 
26
    DuplicateID,
 
27
    DuplicateEntry,
 
28
    MissingParent,
 
29
    ParentLoop,
 
30
    PathConflict,
 
31
    TextConflict,
 
32
    UnversionedParent,
 
33
    resolve,
 
34
    restore,
 
35
    )
 
36
from bzrlib.errors import NotConflicted
 
37
 
 
38
 
 
39
# TODO: Test commit with some added, and added-but-missing files
 
40
# RBC 20060124 is that not tested in test_commit.py ?
 
41
 
 
42
# The order of 'path' here is important - do not let it
 
43
# be a sorted list.
 
44
# u'\xe5' == a with circle
 
45
# '\xc3\xae' == u'\xee' == i with hat
 
46
# So these are u'pathg' and 'idg' only with a circle and a hat. (shappo?)
 
47
example_conflicts = ConflictList([ 
 
48
    MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
 
49
    ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'), 
 
50
    TextConflict(u'p\xe5tha'),
 
51
    PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
 
52
    DuplicateID('Unversioned existing file', u'p\xe5thc', u'p\xe5thc2',
 
53
                '\xc3\xaedc', '\xc3\xaedc'),
 
54
    DuplicateEntry('Moved existing file to',  u'p\xe5thdd.moved', u'p\xe5thd',
 
55
                   '\xc3\xaedd', None),
 
56
    ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
 
57
               None, '\xc3\xaed2e'),
 
58
    UnversionedParent('Versioned directory', u'p\xe5thf', '\xc3\xaedf'),
 
59
])
 
60
 
 
61
 
 
62
class TestConflicts(TestCaseWithTransport):
 
63
 
 
64
    def test_conflicts(self):
 
65
        """Conflicts are detected properly"""
 
66
        tree = self.make_branch_and_tree('.',
 
67
            format=bzrdir.BzrDirFormat6())
 
68
        b = tree.branch
 
69
        file('hello', 'w').write('hello world4')
 
70
        file('hello.THIS', 'w').write('hello world2')
 
71
        file('hello.BASE', 'w').write('hello world1')
 
72
        file('hello.OTHER', 'w').write('hello world3')
 
73
        file('hello.sploo.BASE', 'w').write('yellow world')
 
74
        file('hello.sploo.OTHER', 'w').write('yellow world2')
 
75
        tree.lock_read()
 
76
        self.assertEqual(len(list(tree.list_files())), 6)
 
77
        tree.unlock()
 
78
        conflicts = tree.conflicts()
 
79
        self.assertEqual(len(conflicts), 2)
 
80
        self.assert_('hello' in conflicts[0].path)
 
81
        self.assert_('hello.sploo' in conflicts[1].path)
 
82
        restore('hello')
 
83
        restore('hello.sploo')
 
84
        self.assertEqual(len(tree.conflicts()), 0)
 
85
        self.assertFileEqual('hello world2', 'hello')
 
86
        assert not os.path.lexists('hello.sploo')
 
87
        self.assertRaises(NotConflicted, restore, 'hello')
 
88
        self.assertRaises(NotConflicted, restore, 'hello.sploo')
 
89
 
 
90
    def test_resolve_conflict_dir(self):
 
91
        tree = self.make_branch_and_tree('.')
 
92
        b = tree.branch
 
93
        file('hello', 'w').write('hello world4')
 
94
        tree.add('hello', 'q')
 
95
        file('hello.THIS', 'w').write('hello world2')
 
96
        file('hello.BASE', 'w').write('hello world1')
 
97
        os.mkdir('hello.OTHER')
 
98
        l = ConflictList([TextConflict('hello')])
 
99
        l.remove_files(tree)
 
100
 
 
101
    def test_select_conflicts(self):
 
102
        tree = self.make_branch_and_tree('.')
 
103
        tree_conflicts = ConflictList([ContentsConflict('foo'),
 
104
                                       ContentsConflict('bar')])
 
105
        self.assertEqual((ConflictList([ContentsConflict('bar')]),
 
106
                          ConflictList([ContentsConflict('foo')])),
 
107
                         tree_conflicts.select_conflicts(tree, ['foo']))
 
108
        self.assertEqual((ConflictList(), tree_conflicts),
 
109
                         tree_conflicts.select_conflicts(tree, [''],
 
110
                         ignore_misses=True, recurse=True))
 
111
        tree_conflicts = ConflictList([ContentsConflict('foo/baz'),
 
112
                                       ContentsConflict('bar')])
 
113
        self.assertEqual((ConflictList([ContentsConflict('bar')]),
 
114
                          ConflictList([ContentsConflict('foo/baz')])),
 
115
                         tree_conflicts.select_conflicts(tree, ['foo'],
 
116
                                                         recurse=True,
 
117
                                                         ignore_misses=True))
 
118
        tree_conflicts = ConflictList([PathConflict('qux', 'foo/baz')])
 
119
        self.assertEqual((ConflictList(), tree_conflicts),
 
120
                         tree_conflicts.select_conflicts(tree, ['foo'],
 
121
                                                         recurse=True,
 
122
                                                         ignore_misses=True))
 
123
        self.assertEqual((tree_conflicts, ConflictList()),
 
124
                         tree_conflicts.select_conflicts(tree, ['foo'],
 
125
                                                         ignore_misses=True))
 
126
 
 
127
    def test_resolve_conflicts_recursive(self):
 
128
        tree = self.make_branch_and_tree('.')
 
129
        self.build_tree(['dir/', 'dir/hello'])
 
130
        tree.add(['dir', 'dir/hello'])
 
131
        tree.set_conflicts(ConflictList([TextConflict('dir/hello')]))
 
132
        resolve(tree, ['dir'], recursive=False, ignore_misses=True)
 
133
        self.assertEqual(ConflictList([TextConflict('dir/hello')]),
 
134
                         tree.conflicts())
 
135
        resolve(tree, ['dir'], recursive=True, ignore_misses=True)
 
136
        self.assertEqual(ConflictList([]),
 
137
                         tree.conflicts())
 
138
 
 
139
 
 
140
class TestConflictStanzas(TestCase):
 
141
 
 
142
    def test_stanza_roundtrip(self):
 
143
        # write and read our example stanza.
 
144
        stanza_iter = example_conflicts.to_stanzas()
 
145
        processed = ConflictList.from_stanzas(stanza_iter)
 
146
        for o, p in zip(processed, example_conflicts):
 
147
            self.assertEqual(o, p)
 
148
 
 
149
            self.assertIsInstance(o.path, unicode)
 
150
 
 
151
            if o.file_id is not None:
 
152
                self.assertIsInstance(o.file_id, str)
 
153
 
 
154
            conflict_path = getattr(o, 'conflict_path', None)
 
155
            if conflict_path is not None:
 
156
                self.assertIsInstance(conflict_path, unicode)
 
157
 
 
158
            conflict_file_id = getattr(o, 'conflict_file_id', None)
 
159
            if conflict_file_id is not None:
 
160
                self.assertIsInstance(conflict_file_id, str)
 
161
 
 
162
    def test_stanzification(self):
 
163
        for stanza in example_conflicts.to_stanzas():
 
164
            if 'file_id' in stanza:
 
165
                # In Stanza form, the file_id has to be unicode.
 
166
                self.assertStartsWith(stanza['file_id'], u'\xeed')
 
167
            self.assertStartsWith(stanza['path'], u'p\xe5th')
 
168
            if 'conflict_path' in stanza:
 
169
                self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
 
170
            if 'conflict_file_id' in stanza:
 
171
                self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')