/brz/remove-bazaar

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