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