/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) 2007 Canonical Ltd
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.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
16
17
"""Tests for interface conformance of 'WorkingTree.rename_one'"""
18
19
import os
20
21
from bzrlib import (
22
    errors,
23
    osutils,
3638.3.13 by Vincent Ladeuil
Fix test_rename_to_denormalised_fails for OSX.
24
    tests,
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
25
    )
26
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
27
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
28
29
30
class TestRenameOne(TestCaseWithWorkingTree):
31
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
46
    def test_rename_one_target_not_dir(self):
47
        tree = self.make_branch_and_tree('.')
48
        self.build_tree(['a'])
49
        tree.add(['a'])
50
        tree.commit('initial', rev_id='rev-1')
51
52
        self.assertRaises(errors.BzrMoveFailedError,
53
                          tree.rename_one, 'a', 'not-a-dir/b')
54
55
    def test_rename_one_non_existent(self):
56
        tree = self.make_branch_and_tree('.')
57
        self.build_tree(['a/'])
58
        tree.add(['a'])
59
        tree.commit('initial', rev_id='rev-1')
60
        self.assertRaises(errors.BzrMoveFailedError,
61
                          tree.rename_one, 'not-a-file', 'a/failure')
62
        self.assertRaises(errors.BzrMoveFailedError,
63
                          tree.rename_one, 'not-a-file', 'also_not')
64
65
    def test_rename_one_target_not_versioned(self):
66
        tree = self.make_branch_and_tree('.')
67
        self.build_tree(['a/', 'b'])
68
        tree.add(['b'])
69
        tree.commit('initial', rev_id='rev-1')
70
        self.assertRaises(errors.BzrMoveFailedError,
71
                          tree.rename_one, 'b', 'a/b')
72
73
    def test_rename_one_unversioned(self):
74
        tree = self.make_branch_and_tree('.')
75
        self.build_tree(['a/', 'b'])
76
        tree.add(['a'])
77
        tree.commit('initial', rev_id='rev-1')
78
        self.assertRaises(errors.BzrMoveFailedError,
79
                          tree.rename_one, 'b', 'a/b')
80
81
    def test_rename_one_samedir(self):
82
        tree = self.make_branch_and_tree('.')
83
        self.build_tree(['a', 'b/'])
84
        tree.add(['a', 'b'], ['a-id', 'b-id'])
85
        tree.commit('initial', rev_id='rev-1')
86
        root_id = tree.get_root_id()
87
88
        a_contents = tree.get_file_text('a-id')
89
        tree.rename_one('a', 'foo')
90
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('foo', 'a-id')],
91
                              tree)
92
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
93
                              tree.basis_tree())
94
        self.failIfExists('a')
95
        self.assertFileEqual(a_contents, 'foo')
96
97
    def test_rename_one_not_localdir(self):
98
        tree = self.make_branch_and_tree('tree')
99
        self.build_tree(['tree/a', 'tree/b/'])
100
        tree.add(['a', 'b'], ['a-id', 'b-id'])
101
        tree.commit('initial', rev_id='rev-1')
102
        root_id = tree.get_root_id()
103
104
        a_contents = tree.get_file_text('a-id')
105
        tree.rename_one('a', 'b/foo')
106
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/foo', 'a-id')],
107
                              tree)
108
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
109
                              tree.basis_tree())
110
        self.failIfExists('tree/a')
111
        self.assertFileEqual(a_contents, 'tree/b/foo')
112
113
    def test_rename_one_subdir(self):
114
        tree = self.make_branch_and_tree('.')
115
        self.build_tree(['a', 'b/', 'b/c'])
116
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
117
        tree.commit('initial', rev_id='rev-1')
118
        root_id = tree.get_root_id()
119
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
120
                               ('b/c', 'c-id')], tree)
121
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
122
                               ('b/c', 'c-id')], tree.basis_tree())
123
        a_contents = tree.get_file_text('a-id')
124
        tree.rename_one('a', 'b/d')
125
        self.assertTreeLayout([('', root_id), ('b', 'b-id'), ('b/c', 'c-id'),
126
                               ('b/d', 'a-id')], tree)
