/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
    tests,
21
    )
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
22
from bzrlib.plugins.fastimport.helpers import (
23
    kind_to_mode,
24
    )
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
25
from bzrlib.plugins.fastimport.tests import (
26
    FastimportFeature,
0.65.4 by James Westby
Make the rename handling more robust.
27
    )
28
0.123.14 by Jelmer Vernooij
Simplify imports in case fastimport is not installed.
29
try:
30
    from fastimport import commands
31
except ImportError:
32
    commands = object()
33
0.65.4 by James Westby
Make the rename handling more robust.
34
0.115.2 by John Arbash Meinel
Change to multiplying tests rather than manually.
35
def load_tests(standard_tests, module, loader):
36
    """Parameterize tests for all versions of groupcompress."""
37
    scenarios = [
38
        ('pack-0.92', {'branch_format': 'pack-0.92'}),
39
        ('1.9-rich-root', {'branch_format': '1.9-rich-root'}),
40
    ]
41
    try:
42
        from bzrlib.repofmt.groupcompress_repo import RepositoryFormat2a
43
        scenarios.append(('2a', {'branch_format': '2a'}))
44
    except ImportError:
45
        pass
46
    suite = loader.suiteClass()
47
    result = tests.multiply_tests(standard_tests, scenarios, suite)
48
    return result
49
50
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
51
class TestCaseForGenericProcessor(tests.TestCaseWithTransport):
0.65.4 by James Westby
Make the rename handling more robust.
52
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
53
    _test_needs_features = [FastimportFeature]
54
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
55
    branch_format = "pack-0.92"
56
0.65.4 by James Westby
Make the rename handling more robust.
57
    def get_handler(self):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
58
        from bzrlib.plugins.fastimport.processors import (
59
            generic_processor,
60
            )
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
61
        branch = self.make_branch('.', format=self.branch_format)
0.96.1 by Ian Clatworthy
update existing tests to reflect implicit directory pruning bahaviour
62
        handler = generic_processor.GenericProcessor(branch.bzrdir)
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
63
        return handler, branch
0.65.4 by James Westby
Make the rename handling more robust.
64
65
    # FIXME: [] as a default is bad, as it is mutable, but I want
66
    # to use None to mean "don't check this".
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
67
    def assertChanges(self, branch, revno, expected_added=[],
68
            expected_removed=[], expected_modified=[],
0.80.3 by Ian Clatworthy
file <-> symlink change tests
69
            expected_renamed=[], expected_kind_changed=[]):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
70
        """Check the changes introduced in a revision of a branch.
71
72
        This method checks that a revision introduces expected changes.
73
        The required changes are passed in as a list, where
74
        each entry contains the needed information about the change.
75
76
        If you do not wish to assert anything about a particular
77
        category then pass None instead.
78
79
        branch: The branch.
80
        revno: revision number of revision to check.
81
        expected_added: a list of (filename,) tuples that must have
82
            been added in the delta.
83
        expected_removed: a list of (filename,) tuples that must have
84
            been removed in the delta.
85
        expected_modified: a list of (filename,) tuples that must have
86
            been modified in the delta.
87
        expected_renamed: a list of (old_path, new_path) tuples that
88
            must have been renamed in the delta.
0.80.3 by Ian Clatworthy
file <-> symlink change tests
89
        expected_kind_changed: a list of (path, old_kind, new_kind) tuples
90
            that must have been changed in the delta.
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
91
        :return: revtree1, revtree2
92
        """
93
        repo = branch.repository
0.80.1 by Ian Clatworthy
basic units tests for filemodify
94
        revtree1 = repo.revision_tree(branch.get_rev_id(revno - 1))
95
        revtree2 = repo.revision_tree(branch.get_rev_id(revno))
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
96
        changes = revtree2.changes_from(revtree1)
0.80.3 by Ian Clatworthy
file <-> symlink change tests
97
        self._check_changes(changes, expected_added, expected_removed,
98
            expected_modified, expected_renamed, expected_kind_changed)
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
99
        return revtree1, revtree2
100
0.80.3 by Ian Clatworthy
file <-> symlink change tests
101
    def _check_changes(self, changes, expected_added=[],
0.65.4 by James Westby
Make the rename handling more robust.
102
            expected_removed=[], expected_modified=[],
0.80.3 by Ian Clatworthy
file <-> symlink change tests
103
            expected_renamed=[], expected_kind_changed=[]):
0.65.4 by James Westby
Make the rename handling more robust.
104
        """Check the changes in a TreeDelta
105
106
        This method checks that the TreeDelta contains the expected
107
        modifications between the two trees that were used to generate
108
        it. The required changes are passed in as a list, where
109
        each entry contains the needed information about the change.
110
111
        If you do not wish to assert anything about a particular
112
        category then pass None instead.
113
114
        changes: The TreeDelta to check.
115
        expected_added: a list of (filename,) tuples that must have
116
            been added in the delta.
117
        expected_removed: a list of (filename,) tuples that must have
118
            been removed in the delta.
119
        expected_modified: a list of (filename,) tuples that must have
120
            been modified in the delta.
121
        expected_renamed: a list of (old_path, new_path) tuples that
122
            must have been renamed in the delta.
0.80.3 by Ian Clatworthy
file <-> symlink change tests
123
        expected_kind_changed: a list of (path, old_kind, new_kind) tuples
124
            that must have been changed in the delta.
0.65.4 by James Westby
Make the rename handling more robust.
125
        """
126
        renamed = changes.renamed
127
        added = changes.added
128
        removed = changes.removed
129
        modified = changes.modified
0.80.3 by Ian Clatworthy
file <-> symlink change tests
130
        kind_changed = changes.kind_changed
0.65.4 by James Westby
Make the rename handling more robust.
131
        if expected_renamed is not None:
132
            self.assertEquals(len(renamed), len(expected_renamed),
0.74.1 by John Arbash Meinel
Change the rename code to create a new text entry.
133
                "%s is renamed, expected %s" % (renamed, expected_renamed))
0.65.4 by James Westby
Make the rename handling more robust.
134
            renamed_files = [(item[0], item[1]) for item in renamed]
135
            for expected_renamed_entry in expected_renamed:
136
                self.assertTrue(expected_renamed_entry in renamed_files,
137
                    "%s is not renamed, %s are" % (str(expected_renamed_entry),
138
                        renamed_files))
139
        if expected_added is not None:
140
            self.assertEquals(len(added), len(expected_added),
141
                "%s is added" % str(added))
142
            added_files = [(item[0],) for item in added]
143
            for expected_added_entry in expected_added:
144
                self.assertTrue(expected_added_entry in added_files,
145
                    "%s is not added, %s are" % (str(expected_added_entry),
146
                        added_files))
147
        if expected_removed is not None:
148
            self.assertEquals(len(removed), len(expected_removed),
149
                "%s is removed" % str(removed))
150
            removed_files = [(item[0],) for item in removed]
151
            for expected_removed_entry in expected_removed:
152
                self.assertTrue(expected_removed_entry in removed_files,
153
                    "%s is not removed, %s are" % (str(expected_removed_entry),
154
                        removed_files))
155
        if expected_modified is not None:
156
            self.assertEquals(len(modified), len(expected_modified),
157
                "%s is modified" % str(modified))
158
            modified_files = [(item[0],) for item in modified]
159
            for expected_modified_entry in expected_modified:
160
                self.assertTrue(expected_modified_entry in modified_files,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
161
                    "%s is not modified, %s are" % (
162
                    str(expected_modified_entry), modified_files))
163
        if expected_kind_changed is not None:
164
            self.assertEquals(len(kind_changed), len(expected_kind_changed),
165
                "%s is kind-changed, expected %s" % (kind_changed,
166
                    expected_kind_changed))
167
            kind_changed_files = [(item[0], item[2], item[3])
168
                for item in kind_changed]
169
            for expected_kind_changed_entry in expected_kind_changed:
170
                self.assertTrue(expected_kind_changed_entry in
171
                    kind_changed_files, "%s is not kind-changed, %s are" % (
172
                    str(expected_kind_changed_entry), kind_changed_files))
0.65.4 by James Westby
Make the rename handling more robust.
173
0.80.1 by Ian Clatworthy
basic units tests for filemodify
174
    def assertContent(self, branch, tree, path, content):
175
        file_id = tree.inventory.path2id(path)
176
        branch.lock_read()
177
        self.addCleanup(branch.unlock)
178
        self.assertEqual(tree.get_file_text(file_id), content)
179
180
    def assertSymlinkTarget(self, branch, tree, path, target):
181
        file_id = tree.inventory.path2id(path)
182
        branch.lock_read()
183
        self.addCleanup(branch.unlock)
184
        self.assertEqual(tree.get_symlink_target(file_id), target)
185
0.80.4 by Ian Clatworthy
file executable off <-> on tests
186
    def assertExecutable(self, branch, tree, path, executable):
187
        file_id = tree.inventory.path2id(path)
188
        branch.lock_read()
189
        self.addCleanup(branch.unlock)
190
        self.assertEqual(tree.is_executable(file_id), executable)
191
0.80.1 by Ian Clatworthy
basic units tests for filemodify
192
    def assertRevisionRoot(self, revtree, path):
193
        self.assertEqual(revtree.get_revision_id(),
194
                         revtree.inventory.root.children[path].revision)
195
196
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
197
class TestImportToPackModify(TestCaseForGenericProcessor):
0.80.1 by Ian Clatworthy
basic units tests for filemodify
198
0.80.3 by Ian Clatworthy
file <-> symlink change tests
199
    def file_command_iter(self, path, kind='file', content='aaa',
0.80.4 by Ian Clatworthy
file executable off <-> on tests
200
        executable=False, to_kind=None, to_content='bbb', to_executable=None):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
201
0.80.4 by Ian Clatworthy
file executable off <-> on tests
202
        # Revno 1: create a file or symlink
203
        # Revno 2: modify it
0.80.3 by Ian Clatworthy
file <-> symlink change tests
204
        if to_kind is None:
205
            to_kind = kind
0.80.4 by Ian Clatworthy
file executable off <-> on tests
206
        if to_executable is None:
207
            to_executable = executable
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
208
        mode = kind_to_mode(kind, executable)
209
        to_mode = kind_to_mode(to_kind, to_executable)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
210
        def command_list():
211
            author = ['', 'bugs@a.com', time.time(), time.timezone]
212
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
213
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
214
                yield commands.FileModifyCommand(path, mode, None, content)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
215
            yield commands.CommitCommand('head', '1', author,
216
                committer, "commit 1", None, [], files_one)
217
            def files_two():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
218
                yield commands.FileModifyCommand(path, to_mode, None, to_content)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
219
            yield commands.CommitCommand('head', '2', author,
220
                committer, "commit 2", ":1", [], files_two)
221
        return command_list
222
223
    def test_modify_file_in_root(self):
224
        handler, branch = self.get_handler()
225
        path = 'a'
226
        handler.process(self.file_command_iter(path))
227
        revtree0, revtree1 = self.assertChanges(branch, 1,
228
            expected_added=[(path,)])
229
        revtree1, revtree2 = self.assertChanges(branch, 2,
230
            expected_modified=[(path,)])
231
        self.assertContent(branch, revtree1, path, "aaa")
232
        self.assertContent(branch, revtree2, path, "bbb")
233
        self.assertRevisionRoot(revtree1, path)
234
        self.assertRevisionRoot(revtree2, path)
235
236
    def test_modify_file_in_subdir(self):
237
        handler, branch = self.get_handler()
238
        path = 'a/a'
239
        handler.process(self.file_command_iter(path))
240
        revtree0, revtree1 = self.assertChanges(branch, 1,
241
            expected_added=[('a',), (path,)])
242
        revtree1, revtree2 = self.assertChanges(branch, 2,
243
            expected_modified=[(path,)])
244
        self.assertContent(branch, revtree1, path, "aaa")
245
        self.assertContent(branch, revtree2, path, "bbb")
246
247
    def test_modify_symlink_in_root(self):
248
        handler, branch = self.get_handler()
249
        path = 'a'
250
        handler.process(self.file_command_iter(path, kind='symlink'))
