/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.65.4 by James Westby
Make the rename handling more robust.
1
# Copyright (C) 2008 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
import time
18
19
from bzrlib import (
20
    branch,
21
    tests,
22
    )
23
24
from bzrlib.plugins.fastimport import (
25
    commands,
26
    errors,
27
    )
28
29
from bzrlib.plugins.fastimport.processors import (
30
    generic_processor,
31
    )
32
33
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
34
class TestCaseForGenericProcessor(tests.TestCaseWithTransport):
0.65.4 by James Westby
Make the rename handling more robust.
35
36
    def get_handler(self):
37
        branch = self.make_branch('.')
38
        handler = generic_processor.GenericProcessor(branch.bzrdir)
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
39
        return handler, branch
0.65.4 by James Westby
Make the rename handling more robust.
40
41
    # FIXME: [] as a default is bad, as it is mutable, but I want
42
    # to use None to mean "don't check this".
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
43
    def assertChanges(self, branch, revno, expected_added=[],
44
            expected_removed=[], expected_modified=[],
0.80.3 by Ian Clatworthy
file <-> symlink change tests
45
            expected_renamed=[], expected_kind_changed=[]):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
46
        """Check the changes introduced in a revision of a branch.
47
48
        This method checks that a revision introduces expected changes.
49
        The required changes are passed in as a list, where
50
        each entry contains the needed information about the change.
51
52
        If you do not wish to assert anything about a particular
53
        category then pass None instead.
54
55
        branch: The branch.
56
        revno: revision number of revision to check.
57
        expected_added: a list of (filename,) tuples that must have
58
            been added in the delta.
59
        expected_removed: a list of (filename,) tuples that must have
60
            been removed in the delta.
61
        expected_modified: a list of (filename,) tuples that must have
62
            been modified in the delta.
63
        expected_renamed: a list of (old_path, new_path) tuples that
64
            must have been renamed in the delta.
0.80.3 by Ian Clatworthy
file <-> symlink change tests
65
        expected_kind_changed: a list of (path, old_kind, new_kind) tuples
66
            that must have been changed in the delta.
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
67
        :return: revtree1, revtree2
68
        """
69
        repo = branch.repository
0.80.1 by Ian Clatworthy
basic units tests for filemodify
70
        revtree1 = repo.revision_tree(branch.get_rev_id(revno - 1))
71
        revtree2 = repo.revision_tree(branch.get_rev_id(revno))
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
72
        changes = revtree2.changes_from(revtree1)
0.80.3 by Ian Clatworthy
file <-> symlink change tests
73
        self._check_changes(changes, expected_added, expected_removed,
74
            expected_modified, expected_renamed, expected_kind_changed)
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
75
        return revtree1, revtree2
76
0.80.3 by Ian Clatworthy
file <-> symlink change tests
77
    def _check_changes(self, changes, expected_added=[],
0.65.4 by James Westby
Make the rename handling more robust.
78
            expected_removed=[], expected_modified=[],
0.80.3 by Ian Clatworthy
file <-> symlink change tests
79
            expected_renamed=[], expected_kind_changed=[]):
0.65.4 by James Westby
Make the rename handling more robust.
80
        """Check the changes in a TreeDelta
81
82
        This method checks that the TreeDelta contains the expected
83
        modifications between the two trees that were used to generate
84
        it. The required changes are passed in as a list, where
85
        each entry contains the needed information about the change.
86
87
        If you do not wish to assert anything about a particular
88
        category then pass None instead.
89
90
        changes: The TreeDelta to check.
91
        expected_added: a list of (filename,) tuples that must have
92
            been added in the delta.
93
        expected_removed: a list of (filename,) tuples that must have
94
            been removed in the delta.
95
        expected_modified: a list of (filename,) tuples that must have
96
            been modified in the delta.
97
        expected_renamed: a list of (old_path, new_path) tuples that
98
            must have been renamed in the delta.
0.80.3 by Ian Clatworthy
file <-> symlink change tests
99
        expected_kind_changed: a list of (path, old_kind, new_kind) tuples
100
            that must have been changed in the delta.
0.65.4 by James Westby
Make the rename handling more robust.
101
        """