127
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
128
                               ('b/c', 'c-id')], tree.basis_tree())
129
        self.failIfExists('a')
130
        self.assertFileEqual(a_contents, 'b/d')
131
132
    def test_rename_one_parent_dir(self):
133
        tree = self.make_branch_and_tree('.')
134
        self.build_tree(['a', 'b/', 'b/c'])
135
        tree.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
136
        tree.commit('initial', rev_id='rev-1')
137
        root_id = tree.get_root_id()
138
        c_contents = tree.get_file_text('c-id')
139
        tree.rename_one('b/c', 'd')
140
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
141
                               ('d', 'c-id')], tree)
142
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
143
                               ('b/c', 'c-id')], tree.basis_tree())
144
        self.failIfExists('b/c')
145
        self.assertFileEqual(c_contents, 'd')
146
147
    def test_rename_one_fail_consistent(self):
148
        tree = self.make_branch_and_tree('.')
149
        self.build_tree(['a', 'b/', 'b/a', 'c'])
150
        tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
151
        tree.commit('initial', rev_id='rev-1')
152
        root_id = tree.get_root_id()
153
        # Target already exists
154
        self.assertRaises(errors.RenameFailedFilesExist,
155
                          tree.rename_one, 'a', 'b/a')
156
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
157
                               ('c', 'c-id')], tree)
158
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id'),
159
                               ('c', 'c-id')], tree.basis_tree())
160
161
    def test_rename_one_onto_existing(self):
162
        tree = self.make_branch_and_tree('.')
163
        self.build_tree(['a', 'b'])
164
        tree.add(['a', 'b'], ['a-id', 'b-id'])
165
        tree.commit('initial', rev_id='rev-1')
166
167
        self.assertRaises(errors.BzrMoveFailedError,
168
                          tree.rename_one, 'a', 'b')
169
170
    def test_rename_one_onto_self(self):
171
        tree = self.make_branch_and_tree('.')
172
        self.build_tree(['b/', 'b/a'])
173
        tree.add(['b', 'b/a'], ['b-id', 'a-id'])
174
        tree.commit('initial', rev_id='rev-1')
175
176
        self.assertRaises(errors.BzrMoveFailedError,
177
                          tree.rename_one, 'b/a', 'b/a')
178
179
    def test_rename_one_onto_self_root(self):
180
        tree = self.make_branch_and_tree('.')
181
        self.build_tree(['a'])
182
        tree.add(['a'], ['a-id'])
183
        tree.commit('initial', rev_id='rev-1')
184
185
        self.assertRaises(errors.BzrMoveFailedError,
186
                          tree.rename_one, 'a', 'a')
187
188
    def test_rename_one_after(self):
189
        tree = self.make_branch_and_tree('.')
190
        self.build_tree(['a', 'b/'])
191
        tree.add(['a', 'b'], ['a-id', 'b-id'])
192
        tree.commit('initial', rev_id='rev-1')
193
        root_id = tree.get_root_id()
194
        os.rename('a', 'b/foo')
195
196
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
197
                              tree)
198
        # We don't need after=True as long as source is missing and target
199
        # exists.
200
        tree.rename_one('a', 'b/foo')
201
        self.assertTreeLayout([('', root_id), ('b', 'b-id'),
202
                               ('b/foo', 'a-id')], tree)
203
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
204
                              tree.basis_tree())
205
206
    def test_rename_one_after_with_after(self):
207
        tree = self.make_branch_and_tree('.')
208
        self.build_tree(['a', 'b/'])
209
        tree.add(['a', 'b'], ['a-id', 'b-id'])
210
        tree.commit('initial', rev_id='rev-1')
211
        root_id = tree.get_root_id()
212
        os.rename('a', 'b/foo')
213
214
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
215
                              tree)
216
        # Passing after=True should work as well
217
        tree.rename_one('a', 'b/foo', after=True)
218
        self.assertTreeLayout([('', root_id), ('b', 'b-id'),
219
                               ('b/foo', 'a-id')], tree)
220
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
221
                              tree.basis_tree())
222
4371.6.1 by Marius Kruger
Allow renaming of files already removed from the inventory
223
    def test_rename_one_after_source_removed(self):
