~bzr-pqm/bzr/bzr.dev

2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
1
# Copyright (C) 2006, 2007 Canonical Ltd
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
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
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
17
"""Tests for interface conformance of 'WorkingTree.move'"""
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
18
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
19
import os
20
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
21
from bzrlib import (
22
    errors,
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
23
    osutils,
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
24
    )
25
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
26
from bzrlib.workingtree_4 import WorkingTreeFormat4
27
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
28
29
30
class TestMove(TestCaseWithWorkingTree):
31
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
32
    def get_tree_layout(self, tree):
33
        """Get the (path, file_id) pairs for the current tree."""
34
        tree.lock_read()
35
        try:
36
            return [(path, ie.file_id) for path, ie
37
                    in tree.iter_entries_by_dir()]
38
        finally:
39
            tree.unlock()
40
41
    def assertTreeLayout(self, expected, tree):
42
        """Check that the tree has the correct layout."""
43
        actual = self.get_tree_layout(tree)
44
        self.assertEqual(expected, actual)
45
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
46
    def test_move_correct_call_named(self):
47
        """tree.move has the deprecated parameter 'to_name'.
48
        It has been replaced by 'to_dir' for consistency.
49
        Test the new API using named parameter
50
        """
51
        self.build_tree(['a1', 'sub1/'])
52
        tree = self.make_branch_and_tree('.')
53
        tree.add(['a1', 'sub1'])
54
        tree.commit('initial commit')
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
55
        self.assertEqual([('a1', 'sub1/a1')],
56
            tree.move(['a1'], to_dir='sub1', after=False))
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
57
        tree._validate()
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
58
59
    def test_move_correct_call_unnamed(self):
60
        """tree.move has the deprecated parameter 'to_name'.
61
        It has been replaced by 'to_dir' for consistency.
62
        Test the new API using unnamed parameter
63
        """
64
        self.build_tree(['a1', 'sub1/'])
65
        tree = self.make_branch_and_tree('.')
66
        tree.add(['a1', 'sub1'])
67
        tree.commit('initial commit')
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
68
        self.assertEqual([('a1', 'sub1/a1')],
69
            tree.move(['a1'], 'sub1', after=False))
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
70
        tree._validate()
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
71
72
    def test_move_deprecated_wrong_call(self):
73
        """tree.move has the deprecated parameter 'to_name'.
74
        It has been replaced by 'to_dir' for consistency.
75
        Test the new API using wrong parameter
76
        """
77
        self.build_tree(['a1', 'sub1/'])
78
        tree = self.make_branch_and_tree('.')
79
        tree.add(['a1', 'sub1'])
80
        tree.commit('initial commit')
81
        self.assertRaises(TypeError, tree.move, ['a1'],
82
                          to_this_parameter_does_not_exist='sub1',
83
                          after=False)
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
84
        tree._validate()
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
85
86
    def test_move_deprecated_call(self):
87
        """tree.move has the deprecated parameter 'to_name'.
88
        It has been replaced by 'to_dir' for consistency.
89
        Test the new API using deprecated parameter
90
        """
91
        self.build_tree(['a1', 'sub1/'])
92
        tree = self.make_branch_and_tree('.')
93
        tree.add(['a1', 'sub1'])
94
        tree.commit('initial commit')
95
96
        try:
97
            self.callDeprecated(['The parameter to_name was deprecated'
98
                                 ' in version 0.13. Use to_dir instead'],
99
                                tree.move, ['a1'], to_name='sub1',
100
                                after=False)
101
        except TypeError:
102
            # WorkingTreeFormat4 doesn't have to maintain api compatibility
103
            # since it was deprecated before the class was introduced.
104
            if not isinstance(self.workingtree_format, WorkingTreeFormat4):
105
                raise
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
106
        tree._validate()
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
107
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
108
    def test_move_target_not_dir(self):
109
        tree = self.make_branch_and_tree('.')
