/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,
31
    )
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
32
33
6734.1.22 by Jelmer Vernooij
review comments.
34
class TestErrors(TestCase):
6731.1.1 by Jelmer Vernooij
Move FileTimestampUnavailable to breezy.tree.
35
36
    def test_file_timestamp_unavailable(self):
37
        e = FileTimestampUnavailable("/path/foo")
38
        self.assertEqual("The filestamp for /path/foo is not available.",
39
                         str(e))
40
41
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
42
class TestInterTree(TestCaseWithTransport):
43
44
    def test_revision_tree_revision_tree(self):
45
        # we should have an InterTree registered for RevisionTree to
46
        # RevisionTree.
47
        tree = self.make_branch_and_tree('.')
48
        rev_id = tree.commit('first post')
49
        rev_id2 = tree.commit('second post', allow_pointless=True)
50
        rev_tree = tree.branch.repository.revision_tree(rev_id)
51
        rev_tree2 = tree.branch.repository.revision_tree(rev_id2)
52
        optimiser = InterTree.get(rev_tree, rev_tree2)
53
        self.assertIsInstance(optimiser, InterTree)
54
        optimiser = InterTree.get(rev_tree2, rev_tree)
55
        self.assertIsInstance(optimiser, InterTree)
56
57
    def test_working_tree_revision_tree(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
58
        # we should have an InterTree available for WorkingTree to
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
59
        # RevisionTree.
60
        tree = self.make_branch_and_tree('.')
61
        rev_id = tree.commit('first post')
62
        rev_tree = tree.branch.repository.revision_tree(rev_id)
63
        optimiser = InterTree.get(rev_tree, tree)
64
        self.assertIsInstance(optimiser, InterTree)
65
        optimiser = InterTree.get(tree, rev_tree)
66
        self.assertIsInstance(optimiser, InterTree)
67
68
    def test_working_tree_working_tree(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
69
        # we should have an InterTree available for WorkingTree to
1852.8.2 by Robert Collins
Add InterTree class to represent InterTree operations.
70
        # WorkingTree.
71
        tree = self.make_branch_and_tree('1')
72
        tree2 = self.make_branch_and_tree('2')
73
        optimiser = InterTree.get(tree, tree2)
74
        self.assertIsInstance(optimiser, InterTree)
75
        optimiser = InterTree.get(tree2, tree)
76
        self.assertIsInstance(optimiser, InterTree)
1852.8.4 by Robert Collins
Hook InterTree into Tree.
77
78
79
class RecordingOptimiser(InterTree):
80
81
    calls = []
82
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
83
    def compare(self, want_unchanged=False, specific_files=None,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
84
        extra_trees=None, require_versioned=False, include_root=False,
85
        want_unversioned=False):
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
86
        self.calls.append(
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
87
            ('compare', self.source, self.target, want_unchanged,
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
88
             specific_files, extra_trees, require_versioned,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
89
             include_root, want_unversioned)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
90
            )
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
91
1852.8.4 by Robert Collins
Hook InterTree into Tree.
92
    @classmethod
93
    def is_compatible(klass, source, target):
94
        return True
95
96
97
class TestTree(TestCaseWithTransport):
98
99
    def test_compare_calls_InterTree_compare(self):
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
100
        """This test tests the way Tree.compare() uses InterTree."""
1852.8.4 by Robert Collins
Hook InterTree into Tree.
101
        old_optimisers = InterTree._optimisers
102
        try:
1910.2.15 by Aaron Bentley
Back out inter.get changes, make optimizers an ordered list
103
            InterTree._optimisers = []
1852.8.4 by Robert Collins
Hook InterTree into Tree.
104
            RecordingOptimiser.calls = []
105
            InterTree.register_optimiser(RecordingOptimiser)
106
            tree = self.make_branch_and_tree('1')
107
            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.
108
            # do a series of calls:
109
            # trivial usage
1852.8.8 by Robert Collins
change Tree.compare to Tree.changes_from - its better for the common case.
110
            tree.changes_from(tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
111
            # pass in all optional arguments by position
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
112
            tree.changes_from(tree2, 'unchanged', 'specific', 'extra',
1910.2.57 by Aaron Bentley
Got 0.9 bundles working, with root included by changes_from
113
                              'require', True)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
114
            # pass in all optional arguments by keyword
1852.9.6 by Robert Collins
Merge the change from Tree.compare to Tree.changes_from.
115
            tree.changes_from(tree2,
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
116
                specific_files='specific',
117
                want_unchanged='unchanged',
118
                extra_trees='extra',
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
119
                require_versioned='require',
1910.2.57 by Aaron Bentley
Got 0.9 bundles working, with root included by changes_from
120
                include_root=True,
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
121
                want_unversioned=True,
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
122
                )
1852.8.4 by Robert Collins
Hook InterTree into Tree.
123
        finally:
124
            InterTree._optimisers = old_optimisers
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
125
        self.assertEqual(
126
            [
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
127
             ('compare', tree2, tree, False, None, None, False, False, False),
128
             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
129
              'require', True, False),
130
             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
131
              'require', True, True),
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
132
            ], RecordingOptimiser.calls)
1731.1.33 by Aaron Bentley
Revert no-special-root changes
133
134
    def test_changes_from_with_root(self):
135
        """Ensure the include_root option does what's expected."""
136
        wt = self.make_branch_and_tree('.')
137
        delta = wt.changes_from(wt.basis_tree())
138
        self.assertEqual(len(delta.added), 0)
4570.2.7 by Robert Collins
Fix misuse of tree.compare API in test_tree.py
139
        delta = wt.changes_from(wt.basis_tree(), include_root=True)
1731.1.33 by Aaron Bentley
Revert no-special-root changes
140
        self.assertEqual(len(delta.added), 1)
141
        self.assertEqual(delta.added[0][0], '')
2655.2.1 by Marius Kruger
InterTree.compare and delta._compare_trees did not pass its
142
143
    def test_changes_from_with_require_versioned(self):
144
        """Ensure the require_versioned option does what's expected."""
145
        wt = self.make_branch_and_tree('.')
146
        self.build_tree(['known_file', 'unknown_file'])
147
        wt.add('known_file')
148
2655.2.2 by Marius Kruger
Rather use assertRaises in test_changes_from_with_require_versioned
149
        self.assertRaises(errors.PathsNotVersionedError,
150
            wt.changes_from, wt.basis_tree(), wt, specific_files=['known_file',
151
            'unknown_file'], require_versioned=True)
2655.2.1 by Marius Kruger
InterTree.compare and delta._compare_trees did not pass its
152
153
        # we need to pass a known file with an unknown file to get this to
154
        # fail when expected.
4570.2.7 by Robert Collins
Fix misuse of tree.compare API in test_tree.py
155
        delta = wt.changes_from(wt.basis_tree(),
2655.2.1 by Marius Kruger
InterTree.compare and delta._compare_trees did not pass its
156
            specific_files=['known_file', 'unknown_file'] ,
157
            require_versioned=False)
158
        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.
159
160
161
class TestMultiWalker(TestCaseWithTransport):
162
163
    def assertStepOne(self, has_more, path, file_id, iterator):
164
        retval = _mod_tree.MultiWalker._step_one(iterator)
165
        if not has_more:
166
            self.assertIs(None, path)
167
            self.assertIs(None, file_id)
168
            self.assertEqual((False, None, None), retval)
169
        else:
170
            self.assertEqual((has_more, path, file_id),
171
                             (retval[0], retval[1], retval[2].file_id))
172
173
    def test__step_one_empty(self):
174
        tree = self.make_branch_and_tree('empty')
175
        repo = tree.branch.repository
176
        empty_tree = repo.revision_tree(revision.NULL_REVISION)
177
178
        iterator = empty_tree.iter_entries_by_dir()
179
        self.assertStepOne(False, None, None, iterator)
180
        self.assertStepOne(False, None, None, iterator)
181
182
    def test__step_one(self):
183
        tree = self.make_branch_and_tree('tree')
184
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
185
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
186
187
        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.
188
        tree.lock_read()
189
        self.addCleanup(tree.unlock)
190
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
191
        root_id = tree.path2id('')
192
        self.assertStepOne(True, '', root_id, iterator)
193
        self.assertStepOne(True, 'a', 'a-id', iterator)
194
        self.assertStepOne(True, 'b', 'b-id', iterator)
195
        self.assertStepOne(True, 'b/c', 'c-id', iterator)
196
        self.assertStepOne(False, None, None, iterator)
197
        self.assertStepOne(False, None, None, iterator)
198
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
199
    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
200
                         exp_other_paths, iterator):