224
        """Rename even if the source was removed from the inventory already"""
225
        tree = self.make_branch_and_tree('.')
226
        self.build_tree(['a', 'b/'])
227
        tree.add(['a', 'b'], ['a-id', 'b-id'])
228
        tree.commit('initial', rev_id='rev-1')
229
        root_id = tree.get_root_id()
230
        os.rename('a', 'b/foo')
231
        tree.remove(['a'])
232
233
        self.assertTreeLayout([('', root_id), ('b', 'b-id')], tree)
234
        # We don't need after=True as long as source is missing and target
235
        # exists.
236
        tree.rename_one('a', 'b/foo')
237
        self.assertTreeLayout([('', root_id), ('b', 'b-id'),
238
                               ('b/foo', 'a-id')], tree)
239
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
240
                              tree.basis_tree())
241
2255.7.9 by John Arbash Meinel
Add more tests for WorkingTree.move() and a similar suite
242
    def test_rename_one_after_no_target(self):
243
        tree = self.make_branch_and_tree('.')
244
        self.build_tree(['a', 'b/'])
245
        tree.add(['a', 'b'], ['a-id', 'b-id'])
246
        tree.commit('initial', rev_id='rev-1')
247
        root_id = tree.get_root_id()
248
249
        # Passing after when the file hasn't been rename_one raises an exception
250
        self.assertRaises(errors.BzrMoveFailedError,
251
                          tree.rename_one, 'a', 'b/foo', after=True)
252
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
253
                              tree)
254
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
255
                              tree.basis_tree())
256
257
    def test_rename_one_after_source_and_dest(self):
258
        tree = self.make_branch_and_tree('.')
259
        self.build_tree(['a', 'b/', 'b/foo'])
260
        tree.add(['a', 'b'], ['a-id', 'b-id'])
261
        tree.commit('initial', rev_id='rev-1')
262
        root_id = tree.get_root_id()
263
264
        # TODO: jam 20070225 I would usually use 'rb', but assertFileEqual
265
        #       uses 'r'.
266
        a_file = open('a', 'r')
267
        try:
268
            a_text = a_file.read()
269
        finally:
270
            a_file.close()
271
        foo_file = open('b/foo', 'r')
272
        try:
273
            foo_text = foo_file.read()
274
        finally:
275
            foo_file.close()
276
277
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
278
                              tree)
279
        self.assertRaises(errors.RenameFailedFilesExist,
280
                          tree.rename_one, 'a', 'b/foo', after=False)
281
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
282
                              tree)
283
        self.assertFileEqual(a_text, 'a')
284
        self.assertFileEqual(foo_text, 'b/foo')
285
        # But you can pass after=True
286
        tree.rename_one('a', 'b/foo', after=True)
287
        self.assertTreeLayout([('', root_id), ('b', 'b-id'),
288
                               ('b/foo', 'a-id')], tree)
289
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('b', 'b-id')],
290
                              tree.basis_tree())
291
        # But it shouldn't actually move anything
292
        self.assertFileEqual(a_text, 'a')
293
        self.assertFileEqual(foo_text, 'b/foo')
294
295
    def test_rename_one_directory(self):
296
        tree = self.make_branch_and_tree('.')
297
        self.build_tree(['a/', 'a/b', 'a/c/', 'a/c/d', 'e/'])
298
        tree.add(['a', 'a/b', 'a/c', 'a/c/d', 'e'],
299
                 ['a-id', 'b-id', 'c-id', 'd-id', 'e-id'])
300
        tree.commit('initial', rev_id='rev-1')
301
        root_id = tree.get_root_id()
302
303
        tree.rename_one('a', 'e/f')
304
        self.assertTreeLayout([('', root_id), ('e', 'e-id'), ('e/f', 'a-id'),
305
                               ('e/f/b', 'b-id'), ('e/f/c', 'c-id'),
306
                               ('e/f/c/d', 'd-id')], tree)
307
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('e', 'e-id'),
308
                               ('a/b', 'b-id'), ('a/c', 'c-id'),
309
                               ('a/c/d', 'd-id')], tree.basis_tree())
310
311
    def test_rename_one_moved(self):
