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