/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.65.4 by James Westby
Make the rename handling more robust.
1
# Copyright (C) 2008 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
import time
18
19
from bzrlib import (
20
    branch,
21
    tests,
22
    )
23
24
from bzrlib.plugins.fastimport import (
25
    commands,
26
    errors,
27
    )
28
29
from bzrlib.plugins.fastimport.processors import (
30
    generic_processor,
31
    )
32
33
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
34
class TestCaseForGenericProcessor(tests.TestCaseWithTransport):
0.65.4 by James Westby
Make the rename handling more robust.
35
36
    def get_handler(self):
37
        branch = self.make_branch('.')
38
        handler = generic_processor.GenericProcessor(branch.bzrdir)
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
39
        # Hack in the DeltaCommitHandler using experimental
40
        # This really need to be a parameterised test instead
41
        #handler = generic_processor.GenericProcessor(branch.bzrdir,
42
        #    params = {'experimental': True})
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
43
        return handler, branch
0.65.4 by James Westby
Make the rename handling more robust.
44
45
    # FIXME: [] as a default is bad, as it is mutable, but I want
46
    # to use None to mean "don't check this".
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
47
    def assertChanges(self, branch, revno, expected_added=[],
48
            expected_removed=[], expected_modified=[],
0.80.3 by Ian Clatworthy
file <-> symlink change tests
49
            expected_renamed=[], expected_kind_changed=[]):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
50
        """Check the changes introduced in a revision of a branch.
51
52
        This method checks that a revision introduces expected changes.
53
        The required changes are passed in as a list, where
54
        each entry contains the needed information about the change.
55
56
        If you do not wish to assert anything about a particular
57
        category then pass None instead.
58
59
        branch: The branch.
60
        revno: revision number of revision to check.
61
        expected_added: a list of (filename,) tuples that must have
62
            been added in the delta.
63
        expected_removed: a list of (filename,) tuples that must have
64
            been removed in the delta.
65
        expected_modified: a list of (filename,) tuples that must have
66
            been modified in the delta.
67
        expected_renamed: a list of (old_path, new_path) tuples that
68
            must have been renamed in the delta.
0.80.3 by Ian Clatworthy
file <-> symlink change tests
69
        expected_kind_changed: a list of (path, old_kind, new_kind) tuples
70
            that must have been changed in the delta.
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
71
        :return: revtree1, revtree2
72
        """
73
        repo = branch.repository
0.80.1 by Ian Clatworthy
basic units tests for filemodify
74
        revtree1 = repo.revision_tree(branch.get_rev_id(revno - 1))
75
        revtree2 = repo.revision_tree(branch.get_rev_id(revno))
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
76
        changes = revtree2.changes_from(revtree1)
0.80.3 by Ian Clatworthy
file <-> symlink change tests
77
        self._check_changes(changes, expected_added, expected_removed,
78
            expected_modified, expected_renamed, expected_kind_changed)
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
79
        return revtree1, revtree2
80
0.80.3 by Ian Clatworthy
file <-> symlink change tests
81
    def _check_changes(self, changes, expected_added=[],
0.65.4 by James Westby
Make the rename handling more robust.
82
            expected_removed=[], expected_modified=[],
0.80.3 by Ian Clatworthy
file <-> symlink change tests
83
            expected_renamed=[], expected_kind_changed=[]):
0.65.4 by James Westby
Make the rename handling more robust.
84
        """Check the changes in a TreeDelta
85
86
        This method checks that the TreeDelta contains the expected
87
        modifications between the two trees that were used to generate
88
        it. The required changes are passed in as a list, where
89
        each entry contains the needed information about the change.
90
91
        If you do not wish to assert anything about a particular
92
        category then pass None instead.
93
94
        changes: The TreeDelta to check.
95
        expected_added: a list of (filename,) tuples that must have
96
            been added in the delta.
97
        expected_removed: a list of (filename,) tuples that must have
98
            been removed in the delta.
99
        expected_modified: a list of (filename,) tuples that must have
100
            been modified in the delta.
101
        expected_renamed: a list of (old_path, new_path) tuples that
102
            must have been renamed in the delta.
0.80.3 by Ian Clatworthy
file <-> symlink change tests
103
        expected_kind_changed: a list of (path, old_kind, new_kind) tuples
104
            that must have been changed in the delta.
0.65.4 by James Westby
Make the rename handling more robust.
105
        """