251
        revtree1, revtree2 = self.assertChanges(branch, 2,
252
            expected_modified=[(path,)])
253
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
254
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
255
        self.assertRevisionRoot(revtree1, path)
256
        self.assertRevisionRoot(revtree2, path)
257
258
    def test_modify_symlink_in_subdir(self):
259
        handler, branch = self.get_handler()
260
        path = 'a/a'
261
        handler.process(self.file_command_iter(path, kind='symlink'))
262
        revtree0, revtree1 = self.assertChanges(branch, 1,
263
            expected_added=[('a',), (path,)])
264
        revtree1, revtree2 = self.assertChanges(branch, 2,
265
            expected_modified=[(path,)])
266
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
267
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
268
0.80.3 by Ian Clatworthy
file <-> symlink change tests
269
    def test_modify_file_becomes_symlink(self):
270
        handler, branch = self.get_handler()
271
        path = 'a/a'
272
        handler.process(self.file_command_iter(path,
273
            kind='file', to_kind='symlink'))
274
        revtree0, revtree1 = self.assertChanges(branch, 1,
275
            expected_added=[('a',), (path,)])
276
        revtree1, revtree2 = self.assertChanges(branch, 2,
277
            expected_kind_changed=[(path, 'file', 'symlink')])
278
        self.assertContent(branch, revtree1, path, "aaa")
279
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
280
281
    def test_modify_symlink_becomes_file(self):
282
        handler, branch = self.get_handler()
283
        path = 'a/a'
284
        handler.process(self.file_command_iter(path,
285
            kind='symlink', to_kind='file'))
286
        revtree0, revtree1 = self.assertChanges(branch, 1,
287
            expected_added=[('a',), (path,)])
288
        revtree1, revtree2 = self.assertChanges(branch, 2,
289
            expected_kind_changed=[(path, 'symlink', 'file')])
290
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
291
        self.assertContent(branch, revtree2, path, "bbb")
292
0.80.4 by Ian Clatworthy
file executable off <-> on tests
293
    def test_modify_file_now_executable(self):
294
        handler, branch = self.get_handler()
295
        path = 'a/a'
296
        handler.process(self.file_command_iter(path,
297
            executable=False, to_executable=True, to_content='aaa'))
298
        revtree0, revtree1 = self.assertChanges(branch, 1,
299
            expected_added=[('a',), (path,)])
300
        revtree1, revtree2 = self.assertChanges(branch, 2,
301
            expected_modified=[(path,)])
302
        self.assertExecutable(branch, revtree1, path, False)
303
        self.assertExecutable(branch, revtree2, path, True)
304
305
    def test_modify_file_no_longer_executable(self):
306
        handler, branch = self.get_handler()
307
        path = 'a/a'
308
        handler.process(self.file_command_iter(path,
309
            executable=True, to_executable=False, to_content='aaa'))
310
        revtree0, revtree1 = self.assertChanges(branch, 1,
311
            expected_added=[('a',), (path,)])
312
        revtree1, revtree2 = self.assertChanges(branch, 2,
313
            expected_modified=[(path,)])
314
        self.assertExecutable(branch, revtree1, path, True)
315
        self.assertExecutable(branch, revtree2, path, False)
316
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
317
0.99.5 by Ian Clatworthy
handle adding the same file twice in the one commit
318
class TestImportToPackModifyTwice(TestCaseForGenericProcessor):
319
    """This tests when the same file is modified twice in the one commit.
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
320
0.99.5 by Ian Clatworthy
handle adding the same file twice in the one commit
321
    Note: hg-fast-export produces data like this on occasions.
322
    """
323
324
    def file_command_iter(self, path, kind='file', content='aaa',
325
        executable=False, to_kind=None, to_content='bbb', to_executable=None):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
326
0.99.5 by Ian Clatworthy
handle adding the same file twice in the one commit
327
        # Revno 1: create a file twice
328
        if to_kind is None:
329
            to_kind = kind
330
        if to_executable is None:
331
            to_executable = executable
332
        def command_list():
333
            author = ['', 'bugs@a.com', time.time(), time.timezone]
334
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
335
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
336
                yield commands.FileModifyCommand(path, kind_to_mode(kind, executable),
0.99.5 by Ian Clatworthy
handle adding the same file twice in the one commit
337
                        None, content)
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
338
                yield commands.FileModifyCommand(path, kind_to_mode(to_kind, to_executable),
0.99.5 by Ian Clatworthy
handle adding the same file twice in the one commit
339
                        None, to_content)
340
            yield commands.CommitCommand('head', '1', author,
341
                committer, "commit 1", None, [], files_one)
342
        return command_list
343
344
    def test_modify_file_twice_in_root(self):
345
        handler, branch = self.get_handler()
346
        path = 'a'
347
        handler.process(self.file_command_iter(path))
348
        revtree0, revtree1 = self.assertChanges(branch, 1,
349
            expected_added=[(path,)])
350
        self.assertContent(branch, revtree1, path, "aaa")
351
        self.assertRevisionRoot(revtree1, path)
352
353
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
354
class TestImportToPackModifyTricky(TestCaseForGenericProcessor):
0.80.5 by Ian Clatworthy
file/symlink <-> directory change tests & fix
355
356
    def file_command_iter(self, path1, path2, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
357
0.80.5 by Ian Clatworthy
file/symlink <-> directory change tests & fix
358
        # Revno 1: create a file or symlink in a directory
359
        # Revno 2: create a second file that implicitly deletes the
360
        # first one because either:
361
        # * the new file is a in directory with the old file name
362
        # * the new file has the same name as the directory of the first
363
        def command_list():
364
            author = ['', 'bugs@a.com', time.time(), time.timezone]
365
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
366
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
367
                yield commands.FileModifyCommand(path1, kind_to_mode(kind, False),
0.80.5 by Ian Clatworthy
file/symlink <-> directory change tests & fix
368
                        None, "aaa")
369
            yield commands.CommitCommand('head', '1', author,
370
                committer, "commit 1", None, [], files_one)
371
            def files_two():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
372
                yield commands.FileModifyCommand(path2, kind_to_mode(kind, False),
0.80.5 by Ian Clatworthy
file/symlink <-> directory change tests & fix
373
                        None, "bbb")
374
            yield commands.CommitCommand('head', '2', author,
375
                committer, "commit 2", ":1", [], files_two)
376
        return command_list
377
378
379
    def test_modify_file_becomes_directory(self):
380
        handler, branch = self.get_handler()
381
        path1 = 'a/b'
382
        path2 = 'a/b/c'
383
        handler.process(self.file_command_iter(path1, path2))
384
        revtree0, revtree1 = self.assertChanges(branch, 1,
385
            expected_added=[('a',), (path1,)])
386
        revtree1, revtree2 = self.assertChanges(branch, 2,
387
            expected_added=[(path2,)],
388
            expected_kind_changed=[(path1, 'file', 'directory')])
389
        self.assertContent(branch, revtree1, path1, "aaa")
390
        self.assertContent(branch, revtree2, path2, "bbb")
391
392
    def test_modify_directory_becomes_file(self):
393
        handler, branch = self.get_handler()
394
        path1 = 'a/b/c'
395
        path2 = 'a/b'
396
        handler.process(self.file_command_iter(path1, path2))
397
        revtree0, revtree1 = self.assertChanges(branch, 1,
398
            expected_added=[('a',), ('a/b',), (path1,)])
399
        revtree1, revtree2 = self.assertChanges(branch, 2,
400
            expected_removed=[(path1,),],
401
            expected_kind_changed=[(path2, 'directory', 'file')])
402
        self.assertContent(branch, revtree1, path1, "aaa")
403
        self.assertContent(branch, revtree2, path2, "bbb")
404
405
    def test_modify_symlink_becomes_directory(self):
406
        handler, branch = self.get_handler()
407
        path1 = 'a/b'
408
        path2 = 'a/b/c'
409
        handler.process(self.file_command_iter(path1, path2, 'symlink'))
410
        revtree0, revtree1 = self.assertChanges(branch, 1,
411
            expected_added=[('a',), (path1,)])
412
        revtree1, revtree2 = self.assertChanges(branch, 2,
413
            expected_added=[(path2,)],
414
            expected_kind_changed=[(path1, 'symlink', 'directory')])
415
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
416
        self.assertSymlinkTarget(branch, revtree2, path2, "bbb")
417
418
    def test_modify_directory_becomes_symlink(self):
419
        handler, branch = self.get_handler()
420
        path1 = 'a/b/c'
421
        path2 = 'a/b'
422
        handler.process(self.file_command_iter(path1, path2, 'symlink'))
423
        revtree0, revtree1 = self.assertChanges(branch, 1,
424
            expected_added=[('a',), ('a/b',), (path1,)])
425
        revtree1, revtree2 = self.assertChanges(branch, 2,
426
            expected_removed=[(path1,),],
427
            expected_kind_changed=[(path2, 'directory', 'symlink')])
428
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
429
        self.assertSymlinkTarget(branch, revtree2, path2, "bbb")
430
431
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
432
class TestImportToPackDelete(TestCaseForGenericProcessor):
0.80.2 by Ian Clatworthy
basic delete tests
433
434
    def file_command_iter(self, path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
435
0.80.4 by Ian Clatworthy
file executable off <-> on tests
436
        # Revno 1: create a file or symlink
437
        # Revno 2: delete it
0.80.2 by Ian Clatworthy
basic delete tests
438
        def command_list():
439
            author = ['', 'bugs@a.com', time.time(), time.timezone]
440
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
441
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
442
                yield commands.FileModifyCommand(path, kind_to_mode(kind, False),
0.80.2 by Ian Clatworthy
basic delete tests
443
                        None, "aaa")
444
            yield commands.CommitCommand('head', '1', author,
445
                committer, "commit 1", None, [], files_one)
446
            def files_two():
447
                yield commands.FileDeleteCommand(path)
448
            yield commands.CommitCommand('head', '2', author,
449
                committer, "commit 2", ":1", [], files_two)
450
        return command_list
451
452
    def test_delete_file_in_root(self):
453
        handler, branch = self.get_handler()
454
        path = 'a'
455
        handler.process(self.file_command_iter(path))
456
        revtree0, revtree1 = self.assertChanges(branch, 1,
457
            expected_added=[(path,)])
458
        revtree1, revtree2 = self.assertChanges(branch, 2,
459
            expected_removed=[(path,)])
460
        self.assertContent(branch, revtree1, path, "aaa")
461
        self.assertRevisionRoot(revtree1, path)
462
463
    def test_delete_file_in_subdir(self):
464
        handler, branch = self.get_handler()
465
        path = 'a/a'
466
        handler.process(self.file_command_iter(path))
467
        revtree0, revtree1 = self.assertChanges(branch, 1,
468
            expected_added=[('a',), (path,)])
469
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.96.1 by Ian Clatworthy
update existing tests to reflect implicit directory pruning bahaviour
470
            expected_removed=[('a',), (path,)])
0.80.2 by Ian Clatworthy
basic delete tests
471
        self.assertContent(branch, revtree1, path, "aaa")
472
473
    def test_delete_symlink_in_root(self):
474
        handler, branch = self.get_handler()
475
        path = 'a'
476
        handler.process(self.file_command_iter(path, kind='symlink'))
477
        revtree1, revtree2 = self.assertChanges(branch, 2,
478
            expected_removed=[(path,)])
479
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
480
        self.assertRevisionRoot(revtree1, path)
481
482
    def test_delete_symlink_in_subdir(self):
483
        handler, branch = self.get_handler()
484
        path = 'a/a'
485
        handler.process(self.file_command_iter(path, kind='symlink'))
486
        revtree0, revtree1 = self.assertChanges(branch, 1,
487
            expected_added=[('a',), (path,)])
488
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.96.1 by Ian Clatworthy
update existing tests to reflect implicit directory pruning bahaviour
489
            expected_removed=[('a',), (path,)])
0.80.2 by Ian Clatworthy
basic delete tests
490
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
491
0.96.2 by Ian Clatworthy
test and fix for implicit directory delete recursing up
492
    def test_delete_file_in_deep_subdir(self):