110
        self.build_tree(['a'])
111
        tree.add(['a'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
112
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
113
114
        self.assertRaises(errors.BzrMoveFailedError,
115
                          tree.move, ['a'], 'not-a-dir')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
116
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
117
118
    def test_move_non_existent(self):
119
        tree = self.make_branch_and_tree('.')
120
        self.build_tree(['a/'])
121
        tree.add(['a'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
122
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
123
        self.assertRaises(errors.BzrMoveFailedError,
124
                          tree.move, ['not-a-file'], 'a')
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
125
        self.assertRaises(errors.BzrMoveFailedError,
126
                          tree.move, ['not-a-file'], '')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
127
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
128
129
    def test_move_target_not_versioned(self):
130
        tree = self.make_branch_and_tree('.')
131
        self.build_tree(['a/', 'b'])
132
        tree.add(['b'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
133
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
134
        self.assertRaises(errors.BzrMoveFailedError,
135
                          tree.move, ['b'], 'a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
136
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
137
138
    def test_move_unversioned(self):
139
        tree = self.make_branch_and_tree('.')
140
        self.build_tree(['a/', 'b'])
141
        tree.add(['a'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
142
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
143
        self.assertRaises(errors.BzrMoveFailedError,
144
                          tree.move, ['b'], 'a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
145
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
146
147
    def test_move_multi_unversioned(self):
148
        tree = self.make_branch_and_tree('.')
149
        self.build_tree(['a/', 'b', 'c', 'd'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
150
        tree.add(['a', 'c', 'd'], ['a-id', 'c-id', 'd-id'])
151
        tree.commit('initial', rev_id='rev-1')
152
        root_id = tree.get_root_id()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
153
        self.assertRaises(errors.BzrMoveFailedError,
154
                          tree.move, ['c', 'b', 'd'], 'a')
155
        self.assertRaises(errors.BzrMoveFailedError,
156
                          tree.move, ['b', 'c', 'd'], 'a')
157
        self.assertRaises(errors.BzrMoveFailedError,
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
158
                          tree.move, ['d', 'c', 'b'], 'a')
159
        if osutils.lexists('a/c'):
160
            # If 'c' was actually moved, then 'd' should have also been moved
161
            self.assertTreeLayout([('', root_id), ('a', 'a-id'),
162
                                   ('a/c', 'c-id'),  ('a/d', 'd-id')], tree)
163
        else:
164
            self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
165
                                   ('d', 'd-id')], tree)
166
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
167
                               ('d', 'd-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
168
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
169
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
170
    def test_move_over_deleted(self):
171
        tree = self.make_branch_and_tree('.')
172
        self.build_tree(['a/', 'a/b', 'b'])
173
        tree.add(['a', 'a/b', 'b'], ['a-id', 'ab-id', 'b-id'])
174
        tree.commit('initial', rev_id='rev-1')
175
176
        root_id = tree.get_root_id()
177
        tree.remove(['a/b'], keep_files=False)
178
        self.assertEqual([('b', 'a/b')], tree.move(['b'], 'a'))
179
        self.assertTreeLayout([('', root_id),
180
                               ('a', 'a-id'),
181
                               ('a/b', 'b-id'),
182
                              ], tree)
183
        tree._validate()
184
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
185
    def test_move_subdir(self):
186
        tree = self.make_branch_and_tree('.')
187
        self.build_tree(['a', 'b/', 'b/c'])
188
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
189
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
190
        root_id = tree.get_root_id()
191
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
192
                               ('b/c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
193
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
194
                               ('b/c', 'c-id')], tree.basis_tree())
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
195
        a_contents = tree.get_file_text('a-id')
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
196
        self.assertEqual([('a', 'b/a')],
197
            tree.move(['a'], 'b'))
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
198
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id'),
199
                               ('b/c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
200
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
201
                               ('b/c', 'c-id')], tree.basis_tree())
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
202
        self.failIfExists('a')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
203
        self.assertFileEqual(a_contents, 'b/a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
204
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
205
206
    def test_move_parent_dir(self):
207
        tree = self.make_branch_and_tree('.')
208
        self.build_tree(['a', 'b/', 'b/c'])
209
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
210
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
211
        root_id = tree.get_root_id()
212
        c_contents = tree.get_file_text('c-id')
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
213
        self.assertEqual([('b/c', 'c')],
214
            tree.move(['b/c'], ''))
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
215
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
216
                               ('c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
217
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
218
                               ('b/c', 'c-id')], tree.basis_tree())
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
219
        self.failIfExists('b/c')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
220
        self.assertFileEqual(c_contents, 'c')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
221
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
222
223
    def test_move_fail_consistent(self):
224
        tree = self.make_branch_and_tree('.')
225
        self.build_tree(['a', 'b/', 'b/a', 'c'])
226
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
227
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
228
        root_id = tree.get_root_id()
229
        # Target already exists
230
        self.assertRaises(errors.RenameFailedFilesExist,
231
                          tree.move, ['c', 'a'], 'b')
232
        # 'c' may or may not have been moved, but either way the tree should
233
        # maintain a consistent state.
234
        if osutils.lexists('c'):
235
            self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
236
                                   ('c', 'c-id')], tree)
237
        else:
238
            self.failUnlessExists('b/c')
239
            self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
240
                                   ('b/c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
241
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
242
                               ('c', 'c-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
243
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
244
245
    def test_move_onto_self(self):
246
        tree = self.make_branch_and_tree('.')
247
        self.build_tree(['b/', 'b/a'])
248
        tree.add(['b', 'b/a'], ['b-id', 'a-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
249
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
250
251
        self.assertRaises(errors.BzrMoveFailedError,
252
                          tree.move, ['b/a'], 'b')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
253
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
254
255
    def test_move_onto_self_root(self):
256
        tree = self.make_branch_and_tree('.')
257
        self.build_tree(['a'])
258
        tree.add(['a'], ['a-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
259
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
260
261
        self.assertRaises(errors.BzrMoveFailedError,
262
                          tree.move, ['a'], 'a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
263
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
264
265
    def test_move_after(self):
266
        tree = self.make_branch_and_tree('.')
267
        self.build_tree(['a', 'b/'])
268
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
269
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
270
        root_id = tree.get_root_id()
271
        os.rename('a', 'b/a')
272
273
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
274
                              tree)
275
        # We don't need after=True as long as source is missing and target
276
        # exists.
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
277
        self.assertEqual([('a', 'b/a')],
278
            tree.move(['a'], 'b'))
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
279
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id')],
280
                              tree)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
281
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
282
                              tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
283
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
284
285
    def test_move_after_with_after(self):
286
        tree = self.make_branch_and_tree('.')
287
        self.build_tree(['a', 'b/'])
288
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
289
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
290
        root_id = tree.get_root_id()
291
        os.rename('a', 'b/a')
292
293
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
294
                              tree)
295
        # Passing after=True should work as well
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
296
        self.assertEqual([('a', 'b/a')],
297
            tree.move(['a'], 'b', after=True))
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
298
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id')],
299
                              tree)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
300
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
301
                              tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
302
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
303
304
    def test_move_after_no_target(self):
305
        tree = self.make_branch_and_tree('.')
306
        self.build_tree(['a', 'b/'])
307
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
308
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
309
        root_id = tree.get_root_id()
310
311
        # Passing after when the file hasn't been move raises an exception
312
        self.assertRaises(errors.BzrMoveFailedError,
313
                          tree.move, ['a'], 'b', after=True)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
314
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
315
                              tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
316
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
317
318
    def test_move_after_source_and_dest(self):
319
        tree = self.make_branch_and_tree('.')
320
        self.build_tree(['a', 'b/', 'b/a'])
321
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
322
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
323
        root_id = tree.get_root_id()
324
325
        # TODO: jam 20070225 I would usually use 'rb', but assertFileEqual
326
        #       uses 'r'.
327
        a_file = open('a', 'r')
328
        try:
329
            a_text = a_file.read()
330
        finally:
331
            a_file.close()
332
        ba_file = open('b/a', 'r')
333
        try:
334
            ba_text = ba_file.read()
335
        finally:
336
            ba_file.close()
337
338
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
339
                              tree)
340
        self.assertRaises(errors.RenameFailedFilesExist,
341
                          tree.move, ['a'], 'b', after=False)
342
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
343
                              tree)
344
        self.assertFileEqual(a_text, 'a')
345
        self.assertFileEqual(ba_text, 'b/a')
346
        # But you can pass after=True
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
347
        self.assertEqual([('a', 'b/a')],
348
            tree.move(['a'], 'b', after=True))
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
349
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id')],
350
                              tree)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
351
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
352
                              tree.basis_tree())
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
353
        # But it shouldn't actually move anything
354
        self.assertFileEqual(a_text, 'a')
355
        self.assertFileEqual(ba_text, 'b/a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
356
        tree._validate()
2255.2.146 by John Arbash Meinel
Implement move_directory by factoring out move_one
357
358
    def test_move_directory(self):
359
        tree = self.make_branch_and_tree('.')
360
        self.build_tree(['a/', 'a/b', 'a/c/', 'a/c/d', 'e/'])
361
        tree.add(['a', 'a/b', 'a/c', 'a/c/d', 'e'],
362
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
363
        tree.commit('initial', rev_id='rev-1')
364
        root_id = tree.get_root_id()
365
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
366
        self.assertEqual([('a', 'e/a')],
367
            tree.move(['a'], 'e'))
2255.2.146 by John Arbash Meinel
Implement move_directory by factoring out move_one
368
        self.assertTreeLayout([('', root_id), ('e', 'e-id'), ('e/a', 'a-id'),
369
                               ('e/a/b', 'b-id'), ('e/a/c', 'c-id'),
370
                               ('e/a/c/d', 'd-id')], tree)
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
371
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('e', 'e-id'),
372
                               ('a/b', 'b-id'), ('a/c', 'c-id'),
373
                               ('a/c/d', 'd-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
374
        tree._validate()
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
375
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
376
    def test_move_directory_into_parent(self):
377
        tree = self.make_branch_and_tree('.')
378
        self.build_tree(['c/', 'c/b/', 'c/b/d/'])
379
        tree.add(['c', 'c/b', 'c/b/d'],
380
                 ['c-id', 'b-id', 'd-id'])
381
        tree.commit('initial', rev_id='rev-1')
382
        root_id = tree.get_root_id()
383
384
        self.assertEqual([('c/b', 'b')],
385
                         tree.move(['c/b'], ''))
386
        self.assertTreeLayout([('', root_id),
387
                               ('b', 'b-id'),
388
                               ('c', 'c-id'),
389
                               ('b/d', 'd-id'),
390
                              ], tree)
391
        tree._validate()
392
2438.1.13 by John Arbash Meinel
Add a test for moving a directory where a child has been moved into a subdir.
393
    def test_move_directory_with_children_in_subdir(self):
394
        tree = self.make_branch_and_tree('.')
395
        self.build_tree(['a/', 'a/b', 'a/c/', 'd/'])
396
        tree.add(['a', 'a/b', 'a/c', 'd'],
397
                 ['a-id', 'b-id', 'c-id', 'd-id'])
398
        tree.commit('initial', rev_id='rev-1')
399
        root_id = tree.get_root_id()
400
401
402
        tree.rename_one('a/b', 'a/c/b')
403
        self.assertTreeLayout([('', root_id),
404
                               ('a', 'a-id'),
405
                               ('d', 'd-id'),
406
                               ('a/c', 'c-id'),
407
                               ('a/c/b', 'b-id'),
408
                              ], tree)
409
        self.assertEqual([('a', 'd/a')],
410
                         tree.move(['a'], 'd'))
411
        self.assertTreeLayout([('', root_id),
412
                               ('d', 'd-id'),
413
                               ('d/a', 'a-id'),
414
                               ('d/a/c', 'c-id'),
415
                               ('d/a/c/b', 'b-id'),
416
                              ], tree)
417
        tree._validate()
418
2438.1.7 by John Arbash Meinel
While in this area, add a test for renaming a directory with removed children.
419
    def test_move_directory_with_deleted_children(self):
420
        tree = self.make_branch_and_tree('.')
421
        self.build_tree(['a/', 'a/b', 'a/c', 'a/d', 'b/'])
422
        tree.add(['a', 'b', 'a/b', 'a/c', 'a/d'],
423
                 ['a-id', 'b-id', 'ab-id', 'ac-id', 'ad-id'])
424
        tree.commit('initial', rev_id='rev-1')
425
        root_id = tree.get_root_id()
426
427
        tree.remove(['a/b', 'a/d'])
428
429
        self.assertEqual([('a', 'b/a')],
430
                         tree.move(['a'], 'b'))
431
        self.assertTreeLayout([('', root_id),
432
                               ('b', 'b-id'),
433
                               ('b/a', 'a-id'),
434
                               ('b/a/c', 'ac-id'),
435
                              ], tree)
436
        tree._validate()
437
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
438
    def test_move_directory_with_new_children(self):
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
439
        tree = self.make_branch_and_tree('.')
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
440
        self.build_tree(['a/', 'a/c', 'b/'])
441
        tree.add(['a', 'b', 'a/c'], ['a-id', 'b-id', 'ac-id'])
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
442
        tree.commit('initial', rev_id='rev-1')
443
        root_id = tree.get_root_id()
444
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
445
        self.build_tree(['a/b', 'a/d'])
446
        tree.add(['a/b', 'a/d'], ['ab-id', 'ad-id'])
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
447
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
448
        self.assertEqual([('a', 'b/a')],
449
                         tree.move(['a'], 'b'))
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
450
        self.assertTreeLayout([('', root_id),
451
                               ('b', 'b-id'),
452
                               ('b/a', 'a-id'),
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
453
                               ('b/a/b', 'ab-id'),
454
                               ('b/a/c', 'ac-id'),
455
                               ('b/a/d', 'ad-id'),
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
456
                              ], tree)
457
        tree._validate()
458
2438.1.9 by John Arbash Meinel
Add another (failing) test when we move an entry which has a renamed child.
459
    def test_move_directory_with_moved_children(self):
460
        tree = self.make_branch_and_tree('.')
461
        self.build_tree(['a/', 'a/b', 'a/c', 'd', 'e/'])
462
        tree.add(['a', 'a/b', 'a/c', 'd', 'e'],
463
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
464
        tree.commit('initial', rev_id='rev-1')
465
        root_id = tree.get_root_id()
466
467
        self.assertEqual([('a/b', 'b')],
468
                         tree.move(['a/b'], ''))
469
        self.assertTreeLayout([('', root_id),
470
                               ('a', 'a-id'),
471
                               ('b', 'b-id'),
472
                               ('d', 'd-id'),
473
                               ('e', 'e-id'),
474
                               ('a/c', 'c-id'),
475
                              ], tree)
476
        self.assertEqual([('d', 'a/d')],
477
                         tree.move(['d'], 'a'))
478
        self.assertTreeLayout([('', root_id),
479
                               ('a', 'a-id'),
480
                               ('b', 'b-id'),
481
                               ('e', 'e-id'),
482
                               ('a/c', 'c-id'),
483
                               ('a/d', 'd-id'),
484
                              ], tree)
485
        self.assertEqual([('a', 'e/a')],
486
                         tree.move(['a'], 'e'))
487
        self.assertTreeLayout([('', root_id),
488
                               ('b', 'b-id'),
489
                               ('e', 'e-id'),
490
                               ('e/a', 'a-id'),
491
                               ('e/a/c', 'c-id'),
492
                               ('e/a/d', 'd-id'),
493
                              ], tree)
494
        tree._validate()
495
2438.1.11 by John Arbash Meinel
Add a test for moving a directory with a renamed child.
496
    def test_move_directory_with_renamed_child(self):
497
        tree = self.make_branch_and_tree('.')
498
        self.build_tree(['a/', 'a/b', 'a/c', 'd/'])
499
        tree.add(['a', 'a/b', 'a/c', 'd'],
500
                 ['a-id', 'b-id', 'c-id', 'd-id'])
501
        tree.commit('initial', rev_id='rev-1')
502
        root_id = tree.get_root_id()
503
504
        tree.rename_one('a/b', 'a/d')
505
        self.assertTreeLayout([('', root_id),
506
                               ('a', 'a-id'),
507
                               ('d', 'd-id'),
508
                               ('a/c', 'c-id'),
509
                               ('a/d', 'b-id'),
510
                              ], tree)
511
        self.assertEqual([('a', 'd/a')],
512
                         tree.move(['a'], 'd'))
513
        self.assertTreeLayout([('', root_id),
514
                               ('d', 'd-id'),
515
                               ('d/a', 'a-id'),
516
                               ('d/a/c', 'c-id'),
517
                               ('d/a/d', 'b-id'),
518
                              ], tree)
519
        tree._validate()
520
2438.1.12 by John Arbash Meinel
Add a test with children that have been swapped
521
    def test_move_directory_with_swapped_children(self):
522
        tree = self.make_branch_and_tree('.')
523
        self.build_tree(['a/', 'a/b', 'a/c', 'a/d', 'e/'])
524
        tree.add(['a', 'a/b', 'a/c', 'a/d', 'e'],
525
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
526
        tree.commit('initial', rev_id='rev-1')
527
        root_id = tree.get_root_id()
528
529
        tree.rename_one('a/b', 'a/bb')
530
        tree.rename_one('a/d', 'a/b')
531
        tree.rename_one('a/bb', 'a/d')
532
        self.assertTreeLayout([('', root_id),
533
                               ('a', 'a-id'),
534
                               ('e', 'e-id'),
535
                               ('a/b', 'd-id'),
536
                               ('a/c', 'c-id'),
537
                               ('a/d', 'b-id'),
538
                              ], tree)
539
        self.assertEqual([('a', 'e/a')],
540
                         tree.move(['a'], 'e'))
541
        self.assertTreeLayout([('', root_id),
542
                               ('e', 'e-id'),
543
                               ('e/a', 'a-id'),
544
                               ('e/a/b', 'd-id'),
545
                               ('e/a/c', 'c-id'),
546
                               ('e/a/d', 'b-id'),
547
                              ], tree)
548
        tree._validate()
549
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
550
    def test_move_moved(self):
551
        """Moving a moved entry works as expected."""
552
        tree = self.make_branch_and_tree('.')
553
        self.build_tree(['a/', 'a/b', 'c/'])
554
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
555
        tree.commit('initial', rev_id='rev-1')
556
        root_id = tree.get_root_id()
557
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
558
        self.assertEqual([('a/b', 'c/b')],
559
            tree.move(['a/b'], 'c'))
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
560
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
561
                               ('c/b', 'b-id')], tree)
562
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
563
                               ('a/b', 'b-id')], tree.basis_tree())
564
2255.7.46 by Robert Collins
Fix WorkingTree4.move to return the moved paths, and update the tree implementation tests for move to check them.
565
        self.assertEqual([('c/b', 'b')],
566
            tree.move(['c/b'], ''))
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
567
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
568
                               ('c', 'c-id')], tree)
569
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
570
                               ('a/b', 'b-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
571
        tree._validate()