106
        renamed = changes.renamed
107
        added = changes.added
108
        removed = changes.removed
109
        modified = changes.modified
0.80.3 by Ian Clatworthy
file <-> symlink change tests
110
        kind_changed = changes.kind_changed
0.65.4 by James Westby
Make the rename handling more robust.
111
        if expected_renamed is not None:
112
            self.assertEquals(len(renamed), len(expected_renamed),
0.74.1 by John Arbash Meinel
Change the rename code to create a new text entry.
113
                "%s is renamed, expected %s" % (renamed, expected_renamed))
0.65.4 by James Westby
Make the rename handling more robust.
114
            renamed_files = [(item[0], item[1]) for item in renamed]
115
            for expected_renamed_entry in expected_renamed:
116
                self.assertTrue(expected_renamed_entry in renamed_files,
117
                    "%s is not renamed, %s are" % (str(expected_renamed_entry),
118
                        renamed_files))
119
        if expected_added is not None:
120
            self.assertEquals(len(added), len(expected_added),
121
                "%s is added" % str(added))
122
            added_files = [(item[0],) for item in added]
123
            for expected_added_entry in expected_added:
124
                self.assertTrue(expected_added_entry in added_files,
125
                    "%s is not added, %s are" % (str(expected_added_entry),
126
                        added_files))
127
        if expected_removed is not None:
128
            self.assertEquals(len(removed), len(expected_removed),
129
                "%s is removed" % str(removed))
130
            removed_files = [(item[0],) for item in removed]
131
            for expected_removed_entry in expected_removed:
132
                self.assertTrue(expected_removed_entry in removed_files,
133
                    "%s is not removed, %s are" % (str(expected_removed_entry),
134
                        removed_files))
135
        if expected_modified is not None:
136
            self.assertEquals(len(modified), len(expected_modified),
137
                "%s is modified" % str(modified))
138
            modified_files = [(item[0],) for item in modified]
139
            for expected_modified_entry in expected_modified:
140
                self.assertTrue(expected_modified_entry in modified_files,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
141
                    "%s is not modified, %s are" % (
142
                    str(expected_modified_entry), modified_files))
143
        if expected_kind_changed is not None:
144
            self.assertEquals(len(kind_changed), len(expected_kind_changed),
145
                "%s is kind-changed, expected %s" % (kind_changed,
146
                    expected_kind_changed))
147
            kind_changed_files = [(item[0], item[2], item[3])
148
                for item in kind_changed]
149
            for expected_kind_changed_entry in expected_kind_changed:
150
                self.assertTrue(expected_kind_changed_entry in
151
                    kind_changed_files, "%s is not kind-changed, %s are" % (
152
                    str(expected_kind_changed_entry), kind_changed_files))
0.65.4 by James Westby
Make the rename handling more robust.
153
0.80.1 by Ian Clatworthy
basic units tests for filemodify
154
    def assertContent(self, branch, tree, path, content):
155
        file_id = tree.inventory.path2id(path)
156
        branch.lock_read()
157
        self.addCleanup(branch.unlock)
158
        self.assertEqual(tree.get_file_text(file_id), content)
159
160
    def assertSymlinkTarget(self, branch, tree, path, target):
161
        file_id = tree.inventory.path2id(path)
162
        branch.lock_read()
163
        self.addCleanup(branch.unlock)
164
        self.assertEqual(tree.get_symlink_target(file_id), target)
165
0.80.4 by Ian Clatworthy
file executable off <-> on tests
166
    def assertExecutable(self, branch, tree, path, executable):
167
        file_id = tree.inventory.path2id(path)
168
        branch.lock_read()
169
        self.addCleanup(branch.unlock)
170
        self.assertEqual(tree.is_executable(file_id), executable)
171
0.80.1 by Ian Clatworthy
basic units tests for filemodify
172
    def assertRevisionRoot(self, revtree, path):
173
        self.assertEqual(revtree.get_revision_id(),
174
                         revtree.inventory.root.children[path].revision)
175
176
177
class TestModify(TestCaseForGenericProcessor):
178
0.80.3 by Ian Clatworthy
file <-> symlink change tests
179
    def file_command_iter(self, path, kind='file', content='aaa',
0.80.4 by Ian Clatworthy
file executable off <-> on tests
180
        executable=False, to_kind=None, to_content='bbb', to_executable=None):