102
        renamed = changes.renamed
103
        added = changes.added
104
        removed = changes.removed
105
        modified = changes.modified
0.80.3 by Ian Clatworthy
file <-> symlink change tests
106
        kind_changed = changes.kind_changed
0.65.4 by James Westby
Make the rename handling more robust.
107
        if expected_renamed is not None:
108
            self.assertEquals(len(renamed), len(expected_renamed),
0.74.1 by John Arbash Meinel
Change the rename code to create a new text entry.
109
                "%s is renamed, expected %s" % (renamed, expected_renamed))
0.65.4 by James Westby
Make the rename handling more robust.
110
            renamed_files = [(item[0], item[1]) for item in renamed]
111
            for expected_renamed_entry in expected_renamed:
112
                self.assertTrue(expected_renamed_entry in renamed_files,
113
                    "%s is not renamed, %s are" % (str(expected_renamed_entry),
114
                        renamed_files))
115
        if expected_added is not None:
116
            self.assertEquals(len(added), len(expected_added),
117
                "%s is added" % str(added))
118
            added_files = [(item[0],) for item in added]
119
            for expected_added_entry in expected_added:
120
                self.assertTrue(expected_added_entry in added_files,
121
                    "%s is not added, %s are" % (str(expected_added_entry),
122
                        added_files))
123
        if expected_removed is not None:
124
            self.assertEquals(len(removed), len(expected_removed),
125
                "%s is removed" % str(removed))
126
            removed_files = [(item[0],) for item in removed]
127
            for expected_removed_entry in expected_removed:
128
                self.assertTrue(expected_removed_entry in removed_files,
129
                    "%s is not removed, %s are" % (str(expected_removed_entry),
130
                        removed_files))
131
        if expected_modified is not None:
132
            self.assertEquals(len(modified), len(expected_modified),
133
                "%s is modified" % str(modified))
134
            modified_files = [(item[0],) for item in modified]
135
            for expected_modified_entry in expected_modified:
136
                self.assertTrue(expected_modified_entry in modified_files,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
137
                    "%s is not modified, %s are" % (
138
                    str(expected_modified_entry), modified_files))
139
        if expected_kind_changed is not None:
140
            self.assertEquals(len(kind_changed), len(expected_kind_changed),
141
                "%s is kind-changed, expected %s" % (kind_changed,
142
                    expected_kind_changed))
143
            kind_changed_files = [(item[0], item[2], item[3])
144
                for item in kind_changed]
145
            for expected_kind_changed_entry in expected_kind_changed:
146
                self.assertTrue(expected_kind_changed_entry in
147
                    kind_changed_files, "%s is not kind-changed, %s are" % (
148
                    str(expected_kind_changed_entry), kind_changed_files))
0.65.4 by James Westby
Make the rename handling more robust.
149
0.80.1 by Ian Clatworthy
basic units tests for filemodify
150
    def assertContent(self, branch, tree, path, content):
151
        file_id = tree.inventory.path2id(path)
152
        branch.lock_read()
153
        self.addCleanup(branch.unlock)
154
        self.assertEqual(tree.get_file_text(file_id), content)
155
156
    def assertSymlinkTarget(self, branch, tree, path, target):
157
        file_id = tree.inventory.path2id(path)
158
        branch.lock_read()
159
        self.addCleanup(branch.unlock)
160
        self.assertEqual(tree.get_symlink_target(file_id), target)
161
0.80.4 by Ian Clatworthy
file executable off <-> on tests
162
    def assertExecutable(self, branch, tree, path, executable):
163
        file_id = tree.inventory.path2id(path)
164
        branch.lock_read()