312
        """Moving a moved entry works as expected."""
313
        tree = self.make_branch_and_tree('.')
314
        self.build_tree(['a/', 'a/b', 'c/'])
315
        tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
316
        tree.commit('initial', rev_id='rev-1')
317
        root_id = tree.get_root_id()
318
319
        tree.rename_one('a/b', 'c/foo')
320
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
321
                               ('c/foo', 'b-id')], tree)
322
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
323
                               ('a/b', 'b-id')], tree.basis_tree())
324
325
        tree.rename_one('c/foo', 'bar')
326
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('bar', 'b-id'),
327
                               ('c', 'c-id')], tree)
328
        self.assertTreeLayout([('', root_id), ('a', 'a-id'), ('c', 'c-id'),
329
                               ('a/b', 'b-id')], tree.basis_tree())
2825.6.1 by Robert Collins
* ``WorkingTree.rename_one`` will now raise an error if normalisation of the
330
331
    def test_rename_to_denormalised_fails(self):
3638.3.13 by Vincent Ladeuil
Fix test_rename_to_denormalised_fails for OSX.
332
        if osutils.normalizes_filenames():
333
            raise tests.TestNotApplicable('OSX normalizes filenames')
2825.6.1 by Robert Collins
* ``WorkingTree.rename_one`` will now raise an error if normalisation of the
334
        tree = self.make_branch_and_tree('.')
335
        self.build_tree(['a'])
336
        tree.add(['a'])
337
        self.assertRaises((errors.InvalidNormalization, UnicodeEncodeError),
3201.1.2 by John Arbash Meinel
Test needs to be updated now that ยต is allowed.
338
            tree.rename_one, 'a', u'ba\u030arry')
5609.8.2 by Martin
Add per_workingtree test for every error case bar one that has unicode problems
339
340
    def test_rename_unversioned_non_ascii(self):
341
        """Check error when renaming an unversioned non-ascii file"""
342
        self.requireFeature(tests.UnicodeFilename)
343
        tree = self.make_branch_and_tree(".")
344
        self.build_tree([u"\xA7"])
345
        e = self.assertRaises(errors.BzrRenameFailedError,
346
            tree.rename_one, u"\xA7", "b")
347
        self.assertIsInstance(e.extra, errors.NotVersionedError)
348
        self.assertEqual(e.extra.path, u"\xA7")
349
350
    def test_rename_into_unversioned_non_ascii_dir(self):
351
        """Check error when renaming into unversioned non-ascii directory"""
352
        self.requireFeature(tests.UnicodeFilename)
353
        tree = self.make_branch_and_tree(".")
354
        self.build_tree(["a", u"\xA7/"])
355
        tree.add(["a"])
356
        e = self.assertRaises(errors.BzrMoveFailedError,
357
            tree.rename_one, "a", u"\xA7/a")
358
        self.assertIsInstance(e.extra, errors.NotVersionedError)
359
        self.assertEqual(e.extra.path, u"\xA7")
360
361
    def test_rename_over_already_versioned_non_ascii(self):
362
        """Check error renaming over an already versioned non-ascii file"""
363
        self.requireFeature(tests.UnicodeFilename)
364
        tree = self.make_branch_and_tree(".")
365
        self.build_tree(["a", u"\xA7"])
366
        tree.add(["a", u"\xA7"])
367
        e = self.assertRaises(errors.BzrMoveFailedError,
368
            tree.rename_one, "a", u"\xA7")
369
        self.assertIsInstance(e.extra, errors.AlreadyVersionedError)
370
        self.assertEqual(e.extra.path, u"\xA7")
371
372
    def test_rename_after_non_existant_non_ascii(self):
373
        """Check error renaming after move with missing non-ascii file"""
374
        self.requireFeature(tests.UnicodeFilename)
375
        tree = self.make_branch_and_tree(".")
376
        self.build_tree(["a"])
377
        tree.add(["a"])
378
        e = self.assertRaises(errors.BzrMoveFailedError,
379
            tree.rename_one, "a", u"\xA7", after=True)
380
        self.assertIsInstance(e.extra, errors.NoSuchFile)
381
        self.assertEqual(e.extra.path, u"\xA7")