493
        handler, branch = self.get_handler()
494
        path = 'a/b/c/d'
495
        handler.process(self.file_command_iter(path))
496
        revtree0, revtree1 = self.assertChanges(branch, 1,
497
            expected_added=[('a',), ('a/b',), ('a/b/c',), (path,)])
498
        revtree1, revtree2 = self.assertChanges(branch, 2,
499
            expected_removed=[('a',), ('a/b',), ('a/b/c',), (path,)])
500
        self.assertContent(branch, revtree1, path, "aaa")
501
0.80.2 by Ian Clatworthy
basic delete tests
502
0.99.7 by Ian Clatworthy
handle a delete of a newly added file
503
class TestImportToPackDeleteNew(TestCaseForGenericProcessor):
504
    """Test deletion of a newly added file."""
505
506
    def file_command_iter(self, path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
507
0.99.7 by Ian Clatworthy
handle a delete of a newly added file
508
        # Revno 1: create a file or symlink then delete it
509
        def command_list():
510
            author = ['', 'bugs@a.com', time.time(), time.timezone]
511
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
512
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
513
                yield commands.FileModifyCommand(path, kind_to_mode(kind, False),
0.99.7 by Ian Clatworthy
handle a delete of a newly added file
514
                        None, "aaa")
515
                yield commands.FileDeleteCommand(path)
516
            yield commands.CommitCommand('head', '1', author,
517
                committer, "commit 1", None, [], files_one)
518
        return command_list
519
520
    def test_delete_new_file_in_root(self):
521
        handler, branch = self.get_handler()
522
        path = 'a'
523
        handler.process(self.file_command_iter(path))
524
        revtree0, revtree1 = self.assertChanges(branch, 1,)
525
526
    def test_delete_new_file_in_subdir(self):
527
        handler, branch = self.get_handler()
528
        path = 'a/a'
529
        handler.process(self.file_command_iter(path))
530
        revtree0, revtree1 = self.assertChanges(branch, 1,)
531
532
    def test_delete_new_symlink_in_root(self):
533
        handler, branch = self.get_handler()
534
        path = 'a'
535
        handler.process(self.file_command_iter(path, kind='symlink'))
536
        revtree0, revtree1 = self.assertChanges(branch, 1,)
537
538
    def test_delete_new_symlink_in_subdir(self):
539
        handler, branch = self.get_handler()
540
        path = 'a/a'
541
        handler.process(self.file_command_iter(path, kind='symlink'))
542
        revtree0, revtree1 = self.assertChanges(branch, 1,)
543
544
    def test_delete_new_file_in_deep_subdir(self):
545
        handler, branch = self.get_handler()
546
        path = 'a/b/c/d'
547
        handler.process(self.file_command_iter(path))
548
        revtree0, revtree1 = self.assertChanges(branch, 1,)
549
550
0.101.1 by Tom Widmer
Add test cases to check deletions from multiple levels in a tree still cause pruning of empty dirs to happen correctly.
551
class TestImportToPackDeleteMultiLevel(TestCaseForGenericProcessor):
552
553
    def file_command_iter(self, paths, paths_to_delete):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
554
0.101.1 by Tom Widmer
Add test cases to check deletions from multiple levels in a tree still cause pruning of empty dirs to happen correctly.
555
        # Revno 1: create multiple files
556
        # Revno 2: delete multiple files
557
        def command_list():
558
            author = ['', 'bugs@a.com', time.time(), time.timezone]
559
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
560
            def files_one():
561
                for i, path in enumerate(paths):
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
562
                    yield commands.FileModifyCommand(path, kind_to_mode('file', False),
0.101.1 by Tom Widmer
Add test cases to check deletions from multiple levels in a tree still cause pruning of empty dirs to happen correctly.
563
                            None, "aaa%d" % i)
564
            yield commands.CommitCommand('head', '1', author,
565
                committer, "commit 1", None, [], files_one)
566
            def files_two():
567
                for path in paths_to_delete:
568
                    yield commands.FileDeleteCommand(path)
569
            yield commands.CommitCommand('head', '2', author,
570
                committer, "commit 2", ":1", [], files_two)
571
        return command_list
572
573
    def test_delete_files_in_multiple_levels(self):
574
        handler, branch = self.get_handler()
575
        paths = ['a/b/c', 'a/b/d/e']
576
        paths_to_delete = ['a/b/c', 'a/b/d/e']
577
        handler.process(self.file_command_iter(paths, paths_to_delete))
578
        revtree0, revtree1 = self.assertChanges(branch, 1,
579
            expected_added=[
580
                ('a',), ('a/b',), ('a/b/c',),
581
                ('a/b/d',), ('a/b/d/e',),
582
                ])
583
        revtree1, revtree2 = self.assertChanges(branch, 2,
584
            expected_removed=[
585
                ('a',), ('a/b',), ('a/b/c',),
586
                ('a/b/d',), ('a/b/d/e',),
587
                ])
588
589
    def test_delete_file_single_level(self):
590
        handler, branch = self.get_handler()
591
        paths = ['a/b/c', 'a/b/d/e']
592
        paths_to_delete = ['a/b/d/e']
593
        handler.process(self.file_command_iter(paths, paths_to_delete))
594
        revtree0, revtree1 = self.assertChanges(branch, 1,
595
            expected_added=[
596
                ('a',), ('a/b',), ('a/b/c',),
597
                ('a/b/d',), ('a/b/d/e',),
598
                ])
599
        revtree1, revtree2 = self.assertChanges(branch, 2,
600
            expected_removed=[
601
                ('a/b/d',), ('a/b/d/e',),
602
                ])
603
604
    def test_delete_file_complex_level(self):
605
        handler, branch = self.get_handler()
606
        paths = ['a/b/c', 'a/b/d/e', 'a/f/g', 'a/h', 'a/b/d/i/j']
607
        paths_to_delete = ['a/b/c', 'a/b/d/e', 'a/f/g', 'a/b/d/i/j']
608
        handler.process(self.file_command_iter(paths, paths_to_delete))
609
        revtree0, revtree1 = self.assertChanges(branch, 1,
610
            expected_added=[
611
                ('a',), ('a/b',), ('a/b/c',),
612
                ('a/b/d',), ('a/b/d/e',),
613
                ('a/f',), ('a/f/g',),
614
                ('a/h',),
615
                ('a/b/d/i',), ('a/b/d/i/j',),
616
                ])
617
        revtree1, revtree2 = self.assertChanges(branch, 2,
618
            expected_removed=[
619
                ('a/b',), ('a/b/c',),
620
                ('a/b/d',), ('a/b/d/e',),
621
                ('a/f',), ('a/f/g',),
622
                ('a/b/d/i',), ('a/b/d/i/j',),
623
                ])
624
0.99.13 by Ian Clatworthy
Handle delete then add of a file/symlink in the one commit
625
class TestImportToPackDeleteThenAdd(TestCaseForGenericProcessor):
626
    """Test delete followed by an add. Merges can cause this."""
627
628
    def file_command_iter(self, path, kind='file', content='aaa',
629
        executable=False, to_kind=None, to_content='bbb', to_executable=None):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
630
0.99.13 by Ian Clatworthy
Handle delete then add of a file/symlink in the one commit
631
        # Revno 1: create a file or symlink
632
        # Revno 2: delete it and add it
633
        if to_kind is None:
634
            to_kind = kind
635
        if to_executable is None:
636
            to_executable = executable
637
        def command_list():
638
            author = ['', 'bugs@a.com', time.time(), time.timezone]
639
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
640
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
641
                yield commands.FileModifyCommand(path, kind_to_mode(kind, executable),
0.99.13 by Ian Clatworthy
Handle delete then add of a file/symlink in the one commit
642
                        None, content)
643
            yield commands.CommitCommand('head', '1', author,
644
                committer, "commit 1", None, [], files_one)
645
            def files_two():
646
                yield commands.FileDeleteCommand(path)
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
647
                yield commands.FileModifyCommand(path, kind_to_mode(to_kind, to_executable),
0.99.13 by Ian Clatworthy
Handle delete then add of a file/symlink in the one commit
648
                        None, to_content)
649
            yield commands.CommitCommand('head', '2', author,
650
                committer, "commit 2", ":1", [], files_two)
651
        return command_list
652
653
    def test_delete_then_add_file_in_root(self):
654
        handler, branch = self.get_handler()
655
        path = 'a'
656
        handler.process(self.file_command_iter(path))
657
        revtree0, revtree1 = self.assertChanges(branch, 1,
658
            expected_added=[(path,)])
659
        revtree1, revtree2 = self.assertChanges(branch, 2,
660
            expected_removed=[(path,)],
661
            expected_added=[(path,)])
662
        self.assertContent(branch, revtree1, path, "aaa")
663
        self.assertContent(branch, revtree2, path, "bbb")
664
        self.assertRevisionRoot(revtree1, path)
665
        self.assertRevisionRoot(revtree2, path)
666
667
    def test_delete_then_add_file_in_subdir(self):
668
        handler, branch = self.get_handler()
669
        path = 'a/a'
670
        handler.process(self.file_command_iter(path))
671
        revtree0, revtree1 = self.assertChanges(branch, 1,
672
            expected_added=[('a',), (path,)])
673
        revtree1, revtree2 = self.assertChanges(branch, 2,
674
            expected_removed=[(path,)],
675
            expected_added=[(path,)])
676
        self.assertContent(branch, revtree1, path, "aaa")
677
        self.assertContent(branch, revtree2, path, "bbb")
678
679
    def test_delete_then_add_symlink_in_root(self):
680
        handler, branch = self.get_handler()
681
        path = 'a'
682
        handler.process(self.file_command_iter(path, kind='symlink'))
683
        revtree1, revtree2 = self.assertChanges(branch, 2,
684
            expected_removed=[(path,)],
685
            expected_added=[(path,)])
686
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
687
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
688
        self.assertRevisionRoot(revtree1, path)
689
        self.assertRevisionRoot(revtree2, path)
690
691
    def test_delete_then_add_symlink_in_subdir(self):
692
        handler, branch = self.get_handler()
693
        path = 'a/a'
694
        handler.process(self.file_command_iter(path, kind='symlink'))
695
        revtree0, revtree1 = self.assertChanges(branch, 1,
696
            expected_added=[('a',), (path,)])
697
        revtree1, revtree2 = self.assertChanges(branch, 2,
698
            expected_removed=[(path,)],
699
            expected_added=[(path,)])
700
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
701
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
702
703
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
704
class TestImportToPackDeleteDirectory(TestCaseForGenericProcessor):
0.80.7 by Ian Clatworthy
add directory delete test
705
706
    def file_command_iter(self, paths, dir):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
707
0.80.7 by Ian Clatworthy
add directory delete test
708
        # Revno 1: create multiple files
709
        # Revno 2: delete a directory holding those files
710
        def command_list():
711
            author = ['', 'bugs@a.com', time.time(), time.timezone]
712
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
713
            def files_one():
714
                for i, path in enumerate(paths):
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
715
                    yield commands.FileModifyCommand(path, kind_to_mode('file', False),
0.80.7 by Ian Clatworthy
add directory delete test
716
                            None, "aaa%d" % i)
717
            yield commands.CommitCommand('head', '1', author,
718
                committer, "commit 1", None, [], files_one)
719
            def files_two():
720
                yield commands.FileDeleteCommand(dir)
721
            yield commands.CommitCommand('head', '2', author,
722
                committer, "commit 2", ":1", [], files_two)
723
        return command_list
724
725
    def test_delete_dir(self):
726
        handler, branch = self.get_handler()
727
        paths = ['a/b/c', 'a/b/d', 'a/b/e/f', 'a/g']
728
        dir = 'a/b'
729
        handler.process(self.file_command_iter(paths, dir))
730
        revtree0, revtree1 = self.assertChanges(branch, 1,
731
            expected_added=[
732
                ('a',), ('a/b',), ('a/b/c',),
733
                ('a/b/d',),
734
                ('a/b/e',), ('a/b/e/f',),
735
                ('a/g',),
736
                ])
737
        revtree1, revtree2 = self.assertChanges(branch, 2,
738
            expected_removed=[
739
                ('a/b',), ('a/b/c',),
740
                ('a/b/d',),
741
                ('a/b/e',), ('a/b/e/f',),
742
                ])
743
744
0.99.21 by Ian Clatworthy
Handle deleting a directory then adding a file within it in the same commit
745
class TestImportToPackDeleteDirectoryThenAddFile(TestCaseForGenericProcessor):
746
    """Test deleting a directory then adding a file in the same commit."""
747
748
    def file_command_iter(self, paths, dir, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
749
0.99.21 by Ian Clatworthy
Handle deleting a directory then adding a file within it in the same commit
750
        # Revno 1: create files in a directory
751
        # Revno 2: delete the directory then add a file into it
752
        def command_list():
753
            author = ['', 'bugs@a.com', time.time(), time.timezone]
754
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
755
            def files_one():
756
                for i, path in enumerate(paths):
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
757
                    yield commands.FileModifyCommand(path, kind_to_mode(kind, False),
0.99.21 by Ian Clatworthy
Handle deleting a directory then adding a file within it in the same commit
758
                            None, "aaa%d" % i)
759
            yield commands.CommitCommand('head', '1', author,
760
                committer, "commit 1", None, [], files_one)
761
            def files_two():
762
                yield commands.FileDeleteCommand(dir)
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
763
                yield commands.FileModifyCommand(new_path, kind_to_mode(kind, False),
0.99.21 by Ian Clatworthy
Handle deleting a directory then adding a file within it in the same commit
764
                        None, "bbb")
765
            yield commands.CommitCommand('head', '2', author,
766
                committer, "commit 2", ":1", [], files_two)
767
        return command_list
768
769
    def test_delete_dir_then_add_file(self):
770
        handler, branch = self.get_handler()
771
        paths = ['a/b/c', 'a/b/d']
772
        dir = 'a/b'
773
        new_path = 'a/b/z'
774
        handler.process(self.file_command_iter(paths, dir, new_path))
775
        revtree0, revtree1 = self.assertChanges(branch, 1,
776
            expected_added=[('a',), ('a/b',), ('a/b/c',), ('a/b/d',),])
777
        revtree1, revtree2 = self.assertChanges(branch, 2,
778
            expected_removed=[('a/b',), ('a/b/c',), ('a/b/d',)],
779
            expected_added=[('a/b',), ('a/b/z',)])
780
        self.assertContent(branch, revtree2, new_path, "bbb")
781
782
    def test_delete_dir_then_add_symlink(self):
783
        handler, branch = self.get_handler()
784
        paths = ['a/b/c', 'a/b/d']
785
        dir = 'a/b'
786
        new_path = 'a/b/z'
787
        handler.process(self.file_command_iter(paths, dir, new_path, 'symlink'))
788
        revtree0, revtree1 = self.assertChanges(branch, 1,
789
            expected_added=[('a',), ('a/b',), ('a/b/c',), ('a/b/d',),])
790
        revtree1, revtree2 = self.assertChanges(branch, 2,
791
            expected_removed=[('a/b',), ('a/b/c',), ('a/b/d',)],
792
            expected_added=[('a/b',), ('a/b/z',)])
793
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
794
795
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
796
class TestImportToPackRename(TestCaseForGenericProcessor):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
797
0.99.16 by Ian Clatworthy
add tests for symlink renaming
798
    def get_command_iter(self, old_path, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
799
0.80.4 by Ian Clatworthy
file executable off <-> on tests
800
        # Revno 1: create a file or symlink
801
        # Revno 2: rename it
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
802
        def command_list():
803
            author = ['', 'bugs@a.com', time.time(), time.timezone]
804
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
805
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
806
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
807
                        None, "aaa")
808
            yield commands.CommitCommand('head', '1', author,
809
                committer, "commit 1", None, [], files_one)
810
            def files_two():
811
                yield commands.FileRenameCommand(old_path, new_path)
812
            yield commands.CommitCommand('head', '2', author,
813
                committer, "commit 2", ":1", [], files_two)
814
        return command_list
815
0.99.16 by Ian Clatworthy
add tests for symlink renaming
816
    def test_rename_file_in_root(self):
817
        handler, branch = self.get_handler()
818
        old_path = 'a'
819
        new_path = 'b'
820
        handler.process(self.get_command_iter(old_path, new_path))
821
        revtree1, revtree2 = self.assertChanges(branch, 2,
822
            expected_renamed=[(old_path, new_path)])
823
        self.assertRevisionRoot(revtree1, old_path)
824
        self.assertRevisionRoot(revtree2, new_path)
825
826
    def test_rename_symlink_in_root(self):
827
        handler, branch = self.get_handler()
828
        old_path = 'a'
829
        new_path = 'b'
830
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
831
        revtree1, revtree2 = self.assertChanges(branch, 2,
832
            expected_renamed=[(old_path, new_path)])
833
        self.assertRevisionRoot(revtree1, old_path)
834
        self.assertRevisionRoot(revtree2, new_path)
835
836
    def test_rename_file_in_subdir(self):
837
        handler, branch = self.get_handler()
838
        old_path = 'a/a'
839
        new_path = 'a/b'
840
        handler.process(self.get_command_iter(old_path, new_path))
841
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)])
842
843
    def test_rename_symlink_in_subdir(self):