165
        self.addCleanup(branch.unlock)
166
        self.assertEqual(tree.is_executable(file_id), executable)
167
0.80.1 by Ian Clatworthy
basic units tests for filemodify
168
    def assertRevisionRoot(self, revtree, path):
169
        self.assertEqual(revtree.get_revision_id(),
170
                         revtree.inventory.root.children[path].revision)
171
172
173
class TestModify(TestCaseForGenericProcessor):
174
0.80.3 by Ian Clatworthy
file <-> symlink change tests
175
    def file_command_iter(self, path, kind='file', content='aaa',
0.80.4 by Ian Clatworthy
file executable off <-> on tests
176
        executable=False, to_kind=None, to_content='bbb', to_executable=None):
177
        # Revno 1: create a file or symlink
178
        # Revno 2: modify it
0.80.3 by Ian Clatworthy
file <-> symlink change tests
179
        if to_kind is None:
180
            to_kind = kind
0.80.4 by Ian Clatworthy
file executable off <-> on tests
181
        if to_executable is None:
182
            to_executable = executable
0.80.1 by Ian Clatworthy
basic units tests for filemodify
183
        def command_list():
184
            author = ['', 'bugs@a.com', time.time(), time.timezone]
185
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
186
            def files_one():
0.80.4 by Ian Clatworthy
file executable off <-> on tests
187
                yield commands.FileModifyCommand(path, kind, executable,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
188
                        None, content)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
189
            yield commands.CommitCommand('head', '1', author,
190
                committer, "commit 1", None, [], files_one)
191
            def files_two():
0.80.4 by Ian Clatworthy
file executable off <-> on tests
192
                yield commands.FileModifyCommand(path, to_kind, to_executable,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
193
                        None, to_content)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
194
            yield commands.CommitCommand('head', '2', author,
195
                committer, "commit 2", ":1", [], files_two)
196
        return command_list
197
198
    def test_modify_file_in_root(self):
199
        handler, branch = self.get_handler()
200
        path = 'a'
201
        handler.process(self.file_command_iter(path))
202
        revtree0, revtree1 = self.assertChanges(branch, 1,
203
            expected_added=[(path,)])
204
        revtree1, revtree2 = self.assertChanges(branch, 2,
205
            expected_modified=[(path,)])
206
        self.assertContent(branch, revtree1, path, "aaa")
207
        self.assertContent(branch, revtree2, path, "bbb")
208
        self.assertRevisionRoot(revtree1, path)
209
        self.assertRevisionRoot(revtree2, path)
210
211
    def test_modify_file_in_subdir(self):
212
        handler, branch = self.get_handler()
213
        path = 'a/a'
214
        handler.process(self.file_command_iter(path))
215
        revtree0, revtree1 = self.assertChanges(branch, 1,
216
            expected_added=[('a',), (path,)])
217
        revtree1, revtree2 = self.assertChanges(branch, 2,
218
            expected_modified=[(path,)])
219
        self.assertContent(branch, revtree1, path, "aaa")
220
        self.assertContent(branch, revtree2, path, "bbb")
221
222
    def test_modify_symlink_in_root(self):
223
        handler, branch = self.get_handler()
224
        path = 'a'
225
        handler.process(self.file_command_iter(path, kind='symlink'))
226
        revtree1, revtree2 = self.assertChanges(branch, 2,
227
            expected_modified=[(path,)])
228
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
229
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
230
        self.assertRevisionRoot(revtree1, path)
231
        self.assertRevisionRoot(revtree2, path)
232
233
    def test_modify_symlink_in_subdir(self):
234
        handler, branch = self.get_handler()
235
        path = 'a/a'
236
        handler.process(self.file_command_iter(path, kind='symlink'))
237
        revtree0, revtree1 = self.assertChanges(branch, 1,
238
            expected_added=[('a',), (path,)])
239
        revtree1, revtree2 = self.assertChanges(branch, 2,
240
            expected_modified=[(path,)])
