/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
6072.2.2 by Jelmer Vernooij
Use HasLayout matcher.
27
from bzrlib.tests.matchers import HasLayout
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
28
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
29
from bzrlib.tests import (
30
    features,
31
    )
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
32
33
34
class TestMove(TestCaseWithWorkingTree):
35
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
36
    def assertTreeLayout(self, expected, tree):
37
        """Check that the tree has the correct layout."""
6072.2.2 by Jelmer Vernooij
Use HasLayout matcher.
38
        self.assertThat(tree, HasLayout(expected))
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
39
3923.2.1 by Charles Duffy
Fix bug #314251 (dirstate crash on rename via delete+add)
40
    def test_move_via_rm_and_add(self):
41
        """Move by remove and add-with-id"""
42
        self.build_tree(['a1', 'b1'])
43
        tree = self.make_branch_and_tree('.')
44
        tree.add(['a1'], ids=['a1-id'])
45
        tree.commit('initial commit')
46
        tree.remove('a1', force=True, keep_files=False)
47
        tree.add(['b1'], ids=['a1-id'])
48
        tree._validate()
49
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
50
    def test_move_correct_call_named(self):
51
        """tree.move has the deprecated parameter 'to_name'.
52
        It has been replaced by 'to_dir' for consistency.
53
        Test the new API using named parameter
54
        """
55
        self.build_tree(['a1', 'sub1/'])
56
        tree = self.make_branch_and_tree('.')
57
        tree.add(['a1', 'sub1'])
58
        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.
59
        self.assertEqual([('a1', 'sub1/a1')],
60
            tree.move(['a1'], to_dir='sub1', after=False))
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
61
        tree._validate()
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
62
63
    def test_move_correct_call_unnamed(self):
64
        """tree.move has the deprecated parameter 'to_name'.
65
        It has been replaced by 'to_dir' for consistency.
66
        Test the new API using unnamed parameter
67
        """
68
        self.build_tree(['a1', 'sub1/'])
69
        tree = self.make_branch_and_tree('.')
70
        tree.add(['a1', 'sub1'])
71
        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.
72
        self.assertEqual([('a1', 'sub1/a1')],
73
            tree.move(['a1'], 'sub1', after=False))
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
74
        tree._validate()
2255.2.137 by John Arbash Meinel
Move the WorkingTree.move() tests into their own module
75
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
76
    def test_move_target_not_dir(self):
77
        tree = self.make_branch_and_tree('.')
78
        self.build_tree(['a'])