181
        # Revno 1: create a file or symlink
182
        # Revno 2: modify it
0.80.3 by Ian Clatworthy
file <-> symlink change tests
183
        if to_kind is None:
184
            to_kind = kind
0.80.4 by Ian Clatworthy
file executable off <-> on tests
185
        if to_executable is None:
186
            to_executable = executable
0.80.1 by Ian Clatworthy
basic units tests for filemodify
187
        def command_list():
188
            author = ['', 'bugs@a.com', time.time(), time.timezone]
189
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
190
            def files_one():
0.80.4 by Ian Clatworthy
file executable off <-> on tests
191
                yield commands.FileModifyCommand(path, kind, executable,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
192
                        None, content)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
193
            yield commands.CommitCommand('head', '1', author,
194
                committer, "commit 1", None, [], files_one)
195
            def files_two():
0.80.4 by Ian Clatworthy
file executable off <-> on tests
196
                yield commands.FileModifyCommand(path, to_kind, to_executable,
0.80.3 by Ian Clatworthy
file <-> symlink change tests
197
                        None, to_content)
0.80.1 by Ian Clatworthy
basic units tests for filemodify
198
            yield commands.CommitCommand('head', '2', author,
199
                committer, "commit 2", ":1", [], files_two)
200
        return command_list
201
202
    def test_modify_file_in_root(self):
203
        handler, branch = self.get_handler()
204
        path = 'a'
205
        handler.process(self.file_command_iter(path))
206
        revtree0, revtree1 = self.assertChanges(branch, 1,
207
            expected_added=[(path,)])
208
        revtree1, revtree2 = self.assertChanges(branch, 2,
209
            expected_modified=[(path,)])
210
        self.assertContent(branch, revtree1, path, "aaa")
211
        self.assertContent(branch, revtree2, path, "bbb")
212
        self.assertRevisionRoot(revtree1, path)
213
        self.assertRevisionRoot(revtree2, path)
214
215
    def test_modify_file_in_subdir(self):
216
        handler, branch = self.get_handler()
217
        path = 'a/a'
218
        handler.process(self.file_command_iter(path))
219
        revtree0, revtree1 = self.assertChanges(branch, 1,
220
            expected_added=[('a',), (path,)])
221
        revtree1, revtree2 = self.assertChanges(branch, 2,
222
            expected_modified=[(path,)])
223
        self.assertContent(branch, revtree1, path, "aaa")
224
        self.assertContent(branch, revtree2, path, "bbb")
225
226
    def test_modify_symlink_in_root(self):
227
        handler, branch = self.get_handler()
228
        path = 'a'
229
        handler.process(self.file_command_iter(path, kind='symlink'))
230
        revtree1, revtree2 = self.assertChanges(branch, 2,
231
            expected_modified=[(path,)])
232
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
233
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
234
        self.assertRevisionRoot(revtree1, path)
235
        self.assertRevisionRoot(revtree2, path)
236
237
    def test_modify_symlink_in_subdir(self):
238
        handler, branch = self.get_handler()
239
        path = 'a/a'
240
        handler.process(self.file_command_iter(path, kind='symlink'))
241
        revtree0, revtree1 = self.assertChanges(branch, 1,
242
            expected_added=[('a',), (path,)])
243
        revtree1, revtree2 = self.assertChanges(branch, 2,
244
            expected_modified=[(path,)])
245
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
246
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
247
0.80.3 by Ian Clatworthy
file <-> symlink change tests
248
    def test_modify_file_becomes_symlink(self):
249
        handler, branch = self.get_handler()
250
        path = 'a/a'
251
        handler.process(self.file_command_iter(path,
252
            kind='file', to_kind='symlink'))
253
        revtree0, revtree1 = self.assertChanges(branch, 1,
254
            expected_added=[('a',), (path,)])
255
        revtree1, revtree2 = self.assertChanges(branch, 2,
256
            expected_kind_changed=[(path, 'file', 'symlink')])
257
        self.assertContent(branch, revtree1, path, "aaa")
258
        self.assertSymlinkTarget(branch, revtree2, path, "bbb")
259
260
    def test_modify_symlink_becomes_file(self):
261
        handler, branch = self.get_handler()
262
        path = 'a/a'
263
        handler.process(self.file_command_iter(path,
264
            kind='symlink', to_kind='file'))
265
        revtree0, revtree1 = self.assertChanges(branch, 1,
266
            expected_added=[('a',), (path,)])