241
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
242
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
243
0.80.3 by Ian Clatworthy
file <-> symlink change tests
244
    def test_modify_file_becomes_symlink(self):
245
        handler, branch = self.get_handler()
246
        path = 'a/a'
247
        handler.process(self.file_command_iter(path,
248
            kind='file', to_kind='symlink'))
249
        revtree0, revtree1 = self.assertChanges(branch, 1,
250
            expected_added=[('a',), (path,)])
251
        revtree1, revtree2 = self.assertChanges(branch, 2,
252
            expected_kind_changed=[(path, 'file', 'symlink')])
253
        self.assertContent(branch, revtree1, path, "aaa")
254
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
255
256
    def test_modify_symlink_becomes_file(self):
257
        handler, branch = self.get_handler()
258
        path = 'a/a'
259
        handler.process(self.file_command_iter(path,
260
            kind='symlink', to_kind='file'))
261
        revtree0, revtree1 = self.assertChanges(branch, 1,
262
            expected_added=[('a',), (path,)])
263
        revtree1, revtree2 = self.assertChanges(branch, 2,
264
            expected_kind_changed=[(path, 'symlink', 'file')])
265
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
266
        self.assertContent(branch, revtree2, path, "bbb")
267
0.80.4 by Ian Clatworthy
file executable off <-> on tests
268
    def test_modify_file_now_executable(self):
269
        handler, branch = self.get_handler()
270
        path = 'a/a'
271
        handler.process(self.file_command_iter(path,
272
            executable=False, to_executable=True, to_content='aaa'))
273
        revtree0, revtree1 = self.assertChanges(branch, 1,
274
            expected_added=[('a',), (path,)])
275
        revtree1, revtree2 = self.assertChanges(branch, 2,
276
            expected_modified=[(path,)])
277
        self.assertExecutable(branch, revtree1, path, False)
278
        self.assertExecutable(branch, revtree2, path, True)
279
280
    def test_modify_file_no_longer_executable(self):
281
        handler, branch = self.get_handler()
282
        path = 'a/a'
283
        handler.process(self.file_command_iter(path,
284
            executable=True, to_executable=False, to_content='aaa'))
285
        revtree0, revtree1 = self.assertChanges(branch, 1,
286
            expected_added=[('a',), (path,)])
287
        revtree1, revtree2 = self.assertChanges(branch, 2,
288
            expected_modified=[(path,)])
289
        self.assertExecutable(branch, revtree1, path, True)
290
        self.assertExecutable(branch, revtree2, path, False)
291
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
292
0.80.5 by Ian Clatworthy
file/symlink <-> directory change tests & fix
293
class TestModifyTricky(TestCaseForGenericProcessor):
294
295
    def file_command_iter(self, path1, path2, kind='file'):
296
        # Revno 1: create a file or symlink in a directory
297
        # Revno 2: create a second file that implicitly deletes the
298
        # first one because either:
299
        # * the new file is a in directory with the old file name
300
        # * the new file has the same name as the directory of the first
301
        def command_list():
302
            author = ['', 'bugs@a.com', time.time(), time.timezone]
303
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
304
            def files_one():
305
                yield commands.FileModifyCommand(path1, kind, False,
306
                        None, "aaa")
307
            yield commands.CommitCommand('head', '1', author,
308
                committer, "commit 1", None, [], files_one)
309
            def files_two():
310
                yield commands.FileModifyCommand(path2, kind, False,
311
                        None, "bbb")
312
            yield commands.CommitCommand('head', '2', author,
313
                committer, "commit 2", ":1", [], files_two)
314
        return command_list
315
316
317
    def test_modify_file_becomes_directory(self):
318
        handler, branch = self.get_handler()
319
        path1 = 'a/b'
320
        path2 = 'a/b/c'
321
        handler.process(self.file_command_iter(path1, path2))