79
        tree.add(['a'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
80
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
81
82
        self.assertRaises(errors.BzrMoveFailedError,
83
                          tree.move, ['a'], 'not-a-dir')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
84
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
85
86
    def test_move_non_existent(self):
87
        tree = self.make_branch_and_tree('.')
88
        self.build_tree(['a/'])
89
        tree.add(['a'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
90
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
91
        self.assertRaises(errors.BzrMoveFailedError,
92
                          tree.move, ['not-a-file'], 'a')
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
93
        self.assertRaises(errors.BzrMoveFailedError,
94
                          tree.move, ['not-a-file'], '')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
95
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
96
97
    def test_move_target_not_versioned(self):
98
        tree = self.make_branch_and_tree('.')
99
        self.build_tree(['a/', 'b'])
100
        tree.add(['b'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
101
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
102
        self.assertRaises(errors.BzrMoveFailedError,
103
                          tree.move, ['b'], 'a')
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_unversioned(self):
107
        tree = self.make_branch_and_tree('.')
108
        self.build_tree(['a/', 'b'])
109
        tree.add(['a'])
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_multi_unversioned(self):
116
        tree = self.make_branch_and_tree('.')
117
        self.build_tree(['a/', 'b', 'c', 'd'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
118
        tree.add(['a', 'c', 'd'], ['a-id', 'c-id', 'd-id'])
119
        tree.commit('initial', rev_id='rev-1')
120
        root_id = tree.get_root_id()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
121
        self.assertRaises(errors.BzrMoveFailedError,
122
                          tree.move, ['c', 'b', 'd'], 'a')
123
        self.assertRaises(errors.BzrMoveFailedError,
124
                          tree.move, ['b', 'c', 'd'], 'a')
125
        self.assertRaises(errors.BzrMoveFailedError,
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
126
                          tree.move, ['d', 'c', 'b'], 'a')
127
        if osutils.lexists('a/c'):
128
            # If 'c' was actually moved, then 'd' should have also been moved
129
            self.assertTreeLayout([('', root_id), ('a', 'a-id'),
130
                                   ('a/c', 'c-id'),  ('a/d', 'd-id')], tree)
131
        else:
132
            self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
133
                                   ('d', 'd-id')], tree)
134
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
135
                               ('d', 'd-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
136
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
137
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
138
    def test_move_over_deleted(self):
139
        tree = self.make_branch_and_tree('.')
140
        self.build_tree(['a/', 'a/b', 'b'])
141
        tree.add(['a', 'a/b', 'b'], ['a-id', 'ab-id', 'b-id'])
142
        tree.commit('initial', rev_id='rev-1')
143
144
        root_id = tree.get_root_id()
145
        tree.remove(['a/b'], keep_files=False)
146
        self.assertEqual([('b', 'a/b')], tree.move(['b'], 'a'))
147
        self.assertTreeLayout([('', root_id),
148
                               ('a', 'a-id'),
149
                               ('a/b', 'b-id'),
150
                              ], tree)
151
        tree._validate()
152
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
153
    def test_move_subdir(self):
154
        tree = self.make_branch_and_tree('.')
155
        self.build_tree(['a', 'b/', 'b/c'])
156
        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
157
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
158
        root_id = tree.get_root_id()
159
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
160
                               ('b/c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
161
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
162
                               ('b/c', 'c-id')], tree.basis_tree())
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
163
        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.
164
        self.assertEqual([('a', 'b/a')],
165
            tree.move(['a'], 'b'))
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
166
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id'),
167
                               ('b/c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
168
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
169
                               ('b/c', 'c-id')], tree.basis_tree())
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
170
        self.assertPathDoesNotExist('a')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
171
        self.assertFileEqual(a_contents, 'b/a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
172
        tree._validate()
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
173
174
    def test_move_parent_dir(self):
175
        tree = self.make_branch_and_tree('.')
176
        self.build_tree(['a', 'b/', 'b/c'])
177
        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
178
        tree.commit('initial', rev_id='rev-1')
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
179
        root_id = tree.get_root_id()
180
        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.
181
        self.assertEqual([('b/c', 'c')],
182
            tree.move(['b/c'], ''))
2255.2.138 by John Arbash Meinel
implement several new WorkingTree.move() tests
183
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
184
                               ('c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
185
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
186
                               ('b/c', 'c-id')], tree.basis_tree())
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
187
        self.assertPathDoesNotExist('b/c')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
188
        self.assertFileEqual(c_contents, 'c')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
189
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
190
191
    def test_move_fail_consistent(self):
192
        tree = self.make_branch_and_tree('.')
193
        self.build_tree(['a', 'b/', 'b/a', 'c'])
194
        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
195
        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.
196
        root_id = tree.get_root_id()
197
        # Target already exists
198
        self.assertRaises(errors.RenameFailedFilesExist,
199
                          tree.move, ['c', 'a'], 'b')
200
        # 'c' may or may not have been moved, but either way the tree should
201
        # maintain a consistent state.
202
        if osutils.lexists('c'):
203
            self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
204
                                   ('c', 'c-id')], tree)
205
        else:
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
206
            self.assertPathExists('b/c')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
207
            self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
208
                                   ('b/c', 'c-id')], tree)
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
209
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
210
                               ('c', 'c-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
211
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
212
213
    def test_move_onto_self(self):
214
        tree = self.make_branch_and_tree('.')
215
        self.build_tree(['b/', 'b/a'])
216
        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
217
        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.
218
219
        self.assertRaises(errors.BzrMoveFailedError,
220
                          tree.move, ['b/a'], 'b')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
221
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
222
223
    def test_move_onto_self_root(self):
224
        tree = self.make_branch_and_tree('.')
225
        self.build_tree(['a'])
226
        tree.add(['a'], ['a-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
227
        tree.commit('initial', rev_id='rev-1')
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
228
229
        self.assertRaises(errors.BzrMoveFailedError,
230
                          tree.move, ['a'], 'a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
231
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
232
233
    def test_move_after(self):
234
        tree = self.make_branch_and_tree('.')
235
        self.build_tree(['a', 'b/'])
236
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
237
        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.
238
        root_id = tree.get_root_id()
239
        os.rename('a', 'b/a')
240
241
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
242
                              tree)
243
        # We don't need after=True as long as source is missing and target
244
        # 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.
245
        self.assertEqual([('a', 'b/a')],
246
            tree.move(['a'], 'b'))
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
247
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id')],
248
                              tree)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
249
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
250
                              tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
251
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
252
253
    def test_move_after_with_after(self):
254
        tree = self.make_branch_and_tree('.')
255
        self.build_tree(['a', 'b/'])
256
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
257
        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.
258
        root_id = tree.get_root_id()
259
        os.rename('a', 'b/a')
260
261
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
262
                              tree)
263
        # 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.
264
        self.assertEqual([('a', 'b/a')],
265
            tree.move(['a'], 'b', after=True))
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
266
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id')],
267
                              tree)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
268
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
269
                              tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
270
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
271
272
    def test_move_after_no_target(self):
273
        tree = self.make_branch_and_tree('.')
274
        self.build_tree(['a', 'b/'])
275
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
276
        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.
277
        root_id = tree.get_root_id()
278
279
        # Passing after when the file hasn't been move raises an exception
280
        self.assertRaises(errors.BzrMoveFailedError,
281
                          tree.move, ['a'], 'b', after=True)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
282
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
283
                              tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
284
        tree._validate()
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
285
286
    def test_move_after_source_and_dest(self):
287
        tree = self.make_branch_and_tree('.')
288
        self.build_tree(['a', 'b/', 'b/a'])
289
        tree.add(['a', 'b'], ['a-id', 'b-id'])
2255.2.140 by John Arbash Meinel
Update tests to ensure basis tree is not modified
290
        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.
291
        root_id = tree.get_root_id()
292
293
        # TODO: jam 20070225 I would usually use 'rb', but assertFileEqual
294
        #       uses 'r'.
295
        a_file = open('a', 'r')
296
        try:
297
            a_text = a_file.read()
298
        finally:
299
            a_file.close()
300
        ba_file = open('b/a', 'r')
301
        try:
302
            ba_text = ba_file.read()
303
        finally:
304
            ba_file.close()
305
306
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
307
                              tree)