267
        revtree1, revtree2 = self.assertChanges(branch, 2,
268
            expected_kind_changed=[(path, 'symlink', 'file')])
269
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
270
        self.assertContent(branch, revtree2, path, "bbb")
271
0.80.4 by Ian Clatworthy
file executable off <-> on tests
272
    def test_modify_file_now_executable(self):
273
        handler, branch = self.get_handler()
274
        path = 'a/a'
275
        handler.process(self.file_command_iter(path,
276
            executable=False, to_executable=True, to_content='aaa'))
277
        revtree0, revtree1 = self.assertChanges(branch, 1,
278
            expected_added=[('a',), (path,)])
279
        revtree1, revtree2 = self.assertChanges(branch, 2,
280
            expected_modified=[(path,)])
281
        self.assertExecutable(branch, revtree1, path, False)
282
        self.assertExecutable(branch, revtree2, path, True)
283
284
    def test_modify_file_no_longer_executable(self):
285
        handler, branch = self.get_handler()
286
        path = 'a/a'
287
        handler.process(self.file_command_iter(path,
288
            executable=True, to_executable=False, to_content='aaa'))
289
        revtree0, revtree1 = self.assertChanges(branch, 1,
290
            expected_added=[('a',), (path,)])
291
        revtree1, revtree2 = self.assertChanges(branch, 2,
292
            expected_modified=[(path,)])
293
        self.assertExecutable(branch, revtree1, path, True)
294
        self.assertExecutable(branch, revtree2, path, False)
295
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
296
0.80.5 by Ian Clatworthy
file/symlink <-> directory change tests & fix
297
class TestModifyTricky(TestCaseForGenericProcessor):
298
299
    def file_command_iter(self, path1, path2, kind='file'):
300
        # Revno 1: create a file or symlink in a directory
301
        # Revno 2: create a second file that implicitly deletes the
302
        # first one because either:
303
        # * the new file is a in directory with the old file name
304
        # * the new file has the same name as the directory of the first
305
        def command_list():
306
            author = ['', 'bugs@a.com', time.time(), time.timezone]
307
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
308
            def files_one():
309
                yield commands.FileModifyCommand(path1, kind, False,
310
                        None, "aaa")
311
            yield commands.CommitCommand('head', '1', author,
312
                committer, "commit 1", None, [], files_one)
313
            def files_two():
314
                yield commands.FileModifyCommand(path2, kind, False,
315
                        None, "bbb")
316
            yield commands.CommitCommand('head', '2', author,
317
                committer, "commit 2", ":1", [], files_two)
318
        return command_list
319
320
321
    def test_modify_file_becomes_directory(self):
322
        handler, branch = self.get_handler()
323
        path1 = 'a/b'
324
        path2 = 'a/b/c'
325
        handler.process(self.file_command_iter(path1, path2))
326
        revtree0, revtree1 = self.assertChanges(branch, 1,
327
            expected_added=[('a',), (path1,)])
328
        revtree1, revtree2 = self.assertChanges(branch, 2,
329
            expected_added=[(path2,)],
330
            expected_kind_changed=[(path1, 'file', 'directory')])
331
        self.assertContent(branch, revtree1, path1, "aaa")
332
        self.assertContent(branch, revtree2, path2, "bbb")
333
334
    def test_modify_directory_becomes_file(self):
335
        handler, branch = self.get_handler()
336
        path1 = 'a/b/c'
337
        path2 = 'a/b'
338
        handler.process(self.file_command_iter(path1, path2))
339
        revtree0, revtree1 = self.assertChanges(branch, 1,
340
            expected_added=[('a',), ('a/b',), (path1,)])
341
        revtree1, revtree2 = self.assertChanges(branch, 2,
342
            expected_removed=[(path1,),],
343
            expected_kind_changed=[(path2, 'directory', 'file')])
344
        self.assertContent(branch, revtree1, path1, "aaa")
345
        self.assertContent(branch, revtree2, path2, "bbb")
346
347
    def test_modify_symlink_becomes_directory(self):
348
        handler, branch = self.get_handler()
349
        path1 = 'a/b'
350
        path2 = 'a/b/c'
351
        handler.process(self.file_command_iter(path1, path2, 'symlink'))
352
        revtree0, revtree1 = self.assertChanges(branch, 1,
353
            expected_added=[('a',), (path1,)])