322
        revtree0, revtree1 = self.assertChanges(branch, 1,
323
            expected_added=[('a',), (path1,)])
324
        revtree1, revtree2 = self.assertChanges(branch, 2,
325
            expected_added=[(path2,)],
326
            expected_kind_changed=[(path1, 'file', 'directory')])
327
        self.assertContent(branch, revtree1, path1, "aaa")
328
        self.assertContent(branch, revtree2, path2, "bbb")
329
330
    def test_modify_directory_becomes_file(self):
331
        handler, branch = self.get_handler()
332
        path1 = 'a/b/c'
333
        path2 = 'a/b'
334
        handler.process(self.file_command_iter(path1, path2))
335
        revtree0, revtree1 = self.assertChanges(branch, 1,
336
            expected_added=[('a',), ('a/b',), (path1,)])
337
        revtree1, revtree2 = self.assertChanges(branch, 2,
338
            expected_removed=[(path1,),],
339
            expected_kind_changed=[(path2, 'directory', 'file')])
340
        self.assertContent(branch, revtree1, path1, "aaa")
341
        self.assertContent(branch, revtree2, path2, "bbb")
342
343
    def test_modify_symlink_becomes_directory(self):
344
        handler, branch = self.get_handler()
345
        path1 = 'a/b'
346
        path2 = 'a/b/c'
347
        handler.process(self.file_command_iter(path1, path2, 'symlink'))
348
        revtree0, revtree1 = self.assertChanges(branch, 1,
349
            expected_added=[('a',), (path1,)])
350
        revtree1, revtree2 = self.assertChanges(branch, 2,
351
            expected_added=[(path2,)],
352
            expected_kind_changed=[(path1, 'symlink', 'directory')])
353
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
354
        self.assertSymlinkTarget(branch, revtree2, path2, "bbb")
355
356
    def test_modify_directory_becomes_symlink(self):
357
        handler, branch = self.get_handler()
358
        path1 = 'a/b/c'
359
        path2 = 'a/b'
360
        handler.process(self.file_command_iter(path1, path2, 'symlink'))
361
        revtree0, revtree1 = self.assertChanges(branch, 1,
362
            expected_added=[('a',), ('a/b',), (path1,)])
363
        revtree1, revtree2 = self.assertChanges(branch, 2,
364
            expected_removed=[(path1,),],
365
            expected_kind_changed=[(path2, 'directory', 'symlink')])
366
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
367
        self.assertSymlinkTarget(branch, revtree2, path2, "bbb")
368
369
0.80.2 by Ian Clatworthy
basic delete tests
370
class TestDelete(TestCaseForGenericProcessor):
371
372
    def file_command_iter(self, path, kind='file'):
0.80.4 by Ian Clatworthy
file executable off <-> on tests
373
        # Revno 1: create a file or symlink
374
        # Revno 2: delete it
0.80.2 by Ian Clatworthy
basic delete tests
375
        def command_list():
376
            author = ['', 'bugs@a.com', time.time(), time.timezone]
377
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
378
            def files_one():
379
                yield commands.FileModifyCommand(path, kind, False,
380
                        None, "aaa")
381
            yield commands.CommitCommand('head', '1', author,
382
                committer, "commit 1", None, [], files_one)
383
            def files_two():
384
                yield commands.FileDeleteCommand(path)
385
            yield commands.CommitCommand('head', '2', author,
386
                committer, "commit 2", ":1", [], files_two)
387
        return command_list
388
389
    def test_delete_file_in_root(self):
390
        handler, branch = self.get_handler()
391
        path = 'a'
392
        handler.process(self.file_command_iter(path))
393
        revtree0, revtree1 = self.assertChanges(branch, 1,
394
            expected_added=[(path,)])
395
        revtree1, revtree2 = self.assertChanges(branch, 2,
396
            expected_removed=[(path,)])
397
        self.assertContent(branch, revtree1, path, "aaa")
398
        self.assertRevisionRoot(revtree1, path)
