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