~bzr-pqm/bzr/bzr.dev

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