399
400
    def test_delete_file_in_subdir(self):
401
        handler, branch = self.get_handler()
402
        path = 'a/a'
403
        handler.process(self.file_command_iter(path))
404
        revtree0, revtree1 = self.assertChanges(branch, 1,
405
            expected_added=[('a',), (path,)])
406
        revtree1, revtree2 = self.assertChanges(branch, 2,
407
            expected_removed=[(path,)])
408
        self.assertContent(branch, revtree1, path, "aaa")
409
410
    def test_delete_symlink_in_root(self):
411
        handler, branch = self.get_handler()
412
        path = 'a'
413
        handler.process(self.file_command_iter(path, kind='symlink'))
414
        revtree1, revtree2 = self.assertChanges(branch, 2,
415
            expected_removed=[(path,)])
416
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
417
        self.assertRevisionRoot(revtree1, path)
418
419
    def test_delete_symlink_in_subdir(self):
420
        handler, branch = self.get_handler()
421
        path = 'a/a'
422
        handler.process(self.file_command_iter(path, kind='symlink'))
423
        revtree0, revtree1 = self.assertChanges(branch, 1,
424
            expected_added=[('a',), (path,)])
425
        revtree1, revtree2 = self.assertChanges(branch, 2,
426
            expected_removed=[(path,)])
427
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
428
429
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
430
class TestRename(TestCaseForGenericProcessor):
431
432
    def get_command_iter(self, old_path, new_path):
0.80.4 by Ian Clatworthy
file executable off <-> on tests
433
        # Revno 1: create a file or symlink
434
        # Revno 2: rename it
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
435
        def command_list():
436
            author = ['', 'bugs@a.com', time.time(), time.timezone]
437
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
438
            def files_one():
439
                yield commands.FileModifyCommand(old_path, 'file', False,
440
                        None, "aaa")
441
            yield commands.CommitCommand('head', '1', author,
442
                committer, "commit 1", None, [], files_one)
443
            def files_two():
444
                yield commands.FileRenameCommand(old_path, new_path)
445
            yield commands.CommitCommand('head', '2', author,
446
                committer, "commit 2", ":1", [], files_two)
447
        return command_list
448
0.65.4 by James Westby
Make the rename handling more robust.
449
    def test_rename_in_root(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
450
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
451
        old_path = 'a'
452
        new_path = 'b'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
453
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
454
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
455
            expected_renamed=[(old_path, new_path)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
456
        self.assertRevisionRoot(revtree1, old_path)
457
        self.assertRevisionRoot(revtree2, new_path)
0.65.4 by James Westby
Make the rename handling more robust.
458
459
    def test_rename_in_subdir(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
460
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
461
        old_path = 'a/a'
462
        new_path = 'a/b'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
463
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
464
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)])
0.65.4 by James Westby
Make the rename handling more robust.
465
466
    def test_move_to_new_dir(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
467
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
468
        old_path = 'a/a'
469
        new_path = 'b/a'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
470
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
471
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)],
0.65.4 by James Westby
Make the rename handling more robust.
472
            expected_added=[('b',)])
0.64.74 by Ian Clatworthy
fix symlink importing
473
474
0.80.6 by Ian Clatworthy
file/symlink <-> directory rename tests
475
class TestRenameTricky(TestCaseForGenericProcessor):
476
477
    def file_command_iter(self, path1, old_path2, new_path2, kind='file'):
478
        # Revno 1: create two files or symlinks in a directory
479
        # Revno 2: rename the second file so that it implicitly deletes the
480
        # first one because either:
481
        # * the new file is a in directory with the old file name
482
        # * the new file has the same name as the directory of the first
483
        def command_list():
484
            author = ['', 'bugs@a.com', time.time(), time.timezone]
485
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
486
            def files_one():
487
                yield commands.FileModifyCommand(path1, kind, False,
488
                        None, "aaa")
