/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):
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
379
        tree.rename_one('a/b', 'a/c/b')
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
        self.assertEqual([('a', 'd/a')],
387
                         tree.move(['a'], 'd'))
388
        self.assertTreeLayout([('', root_id),
389
                               ('d', 'd-id'),
390
                               ('d/a', 'a-id'),
391
                               ('d/a/c', 'c-id'),
392
                               ('d/a/c/b', 'b-id'),
393
                              ], tree)
394
        tree._validate()
395
2438.1.7 by John Arbash Meinel
While in this area, add a test for renaming a directory with removed children.
396
    def test_move_directory_with_deleted_children(self):
397
        tree = self.make_branch_and_tree('.')
398
        self.build_tree(['a/', 'a/b', 'a/c', 'a/d', 'b/'])
399
        tree.add(['a', 'b', 'a/b', 'a/c', 'a/d'],
400
                 ['a-id', 'b-id', 'ab-id', 'ac-id', 'ad-id'])
401
        tree.commit('initial', rev_id='rev-1')
402
        root_id = tree.get_root_id()
403
404
        tree.remove(['a/b', 'a/d'])
405
406
        self.assertEqual([('a', 'b/a')],
407
                         tree.move(['a'], 'b'))
408
        self.assertTreeLayout([('', root_id),
409
                               ('b', 'b-id'),
410
                               ('b/a', 'a-id'),
411
                               ('b/a/c', 'ac-id'),
412
                              ], tree)
413
        tree._validate()
414
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
415
    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
416
        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.
417
        self.build_tree(['a/', 'a/c', 'b/'])
418
        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
419
        tree.commit('initial', rev_id='rev-1')
420
        root_id = tree.get_root_id()
421
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
422
        self.build_tree(['a/b', 'a/d'])
423
        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
424
2438.1.6 by John Arbash Meinel
Simplify the test since all we require is renaming a newly added entry's parent dir.
425
        self.assertEqual([('a', 'b/a')],
426
                         tree.move(['a'], 'b'))
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
427
        self.assertTreeLayout([('', root_id),
428
                               ('b', 'b-id'),
429
                               ('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.
430
                               ('b/a/b', 'ab-id'),
431
                               ('b/a/c', 'ac-id'),
432
                               ('b/a/d', 'ad-id'),
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
433
                              ], tree)
434
        tree._validate()
435
2438.1.9 by John Arbash Meinel
Add another (failing) test when we move an entry which has a renamed child.
436
    def test_move_directory_with_moved_children(self):
437
        tree = self.make_branch_and_tree('.')
438
        self.build_tree(['a/', 'a/b', 'a/c', 'd', 'e/'])
439
        tree.add(['a', 'a/b', 'a/c', 'd', 'e'],
440
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
441
        tree.commit('initial', rev_id='rev-1')
442
        root_id = tree.get_root_id()
443
444
        self.assertEqual([('a/b', 'b')],
445
                         tree.move(['a/b'], ''))
446
        self.assertTreeLayout([('', root_id),
447
                               ('a', 'a-id'),
448
                               ('b', 'b-id'),
449
                               ('d', 'd-id'),
450
                               ('e', 'e-id'),
451
                               ('a/c', 'c-id'),
452
                              ], tree)
453
        self.assertEqual([('d', 'a/d')],
454
                         tree.move(['d'], 'a'))
455
        self.assertTreeLayout([('', root_id),
456
                               ('a', 'a-id'),
457
                               ('b', 'b-id'),
458
                               ('e', 'e-id'),
459
                               ('a/c', 'c-id'),
460
                               ('a/d', 'd-id'),
461
                              ], tree)
462
        self.assertEqual([('a', 'e/a')],
463
                         tree.move(['a'], 'e'))
464
        self.assertTreeLayout([('', root_id),
465
                               ('b', 'b-id'),
466
                               ('e', 'e-id'),
467
                               ('e/a', 'a-id'),
468
                               ('e/a/c', 'c-id'),
469
                               ('e/a/d', 'd-id'),
470
                              ], tree)
471
        tree._validate()
472
2438.1.11 by John Arbash Meinel
Add a test for moving a directory with a renamed child.
473
    def test_move_directory_with_renamed_child(self):
474
        tree = self.make_branch_and_tree('.')
475
        self.build_tree(['a/', 'a/b', 'a/c', 'd/'])
476
        tree.add(['a', 'a/b', 'a/c', 'd'],
477
                 ['a-id', 'b-id', 'c-id', 'd-id'])
478
        tree.commit('initial', rev_id='rev-1')
479
        root_id = tree.get_root_id()
480
481
        tree.rename_one('a/b', 'a/d')
482
        self.assertTreeLayout([('', root_id),
483
                               ('a', 'a-id'),
484
                               ('d', 'd-id'),
485
                               ('a/c', 'c-id'),
486
                               ('a/d', 'b-id'),
487
                              ], tree)
488
        self.assertEqual([('a', 'd/a')],
489
                         tree.move(['a'], 'd'))
490
        self.assertTreeLayout([('', root_id),
491
                               ('d', 'd-id'),
492
                               ('d/a', 'a-id'),
493
                               ('d/a/c', 'c-id'),
494
                               ('d/a/d', 'b-id'),
495
                              ], tree)
496
        tree._validate()
497
2438.1.12 by John Arbash Meinel
Add a test with children that have been swapped
498
    def test_move_directory_with_swapped_children(self):
499
        tree = self.make_branch_and_tree('.')
500
        self.build_tree(['a/', 'a/b', 'a/c', 'a/d', 'e/'])
501
        tree.add(['a', 'a/b', 'a/c', 'a/d', 'e'],
502
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
503
        tree.commit('initial', rev_id='rev-1')
504
        root_id = tree.get_root_id()
505
506
        tree.rename_one('a/b', 'a/bb')
507
        tree.rename_one('a/d', 'a/b')
508
        tree.rename_one('a/bb', 'a/d')
509
        self.assertTreeLayout([('', root_id),
510
                               ('a', 'a-id'),
511
                               ('e', 'e-id'),
512
                               ('a/b', 'd-id'),
513
                               ('a/c', 'c-id'),
514
                               ('a/d', 'b-id'),
515
                              ], tree)
516
        self.assertEqual([('a', 'e/a')],
517
                         tree.move(['a'], 'e'))
518
        self.assertTreeLayout([('', root_id),
519
                               ('e', 'e-id'),
520
                               ('e/a', 'a-id'),
521
                               ('e/a/b', 'd-id'),
522
                               ('e/a/c', 'c-id'),
523
                               ('e/a/d', 'b-id'),
524
                              ], tree)
525
        tree._validate()
526
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
527
    def test_move_moved(self):
528
        """Moving a moved entry works as expected."""
529
        tree = self.make_branch_and_tree('.')
530
        self.build_tree(['a/', 'a/b', 'c/'])
531
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
532
        tree.commit('initial', rev_id='rev-1')
533
        root_id = tree.get_root_id()
534
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.
535
        self.assertEqual([('a/b', 'c/b')],
536
            tree.move(['a/b'], 'c'))
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
537
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
538
                               ('c/b', 'b-id')], tree)
539
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
540
                               ('a/b', 'b-id')], tree.basis_tree())
