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