844
        handler, branch = self.get_handler()
845
        old_path = 'a/a'
846
        new_path = 'a/b'
847
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
848
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)])
849
850
    def test_rename_file_to_new_dir(self):
851
        handler, branch = self.get_handler()
852
        old_path = 'a/a'
853
        new_path = 'b/a'
854
        handler.process(self.get_command_iter(old_path, new_path))
855
        self.assertChanges(branch, 2,
856
            expected_renamed=[(old_path, new_path)],
857
            expected_added=[('b',)],
858
            expected_removed=[('a',)])
859
860
    def test_rename_symlink_to_new_dir(self):
861
        handler, branch = self.get_handler()
862
        old_path = 'a/a'
863
        new_path = 'b/a'
864
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
0.96.1 by Ian Clatworthy
update existing tests to reflect implicit directory pruning bahaviour
865
        self.assertChanges(branch, 2,
866
            expected_renamed=[(old_path, new_path)],
867
            expected_added=[('b',)],
868
            expected_removed=[('a',)])
0.64.74 by Ian Clatworthy
fix symlink importing
869
870
0.99.6 by Ian Clatworthy
Handle rename of a just added file
871
class TestImportToPackRenameNew(TestCaseForGenericProcessor):
0.99.8 by Ian Clatworthy
handle copy of a newly added file
872
    """Test rename of a newly added file."""
0.99.6 by Ian Clatworthy
Handle rename of a just added file
873
0.99.16 by Ian Clatworthy
add tests for symlink renaming
874
    def get_command_iter(self, old_path, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
875
0.99.6 by Ian Clatworthy
Handle rename of a just added file
876
        # Revno 1: create a file and rename it
877
        def command_list():
878
            author = ['', 'bugs@a.com', time.time(), time.timezone]
879
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
880
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
881
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.99.6 by Ian Clatworthy
Handle rename of a just added file
882
                        None, "aaa")
883
                yield commands.FileRenameCommand(old_path, new_path)
884
            yield commands.CommitCommand('head', '1', author,
885
                committer, "commit 1", None, [], files_one)
886
        return command_list
887
0.99.16 by Ian Clatworthy
add tests for symlink renaming
888
    def test_rename_new_file_in_root(self):
889
        handler, branch = self.get_handler()
890
        old_path = 'a'
891
        new_path = 'b'
892
        handler.process(self.get_command_iter(old_path, new_path))
893
        revtree0, revtree1 = self.assertChanges(branch, 1,
894
            expected_added=[(new_path,)])
895
        self.assertRevisionRoot(revtree1, new_path)
896
897
    def test_rename_new_symlink_in_root(self):
898
        handler, branch = self.get_handler()
899
        old_path = 'a'
900
        new_path = 'b'
901
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
902
        revtree0, revtree1 = self.assertChanges(branch, 1,
903
            expected_added=[(new_path,)])
904
        self.assertRevisionRoot(revtree1, new_path)
905
906
    def test_rename_new_file_in_subdir(self):
907
        handler, branch = self.get_handler()
908
        old_path = 'a/a'
909
        new_path = 'a/b'
910
        handler.process(self.get_command_iter(old_path, new_path))
911
        revtree0, revtree1 = self.assertChanges(branch, 1,
912
            expected_added=[('a',), (new_path,)])
913
914
    def test_rename_new_symlink_in_subdir(self):
915
        handler, branch = self.get_handler()
916
        old_path = 'a/a'
917
        new_path = 'a/b'
918
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
0.99.6 by Ian Clatworthy
Handle rename of a just added file
919
        revtree0, revtree1 = self.assertChanges(branch, 1,
920
            expected_added=[('a',), (new_path,)])
921
922
0.99.14 by Ian Clatworthy
Add tests for renaming to a deleted destination
923
class TestImportToPackRenameToDeleted(TestCaseForGenericProcessor):
924
    """Test rename to a destination path deleted in this commit."""
925
0.99.16 by Ian Clatworthy
add tests for symlink renaming
926
    def get_command_iter(self, old_path, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
927
0.99.14 by Ian Clatworthy
Add tests for renaming to a deleted destination
928
        # Revno 1: create two files
929
        # Revno 2: delete one, rename the other one to that path
930
        def command_list():
931
            author = ['', 'bugs@a.com', time.time(), time.timezone]
932
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
933
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
934
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.99.14 by Ian Clatworthy
Add tests for renaming to a deleted destination
935
                        None, "aaa")
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
936
                yield commands.FileModifyCommand(new_path, kind_to_mode(kind, False),
0.99.14 by Ian Clatworthy
Add tests for renaming to a deleted destination
937
                        None, "bbb")
938
            yield commands.CommitCommand('head', '1', author,
939
                committer, "commit 1", None, [], files_one)
940
            def files_two():
941
                yield commands.FileDeleteCommand(new_path)
942
                yield commands.FileRenameCommand(old_path, new_path)
943
            yield commands.CommitCommand('head', '2', author,
944
                committer, "commit 2", ":1", [], files_two)
945
        return command_list
946
0.99.16 by Ian Clatworthy
add tests for symlink renaming
947
    def test_rename_to_deleted_file_in_root(self):
948
        handler, branch = self.get_handler()
949
        old_path = 'a'
950
        new_path = 'b'
951
        handler.process(self.get_command_iter(old_path, new_path))
952
        revtree0, revtree1 = self.assertChanges(branch, 1,
953
            expected_added=[(old_path,), (new_path,)])
954
        revtree1, revtree2 = self.assertChanges(branch, 2,
955
            expected_removed=[(new_path,)],
956
            expected_renamed=[(old_path, new_path)])
957
        self.assertContent(branch, revtree1, old_path, "aaa")
958
        self.assertContent(branch, revtree1, new_path, "bbb")
959
        self.assertContent(branch, revtree2, new_path, "aaa")
960
        self.assertRevisionRoot(revtree1, old_path)
961
        self.assertRevisionRoot(revtree1, new_path)
962
963
    def test_rename_to_deleted_symlink_in_root(self):
964
        handler, branch = self.get_handler()
965
        old_path = 'a'
966
        new_path = 'b'
967
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
968
        revtree0, revtree1 = self.assertChanges(branch, 1,
969
            expected_added=[(old_path,), (new_path,)])
970
        revtree1, revtree2 = self.assertChanges(branch, 2,
971
            expected_removed=[(new_path,)],
972
            expected_renamed=[(old_path, new_path)])
973
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
974
        self.assertSymlinkTarget(branch, revtree1, new_path, "bbb")
975
        self.assertSymlinkTarget(branch, revtree2, new_path, "aaa")
976
        self.assertRevisionRoot(revtree1, old_path)
977
        self.assertRevisionRoot(revtree1, new_path)
978
979
    def test_rename_to_deleted_file_in_subdir(self):
980
        handler, branch = self.get_handler()
981
        old_path = 'd/a'
982
        new_path = 'd/b'