201
        """Check what happens when we step the iterator.
202
203
        :param path: The path for this entry
204
        :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.
205
        :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
206
        :param exp_other_paths: A list of other_path values.
207
        :param iterator: The iterator to step
208
        """
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
209
        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.
210
        self.assertEqual((exp_path, exp_file_id), (path, file_id),
211
                         'Master entry did not match')
212
        if master_has_node:
213
            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
214
        else:
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
215
            self.assertIs(None, master_ie, 'master should not have an entry')
216
        self.assertEqual(len(exp_other_paths), len(other_values),
217
                            'Wrong number of other entries')
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
218
        other_paths = []
219
        other_file_ids = []
220
        for path, ie in other_values:
221
            other_paths.append(path)
222
            if ie is None:
223
                other_file_ids.append(None)
224
            else:
225
                other_file_ids.append(ie.file_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
226
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
227
        exp_file_ids = []
228
        for path in exp_other_paths:
229
            if path is None:
230
                exp_file_ids.append(None)
231
            else:
232
                exp_file_ids.append(file_id)
233
        self.assertEqual(exp_other_paths, other_paths, "Other paths incorrect")
234
        self.assertEqual(exp_file_ids, other_file_ids,
235
                         "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.
236
237
    def lock_and_get_basis_and_root_id(self, tree):
238
        tree.lock_read()
239
        self.addCleanup(tree.unlock)
240
        basis_tree = tree.basis_tree()
241
        basis_tree.lock_read()
242
        self.addCleanup(basis_tree.unlock)
243
        root_id = tree.path2id('')
244
        return basis_tree, root_id
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
245
3514.3.1 by John Arbash Meinel
Start working on a special walker that can iterate several trees at once.
246
    def test_simple_stepping(self):
247
        tree = self.make_branch_and_tree('tree')
248
        self.build_tree(['tree/a', 'tree/b/', 'tree/b/c'])
249
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
250
251
        tree.commit('first', rev_id='first-rev-id')
252
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
253
        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
254
255
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
256
        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.
257
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
258
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
259
        self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
260
        self.assertWalkerNext(u'b/c', 'c-id', True, [u'b/c'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
261
        self.assertRaises(StopIteration, next, iterator)
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
262
263
    def test_master_has_extra(self):
264
        tree = self.make_branch_and_tree('tree')
265
        self.build_tree(['tree/a', 'tree/b/', 'tree/c', 'tree/d'])
266
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
267
268
        tree.commit('first', rev_id='first-rev-id')
269
270
        tree.add(['c'], ['c-id'])
3514.3.3 by John Arbash Meinel
Handle when the other tree has extra nodes, and we need to yield them.
271
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
272
273
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
274
        iterator = walker.iter_all()
275
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
276
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
277
        self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
278
        self.assertWalkerNext(u'c', 'c-id', True, [None], iterator)
279
        self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
280
        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.
281
282
    def test_master_renamed_to_earlier(self):
283
        """The record is still present, it just shows up early."""
284
        tree = self.make_branch_and_tree('tree')
285
        self.build_tree(['tree/a', 'tree/c', 'tree/d'])
286
        tree.add(['a', 'c', 'd'], ['a-id', 'c-id', 'd-id'])
287
        tree.commit('first', rev_id='first-rev-id')
288
        tree.rename_one('d', 'b')
289
290
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
291
292
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
293
        iterator = walker.iter_all()
294
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
295
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
296
        self.assertWalkerNext(u'b', 'd-id', True, [u'd'], iterator)
297
        self.assertWalkerNext(u'c', 'c-id', True, [u'c'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
298
        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.
299
300
    def test_master_renamed_to_later(self):
301
        tree = self.make_branch_and_tree('tree')
302
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
303
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
304
        tree.commit('first', rev_id='first-rev-id')
305
        tree.rename_one('b', 'e')
306
307
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
308
309
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
310
        iterator = walker.iter_all()
311
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
312
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
313
        self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
314
        self.assertWalkerNext(u'e', 'b-id', True, [u'b'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
315
        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.
316
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
317
    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.
318
        tree = self.make_branch_and_tree('tree')
319
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
320
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
321
        tree.commit('first', rev_id='first-rev-id')
322
        tree.remove(['b'])
323
324
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
325
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
326
        iterator = walker.iter_all()
327
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
328
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
329
        self.assertWalkerNext(u'd', 'd-id', True, [u'd'], iterator)
3514.3.2 by John Arbash Meinel
Handle the case when a record is missing in base
330
        self.assertWalkerNext(u'b', 'b-id', False, [u'b'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
331
        self.assertRaises(StopIteration, next, iterator)
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
332
333
    def test_other_extra_at_end(self):
334
        tree = self.make_branch_and_tree('tree')
335
        self.build_tree(['tree/a', 'tree/b', 'tree/d'])
336
        tree.add(['a', 'b', 'd'], ['a-id', 'b-id', 'd-id'])
337
        tree.commit('first', rev_id='first-rev-id')
338
        tree.remove(['d'])
339
340
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
341
        walker = _mod_tree.MultiWalker(tree, [basis_tree])
342
        iterator = walker.iter_all()
343
        self.assertWalkerNext(u'', root_id, True, [u''], iterator)
344
        self.assertWalkerNext(u'a', 'a-id', True, [u'a'], iterator)
345
        self.assertWalkerNext(u'b', 'b-id', True, [u'b'], iterator)
346
        self.assertWalkerNext(u'd', 'd-id', False, [u'd'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
347
        self.assertRaises(StopIteration, next, iterator)
3514.3.4 by John Arbash Meinel
Handle more cases when the other tree has extra nodes.
348
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
349
    def test_others_extra_at_end(self):
350
        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
351
        self.build_tree(['tree/a', 'tree/b', 'tree/c', 'tree/d', 'tree/e'])
352
        tree.add(['a', 'b', 'c', 'd', 'e'],
353
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
354
        tree.commit('first', rev_id='first-rev-id')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
355
        tree.remove(['e'])
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
356
        tree.commit('second', rev_id='second-rev-id')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
357
        tree.remove(['d'])
358
        tree.commit('third', rev_id='third-rev-id')
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
359
        tree.remove(['c'])
360
361
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
362
        first_tree = tree.branch.repository.revision_tree('first-rev-id')
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
363
        second_tree = tree.branch.repository.revision_tree('second-rev-id')
364
        walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree,
365
                                              second_tree])
3514.3.5 by John Arbash Meinel
Handle some edge cases when we have multiple other trees.
366
        iterator = walker.iter_all()
3514.3.6 by John Arbash Meinel
check when there are 3 other trees, rather than just 2
367
        self.assertWalkerNext(u'', root_id, True, [u'', u'', u''], iterator)
368
        self.assertWalkerNext(u'a', 'a-id', True, [u'a', u'a', u'a'], iterator)
369
        self.assertWalkerNext(u'b', 'b-id', True, [u'b', u'b', u'b'], iterator)
370
        self.assertWalkerNext(u'c', 'c-id', False, [u'c', u'c', u'c'], iterator)
371
        self.assertWalkerNext(u'd', 'd-id', False, [None, u'd', u'd'], iterator)
372
        self.assertWalkerNext(u'e', 'e-id', False, [None, u'e', None], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
373
        self.assertRaises(StopIteration, next, iterator)
3514.3.10 by John Arbash Meinel
A mix-matched commit with things moving in each tree.
374
375
    def test_different_file_id_in_others(self):
376
        tree = self.make_branch_and_tree('tree')
377
        self.build_tree(['tree/a', 'tree/b', 'tree/c/'])
378
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
379
        tree.commit('first', rev_id='first-rev-id')
380
381
        tree.rename_one('b', 'c/d')
382
        self.build_tree(['tree/b'])
383
        tree.add(['b'], ['b2-id'])
384
        tree.commit('second', rev_id='second-rev-id')
385
386
        tree.rename_one('a', 'c/e')
387
        self.build_tree(['tree/a'])
388
        tree.add(['a'], ['a2-id'])
389
390
        basis_tree, root_id = self.lock_and_get_basis_and_root_id(tree)
391
        first_tree = tree.branch.repository.revision_tree('first-rev-id')
392
        walker = _mod_tree.MultiWalker(tree, [basis_tree, first_tree])
393
394
        iterator = walker.iter_all()
395
        self.assertWalkerNext(u'', root_id, True, [u'', u''], iterator)
396
        self.assertWalkerNext(u'a', 'a2-id', True, [None, None], iterator)
397
        self.assertWalkerNext(u'b', 'b2-id', True, [u'b', None], iterator)
398
        self.assertWalkerNext(u'c', 'c-id', True, [u'c', u'c'], iterator)
399
        self.assertWalkerNext(u'c/d', 'b-id', True, [u'c/d', u'b'], iterator)
400
        self.assertWalkerNext(u'c/e', 'a-id', True, [u'a', u'a'], iterator)
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
401
        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
402
403
    def assertCmpByDirblock(self, cmp_val, path1, path2):
404
        self.assertEqual(cmp_val,
405
            _mod_tree.MultiWalker._cmp_path_by_dirblock(path1, path2))
406
407
    def test__cmp_path_by_dirblock(self):
408
        # We only support Unicode strings at this point
409
        self.assertRaises(TypeError,
410
            _mod_tree.MultiWalker._cmp_path_by_dirblock, '', 'b')
411
        self.assertCmpByDirblock(0, u'', u'')
412
        self.assertCmpByDirblock(0, u'a', u'a')
413
        self.assertCmpByDirblock(0, u'a/b', u'a/b')
414
        self.assertCmpByDirblock(0, u'a/b/c', u'a/b/c')
415
        self.assertCmpByDirblock(1, u'a-a', u'a')
416
        self.assertCmpByDirblock(-1, u'a-a', u'a/a')
417
        self.assertCmpByDirblock(-1, u'a=a', u'a/a')
418
        self.assertCmpByDirblock(1, u'a-a/a', u'a/a')
419
        self.assertCmpByDirblock(1, u'a=a/a', u'a/a')
420
        self.assertCmpByDirblock(1, u'a-a/a', u'a/a/a')
421
        self.assertCmpByDirblock(1, u'a=a/a', u'a/a/a')
422
        self.assertCmpByDirblock(1, u'a-a/a/a', u'a/a/a')
423
        self.assertCmpByDirblock(1, u'a=a/a/a', u'a/a/a')
424
3514.3.13 by John Arbash Meinel
One code path was using a tuple, another a plain path
425
    def assertPathToKey(self, expected, path):
426
        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
427
3514.3.13 by John Arbash Meinel
One code path was using a tuple, another a plain path
428
    def test__path_to_key(self):
429
        self.assertPathToKey(([u''], u''), u'')
430
        self.assertPathToKey(([u''], u'a'), u'a')
431
        self.assertPathToKey(([u'a'], u'b'), u'a/b')
432
        self.assertPathToKey(([u'a', u'b'], u'c'), u'a/b/c')