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