983
        handler.process(self.get_command_iter(old_path, new_path))
984
        revtree0, revtree1 = self.assertChanges(branch, 1,
985
            expected_added=[('d',), (old_path,), (new_path,)])
986
        revtree1, revtree2 = self.assertChanges(branch, 2,
987
            expected_removed=[(new_path,)],
988
            expected_renamed=[(old_path, new_path)])
989
        self.assertContent(branch, revtree1, old_path, "aaa")
990
        self.assertContent(branch, revtree1, new_path, "bbb")
991
        self.assertContent(branch, revtree2, new_path, "aaa")
992
993
    def test_rename_to_deleted_symlink_in_subdir(self):
994
        handler, branch = self.get_handler()
995
        old_path = 'd/a'
996
        new_path = 'd/b'
997
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
998
        revtree0, revtree1 = self.assertChanges(branch, 1,
999
            expected_added=[('d',), (old_path,), (new_path,)])
1000
        revtree1, revtree2 = self.assertChanges(branch, 2,
1001
            expected_removed=[(new_path,)],
1002
            expected_renamed=[(old_path, new_path)])
1003
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1004
        self.assertSymlinkTarget(branch, revtree1, new_path, "bbb")
1005
        self.assertSymlinkTarget(branch, revtree2, new_path, "aaa")
1006
1007
    def test_rename_to_deleted_file_in_new_dir(self):
1008
        handler, branch = self.get_handler()
1009
        old_path = 'd1/a'
1010
        new_path = 'd2/b'
1011
        handler.process(self.get_command_iter(old_path, new_path))
1012
        revtree0, revtree1 = self.assertChanges(branch, 1,
1013
            expected_added=[('d1',), (old_path,), ('d2',), (new_path,)])
1014
        revtree1, revtree2 = self.assertChanges(branch, 2,
1015
            expected_removed=[('d1',), (new_path,)],
1016
            expected_renamed=[(old_path, new_path)])
1017
        self.assertContent(branch, revtree1, old_path, "aaa")
1018
        self.assertContent(branch, revtree1, new_path, "bbb")
1019
        self.assertContent(branch, revtree2, new_path, "aaa")
1020
1021
    def test_rename_to_deleted_symlink_in_new_dir(self):
1022
        handler, branch = self.get_handler()
1023
        old_path = 'd1/a'
1024
        new_path = 'd2/b'
1025
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1026
        revtree0, revtree1 = self.assertChanges(branch, 1,
1027
            expected_added=[('d1',), (old_path,), ('d2',), (new_path,)])
1028
        revtree1, revtree2 = self.assertChanges(branch, 2,
1029
            expected_removed=[('d1',), (new_path,)],
1030
            expected_renamed=[(old_path, new_path)])
1031
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1032
        self.assertSymlinkTarget(branch, revtree1, new_path, "bbb")
1033
        self.assertSymlinkTarget(branch, revtree2, new_path, "aaa")
0.99.14 by Ian Clatworthy
Add tests for renaming to a deleted destination
1034
1035
0.99.17 by Ian Clatworthy
Handle rename of a file/symlink modified already in this commit
1036
class TestImportToPackRenameModified(TestCaseForGenericProcessor):
1037
    """Test rename of a path previously modified in this commit."""
1038
1039
    def get_command_iter(self, old_path, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1040
0.99.17 by Ian Clatworthy
Handle rename of a file/symlink modified already in this commit
1041
        # Revno 1: create a file or symlink
1042
        # Revno 2: modify then rename it
1043
        def command_list():
1044
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1045
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1046
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1047
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.99.17 by Ian Clatworthy
Handle rename of a file/symlink modified already in this commit
1048
                        None, "aaa")
1049
            yield commands.CommitCommand('head', '1', author,
1050
                committer, "commit 1", None, [], files_one)
1051
            def files_two():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1052
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.99.17 by Ian Clatworthy
Handle rename of a file/symlink modified already in this commit
1053
                        None, "bbb")
1054
                yield commands.FileRenameCommand(old_path, new_path)
1055
            yield commands.CommitCommand('head', '2', author,
1056
                committer, "commit 2", ":1", [], files_two)
1057
        return command_list
1058
1059
    def test_rename_of_modified_file_in_root(self):
1060
        handler, branch = self.get_handler()
1061
        old_path = 'a'
1062
        new_path = 'b'
1063
        handler.process(self.get_command_iter(old_path, new_path))
1064
        revtree0, revtree1 = self.assertChanges(branch, 1,
1065
            expected_added=[(old_path,)])
1066
        # Note: the delta doesn't show the modification?
1067
        # The actual new content is validated in the assertions following.
1068
        revtree1, revtree2 = self.assertChanges(branch, 2,
1069
            expected_renamed=[(old_path, new_path)])
1070
        self.assertContent(branch, revtree1, old_path, "aaa")
1071
        self.assertContent(branch, revtree2, new_path, "bbb")
1072
        self.assertRevisionRoot(revtree1, old_path)
1073
        self.assertRevisionRoot(revtree2, new_path)
1074
1075
    def test_rename_of_modified_symlink_in_root(self):
1076
        handler, branch = self.get_handler()
1077
        old_path = 'a'
1078
        new_path = 'b'
1079
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1080
        revtree0, revtree1 = self.assertChanges(branch, 1,
1081
            expected_added=[(old_path,)])
1082
        # Note: the delta doesn't show the modification?
1083
        # The actual new content is validated in the assertions following.
1084
        revtree1, revtree2 = self.assertChanges(branch, 2,
1085
            expected_renamed=[(old_path, new_path)])
1086
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1087
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1088
        self.assertRevisionRoot(revtree1, old_path)
1089
        self.assertRevisionRoot(revtree2, new_path)
1090
1091
    def test_rename_of_modified_file_in_subdir(self):
1092
        handler, branch = self.get_handler()
1093
        old_path = 'd/a'
1094
        new_path = 'd/b'
1095
        handler.process(self.get_command_iter(old_path, new_path))
1096
        revtree0, revtree1 = self.assertChanges(branch, 1,
1097
            expected_added=[('d',), (old_path,)])
1098
        # Note: the delta doesn't show the modification?
1099
        # The actual new content is validated in the assertions following.
1100
        revtree1, revtree2 = self.assertChanges(branch, 2,
1101
            expected_renamed=[(old_path, new_path)])
1102
        self.assertContent(branch, revtree1, old_path, "aaa")
1103
        self.assertContent(branch, revtree2, new_path, "bbb")
1104
1105
    def test_rename_of_modified_symlink_in_subdir(self):
1106
        handler, branch = self.get_handler()
1107
        old_path = 'd/a'
1108
        new_path = 'd/b'
1109
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1110
        revtree0, revtree1 = self.assertChanges(branch, 1,
1111
            expected_added=[('d',), (old_path,)])
1112
        # Note: the delta doesn't show the modification?
1113
        # The actual new content is validated in the assertions following.
1114
        revtree1, revtree2 = self.assertChanges(branch, 2,
1115
            expected_renamed=[(old_path, new_path)])
1116
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1117
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1118
1119
    def test_rename_of_modified_file_to_new_dir(self):
1120
        handler, branch = self.get_handler()
1121
        old_path = 'd1/a'
1122
        new_path = 'd2/b'
1123
        handler.process(self.get_command_iter(old_path, new_path))
1124
        revtree0, revtree1 = self.assertChanges(branch, 1,
1125
            expected_added=[('d1',), (old_path,)])
1126
        # Note: the delta doesn't show the modification?
1127
        # The actual new content is validated in the assertions following.
1128
        revtree1, revtree2 = self.assertChanges(branch, 2,
1129
            expected_renamed=[(old_path, new_path)],
1130
            expected_added=[('d2',)],
1131
            expected_removed=[('d1',)])
1132
        self.assertContent(branch, revtree1, old_path, "aaa")
1133
        self.assertContent(branch, revtree2, new_path, "bbb")
1134
1135
    def test_rename_of_modified_symlink_to_new_dir(self):
1136
        handler, branch = self.get_handler()
1137
        old_path = 'd1/a'
1138
        new_path = 'd2/b'
1139
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1140
        revtree0, revtree1 = self.assertChanges(branch, 1,
1141
            expected_added=[('d1',), (old_path,)])
1142
        # Note: the delta doesn't show the modification?
1143
        # The actual new content is validated in the assertions following.
1144
        revtree1, revtree2 = self.assertChanges(branch, 2,
1145
            expected_renamed=[(old_path, new_path)],
1146
            expected_added=[('d2',)],
1147
            expected_removed=[('d1',)])
1148
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1149
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1150
1151
0.99.19 by Ian Clatworthy
Handle rename then modification of the new path
1152
class TestImportToPackRenameThenModify(TestCaseForGenericProcessor):
1153
    """Test rename of a path then modfy the new-path in the same commit."""
1154
1155
    def get_command_iter(self, old_path, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1156
0.99.19 by Ian Clatworthy
Handle rename then modification of the new path
1157
        # Revno 1: create a file or symlink
1158
        # Revno 2: rename it then modify the newly created path
1159
        def command_list():
1160
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1161
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1162
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1163
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.99.19 by Ian Clatworthy
Handle rename then modification of the new path
1164
                        None, "aaa")
1165
            yield commands.CommitCommand('head', '1', author,
1166
                committer, "commit 1", None, [], files_one)
1167
            def files_two():
1168
                yield commands.FileRenameCommand(old_path, new_path)
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1169
                yield commands.FileModifyCommand(new_path, kind_to_mode(kind, False),
0.99.19 by Ian Clatworthy
Handle rename then modification of the new path
1170
                        None, "bbb")
1171
            yield commands.CommitCommand('head', '2', author,
1172
                committer, "commit 2", ":1", [], files_two)
1173
        return command_list
1174
1175
    def test_rename_then_modify_file_in_root(self):
1176
        handler, branch = self.get_handler()
1177
        old_path = 'a'
1178
        new_path = 'b'
1179
        handler.process(self.get_command_iter(old_path, new_path))
1180
        revtree0, revtree1 = self.assertChanges(branch, 1,
1181
            expected_added=[(old_path,)])
1182
        # Note: the delta doesn't show the modification?
1183
        # The actual new content is validated in the assertions following.
1184
        revtree1, revtree2 = self.assertChanges(branch, 2,
1185
            expected_renamed=[(old_path, new_path)])
1186
        self.assertContent(branch, revtree1, old_path, "aaa")
1187
        self.assertContent(branch, revtree2, new_path, "bbb")
1188
        self.assertRevisionRoot(revtree1, old_path)
1189
        self.assertRevisionRoot(revtree2, new_path)
1190
1191
    def test_rename_then_modify_file_in_subdir(self):
1192
        handler, branch = self.get_handler()
1193
        old_path = 'd/a'
1194
        new_path = 'd/b'
1195
        handler.process(self.get_command_iter(old_path, new_path))
1196
        revtree0, revtree1 = self.assertChanges(branch, 1,
1197
            expected_added=[('d',), (old_path,)])
1198
        # Note: the delta doesn't show the modification?
1199
        # The actual new content is validated in the assertions following.
1200
        revtree1, revtree2 = self.assertChanges(branch, 2,
1201
            expected_renamed=[(old_path, new_path)])
1202
        self.assertContent(branch, revtree1, old_path, "aaa")
1203
        self.assertContent(branch, revtree2, new_path, "bbb")
1204
1205
    def test_rename_then_modify_file_in_new_dir(self):
1206
        handler, branch = self.get_handler()
1207
        old_path = 'd1/a'
1208
        new_path = 'd2/b'
1209
        handler.process(self.get_command_iter(old_path, new_path))
1210
        revtree0, revtree1 = self.assertChanges(branch, 1,
1211
            expected_added=[('d1',), (old_path,)])
1212
        # Note: the delta doesn't show the modification?
1213
        # The actual new content is validated in the assertions following.
1214
        revtree1, revtree2 = self.assertChanges(branch, 2,
1215
            expected_renamed=[(old_path, new_path)],
1216
            expected_added=[('d2',)],
1217
            expected_removed=[('d1',)])