308
        self.assertRaises(errors.RenameFailedFilesExist,
309
                          tree.move, ['a'], 'b', after=False)
310
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
311
                              tree)
312
        self.assertFileEqual(a_text, 'a')
313
        self.assertFileEqual(ba_text, 'b/a')
314
        # 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.
315
        self.assertEqual([('a', 'b/a')],
316
            tree.move(['a'], 'b', after=True))
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
317
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/a', 'a-id')],
318
                              tree)
2255.2.141 by John Arbash Meinel
Some small changes to move tests.
319
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
320
                              tree.basis_tree())
2255.2.139 by John Arbash Meinel
test cases for moving after a file has already been moved.
321
        # But it shouldn't actually move anything
322
        self.assertFileEqual(a_text, 'a')
323
        self.assertFileEqual(ba_text, 'b/a')
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
324
        tree._validate()
2255.2.146 by John Arbash Meinel
Implement move_directory by factoring out move_one
325
326
    def test_move_directory(self):
327
        tree = self.make_branch_and_tree('.')
328
        self.build_tree(['a/', 'a/b', 'a/c/', 'a/c/d', 'e/'])
329
        tree.add(['a', 'a/b', 'a/c', 'a/c/d', 'e'],
330
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
331
        tree.commit('initial', rev_id='rev-1')
332
        root_id = tree.get_root_id()
333
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.
334
        self.assertEqual([('a', 'e/a')],
335
            tree.move(['a'], 'e'))
2255.2.146 by John Arbash Meinel
Implement move_directory by factoring out move_one
336
        self.assertTreeLayout([('', root_id), ('e', 'e-id'), ('e/a', 'a-id'),
337
                               ('e/a/b', 'b-id'), ('e/a/c', 'c-id'),
338
                               ('e/a/c/d', 'd-id')], tree)
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
339
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('e', 'e-id'),
340
                               ('a/b', 'b-id'), ('a/c', 'c-id'),
341
                               ('a/c/d', 'd-id')], tree.basis_tree())
2371.2.1 by John Arbash Meinel
Update DirState._validate() to detect rename errors.
342
        tree._validate()
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
343
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
344
    def test_move_directory_into_parent(self):
6039.1.3 by Jelmer Vernooij
Cope with versioned directories in test_move_directory_into_parent.
345
        if not self.workingtree_format.supports_versioned_directories:
346
            raise tests.TestNotApplicable(
347
                "test requires versioned directories")
2438.1.3 by John Arbash Meinel
Add 2 new WT.move() tests, one of which exposes bug #105479
348
        tree = self.make_branch_and_tree('.')
349
        self.build_tree(['c/', 'c/b/', 'c/b/d/'])
350
        tree.add(['c', 'c/b', 'c/b/d'],
351
                 ['c-id', 'b-id', 'd-id'])
352
        tree.commit('initial', rev_id='rev-1')
353
        root_id = tree.get_root_id()
354
355
        self.assertEqual([('c/b', 'b')],
356
                         tree.move(['c/b'], ''))
357
        self.assertTreeLayout([('', root_id),
358
                               ('b', 'b-id'),
359
                               ('c', 'c-id'),
360
                               ('b/d', 'd-id'),
361
                              ], tree)
362
        tree._validate()
363
2438.1.13 by John Arbash Meinel
Add a test for moving a directory where a child has been moved into a subdir.
364
    def test_move_directory_with_children_in_subdir(self):
365
        tree = self.make_branch_and_tree('.')
366
        self.build_tree(['a/', 'a/b', 'a/c/', 'd/'])
367
        tree.add(['a', 'a/b', 'a/c', 'd'],
368
                 ['a-id', 'b-id', 'c-id', 'd-id'])
369
        tree.commit('initial', rev_id='rev-1')
370
        root_id = tree.get_root_id()
371
372
        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.
373
        if self.workingtree_format.supports_versioned_directories:
374
            self.assertTreeLayout([('', root_id),
375
                                   ('a', 'a-id'),
376
                                   ('d', 'd-id'),
377
                                   ('a/c', 'c-id'),
378
                                   ('a/c/b', 'b-id'),
379
                                  ], tree)
380
        else:
381
            self.assertTreeLayout([('', root_id),
382
                                   ('a', 'a-id'),
383
                                   ('a/c', 'c-id'),
384
                                   ('a/c/b', 'b-id'),
385
                                  ], tree)
2438.1.13 by John Arbash Meinel
Add a test for moving a directory where a child has been moved into a subdir.
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")