/brz/remove-bazaar

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