489
                yield commands.FileModifyCommand(old_path2, kind, False,
490
                        None, "bbb")
491
            yield commands.CommitCommand('head', '1', author,
492
                committer, "commit 1", None, [], files_one)
493
            def files_two():
494
                yield commands.FileRenameCommand(old_path2, new_path2)
495
            yield commands.CommitCommand('head', '2', author,
496
                committer, "commit 2", ":1", [], files_two)
497
        return command_list
498
499
500
    def test_rename_file_becomes_directory(self):
501
        handler, branch = self.get_handler()
502
        old_path2 = 'foo'
503
        path1     = 'a/b'
504
        new_path2 = 'a/b/c'
505
        handler.process(self.file_command_iter(path1, old_path2, new_path2))
506
        revtree0, revtree1 = self.assertChanges(branch, 1,
507
            expected_added=[('a',), (path1,), (old_path2,)])
508
        revtree1, revtree2 = self.assertChanges(branch, 2,
509
            expected_renamed=[(old_path2, new_path2)],
510
            expected_kind_changed=[(path1, 'file', 'directory')])
511
        self.assertContent(branch, revtree1, path1, "aaa")
512
        self.assertContent(branch, revtree2, new_path2, "bbb")
513
514
    def test_rename_directory_becomes_file(self):
515
        handler, branch = self.get_handler()
516
        old_path2 = 'foo'
517
        path1     = 'a/b/c'
518
        new_path2 = 'a/b'
519
        handler.process(self.file_command_iter(path1, old_path2, new_path2))
520
        revtree0, revtree1 = self.assertChanges(branch, 1,
521
            expected_added=[('a',), ('a/b',), (path1,), (old_path2,)])
522
        revtree1, revtree2 = self.assertChanges(branch, 2,
523
            expected_renamed=[(old_path2, new_path2)],
524
            expected_removed=[(path1,), (new_path2,)])
525
        self.assertContent(branch, revtree1, path1, "aaa")
526
        self.assertContent(branch, revtree2, new_path2, "bbb")
527
528
    def test_rename_symlink_becomes_directory(self):
529
        handler, branch = self.get_handler()
530
        old_path2 = 'foo'
531
        path1     = 'a/b'
532
        new_path2 = 'a/b/c'
533
        handler.process(self.file_command_iter(path1, old_path2, new_path2,
534
            'symlink'))
535
        revtree0, revtree1 = self.assertChanges(branch, 1,
536
            expected_added=[('a',), (path1,), (old_path2,)])
537
        revtree1, revtree2 = self.assertChanges(branch, 2,
538
            expected_renamed=[(old_path2, new_path2)],
539
            expected_kind_changed=[(path1, 'symlink', 'directory')])
540
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
541
        self.assertSymlinkTarget(branch, revtree2, new_path2, "bbb")
542
543
    def test_rename_directory_becomes_symlink(self):
544
        handler, branch = self.get_handler()
545
        old_path2 = 'foo'
546
        path1     = 'a/b/c'
547
        new_path2 = 'a/b'
548
        handler.process(self.file_command_iter(path1, old_path2, new_path2,
549
            'symlink'))
550
        revtree0, revtree1 = self.assertChanges(branch, 1,
551
            expected_added=[('a',), ('a/b',), (path1,), (old_path2,)])
552
        revtree1, revtree2 = self.assertChanges(branch, 2,
553
            expected_renamed=[(old_path2, new_path2)],
554
            expected_removed=[(path1,), (new_path2,)])
555
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
556
        self.assertSymlinkTarget(branch, revtree2, new_path2, "bbb")
557
558
0.76.2 by Ian Clatworthy
code & tests for file copying
559
class TestCopy(TestCaseForGenericProcessor):
560
0.80.1 by Ian Clatworthy
basic units tests for filemodify
561
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.80.4 by Ian Clatworthy
file executable off <-> on tests
562
        # Revno 1: create a file or symlink
