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