354
        revtree1, revtree2 = self.assertChanges(branch, 2,
355
            expected_added=[(path2,)],
356
            expected_kind_changed=[(path1, 'symlink', 'directory')])
357
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
358
        self.assertSymlinkTarget(branch, revtree2, path2, "bbb")
359
360
    def test_modify_directory_becomes_symlink(self):
361
        handler, branch = self.get_handler()
362
        path1 = 'a/b/c'
363
        path2 = 'a/b'
364
        handler.process(self.file_command_iter(path1, path2, 'symlink'))
365
        revtree0, revtree1 = self.assertChanges(branch, 1,
366
            expected_added=[('a',), ('a/b',), (path1,)])
367
        revtree1, revtree2 = self.assertChanges(branch, 2,
368
            expected_removed=[(path1,),],
369
            expected_kind_changed=[(path2, 'directory', 'symlink')])
370
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
371
        self.assertSymlinkTarget(branch, revtree2, path2, "bbb")
372
373
0.80.2 by Ian Clatworthy
basic delete tests
374
class TestDelete(TestCaseForGenericProcessor):
375
376
    def file_command_iter(self, path, kind='file'):
0.80.4 by Ian Clatworthy
file executable off <-> on tests
377
        # Revno 1: create a file or symlink
378
        # Revno 2: delete it
0.80.2 by Ian Clatworthy
basic delete tests
379
        def command_list():
380
            author = ['', 'bugs@a.com', time.time(), time.timezone]
381
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
382
            def files_one():
383
                yield commands.FileModifyCommand(path, kind, False,
384
                        None, "aaa")
385
            yield commands.CommitCommand('head', '1', author,
386
                committer, "commit 1", None, [], files_one)
387
            def files_two():
388
                yield commands.FileDeleteCommand(path)
389
            yield commands.CommitCommand('head', '2', author,
390
                committer, "commit 2", ":1", [], files_two)
391
        return command_list
392
393
    def test_delete_file_in_root(self):
394
        handler, branch = self.get_handler()
395
        path = 'a'
396
        handler.process(self.file_command_iter(path))
397
        revtree0, revtree1 = self.assertChanges(branch, 1,
398
            expected_added=[(path,)])
399
        revtree1, revtree2 = self.assertChanges(branch, 2,
400
            expected_removed=[(path,)])
401
        self.assertContent(branch, revtree1, path, "aaa")
402
        self.assertRevisionRoot(revtree1, path)
403
404
    def test_delete_file_in_subdir(self):
405
        handler, branch = self.get_handler()
406
        path = 'a/a'
407
        handler.process(self.file_command_iter(path))
408
        revtree0, revtree1 = self.assertChanges(branch, 1,
409
            expected_added=[('a',), (path,)])
410
        revtree1, revtree2 = self.assertChanges(branch, 2,
411
            expected_removed=[(path,)])
412
        self.assertContent(branch, revtree1, path, "aaa")
413
414
    def test_delete_symlink_in_root(self):
415
        handler, branch = self.get_handler()
416
        path = 'a'
417
        handler.process(self.file_command_iter(path, kind='symlink'))
418
        revtree1, revtree2 = self.assertChanges(branch, 2,
419
            expected_removed=[(path,)])
420
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
421
        self.assertRevisionRoot(revtree1, path)
422
423
    def test_delete_symlink_in_subdir(self):
424
        handler, branch = self.get_handler()
425
        path = 'a/a'
426
        handler.process(self.file_command_iter(path, kind='symlink'))
427
        revtree0, revtree1 = self.assertChanges(branch, 1,
428
            expected_added=[('a',), (path,)])
429
        revtree1, revtree2 = self.assertChanges(branch, 2,
430
            expected_removed=[(path,)])
431
        self.assertSymlinkTarget(branch, revtree1, path, "aaa")
432
433
0.80.7 by Ian Clatworthy
add directory delete test
434
class TestDeleteDirectory(TestCaseForGenericProcessor):
435
436
    def file_command_iter(self, paths, dir):
437
        # Revno 1: create multiple files
438
        # Revno 2: delete a directory holding those files
439
        def command_list():
440
            author = ['', 'bugs@a.com', time.time(), time.timezone]
441
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
442
            def files_one():
443
                for i, path in enumerate(paths):
444
                    yield commands.FileModifyCommand(path, 'file', False,
445
                            None, "aaa%d" % i)