563
        # Revno 2: copy it
0.76.2 by Ian Clatworthy
code & tests for file copying
564
        def command_list():
565
            author = ['', 'bugs@a.com', time.time(), time.timezone]
566
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
567
            def files_one():
0.80.1 by Ian Clatworthy
basic units tests for filemodify
568
                yield commands.FileModifyCommand(src_path, kind, False,
0.76.2 by Ian Clatworthy
code & tests for file copying
569
                        None, "aaa")
570
            yield commands.CommitCommand('head', '1', author,
571
                committer, "commit 1", None, [], files_one)
572
            def files_two():
573
                yield commands.FileCopyCommand(src_path, dest_path)
574
            yield commands.CommitCommand('head', '2', author,
575
                committer, "commit 2", ":1", [], files_two)
576
        return command_list
577
578
    def test_copy_file_in_root(self):
579
        handler, branch = self.get_handler()
580
        src_path = 'a'
581
        dest_path = 'b'
582
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
583
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
584
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
585
        self.assertContent(branch, revtree1, src_path, "aaa")
586
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
587
        self.assertContent(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
588
        self.assertRevisionRoot(revtree1, src_path)
589
        self.assertRevisionRoot(revtree2, dest_path)
0.76.2 by Ian Clatworthy
code & tests for file copying
590
591
    def test_copy_file_in_subdir(self):
592
        handler, branch = self.get_handler()
593
        src_path = 'a/a'
594
        dest_path = 'a/b'
595
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
596
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
597
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
598
        self.assertContent(branch, revtree1, src_path, "aaa")
599
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
600
        self.assertContent(branch, revtree2, dest_path, "aaa")
601
602
    def test_copy_file_to_new_dir(self):
603
        handler, branch = self.get_handler()
604
        src_path = 'a/a'
605
        dest_path = 'b/a'
606
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
607
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
608
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
609
        self.assertContent(branch, revtree1, src_path, "aaa")
610
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
611
        self.assertContent(branch, revtree2, dest_path, "aaa")
612
0.76.3 by Ian Clatworthy
symlink copying tests
613
    def test_copy_symlink_in_root(self):
614
        handler, branch = self.get_handler()
615
        src_path = 'a'
616
        dest_path = 'b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
617
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
618
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
619
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
620
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
621
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
622
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
623
        self.assertRevisionRoot(revtree1, src_path)
624
        self.assertRevisionRoot(revtree2, dest_path)
0.76.3 by Ian Clatworthy
symlink copying tests
625
626
    def test_copy_symlink_in_subdir(self):
627
        handler, branch = self.get_handler()
628
        src_path = 'a/a'
629
        dest_path = 'a/b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
630
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
631
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
632
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
633
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
634
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
635
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
636
637
    def test_copy_symlink_to_new_dir(self):
638
        handler, branch = self.get_handler()
639
        src_path = 'a/a'
640
        dest_path = 'b/a'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
641
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
642
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
643
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
644
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
645
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
646
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
647
0.76.2 by Ian Clatworthy
code & tests for file copying
648
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
649
class TestFileKinds(TestCaseForGenericProcessor):
0.64.74 by Ian Clatworthy
fix symlink importing
650
651
    def get_command_iter(self, path, kind, content):
652
        def command_list():
653
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
654
            def files_one():
655
                yield commands.FileModifyCommand(path, kind, False,
656
                        None, content)
657
            yield commands.CommitCommand('head', '1', None,
658
                committer, "commit 1", None, [], files_one)
659
        return command_list
660
661
    def test_import_plainfile(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
662
        handler, branch = self.get_handler()
663
        handler.process(self.get_command_iter('foo', 'file', 'aaa'))
0.64.74 by Ian Clatworthy
fix symlink importing
664
665
    def test_import_symlink(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
666
        handler, branch = self.get_handler()
667
        handler.process(self.get_command_iter('foo', 'symlink', 'bar'))