/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2006-2009, 2011 Canonical Ltd
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
16
17
"""Tests for Tree and InterTree."""
18
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
19
from breezy import (
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
20
    errors,
21
    revision,
22
    tree as _mod_tree,
23
    )
6731.1.1 by Jelmer Vernooij
Move FileTimestampUnavailable to breezy.tree.
24
from breezy.tests import (
25
    TestCase,
26
    TestCaseWithTransport,
27
    )
6731.1.5 by Jelmer Vernooij
Fix import errors.
28
from breezy.tree import (
29
    FileTimestampUnavailable,
30
    InterTree,
6883.5.2 by Jelmer Vernooij
Add find_previous_paths call.
31
    find_previous_paths,
7131.4.1 by Jelmer Vernooij
Fix get_canonical_path and add some basic tests.
32
    get_canonical_path,
6731.1.5 by Jelmer Vernooij
Fix import errors.
33
    )
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
34
35
6734.1.22 by Jelmer Vernooij
review comments.
36
class TestErrors(TestCase):
6731.1.1 by Jelmer Vernooij
Move FileTimestampUnavailable to breezy.tree.
37
38
    def test_file_timestamp_unavailable(self):
39
        e = FileTimestampUnavailable("/path/foo")
40
        self.assertEqual("The filestamp for /path/foo is not available.",
41
                         str(e))
42
43
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
44
class TestInterTree(TestCaseWithTransport):
45
46
    def test_revision_tree_revision_tree(self):
47
        # we should have an InterTree registered for RevisionTree to
48
        # RevisionTree.
49
        tree = self.make_branch_and_tree('.')
50
        rev_id = tree.commit('first post')
51
        rev_id2 = tree.commit('second post', allow_pointless=True)
52
        rev_tree = tree.branch.repository.revision_tree(rev_id)
53
        rev_tree2 = tree.branch.repository.revision_tree(rev_id2)
54
        optimiser = InterTree.get(rev_tree, rev_tree2)
55
        self.assertIsInstance(optimiser, InterTree)
56
        optimiser = InterTree.get(rev_tree2, rev_tree)
57
        self.assertIsInstance(optimiser, InterTree)