446
            yield commands.CommitCommand('head', '1', author,
447
                committer, "commit 1", None, [], files_one)
448
            def files_two():
449
                yield commands.FileDeleteCommand(dir)
450
            yield commands.CommitCommand('head', '2', author,
451
                committer, "commit 2", ":1", [], files_two)
452
        return command_list
453
454
    def test_delete_dir(self):
455
        handler, branch = self.get_handler()
456
        paths = ['a/b/c', 'a/b/d', 'a/b/e/f', 'a/g']
457
        dir = 'a/b'
458
        handler.process(self.file_command_iter(paths, dir))
459
        revtree0, revtree1 = self.assertChanges(branch, 1,
460
            expected_added=[
461
                ('a',), ('a/b',), ('a/b/c',),
462
                ('a/b/d',),
463
                ('a/b/e',), ('a/b/e/f',),
464
                ('a/g',),
465
                ])
466
        revtree1, revtree2 = self.assertChanges(branch, 2,
467
            expected_removed=[
468
                ('a/b',), ('a/b/c',),
469
                ('a/b/d',),
470
                ('a/b/e',), ('a/b/e/f',),
471
                ])
472
473
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
474
class TestRename(TestCaseForGenericProcessor):
475
476
    def get_command_iter(self, old_path, new_path):
0.80.4 by Ian Clatworthy
file executable off <-> on tests
477
        # Revno 1: create a file or symlink
478
        # Revno 2: rename it
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
479
        def command_list():
480
            author = ['', 'bugs@a.com', time.time(), time.timezone]
481
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
482
            def files_one():
483
                yield commands.FileModifyCommand(old_path, 'file', False,
484
                        None, "aaa")
485
            yield commands.CommitCommand('head', '1', author,
486
                committer, "commit 1", None, [], files_one)
487
            def files_two():
488
                yield commands.FileRenameCommand(old_path, new_path)
489
            yield commands.CommitCommand('head', '2', author,
490
                committer, "commit 2", ":1", [], files_two)
491
        return command_list