541
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.
542
        self.assertEqual([('c/b', 'b')],
543
            tree.move(['c/b'], ''))
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
544
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
545
                               ('c', 'c-id')], tree)
546
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
547
                               ('a/b', 'b-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
548
        tree._validate()
5609.8.2 by Martin
Add per_workingtree test for every error case bar one that has unicode problems
549
550
    def test_move_to_unversioned_non_ascii_dir(self):
551
        """Check error when moving to unversioned non-ascii directory"""
5967.12.3 by Martin Pool
Unify duplicated UnicodeFilename and _PosixPermissionsFeature
552
        self.requireFeature(features.UnicodeFilenameFeature)
5609.8.2 by Martin
Add per_workingtree test for every error case bar one that has unicode problems
553
        tree = self.make_branch_and_tree(".")
554
        self.build_tree(["a", u"\xA7/"])
555
        tree.add(["a"])
556
        e = self.assertRaises(errors.BzrMoveFailedError,
557
            tree.move, ["a"], u"\xA7")
558
        self.assertIsInstance(e.extra, errors.NotVersionedError)
559
        self.assertEqual(e.extra.path, u"\xA7")
560
561
    def test_move_unversioned_non_ascii(self):
562
        """Check error when moving an unversioned non-ascii file"""
5967.12.3 by Martin Pool
Unify duplicated UnicodeFilename and _PosixPermissionsFeature
563
        self.requireFeature(features.UnicodeFilenameFeature)
5609.8.2 by Martin
Add per_workingtree test for every error case bar one that has unicode problems
564
        tree = self.make_branch_and_tree(".")
565
        self.build_tree([u"\xA7", "dir/"])
566
        tree.add("dir")
567
        e = self.assertRaises(errors.BzrMoveFailedError,
568
            tree.move, [u"\xA7"], "dir")
569
        self.assertIsInstance(e.extra, errors.NotVersionedError)
570
        self.assertEqual(e.extra.path, u"\xA7")