1218
        self.assertContent(branch, revtree1, old_path, "aaa")
1219
        self.assertContent(branch, revtree2, new_path, "bbb")
1220
1221
    def test_rename_then_modify_symlink_in_root(self):
1222
        handler, branch = self.get_handler()
1223
        old_path = 'a'
1224
        new_path = 'b'
1225
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1226
        revtree0, revtree1 = self.assertChanges(branch, 1,
1227
            expected_added=[(old_path,)])
1228
        # Note: the delta doesn't show the modification?
1229
        # The actual new content is validated in the assertions following.
1230
        revtree1, revtree2 = self.assertChanges(branch, 2,
1231
            expected_renamed=[(old_path, new_path)])
1232
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1233
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1234
        self.assertRevisionRoot(revtree1, old_path)
1235
        self.assertRevisionRoot(revtree2, new_path)
1236
1237
    def test_rename_then_modify_symlink_in_subdir(self):
1238
        handler, branch = self.get_handler()
1239
        old_path = 'd/a'
1240
        new_path = 'd/b'
1241
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1242
        revtree0, revtree1 = self.assertChanges(branch, 1,
1243
            expected_added=[('d',), (old_path,)])
1244
        # Note: the delta doesn't show the modification?
1245
        # The actual new content is validated in the assertions following.
1246
        revtree1, revtree2 = self.assertChanges(branch, 2,
1247
            expected_renamed=[(old_path, new_path)])
1248
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1249
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1250
1251
    def test_rename_then_modify_symlink_in_new_dir(self):
1252
        handler, branch = self.get_handler()
1253
        old_path = 'd1/a'
1254
        new_path = 'd2/b'
1255
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1256
        revtree0, revtree1 = self.assertChanges(branch, 1,
1257
            expected_added=[('d1',), (old_path,)])
1258
        # Note: the delta doesn't show the modification?
1259
        # The actual new content is validated in the assertions following.
1260
        revtree1, revtree2 = self.assertChanges(branch, 2,
1261
            expected_renamed=[(old_path, new_path)],
1262
            expected_added=[('d2',)],
1263
            expected_removed=[('d1',)])
1264
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1265
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1266
1267
0.64.233 by Ian Clatworthy
Handle delete, rename then modify all in the one commit
1268
class TestImportToPackDeleteRenameThenModify(TestCaseForGenericProcessor):
1269
    """Test rename of to a deleted path then modfy the new-path in the same commit."""