492
0.65.4 by James Westby
Make the rename handling more robust.
493
    def test_rename_in_root(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
494
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
495
        old_path = 'a'
496
        new_path = 'b'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
497
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
498
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
499
            expected_renamed=[(old_path, new_path)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
500
        self.assertRevisionRoot(revtree1, old_path)
501
        self.assertRevisionRoot(revtree2, new_path)
0.65.4 by James Westby
Make the rename handling more robust.
502
503
    def test_rename_in_subdir(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
504
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
505
        old_path = 'a/a'
506
        new_path = 'a/b'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
507
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
508
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)])
0.65.4 by James Westby
Make the rename handling more robust.
509
510
    def test_move_to_new_dir(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
511
        handler, branch = self.get_handler()
0.65.4 by James Westby
Make the rename handling more robust.
512
        old_path = 'a/a'
513
        new_path = 'b/a'
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
514
        handler.process(self.get_command_iter(old_path, new_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
515
        self.assertChanges(branch, 2, expected_renamed=[(old_path, new_path)],
0.65.4 by James Westby
Make the rename handling more robust.
516
            expected_added=[('b',)])
0.64.74 by Ian Clatworthy
fix symlink importing
517
518
0.80.6 by Ian Clatworthy
file/symlink <-> directory rename tests
519
class TestRenameTricky(TestCaseForGenericProcessor):
520
521
    def file_command_iter(self, path1, old_path2, new_path2, kind='file'):
522
        # Revno 1: create two files or symlinks in a directory
523
        # Revno 2: rename the second file so that it implicitly deletes the
524
        # first one because either:
525
        # * the new file is a in directory with the old file name
526
        # * the new file has the same name as the directory of the first
527
        def command_list():
528
            author = ['', 'bugs@a.com', time.time(), time.timezone]
529
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
530
            def files_one():
531
                yield commands.FileModifyCommand(path1, kind, False,
532
                        None, "aaa")
533
                yield commands.FileModifyCommand(old_path2, kind, False,
534
                        None, "bbb")
535
            yield commands.CommitCommand('head', '1', author,
536
                committer, "commit 1", None, [], files_one)
537
            def files_two():
538
                yield commands.FileRenameCommand(old_path2, new_path2)
539
            yield commands.CommitCommand('head', '2', author,
540
                committer, "commit 2", ":1", [], files_two)
541
        return command_list
542
543
544
    def test_rename_file_becomes_directory(self):
545
        handler, branch = self.get_handler()
546
        old_path2 = 'foo'
547
        path1     = 'a/b'
548
        new_path2 = 'a/b/c'
549
        handler.process(self.file_command_iter(path1, old_path2, new_path2))
550
        revtree0, revtree1 = self.assertChanges(branch, 1,
551
            expected_added=[('a',), (path1,), (old_path2,)])
552
        revtree1, revtree2 = self.assertChanges(branch, 2,
553
            expected_renamed=[(old_path2, new_path2)],
554
            expected_kind_changed=[(path1, 'file', 'directory')])
555
        self.assertContent(branch, revtree1, path1, "aaa")
556
        self.assertContent(branch, revtree2, new_path2, "bbb")
557
558
    def test_rename_directory_becomes_file(self):
559
        handler, branch = self.get_handler()
560
        old_path2 = 'foo'
561
        path1     = 'a/b/c'
562
        new_path2 = 'a/b'
563
        handler.process(self.file_command_iter(path1, old_path2, new_path2))
564
        revtree0, revtree1 = self.assertChanges(branch, 1,
565
            expected_added=[('a',), ('a/b',), (path1,), (old_path2,)])
566
        revtree1, revtree2 = self.assertChanges(branch, 2,
567
            expected_renamed=[(old_path2, new_path2)],
568
            expected_removed=[(path1,), (new_path2,)])
569
        self.assertContent(branch, revtree1, path1, "aaa")
570
        self.assertContent(branch, revtree2, new_path2, "bbb")
571
572
    def test_rename_symlink_becomes_directory(self):
573
        handler, branch = self.get_handler()
574
        old_path2 = 'foo'
575
        path1     = 'a/b'
576
        new_path2 = 'a/b/c'
577
        handler.process(self.file_command_iter(path1, old_path2, new_path2,
578
            'symlink'))
579
        revtree0, revtree1 = self.assertChanges(branch, 1,
580
            expected_added=[('a',), (path1,), (old_path2,)])
581
        revtree1, revtree2 = self.assertChanges(branch, 2,
582
            expected_renamed=[(old_path2, new_path2)],
583
            expected_kind_changed=[(path1, 'symlink', 'directory')])
584
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
585
        self.assertSymlinkTarget(branch, revtree2, new_path2, "bbb")
586
587
    def test_rename_directory_becomes_symlink(self):
588
        handler, branch = self.get_handler()
589
        old_path2 = 'foo'
590
        path1     = 'a/b/c'
591
        new_path2 = 'a/b'
592
        handler.process(self.file_command_iter(path1, old_path2, new_path2,
593
            'symlink'))
594
        revtree0, revtree1 = self.assertChanges(branch, 1,
595
            expected_added=[('a',), ('a/b',), (path1,), (old_path2,)])
596
        revtree1, revtree2 = self.assertChanges(branch, 2,
597
            expected_renamed=[(old_path2, new_path2)],
598
            expected_removed=[(path1,), (new_path2,)])
599
        self.assertSymlinkTarget(branch, revtree1, path1, "aaa")
600
        self.assertSymlinkTarget(branch, revtree2, new_path2, "bbb")
601
602
0.76.2 by Ian Clatworthy
code & tests for file copying
603
class TestCopy(TestCaseForGenericProcessor):
604
0.80.1 by Ian Clatworthy
basic units tests for filemodify
605
    def file_command_iter(self, src_path, dest_path, kind='file'):
0.80.4 by Ian Clatworthy
file executable off <-> on tests
606
        # Revno 1: create a file or symlink
607
        # Revno 2: copy it
0.76.2 by Ian Clatworthy
code & tests for file copying
608
        def command_list():
609
            author = ['', 'bugs@a.com', time.time(), time.timezone]
610
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
611
            def files_one():
0.80.1 by Ian Clatworthy
basic units tests for filemodify
612
                yield commands.FileModifyCommand(src_path, kind, False,
0.76.2 by Ian Clatworthy
code & tests for file copying
613
                        None, "aaa")
614
            yield commands.CommitCommand('head', '1', author,
615
                committer, "commit 1", None, [], files_one)
616
            def files_two():
617
                yield commands.FileCopyCommand(src_path, dest_path)
618
            yield commands.CommitCommand('head', '2', author,
619
                committer, "commit 2", ":1", [], files_two)
620
        return command_list
621
622
    def test_copy_file_in_root(self):
623
        handler, branch = self.get_handler()
624
        src_path = 'a'
625
        dest_path = 'b'
626
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
627
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
628
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
629
        self.assertContent(branch, revtree1, src_path, "aaa")
630
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
631
        self.assertContent(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
632
        self.assertRevisionRoot(revtree1, src_path)
633
        self.assertRevisionRoot(revtree2, dest_path)
0.76.2 by Ian Clatworthy
code & tests for file copying
634
635
    def test_copy_file_in_subdir(self):
636
        handler, branch = self.get_handler()
637
        src_path = 'a/a'
638
        dest_path = 'a/b'
639
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
640
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
641
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
642
        self.assertContent(branch, revtree1, src_path, "aaa")
643
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
644
        self.assertContent(branch, revtree2, dest_path, "aaa")
645
646
    def test_copy_file_to_new_dir(self):
647
        handler, branch = self.get_handler()
648
        src_path = 'a/a'
649
        dest_path = 'b/a'
650
        handler.process(self.file_command_iter(src_path, dest_path))
0.80.1 by Ian Clatworthy
basic units tests for filemodify
651
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.2 by Ian Clatworthy
code & tests for file copying
652
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
653
        self.assertContent(branch, revtree1, src_path, "aaa")
654
        self.assertContent(branch, revtree2, src_path, "aaa")
0.76.2 by Ian Clatworthy
code & tests for file copying
655
        self.assertContent(branch, revtree2, dest_path, "aaa")
656
0.76.3 by Ian Clatworthy
symlink copying tests
657
    def test_copy_symlink_in_root(self):
658
        handler, branch = self.get_handler()
659
        src_path = 'a'
660
        dest_path = 'b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
661
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
662
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
663
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
664
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
665
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
666
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
0.80.1 by Ian Clatworthy
basic units tests for filemodify
667
        self.assertRevisionRoot(revtree1, src_path)
668
        self.assertRevisionRoot(revtree2, dest_path)
0.76.3 by Ian Clatworthy
symlink copying tests
669
670
    def test_copy_symlink_in_subdir(self):
671
        handler, branch = self.get_handler()
672
        src_path = 'a/a'
673
        dest_path = 'a/b'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
674
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
675
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
676
            expected_added=[(dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
677
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
678
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
679
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
680
681
    def test_copy_symlink_to_new_dir(self):
682
        handler, branch = self.get_handler()
683
        src_path = 'a/a'
684
        dest_path = 'b/a'
0.80.1 by Ian Clatworthy
basic units tests for filemodify
685
        handler.process(self.file_command_iter(src_path, dest_path, 'symlink'))
686
        revtree1, revtree2 = self.assertChanges(branch, 2,
0.76.3 by Ian Clatworthy
symlink copying tests
687
            expected_added=[('b',), (dest_path,)])
0.80.1 by Ian Clatworthy
basic units tests for filemodify
688
        self.assertSymlinkTarget(branch, revtree1, src_path, "aaa")
689
        self.assertSymlinkTarget(branch, revtree2, src_path, "aaa")
0.76.3 by Ian Clatworthy
symlink copying tests
690
        self.assertSymlinkTarget(branch, revtree2, dest_path, "aaa")
691
0.76.2 by Ian Clatworthy
code & tests for file copying
692
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
693
class TestFileKinds(TestCaseForGenericProcessor):
0.64.74 by Ian Clatworthy
fix symlink importing
694
695
    def get_command_iter(self, path, kind, content):
696
        def command_list():
697
            committer = ['', 'elmer@a.com', time.time(), time.timezone]
698
            def files_one():
699
                yield commands.FileModifyCommand(path, kind, False,
700
                        None, content)
701
            yield commands.CommitCommand('head', '1', None,
702
                committer, "commit 1", None, [], files_one)
703
        return command_list
704
705
    def test_import_plainfile(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
706
        handler, branch = self.get_handler()
707
        handler.process(self.get_command_iter('foo', 'file', 'aaa'))
0.64.74 by Ian Clatworthy
fix symlink importing
708
709
    def test_import_symlink(self):
0.76.1 by Ian Clatworthy
clean-up tests for GenericProcessor
710
        handler, branch = self.get_handler()
711
        handler.process(self.get_command_iter('foo', 'symlink', 'bar'))