58
59
    def test_working_tree_revision_tree(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
60
        # we should have an InterTree available for WorkingTree to
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
61
        # RevisionTree.
62
        tree = self.make_branch_and_tree('.')
63
        rev_id = tree.commit('first post')
64
        rev_tree = tree.branch.repository.revision_tree(rev_id)
65
        optimiser = InterTree.get(rev_tree, tree)
66
        self.assertIsInstance(optimiser, InterTree)
67
        optimiser = InterTree.get(tree, rev_tree)
68
        self.assertIsInstance(optimiser, InterTree)
69
70
    def test_working_tree_working_tree(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
71
        # we should have an InterTree available for WorkingTree to
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
72
        # WorkingTree.
73
        tree = self.make_branch_and_tree('1')
74
        tree2 = self.make_branch_and_tree('2')
75
        optimiser = InterTree.get(tree, tree2)
76
        self.assertIsInstance(optimiser, InterTree)
77
        optimiser = InterTree.get(tree2, tree)
78
        self.assertIsInstance(optimiser, InterTree)
1852.8.4 by Robert Collins
Hook InterTree into Tree.
79
80
81
class RecordingOptimiser(InterTree):
82
83
    calls = []
84
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
85
    def compare(self, want_unchanged=False, specific_files=None,
7143.15.2 by Jelmer Vernooij
Run autopep8.
86
                extra_trees=None, require_versioned=False, include_root=False,
87
                want_unversioned=False):
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
88
        self.calls.append(
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
89
            ('compare', self.source, self.target, want_unchanged,
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
90
             specific_files, extra_trees, require_versioned,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
91
             include_root, want_unversioned)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
92
            )
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
93
1852.8.4 by Robert Collins
Hook InterTree into Tree.
94
    @classmethod
95
    def is_compatible(klass, source, target):
96
        return True
97
98
99
class TestTree(TestCaseWithTransport):
100
101
    def test_compare_calls_InterTree_compare(self):
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
102
        """This test tests the way Tree.compare() uses InterTree."""
1852.8.4 by Robert Collins
Hook InterTree into Tree.
103
        old_optimisers = InterTree._optimisers
104
        try:
1910.2.15 by Aaron Bentley
Back out inter.get changes, make optimizers an ordered list
105
            InterTree._optimisers = []
1852.8.4 by Robert Collins
Hook InterTree into Tree.
106
            RecordingOptimiser.calls = []
107
            InterTree.register_optimiser(RecordingOptimiser)
108
            tree = self.make_branch_and_tree('1')
109
            tree2 = self.make_branch_and_tree('2')
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
110
            # do a series of calls:
111
            # trivial usage
1852.8.8 by Robert Collins
change Tree.compare to Tree.changes_from - its better for the common case.
112
            tree.changes_from(tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
113
            # pass in all optional arguments by position
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
114
            tree.changes_from(tree2, 'unchanged', 'specific', 'extra',
1910.2.57 by Aaron Bentley
Got 0.9 bundles working, with root included by changes_from
115
                              'require', True)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
116
            # pass in all optional arguments by keyword
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
117
            tree.changes_from(tree2,
7143.15.2 by Jelmer Vernooij
Run autopep8.
118
                              specific_files='specific',
119
                              want_unchanged='unchanged',
120
                              extra_trees='extra',
121
                              require_versioned='require',
122
                              include_root=True,
123
                              want_unversioned=True,
124
                              )
1852.8.4 by Robert Collins
Hook InterTree into Tree.
125
        finally:
126
            InterTree._optimisers = old_optimisers
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
127
        self.assertEqual(
128
            [
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
129
                ('compare', tree2, tree, False, None, None, False, False,
130
                    False),
7143.15.2 by Jelmer Vernooij
Run autopep8.
131
                ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
132
                    'require', True, False),
133
                ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
134
                    'require', True, True),
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
135
            ], RecordingOptimiser.calls)
1731.1.33 by Aaron Bentley
Revert no-special-root changes
136
137
    def test_changes_from_with_root(self):
138
        """Ensure the include_root option does what's expected."""
139
        wt = self.make_branch_and_tree('.')
140
        delta = wt.changes_from(wt.basis_tree())
141
        self.assertEqual(len(delta.added), 0)
4570.2.7 by Robert Collins
Fix misuse of tree.compare API in test_tree.py
142
        delta = wt.changes_from(wt.basis_tree(), include_root=True)
1731.1.33 by Aaron Bentley
Revert no-special-root changes
143
        self.assertEqual(len(delta.added), 1)
144
        self.assertEqual(delta.added[0][0], '')
2655.2.1 by Marius Kruger
InterTree.compare and delta._compare_trees did not pass its
145
146
    def test_changes_from_with_require_versioned(self):
147
        """Ensure the require_versioned option does what's expected."""
148
        wt = self.make_branch_and_tree('.')
149
        self.build_tree(['known_file', 'unknown_file'])
150
        wt.add('known_file')
151
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
152
        self.assertRaises(
153
            errors.PathsNotVersionedError,
154
            wt.changes_from, wt.basis_tree(), wt,
155
            specific_files=['known_file', 'unknown_file'],
156
            require_versioned=True)
2655.2.1 by Marius Kruger
InterTree.compare and delta._compare_trees did not pass its
157
158
        # we need to pass a known file with an unknown file to get this to
159
        # fail when expected.
4570.2.7 by Robert Collins
Fix misuse of tree.compare API in test_tree.py
160
        delta = wt.changes_from(wt.basis_tree(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
161
                                specific_files=['known_file', 'unknown_file'],
162
                                require_versioned=False)
2655.2.1 by Marius Kruger
InterTree.compare and delta._compare_trees did not pass its
163
        self.assertEqual(len(delta.added), 1)
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
164
165
166
class TestMultiWalker(TestCaseWithTransport):
167
168
    def assertStepOne(self, has_more, path, file_id, iterator):
169
        retval = _mod_tree.MultiWalker._step_one(iterator)
170
        if not has_more:
171
            self.assertIs(None, path)
172
            self.assertIs(None, file_id)
173
            self.assertEqual((False, None, None), retval)
174
        else:
175
            self.assertEqual((has_more, path, file_id),
176
                             (retval[0], retval[1], retval[2].file_id))
177
178
    def test__step_one_empty(self):
179
        tree = self.make_branch_and_tree('empty')
180
        repo = tree.branch.repository
181
        empty_tree = repo.revision_tree(revision.NULL_REVISION)
182
183
        iterator = empty_tree.iter_entries_by_dir()
184
        self.assertStepOne(False, None, None, iterator)
185
        self.assertStepOne(False, None, None, iterator)
186
187
    def test__step_one(self):
188
        tree = self.make_branch_and_tree('tree')
189
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
190
        tree.add(['a', 'b', 'b/c'], [b'a-id', b'b-id', b'c-id'])
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
191
192
        iterator = tree.iter_entries_by_dir()
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
193
        tree.lock_read()
194
        self.addCleanup(tree.unlock)
195
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
196
        root_id = tree.path2id('')
197
        self.assertStepOne(True, '', root_id, iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
198
        self.assertStepOne(True, 'a', b'a-id', iterator)
199
        self.assertStepOne(True, 'b', b'b-id', iterator)
200
        self.assertStepOne(True, 'b/c', b'c-id', iterator)
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
201
        self.assertStepOne(False, None, None, iterator)
202
        self.assertStepOne(False, None, None, iterator)
203
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
204
    def assertWalkerNext(self, exp_path, exp_file_id, master_has_node,
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
205
                         exp_other_paths, iterator):
206
        """Check what happens when we step the iterator.
207
208
        :param path: The path for this entry
209
        :param file_id: The file_id for this entry
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
210
        :param master_has_node: Does the master tree have this entry?
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
211
        :param exp_other_paths: A list of other_path values.
212
        :param iterator: The iterator to step
213
        """
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
214
        path, file_id, master_ie, other_values = next(iterator)
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
215
        self.assertEqual((exp_path, exp_file_id), (path, file_id),
216
                         'Master entry did not match')
217
        if master_has_node:
218
            self.assertIsNot(None, master_ie, 'master should have an entry')
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
219
        else:
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
220
            self.assertIs(None, master_ie, 'master should not have an entry')
221
        self.assertEqual(len(exp_other_paths), len(other_values),
7143.15.2 by Jelmer Vernooij
Run autopep8.
222
                         'Wrong number of other entries')
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
223
        other_paths = []
224
        other_file_ids = []
225
        for path, ie in other_values:
226
            other_paths.append(path)
227
            if ie is None:
228
                other_file_ids.append(None)
229
            else:
230
                other_file_ids.append(ie.file_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
231
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
232
        exp_file_ids = []
233
        for path in exp_other_paths:
234
            if path is None:
235
                exp_file_ids.append(None)
236
            else:
237
                exp_file_ids.append(file_id)
238
        self.assertEqual(exp_other_paths, other_paths, "Other paths incorrect")
239
        self.assertEqual(exp_file_ids, other_file_ids,
240
                         "Other file_ids incorrect")
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
241
242
    def lock_and_get_basis_and_root_id(self, tree):
243
        tree.lock_read()
244
        self.addCleanup(tree.unlock)
245
        basis_tree = tree.basis_tree()
246
        basis_tree.lock_read()
247
        self.addCleanup(basis_tree.unlock)
248
        root_id = tree.path2id('')
249
        return basis_tree, root_id
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
250
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
251
    def test_simple_stepping(self):
252
        tree = self.make_branch_and_tree('tree')
253
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
254
        tree.add(['a', 'b', 'b/c'], [b'a-id', b'b-id', b'c-id'])
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
255
6855.4.1 by Jelmer Vernooij
Yet more bees.
256
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
257
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
258
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
259
260
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
261
        iterator = walker.iter_all()
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
262
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
263
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
264
        self.assertWalkerNext(u'b', b'b-id', True, [u'b'], iterator)
265
        self.assertWalkerNext(u'b/c', b'c-id', True, [u'b/c'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
266
        self.assertRaises(StopIteration, next, iterator)
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
267
268
    def test_master_has_extra(self):
269
        tree = self.make_branch_and_tree('tree')
270
        self.build_tree(['tree/a', 'tree/b/', 'tree/c', 'tree/d'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
271
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
272
273
        tree.commit('first', rev_id=b'first-rev-id')
274
275
        tree.add(['c'], [b'c-id'])
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
276
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
277
278
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
279
        iterator = walker.iter_all()
280
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
281
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
282
        self.assertWalkerNext(u'b', b'b-id', True, [u'b'], iterator)
283
        self.assertWalkerNext(u'c', b'c-id', True, [None], iterator)
284
        self.assertWalkerNext(u'd', b'd-id', True, [u'd'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
285
        self.assertRaises(StopIteration, next, iterator)
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
286
287
    def test_master_renamed_to_earlier(self):
288
        """The record is still present, it just shows up early."""
289
        tree = self.make_branch_and_tree('tree')
290
        self.build_tree(['tree/a', 'tree/c', 'tree/d'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
291
        tree.add(['a', 'c', 'd'], [b'a-id', b'c-id', b'd-id'])
292
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
293
        tree.rename_one('d', 'b')
294
295
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
296
297
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
298
        iterator = walker.iter_all()
299
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
300
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
301
        self.assertWalkerNext(u'b', b'd-id', True, [u'd'], iterator)
302
        self.assertWalkerNext(u'c', b'c-id', True, [u'c'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
303
        self.assertRaises(StopIteration, next, iterator)
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
304
305
    def test_master_renamed_to_later(self):
306
        tree = self.make_branch_and_tree('tree')
307
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
308
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
309
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
310
        tree.rename_one('b', 'e')
311
312
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
313
314
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
315
        iterator = walker.iter_all()
316
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
317
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
318
        self.assertWalkerNext(u'd', b'd-id', True, [u'd'], iterator)
319
        self.assertWalkerNext(u'e', b'b-id', True, [u'b'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
320
        self.assertRaises(StopIteration, next, iterator)
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
321
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
322
    def test_other_extra_in_middle(self):
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
323
        tree = self.make_branch_and_tree('tree')
324
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
325
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
326
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
327
        tree.remove(['b'])
328
329
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
330
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
331
        iterator = walker.iter_all()
332
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
333
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
334
        self.assertWalkerNext(u'd', b'd-id', True, [u'd'], iterator)
335
        self.assertWalkerNext(u'b', b'b-id', False, [u'b'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
336
        self.assertRaises(StopIteration, next, iterator)
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
337
338
    def test_other_extra_at_end(self):
339
        tree = self.make_branch_and_tree('tree')
340
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
341
        tree.add(['a', 'b', 'd'], [b'a-id', b'b-id', b'd-id'])
342
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
343
        tree.remove(['d'])
344
345
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
346
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
347
        iterator = walker.iter_all()
348
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
349
        self.assertWalkerNext(u'a', b'a-id', True, [u'a'], iterator)
350
        self.assertWalkerNext(u'b', b'b-id', True, [u'b'], iterator)
351
        self.assertWalkerNext(u'd', b'd-id', False, [u'd'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
352
        self.assertRaises(StopIteration, next, iterator)
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
353
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
354
    def test_others_extra_at_end(self):
355
        tree = self.make_branch_and_tree('tree')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
356
        self.build_tree(['tree/a', 'tree/b', 'tree/c', 'tree/d', 'tree/e'])
357
        tree.add(['a', 'b', 'c', 'd', 'e'],
6855.4.1 by Jelmer Vernooij
Yet more bees.
358
                 [b'a-id', b'b-id', b'c-id', b'd-id', b'e-id'])
359
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
360
        tree.remove(['e'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
361
        tree.commit('second', rev_id=b'second-rev-id')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
362
        tree.remove(['d'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
363
        tree.commit('third', rev_id=b'third-rev-id')
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
364
        tree.remove(['c'])
365
366
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
367
        first_tree = tree.branch.repository.revision_tree(b'first-rev-id')
368
        second_tree = tree.branch.repository.revision_tree(b'second-rev-id')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
369
        walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree,
370
                                              second_tree])
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
371
        iterator = walker.iter_all()
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
372
        self.assertWalkerNext(u'', root_id, True, [u'', u'', u''], iterator)
7143.15.2 by Jelmer Vernooij
Run autopep8.
373
        self.assertWalkerNext(u'a', b'a-id', True,
374
                              [u'a', u'a', u'a'], iterator)
375
        self.assertWalkerNext(u'b', b'b-id', True,
376
                              [u'b', u'b', u'b'], iterator)
377
        self.assertWalkerNext(u'c', b'c-id', False,
378
                              [u'c', u'c', u'c'], iterator)
379
        self.assertWalkerNext(u'd', b'd-id', False,
380
                              [None, u'd', u'd'], iterator)
381
        self.assertWalkerNext(u'e', b'e-id', False,
382
                              [None, u'e', None], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
383
        self.assertRaises(StopIteration, next, iterator)
3514.3.10 by John Arbash Meinel
A mix-matched commit with things moving in each tree.
384
385
    def test_different_file_id_in_others(self):
386
        tree = self.make_branch_and_tree('tree')
387
        self.build_tree(['tree/a', 'tree/b', 'tree/c/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
388
        tree.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
389
        tree.commit('first', rev_id=b'first-rev-id')
3514.3.10 by John Arbash Meinel
A mix-matched commit with things moving in each tree.
390
391
        tree.rename_one('b', 'c/d')
392
        self.build_tree(['tree/b'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
393
        tree.add(['b'], [b'b2-id'])
394
        tree.commit('second', rev_id=b'second-rev-id')
3514.3.10 by John Arbash Meinel
A mix-matched commit with things moving in each tree.
395
396
        tree.rename_one('a', 'c/e')
397
        self.build_tree(['tree/a'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
398
        tree.add(['a'], [b'a2-id'])
3514.3.10 by John Arbash Meinel
A mix-matched commit with things moving in each tree.
399
400
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
6855.4.1 by Jelmer Vernooij
Yet more bees.
401
        first_tree = tree.branch.repository.revision_tree(b'first-rev-id')
3514.3.10 by John Arbash Meinel
A mix-matched commit with things moving in each tree.
402
        walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree])
403
404
        iterator = walker.iter_all()
405
        self.assertWalkerNext(u'', root_id, True, [u'', u''], iterator)
6855.4.1 by Jelmer Vernooij
Yet more bees.
406
        self.assertWalkerNext(u'a', b'a2-id', True, [None, None], iterator)
407
        self.assertWalkerNext(u'b', b'b2-id', True, [u'b', None], iterator)
408
        self.assertWalkerNext(u'c', b'c-id', True, [u'c', u'c'], iterator)
409
        self.assertWalkerNext(u'c/d', b'b-id', True, [u'c/d', u'b'], iterator)
410
        self.assertWalkerNext(u'c/e', b'a-id', True, [u'a', u'a'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
411
        self.assertRaises(StopIteration, next, iterator)
3514.3.12 by John Arbash Meinel
Found some problems in _path_key, and made sure to have proper testing of _cmp_paths_by_dirblock
412
7045.4.26 by Jelmer Vernooij
Fix some tree tests.
413
    def assertLtByDirblock(self, lt_val, path1, path2):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
414
        self.assertEqual(
415
            lt_val, _mod_tree.MultiWalker._lt_path_by_dirblock(path1, path2))
3514.3.12 by John Arbash Meinel
Found some problems in _path_key, and made sure to have proper testing of _cmp_paths_by_dirblock
416
7045.4.26 by Jelmer Vernooij
Fix some tree tests.
417
    def test__lt_path_by_dirblock(self):
3514.3.12 by John Arbash Meinel
Found some problems in _path_key, and made sure to have proper testing of _cmp_paths_by_dirblock
418
        # We only support Unicode strings at this point
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
419
        self.assertRaises(
420
            TypeError, _mod_tree.MultiWalker._lt_path_by_dirblock, b'', b'b')
7045.4.26 by Jelmer Vernooij
Fix some tree tests.
421
        self.assertLtByDirblock(False, u'', u'')
422
        self.assertLtByDirblock(False, u'a', u'a')
423
        self.assertLtByDirblock(False, u'a/b', u'a/b')
424
        self.assertLtByDirblock(False, u'a/b/c', u'a/b/c')
425
        self.assertLtByDirblock(False, u'a-a', u'a')
426
        self.assertLtByDirblock(True, u'a-a', u'a/a')
427
        self.assertLtByDirblock(True, u'a=a', u'a/a')
428
        self.assertLtByDirblock(False, u'a-a/a', u'a/a')
429
        self.assertLtByDirblock(False, u'a=a/a', u'a/a')
430
        self.assertLtByDirblock(False, u'a-a/a', u'a/a/a')
431
        self.assertLtByDirblock(False, u'a=a/a', u'a/a/a')
432
        self.assertLtByDirblock(False, u'a-a/a/a', u'a/a/a')
433
        self.assertLtByDirblock(False, u'a=a/a/a', u'a/a/a')
3514.3.12 by John Arbash Meinel
Found some problems in _path_key, and made sure to have proper testing of _cmp_paths_by_dirblock
434
3514.3.13 by John Arbash Meinel
One code path was using a tuple, another a plain path
435
    def assertPathToKey(self, expected, path):
436
        self.assertEqual(expected, _mod_tree.MultiWalker._path_to_key(path))
3514.3.12 by John Arbash Meinel
Found some problems in _path_key, and made sure to have proper testing of _cmp_paths_by_dirblock
437
3514.3.13 by John Arbash Meinel
One code path was using a tuple, another a plain path
438
    def test__path_to_key(self):
439
        self.assertPathToKey(([u''], u''), u'')
440
        self.assertPathToKey(([u''], u'a'), u'a')
441
        self.assertPathToKey(([u'a'], u'b'), u'a/b')
442
        self.assertPathToKey(([u'a', u'b'], u'c'), u'a/b/c')
6883.5.2 by Jelmer Vernooij
Add find_previous_paths call.
443
444
445
class FindPreviousPathsTests(TestCaseWithTransport):
446
447
    def test_new(self):
448
        tree = self.make_branch_and_tree('tree')
449
        self.build_tree(['tree/b'])
450
        tree.add(['b'])
451
        revid1 = tree.commit('first')
452
        tree1 = tree.branch.repository.revision_tree(revid1)
453
454
        tree0 = tree.branch.repository.revision_tree(revision.NULL_REVISION)
455
456
        self.assertEqual({'b': None}, find_previous_paths(tree1, tree0, ['b']))
457
458
    def test_find_previous_paths(self):
459
        tree = self.make_branch_and_tree('tree')
460
        self.build_tree(['tree/b'])
461
        tree.add(['b'])
462
        revid1 = tree.commit('first')
463
        tree1 = tree.branch.repository.revision_tree(revid1)
464
465
        tree.rename_one('b', 'c')
466
        self.build_tree(['tree/b'])
467
        tree.add(['b'])
468
        revid2 = tree.commit('second')
469
        tree2 = tree.branch.repository.revision_tree(revid2)
470
471
        self.assertEqual({'c': 'b', 'b': None},
472
                         find_previous_paths(tree2, tree1, ['b', 'c']))
7131.4.1 by Jelmer Vernooij
Fix get_canonical_path and add some basic tests.
473
474
475
class GetCanonicalPath(TestCaseWithTransport):
476
477
    def test_existing_case(self):
478
        # Test that we can find a file from a path with different case
479
        tree = self.make_branch_and_tree('tree')
480
        self.build_tree(['tree/b'])
481
        tree.add(['b'])
482
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
483
            'b',
484
            get_canonical_path(tree, 'b', lambda x: x.lower()))
7131.4.1 by Jelmer Vernooij
Fix get_canonical_path and add some basic tests.
485
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
486
            'b',
487
            get_canonical_path(tree, 'B', lambda x: x.lower()))
7131.4.1 by Jelmer Vernooij
Fix get_canonical_path and add some basic tests.
488
489
    def test_nonexistant_preserves_case(self):
490
        tree = self.make_branch_and_tree('tree')
491
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
492
            'b',
493
            get_canonical_path(tree, 'b', lambda x: x.lower()))
7131.4.1 by Jelmer Vernooij
Fix get_canonical_path and add some basic tests.
494
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
495
            'B',
496
            get_canonical_path(tree, 'B', lambda x: x.lower()))
7131.4.1 by Jelmer Vernooij
Fix get_canonical_path and add some basic tests.
497
498
    def test_in_directory_with_case(self):
499
        tree = self.make_branch_and_tree('tree')
500
        self.build_tree(['tree/a/', 'tree/a/b'])
501
        tree.add(['a', 'a/b'])
502
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
503
            'a/b',
504
            get_canonical_path(tree, 'a/b', lambda x: x.lower()))
505
        self.assertEqual(
506
            'a/b',
507
            get_canonical_path(tree, 'A/B', lambda x: x.lower()))
508
        self.assertEqual(
509
            'a/b',
510
            get_canonical_path(tree, 'A/b', lambda x: x.lower()))
511
        self.assertEqual(
512
            'a/C',
513
            get_canonical_path(tree, 'A/C', lambda x: x.lower()))