1270
1271
    def get_command_iter(self, old_path, new_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1272
0.64.233 by Ian Clatworthy
Handle delete, rename then modify all in the one commit
1273
        # Revno 1: create two files or symlinks
1274
        # Revno 2: delete one, rename the other to it then modify the newly created path
1275
        def command_list():
1276
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1277
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1278
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1279
                yield commands.FileModifyCommand(old_path, kind_to_mode(kind, False),
0.64.233 by Ian Clatworthy
Handle delete, rename then modify all in the one commit
1280
                        None, "aaa")
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1281
                yield commands.FileModifyCommand(new_path, kind_to_mode(kind, False),
0.64.233 by Ian Clatworthy
Handle delete, rename then modify all in the one commit
1282
                        None, "zzz")
1283
            yield commands.CommitCommand('head', '1', author,
1284
                committer, "commit 1", None, [], files_one)
1285
            def files_two():
1286
                yield commands.FileDeleteCommand(new_path)
1287
                yield commands.FileRenameCommand(old_path, new_path)
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1288
                yield commands.FileModifyCommand(new_path, kind_to_mode(kind, False),
0.64.233 by Ian Clatworthy
Handle delete, rename then modify all in the one commit
1289
                        None, "bbb")
1290
            yield commands.CommitCommand('head', '2', author,
1291
                committer, "commit 2", ":1", [], files_two)
1292
        return command_list
1293
1294
    def test_delete_rename_then_modify_file_in_root(self):
1295
        handler, branch = self.get_handler()
1296
        old_path = 'a'
1297
        new_path = 'b'
1298
        handler.process(self.get_command_iter(old_path, new_path))
1299
        revtree0, revtree1 = self.assertChanges(branch, 1,
1300
            expected_added=[(old_path,), (new_path,)])
1301
        # Note: the delta doesn't show the modification?
1302
        # The actual new content is validated in the assertions following.
1303
        revtree1, revtree2 = self.assertChanges(branch, 2,
1304
            expected_removed=[(new_path,)],
1305
            expected_renamed=[(old_path, new_path)])
1306
        self.assertContent(branch, revtree1, old_path, "aaa")
1307
        self.assertContent(branch, revtree1, new_path, "zzz")
1308
        self.assertContent(branch, revtree2, new_path, "bbb")
1309
        self.assertRevisionRoot(revtree1, old_path)
1310
        self.assertRevisionRoot(revtree1, new_path)
1311
        self.assertRevisionRoot(revtree2, new_path)
1312
1313
    def test_delete_rename_then_modify_file_in_subdir(self):
1314
        handler, branch = self.get_handler()
1315
        old_path = 'd/a'
1316
        new_path = 'd/b'
1317
        handler.process(self.get_command_iter(old_path, new_path))
1318
        revtree0, revtree1 = self.assertChanges(branch, 1,
1319
            expected_added=[('d',), (old_path,), (new_path,)])
1320
        # Note: the delta doesn't show the modification?
1321
        # The actual new content is validated in the assertions following.
1322
        revtree1, revtree2 = self.assertChanges(branch, 2,
1323
            expected_removed=[(new_path,)],
1324
            expected_renamed=[(old_path, new_path)])
1325
        self.assertContent(branch, revtree1, old_path, "aaa")
1326
        self.assertContent(branch, revtree1, new_path, "zzz")
1327
        self.assertContent(branch, revtree2, new_path, "bbb")
1328
1329
    def test_delete_rename_then_modify_file_in_new_dir(self):
1330
        handler, branch = self.get_handler()
1331
        old_path = 'd1/a'
1332
        new_path = 'd2/b'
1333
        handler.process(self.get_command_iter(old_path, new_path))
1334
        revtree0, revtree1 = self.assertChanges(branch, 1,
1335
            expected_added=[('d1',), ('d2',), (old_path,), (new_path,)])
1336
        # Note: the delta doesn't show the modification?
1337
        # The actual new content is validated in the assertions following.
1338
        revtree1, revtree2 = self.assertChanges(branch, 2,
1339
            expected_removed=[('d1',), (new_path,)],
1340
            expected_renamed=[(old_path, new_path)])
1341
        self.assertContent(branch, revtree1, old_path, "aaa")
1342
        self.assertContent(branch, revtree1, new_path, "zzz")
1343
        self.assertContent(branch, revtree2, new_path, "bbb")
1344
1345
    def test_delete_rename_then_modify_symlink_in_root(self):
1346
        handler, branch = self.get_handler()
1347
        old_path = 'a'
1348
        new_path = 'b'
1349
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1350
        revtree0, revtree1 = self.assertChanges(branch, 1,
1351
            expected_added=[(old_path,), (new_path,)])
1352
        # Note: the delta doesn't show the modification?
1353
        # The actual new content is validated in the assertions following.
1354
        revtree1, revtree2 = self.assertChanges(branch, 2,
1355
            expected_removed=[(new_path,)],
1356
            expected_renamed=[(old_path, new_path)])
1357
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1358
        self.assertSymlinkTarget(branch, revtree1, new_path, "zzz")
1359
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1360
        self.assertRevisionRoot(revtree1, old_path)
1361
        self.assertRevisionRoot(revtree1, new_path)
1362
        self.assertRevisionRoot(revtree2, new_path)
1363
1364
    def test_delete_rename_then_modify_symlink_in_subdir(self):
1365
        handler, branch = self.get_handler()
1366
        old_path = 'd/a'
1367
        new_path = 'd/b'
1368
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1369
        revtree0, revtree1 = self.assertChanges(branch, 1,
1370
            expected_added=[('d',), (old_path,), (new_path,)])
1371
        # Note: the delta doesn't show the modification?
1372
        # The actual new content is validated in the assertions following.
1373
        revtree1, revtree2 = self.assertChanges(branch, 2,
1374
            expected_removed=[(new_path,)],
1375
            expected_renamed=[(old_path, new_path)])
1376
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1377
        self.assertSymlinkTarget(branch, revtree1, new_path, "zzz")
1378
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1379
1380
    def test_delete_rename_then_modify_symlink_in_new_dir(self):
1381
        handler, branch = self.get_handler()
1382
        old_path = 'd1/a'
1383
        new_path = 'd2/b'
1384
        handler.process(self.get_command_iter(old_path, new_path, 'symlink'))
1385
        revtree0, revtree1 = self.assertChanges(branch, 1,
1386
            expected_added=[('d1',), ('d2',), (old_path,), (new_path,)])
1387
        # Note: the delta doesn't show the modification?
1388
        # The actual new content is validated in the assertions following.
1389
        revtree1, revtree2 = self.assertChanges(branch, 2,
1390
            expected_removed=[('d1',), (new_path,)],
1391
            expected_renamed=[(old_path, new_path)])
1392
        self.assertSymlinkTarget(branch, revtree1, old_path, "aaa")
1393
        self.assertSymlinkTarget(branch, revtree1, new_path, "zzz")
1394
        self.assertSymlinkTarget(branch, revtree2, new_path, "bbb")
1395
1396
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
1397
class TestImportToPackRenameTricky(TestCaseForGenericProcessor):
0.80.6 by Ian Clatworthy
file/symlink <-> directory rename tests
1398
1399
    def file_command_iter(self, path1, old_path2, new_path2, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1400
0.80.6 by Ian Clatworthy
file/symlink <-> directory rename tests
1401
        # Revno 1: create two files or symlinks in a directory
1402
        # Revno 2: rename the second file so that it implicitly deletes the
1403
        # first one because either:
1404
        # * the new file is a in directory with the old file name
1405
        # * the new file has the same name as the directory of the first
1406
        def command_list():
1407
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1408
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1409
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1410
                yield commands.FileModifyCommand(path1, kind_to_mode(kind, False),
0.80.6 by Ian Clatworthy
file/symlink <-> directory rename tests
1411
                        None, "aaa")
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1412
                yield commands.FileModifyCommand(old_path2, kind_to_mode(kind, False),
0.80.6 by Ian Clatworthy
file/symlink <-> directory rename tests
1413
                        None, "bbb")
1414
            yield commands.CommitCommand('head', '1', author,
1415
                committer, "commit 1", None, [], files_one)
1416
            def files_two():
1417
                yield commands.FileRenameCommand(old_path2, new_path2)
1418
            yield commands.CommitCommand('head', '2', author,
1419
                committer, "commit 2", ":1", [], files_two)
1420
        return command_list
1421
1422
    def test_rename_file_becomes_directory(self):
1423
        handler, branch = self.get_handler()
1424
        old_path2 = 'foo'
1425
        path1     = 'a/b'
1426
        new_path2 = 'a/b/c'
1427
        handler.process(self.file_command_iter(path1, old_path2, new_path2))
1428
        revtree0, revtree1 = self.assertChanges(branch, 1,
1429
            expected_added=[('a',), (path1,), (old_path2,)])
1430
        revtree1, revtree2 = self.assertChanges(branch, 2,
1431
            expected_renamed=[(old_path2, new_path2)],
1432
            expected_kind_changed=[(path1, 'file', 'directory')])
1433
        self.assertContent(branch, revtree1, path1, "aaa")
1434
        self.assertContent(branch, revtree2, new_path2, "bbb")
1435
1436
    def test_rename_directory_becomes_file(self):
1437
        handler, branch = self.get_handler()
1438
        old_path2 = 'foo'
1439
        path1     = 'a/b/c'
1440
        new_path2 = 'a/b'
1441
        handler.process(self.file_command_iter(path1, old_path2, new_path2))
1442
        revtree0, revtree1 = self.assertChanges(branch, 1,
1443
            expected_added=[('a',), ('a/b',), (path1,), (old_path2,)])
1444
        revtree1, revtree2 = self.assertChanges(branch, 2,
1445
            expected_renamed=[(old_path2, new_path2)],
1446
            expected_removed=[(path1,), (new_path2,)])
1447
        self.assertContent(branch, revtree1, path1, "aaa")
1448
        self.assertContent(branch, revtree2, new_path2, "bbb")
1449
1450
    def test_rename_symlink_becomes_directory(self):
1451
        handler, branch = self.get_handler()
1452
        old_path2 = 'foo'
1453
        path1     = 'a/b'
1454
        new_path2 = 'a/b/c'
1455
        handler.process(self.file_command_iter(path1, old_path2, new_path2,
1456
            'symlink'))
1457
        revtree0, revtree1 = self.assertChanges(branch, 1,
1458
            expected_added=[('a',), (path1,), (old_path2,)])
1459
        revtree1, revtree2 = self.assertChanges(branch, 2,
1460
            expected_renamed=[(old_path2, new_path2)],
1461
            expected_kind_changed=[(path1, 'symlink', 'directory')])
1462
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
1463
        self.assertSymlinkTarget(branch, revtree2, new_path2, "bbb")
1464
1465
    def test_rename_directory_becomes_symlink(self):
1466
        handler, branch = self.get_handler()
1467
        old_path2 = 'foo'
1468
        path1     = 'a/b/c'
1469
        new_path2 = 'a/b'
1470
        handler.process(self.file_command_iter(path1, old_path2, new_path2,
1471
            'symlink'))
1472
        revtree0, revtree1 = self.assertChanges(branch, 1,
1473
            expected_added=[('a',), ('a/b',), (path1,), (old_path2,)])
1474
        revtree1, revtree2 = self.assertChanges(branch, 2,
1475
            expected_renamed=[(old_path2, new_path2)],
1476
            expected_removed=[(path1,), (new_path2,)])
1477
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
1478
        self.assertSymlinkTarget(branch, revtree2, new_path2, "bbb")
1479
1480
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
1481
class TestImportToPackCopy(TestCaseForGenericProcessor):
0.76.2 by Ian Clatworthy
code & tests for file copying
1482
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1483
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1484
0.80.4 by Ian Clatworthy
file executable off <-> on tests
1485
        # Revno 1: create a file or symlink
1486
        # Revno 2: copy it
0.76.2 by Ian Clatworthy
code & tests for file copying
1487
        def command_list():
1488
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1489
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1490
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1491
                yield commands.FileModifyCommand(src_path, kind_to_mode(kind, False),
0.76.2 by Ian Clatworthy
code & tests for file copying
1492
                        None, "aaa")
1493
            yield commands.CommitCommand('head', '1', author,
1494
                committer, "commit 1", None, [], files_one)
1495
            def files_two():
1496
                yield commands.FileCopyCommand(src_path, dest_path)
1497
            yield commands.CommitCommand('head', '2', author,
1498
                committer, "commit 2", ":1", [], files_two)
1499
        return command_list
1500
1501
    def test_copy_file_in_root(self):
1502
        handler, branch = self.get_handler()
1503
        src_path = 'a'
1504
        dest_path = 'b'
1505
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1506
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
1507
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1508
        self.assertContent(branch, revtree1, src_path, "aaa")
1509
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
1510
        self.assertContent(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1511
        self.assertRevisionRoot(revtree1, src_path)
1512
        self.assertRevisionRoot(revtree2, dest_path)
0.76.2 by Ian Clatworthy
code & tests for file copying
1513
1514
    def test_copy_file_in_subdir(self):
1515
        handler, branch = self.get_handler()
1516
        src_path = 'a/a'
1517
        dest_path = 'a/b'
1518
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1519
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
1520
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1521
        self.assertContent(branch, revtree1, src_path, "aaa")
1522
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
1523
        self.assertContent(branch, revtree2, dest_path, "aaa")
1524
1525
    def test_copy_file_to_new_dir(self):
1526
        handler, branch = self.get_handler()
1527
        src_path = 'a/a'
1528
        dest_path = 'b/a'
1529
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1530
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
1531
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1532
        self.assertContent(branch, revtree1, src_path, "aaa")
1533
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
1534
        self.assertContent(branch, revtree2, dest_path, "aaa")
1535
0.76.3 by Ian Clatworthy
symlink copying tests
1536
    def test_copy_symlink_in_root(self):
1537
        handler, branch = self.get_handler()
1538
        src_path = 'a'
1539
        dest_path = 'b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1540
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1541
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
1542
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1543
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1544
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
1545
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1546
        self.assertRevisionRoot(revtree1, src_path)
1547
        self.assertRevisionRoot(revtree2, dest_path)
0.76.3 by Ian Clatworthy
symlink copying tests
1548
1549
    def test_copy_symlink_in_subdir(self):
1550
        handler, branch = self.get_handler()
1551
        src_path = 'a/a'
1552
        dest_path = 'a/b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1553
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1554
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
1555
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1556
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1557
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
1558
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
1559
1560
    def test_copy_symlink_to_new_dir(self):
1561
        handler, branch = self.get_handler()
1562
        src_path = 'a/a'
1563
        dest_path = 'b/a'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1564
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1565
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
1566
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
1567
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1568
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
1569
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
1570
0.76.2 by Ian Clatworthy
code & tests for file copying
1571
0.99.8 by Ian Clatworthy
handle copy of a newly added file
1572
class TestImportToPackCopyNew(TestCaseForGenericProcessor):
1573
    """Test copy of a newly added file."""
1574
1575
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1576
0.99.8 by Ian Clatworthy
handle copy of a newly added file
1577
        # Revno 1: create a file or symlink and copy it
1578
        def command_list():
1579
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1580
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1581
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1582
                yield commands.FileModifyCommand(src_path, kind_to_mode(kind, False),
0.99.8 by Ian Clatworthy
handle copy of a newly added file
1583
                        None, "aaa")
1584
                yield commands.FileCopyCommand(src_path, dest_path)
1585
            yield commands.CommitCommand('head', '1', author,
1586
                committer, "commit 1", None, [], files_one)
1587
        return command_list
1588
1589
    def test_copy_new_file_in_root(self):
1590
        handler, branch = self.get_handler()
1591
        src_path = 'a'
1592
        dest_path = 'b'
1593
        handler.process(self.file_command_iter(src_path, dest_path))
1594
        revtree0, revtree1 = self.assertChanges(branch, 1,
1595
            expected_added=[(src_path,), (dest_path,)])
1596
        self.assertContent(branch, revtree1, src_path, "aaa")
1597
        self.assertContent(branch, revtree1, dest_path, "aaa")
1598
        self.assertRevisionRoot(revtree1, src_path)
1599
        self.assertRevisionRoot(revtree1, dest_path)
1600
1601
    def test_copy_new_file_in_subdir(self):
1602
        handler, branch = self.get_handler()
1603
        src_path = 'a/a'
1604
        dest_path = 'a/b'
1605
        handler.process(self.file_command_iter(src_path, dest_path))
1606
        revtree0, revtree1 = self.assertChanges(branch, 1,
1607
            expected_added=[('a',), (src_path,), (dest_path,)])
1608
        self.assertContent(branch, revtree1, src_path, "aaa")
1609
        self.assertContent(branch, revtree1, dest_path, "aaa")
1610
1611
    def test_copy_new_file_to_new_dir(self):
1612
        handler, branch = self.get_handler()
1613
        src_path = 'a/a'
1614
        dest_path = 'b/a'
1615
        handler.process(self.file_command_iter(src_path, dest_path))
1616
        revtree0, revtree1 = self.assertChanges(branch, 1,
1617
            expected_added=[('a',), (src_path,), ('b',), (dest_path,)])
1618
        self.assertContent(branch, revtree1, src_path, "aaa")
1619
        self.assertContent(branch, revtree1, dest_path, "aaa")
1620
1621
    def test_copy_new_symlink_in_root(self):
1622
        handler, branch = self.get_handler()
1623
        src_path = 'a'
1624
        dest_path = 'b'
1625
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1626
        revtree0, revtree1 = self.assertChanges(branch, 1,
1627
            expected_added=[(src_path,), (dest_path,)])
1628
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1629
        self.assertSymlinkTarget(branch, revtree1, dest_path, "aaa")
1630
        self.assertRevisionRoot(revtree1, src_path)
1631
        self.assertRevisionRoot(revtree1, dest_path)
1632
1633
    def test_copy_new_symlink_in_subdir(self):
1634
        handler, branch = self.get_handler()
1635
        src_path = 'a/a'
1636
        dest_path = 'a/b'
1637
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1638
        revtree0, revtree1 = self.assertChanges(branch, 1,
1639
            expected_added=[('a',), (src_path,), (dest_path,)])
1640
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1641
        self.assertSymlinkTarget(branch, revtree1, dest_path, "aaa")
1642
1643
    def test_copy_new_symlink_to_new_dir(self):
1644
        handler, branch = self.get_handler()
1645
        src_path = 'a/a'
1646
        dest_path = 'b/a'
1647
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1648
        revtree0, revtree1 = self.assertChanges(branch, 1,
1649
            expected_added=[('a',), (src_path,), ('b',), (dest_path,)])
1650
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1651
        self.assertSymlinkTarget(branch, revtree1, dest_path, "aaa")
1652
1653
0.99.15 by Ian Clatworthy
Add tests for copying to a path deleted in the same commit
1654
class TestImportToPackCopyToDeleted(TestCaseForGenericProcessor):
1655
1656
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1657
0.99.15 by Ian Clatworthy
Add tests for copying to a path deleted in the same commit
1658
        # Revno 1: create two files or symlinks
1659
        # Revno 2: delete one and copy the other one to its path
1660
        def command_list():
1661
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1662
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1663
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1664
                yield commands.FileModifyCommand(src_path, kind_to_mode(kind, False),
0.99.15 by Ian Clatworthy
Add tests for copying to a path deleted in the same commit
1665
                        None, "aaa")
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1666
                yield commands.FileModifyCommand(dest_path, kind_to_mode(kind, False),
0.99.15 by Ian Clatworthy
Add tests for copying to a path deleted in the same commit
1667
                        None, "bbb")
1668
            yield commands.CommitCommand('head', '1', author,
1669
                committer, "commit 1", None, [], files_one)
1670
            def files_two():
1671
                yield commands.FileDeleteCommand(dest_path)
1672
                yield commands.FileCopyCommand(src_path, dest_path)
1673
            yield commands.CommitCommand('head', '2', author,
1674
                committer, "commit 2", ":1", [], files_two)
1675
        return command_list
1676
1677
    def test_copy_to_deleted_file_in_root(self):
1678
        handler, branch = self.get_handler()
1679
        src_path = 'a'
1680
        dest_path = 'b'
1681
        handler.process(self.file_command_iter(src_path, dest_path))
1682
        revtree0, revtree1 = self.assertChanges(branch, 1,
1683
            expected_added=[(src_path,), (dest_path,)])
1684
        revtree1, revtree2 = self.assertChanges(branch, 2,
1685
            expected_removed=[(dest_path,)],
1686
            expected_added=[(dest_path,)])
1687
        self.assertContent(branch, revtree1, src_path, "aaa")
1688
        self.assertContent(branch, revtree1, dest_path, "bbb")
1689
        self.assertContent(branch, revtree2, src_path, "aaa")
1690
        self.assertContent(branch, revtree2, dest_path, "aaa")
1691
        self.assertRevisionRoot(revtree1, src_path)
1692
        self.assertRevisionRoot(revtree1, dest_path)
1693
1694
    def test_copy_to_deleted_symlink_in_root(self):
1695
        handler, branch = self.get_handler()
1696
        src_path = 'a'
1697
        dest_path = 'b'
1698
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1699
        revtree0, revtree1 = self.assertChanges(branch, 1,
1700
            expected_added=[(src_path,), (dest_path,)])
1701
        revtree1, revtree2 = self.assertChanges(branch, 2,
1702
            expected_removed=[(dest_path,)],
1703
            expected_added=[(dest_path,)])
1704
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1705
        self.assertSymlinkTarget(branch, revtree1, dest_path, "bbb")
1706
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
1707
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
1708
        self.assertRevisionRoot(revtree1, src_path)
1709
        self.assertRevisionRoot(revtree1, dest_path)
1710
1711
    def test_copy_to_deleted_file_in_subdir(self):
1712
        handler, branch = self.get_handler()
1713
        src_path = 'd/a'
1714
        dest_path = 'd/b'
1715
        handler.process(self.file_command_iter(src_path, dest_path))
1716
        revtree0, revtree1 = self.assertChanges(branch, 1,
1717
            expected_added=[('d',), (src_path,), (dest_path,)])
1718
        revtree1, revtree2 = self.assertChanges(branch, 2,
1719
            expected_removed=[(dest_path,)],
1720
            expected_added=[(dest_path,)])
1721
        self.assertContent(branch, revtree1, src_path, "aaa")
1722
        self.assertContent(branch, revtree1, dest_path, "bbb")
1723
        self.assertContent(branch, revtree2, src_path, "aaa")
1724
        self.assertContent(branch, revtree2, dest_path, "aaa")
1725
1726
    def test_copy_to_deleted_symlink_in_subdir(self):
1727
        handler, branch = self.get_handler()
1728
        src_path = 'd/a'
1729
        dest_path = 'd/b'
1730
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1731
        revtree0, revtree1 = self.assertChanges(branch, 1,
1732
            expected_added=[('d',), (src_path,), (dest_path,)])
1733
        revtree1, revtree2 = self.assertChanges(branch, 2,
1734
            expected_removed=[(dest_path,)],
1735
            expected_added=[(dest_path,)])
1736
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1737
        self.assertSymlinkTarget(branch, revtree1, dest_path, "bbb")
1738
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
1739
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
1740
1741
0.99.18 by Ian Clatworthy
Handle copy of a file/symlink already modified in this commit
1742
class TestImportToPackCopyModified(TestCaseForGenericProcessor):
1743
    """Test copy of file/symlink already modified in this commit."""
1744
1745
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1746
0.99.18 by Ian Clatworthy
Handle copy of a file/symlink already modified in this commit
1747
        # Revno 1: create a file or symlink
1748
        # Revno 2: modify and copy it
1749
        def command_list():
1750
            author = ['', 'bugs@a.com', time.time(), time.timezone]
1751
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1752
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1753
                yield commands.FileModifyCommand(src_path, kind_to_mode(kind, False),
0.99.18 by Ian Clatworthy
Handle copy of a file/symlink already modified in this commit
1754
                        None, "aaa")
1755
            yield commands.CommitCommand('head', '1', author,
1756
                committer, "commit 1", None, [], files_one)
1757
            def files_two():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1758
                yield commands.FileModifyCommand(src_path, kind_to_mode(kind, False),
0.99.18 by Ian Clatworthy
Handle copy of a file/symlink already modified in this commit
1759
                        None, "bbb")
1760
                yield commands.FileCopyCommand(src_path, dest_path)
1761
            yield commands.CommitCommand('head', '2', author,
1762
                committer, "commit 2", ":1", [], files_two)
1763
        return command_list
1764
1765
    def test_copy_of_modified_file_in_root(self):
1766
        handler, branch = self.get_handler()
1767
        src_path = 'a'
1768
        dest_path = 'b'
1769
        handler.process(self.file_command_iter(src_path, dest_path))
1770
        revtree1, revtree2 = self.assertChanges(branch, 2,
1771
            expected_modified=[(src_path,)],
1772
            expected_added=[(dest_path,)])
1773
        self.assertContent(branch, revtree1, src_path, "aaa")
1774
        self.assertContent(branch, revtree2, src_path, "bbb")
1775
        self.assertContent(branch, revtree2, dest_path, "bbb")
1776
        self.assertRevisionRoot(revtree1, src_path)
1777
        self.assertRevisionRoot(revtree2, dest_path)
1778
1779
    def test_copy_of_modified_file_in_subdir(self):
1780
        handler, branch = self.get_handler()
1781
        src_path = 'd/a'
1782
        dest_path = 'd/b'
1783
        handler.process(self.file_command_iter(src_path, dest_path))
1784
        revtree1, revtree2 = self.assertChanges(branch, 2,
1785
            expected_modified=[(src_path,)],
1786
            expected_added=[(dest_path,)])
1787
        self.assertContent(branch, revtree1, src_path, "aaa")
1788
        self.assertContent(branch, revtree2, src_path, "bbb")
1789
        self.assertContent(branch, revtree2, dest_path, "bbb")
1790
1791
    def test_copy_of_modified_file_to_new_dir(self):
1792
        handler, branch = self.get_handler()
1793
        src_path = 'd1/a'
1794
        dest_path = 'd2/a'
1795
        handler.process(self.file_command_iter(src_path, dest_path))
1796
        revtree1, revtree2 = self.assertChanges(branch, 2,
1797
            expected_modified=[(src_path,)],
1798
            expected_added=[('d2',), (dest_path,)])
1799
        self.assertContent(branch, revtree1, src_path, "aaa")
1800
        self.assertContent(branch, revtree2, src_path, "bbb")
1801
        self.assertContent(branch, revtree2, dest_path, "bbb")
1802
1803
    def test_copy_of_modified_symlink_in_root(self):
1804
        handler, branch = self.get_handler()
1805
        src_path = 'a'
1806
        dest_path = 'b'
1807
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1808
        revtree1, revtree2 = self.assertChanges(branch, 2,
1809
            expected_modified=[(src_path,)],
1810
            expected_added=[(dest_path,)])
1811
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1812
        self.assertSymlinkTarget(branch, revtree2, src_path, "bbb")
1813
        self.assertSymlinkTarget(branch, revtree2, dest_path, "bbb")
1814
        self.assertRevisionRoot(revtree1, src_path)
1815
        self.assertRevisionRoot(revtree2, dest_path)
1816
1817
    def test_copy_of_modified_symlink_in_subdir(self):
1818
        handler, branch = self.get_handler()
1819
        src_path = 'd/a'
1820
        dest_path = 'd/b'
1821
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1822
        revtree1, revtree2 = self.assertChanges(branch, 2,
1823
            expected_modified=[(src_path,)],
1824
            expected_added=[(dest_path,)])
1825
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1826
        self.assertSymlinkTarget(branch, revtree2, src_path, "bbb")
1827
        self.assertSymlinkTarget(branch, revtree2, dest_path, "bbb")
1828
1829
    def test_copy_of_modified_symlink_to_new_dir(self):
1830
        handler, branch = self.get_handler()
1831
        src_path = 'd1/a'
1832
        dest_path = 'd2/a'
1833
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
1834
        revtree1, revtree2 = self.assertChanges(branch, 2,
1835
            expected_modified=[(src_path,)],
1836
            expected_added=[('d2',), (dest_path,)])
1837
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
1838
        self.assertSymlinkTarget(branch, revtree2, src_path, "bbb")
1839
        self.assertSymlinkTarget(branch, revtree2, dest_path, "bbb")
0.99.10 by Ian Clatworthy
commented out draft of CopyModified tests
1840
1841
0.85.1 by Ian Clatworthy
extend tests to test the chk code path
1842
class TestImportToPackFileKinds(TestCaseForGenericProcessor):
0.64.74 by Ian Clatworthy
fix symlink importing
1843
1844
    def get_command_iter(self, path, kind, content):
0.123.13 by Jelmer Vernooij
Check for availability of fastimport before running tests.
1845
0.64.74 by Ian Clatworthy
fix symlink importing
1846
        def command_list():
1847
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1848
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1849
                yield commands.FileModifyCommand(path, kind_to_mode(kind, False),
0.64.74 by Ian Clatworthy
fix symlink importing
1850
                        None, content)
1851
            yield commands.CommitCommand('head', '1', None,
1852
                committer, "commit 1", None, [], files_one)
1853
        return command_list
1854
1855
    def test_import_plainfile(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
1856
        handler, branch = self.get_handler()
1857
        handler.process(self.get_command_iter('foo', 'file', 'aaa'))
0.64.74 by Ian Clatworthy
fix symlink importing
1858
1859
    def test_import_symlink(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
1860
        handler, branch = self.get_handler()
1861
        handler.process(self.get_command_iter('foo', 'symlink', 'bar'))
0.115.3 by John Arbash Meinel
add the failing test that we preserve the last-modified revision
1862
1863
1864
class TestModifyRevertInBranch(TestCaseForGenericProcessor):
1865
1866
    def file_command_iter(self):
1867
        # A     add 'foo'
1868
        # |\
1869
        # | B   modify 'foo'
1870
        # | |
1871
        # | C   revert 'foo' back to A
1872
        # |/
1873
        # D     merge 'foo'
1874
        def command_list():
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
1875
            committer_a = ['', 'a@elmer.com', time.time(), time.timezone]
1876
            committer_b = ['', 'b@elmer.com', time.time(), time.timezone]
1877
            committer_c = ['', 'c@elmer.com', time.time(), time.timezone]
1878
            committer_d = ['', 'd@elmer.com', time.time(), time.timezone]
0.115.3 by John Arbash Meinel
add the failing test that we preserve the last-modified revision
1879
            def files_one():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1880
                yield commands.FileModifyCommand('foo', kind_to_mode('file', False),
0.115.3 by John Arbash Meinel
add the failing test that we preserve the last-modified revision
1881
                        None, "content A\n")
1882
            yield commands.CommitCommand('head', '1', None,
1883
                committer_a, "commit 1", None, [], files_one)
1884
            def files_two():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1885
                yield commands.FileModifyCommand('foo', kind_to_mode('file', False),
0.115.3 by John Arbash Meinel
add the failing test that we preserve the last-modified revision
1886
                        None, "content B\n")
1887
            yield commands.CommitCommand('head', '2', None,
1888
                committer_b, "commit 2", ":1", [], files_two)
1889
            def files_three():
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
1890
                yield commands.FileModifyCommand('foo', kind_to_mode('file', False),
0.115.3 by John Arbash Meinel
add the failing test that we preserve the last-modified revision
1891
                        None, "content A\n")
1892
            yield commands.CommitCommand('head', '3', None,
1893
                committer_c, "commit 3", ":2", [], files_three)
1894
            yield commands.CommitCommand('head', '4', None,
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
1895
                committer_d, "commit 4", ":1", [':3'], lambda: [])
0.115.3 by John Arbash Meinel
add the failing test that we preserve the last-modified revision
1896
        return command_list
1897
1898
    def test_modify_revert(self):
1899
        handler, branch = self.get_handler()
1900
        handler.process(self.file_command_iter())
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
1901
        branch.lock_read()
1902
        self.addCleanup(branch.unlock)
1903
        rev_d = branch.last_revision()
1904
        rev_a, rev_c = branch.repository.get_parent_map([rev_d])[rev_d]
1905
        rev_b = branch.repository.get_parent_map([rev_c])[rev_c][0]
1906
        rtree_a, rtree_b, rtree_c, rtree_d = branch.repository.revision_trees([
1907
            rev_a, rev_b, rev_c, rev_d])
1908
        foo_id = rtree_a.path2id('foo')
1909
        self.assertEqual(rev_a, rtree_a.inventory[foo_id].revision)
1910
        self.assertEqual(rev_b, rtree_b.inventory[foo_id].revision)
1911
        self.assertEqual(rev_c, rtree_c.inventory[foo_id].revision)
1912
        self.assertEqual(rev_c, rtree_d.inventory[foo_id].revision)
0.64.303 by Jelmer Vernooij
Cope with non-utf8 characters in commit messages.
1913
1914
1915
class TestCommitCommands(TestCaseForGenericProcessor):
1916
1917
    def test_non_utf8_commit_message(self):
1918
        handler, branch = self.get_handler()
1919
        def files_one():
1920
            yield commands.FileModifyCommand('a',
1921
                kind_to_mode('file', False), None, "data")
1922
        def command_list():
1923
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
1924
            yield commands.CommitCommand('head', '1', None,
1925
                committer, 'This is a funky character: \x83', None, [],
1926
                files_one)
1927
        handler.process(command_list)
1928
        rev = branch.repository.get_revision(branch.last_revision())
1929
        self.assertEquals(u"This is a funky character: \ufffd", rev.message)