diff options
Diffstat (limited to 'tests/test_manifest_xml.py')
-rw-r--r-- | tests/test_manifest_xml.py | 346 |
1 files changed, 321 insertions, 25 deletions
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py index eda06968..cb3eb855 100644 --- a/tests/test_manifest_xml.py +++ b/tests/test_manifest_xml.py | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | import os | 17 | import os |
18 | import platform | 18 | import platform |
19 | import re | ||
19 | import shutil | 20 | import shutil |
20 | import tempfile | 21 | import tempfile |
21 | import unittest | 22 | import unittest |
@@ -52,6 +53,9 @@ INVALID_FS_PATHS = ( | |||
52 | 'blah/foo~', | 53 | 'blah/foo~', |
53 | # Block Unicode characters that get normalized out by filesystems. | 54 | # Block Unicode characters that get normalized out by filesystems. |
54 | u'foo\u200Cbar', | 55 | u'foo\u200Cbar', |
56 | # Block newlines. | ||
57 | 'f\n/bar', | ||
58 | 'f\r/bar', | ||
55 | ) | 59 | ) |
56 | 60 | ||
57 | # Make sure platforms that use path separators (e.g. Windows) are also | 61 | # Make sure platforms that use path separators (e.g. Windows) are also |
@@ -60,6 +64,30 @@ if os.path.sep != '/': | |||
60 | INVALID_FS_PATHS += tuple(x.replace('/', os.path.sep) for x in INVALID_FS_PATHS) | 64 | INVALID_FS_PATHS += tuple(x.replace('/', os.path.sep) for x in INVALID_FS_PATHS) |
61 | 65 | ||
62 | 66 | ||
67 | def sort_attributes(manifest): | ||
68 | """Sort the attributes of all elements alphabetically. | ||
69 | |||
70 | This is needed because different versions of the toxml() function from | ||
71 | xml.dom.minidom outputs the attributes of elements in different orders. | ||
72 | Before Python 3.8 they were output alphabetically, later versions preserve | ||
73 | the order specified by the user. | ||
74 | |||
75 | Args: | ||
76 | manifest: String containing an XML manifest. | ||
77 | |||
78 | Returns: | ||
79 | The XML manifest with the attributes of all elements sorted alphabetically. | ||
80 | """ | ||
81 | new_manifest = '' | ||
82 | # This will find every element in the XML manifest, whether they have | ||
83 | # attributes or not. This simplifies recreating the manifest below. | ||
84 | matches = re.findall(r'(<[/?]?[a-z-]+\s*)((?:\S+?="[^"]+"\s*?)*)(\s*[/?]?>)', manifest) | ||
85 | for head, attrs, tail in matches: | ||
86 | m = re.findall(r'\S+?="[^"]+"', attrs) | ||
87 | new_manifest += head + ' '.join(sorted(m)) + tail | ||
88 | return new_manifest | ||
89 | |||
90 | |||
63 | class ManifestParseTestCase(unittest.TestCase): | 91 | class ManifestParseTestCase(unittest.TestCase): |
64 | """TestCase for parsing manifests.""" | 92 | """TestCase for parsing manifests.""" |
65 | 93 | ||
@@ -91,6 +119,11 @@ class ManifestParseTestCase(unittest.TestCase): | |||
91 | fp.write(data) | 119 | fp.write(data) |
92 | return manifest_xml.XmlManifest(self.repodir, self.manifest_file) | 120 | return manifest_xml.XmlManifest(self.repodir, self.manifest_file) |
93 | 121 | ||
122 | @staticmethod | ||
123 | def encodeXmlAttr(attr): | ||
124 | """Encode |attr| using XML escape rules.""" | ||
125 | return attr.replace('\r', '
').replace('\n', '
') | ||
126 | |||
94 | 127 | ||
95 | class ManifestValidateFilePaths(unittest.TestCase): | 128 | class ManifestValidateFilePaths(unittest.TestCase): |
96 | """Check _ValidateFilePaths helper. | 129 | """Check _ValidateFilePaths helper. |
@@ -232,6 +265,19 @@ class XmlManifestTests(ManifestParseTestCase): | |||
232 | self.assertEqual(manifest.repo_hooks_project.name, 'repohooks') | 265 | self.assertEqual(manifest.repo_hooks_project.name, 'repohooks') |
233 | self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b']) | 266 | self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b']) |
234 | 267 | ||
268 | def test_repo_hooks_unordered(self): | ||
269 | """Check repo-hooks settings work even if the project def comes second.""" | ||
270 | manifest = self.getXmlManifest(""" | ||
271 | <manifest> | ||
272 | <remote name="test-remote" fetch="http://localhost" /> | ||
273 | <default remote="test-remote" revision="refs/heads/main" /> | ||
274 | <repo-hooks in-project="repohooks" enabled-list="a, b"/> | ||
275 | <project name="repohooks" path="src/repohooks"/> | ||
276 | </manifest> | ||
277 | """) | ||
278 | self.assertEqual(manifest.repo_hooks_project.name, 'repohooks') | ||
279 | self.assertEqual(manifest.repo_hooks_project.enabled_repo_hooks, ['a', 'b']) | ||
280 | |||
235 | def test_unknown_tags(self): | 281 | def test_unknown_tags(self): |
236 | """Check superproject settings.""" | 282 | """Check superproject settings.""" |
237 | manifest = self.getXmlManifest(""" | 283 | manifest = self.getXmlManifest(""" |
@@ -246,11 +292,30 @@ class XmlManifestTests(ManifestParseTestCase): | |||
246 | self.assertEqual(manifest.superproject['name'], 'superproject') | 292 | self.assertEqual(manifest.superproject['name'], 'superproject') |
247 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') | 293 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') |
248 | self.assertEqual( | 294 | self.assertEqual( |
249 | manifest.ToXml().toxml(), | 295 | sort_attributes(manifest.ToXml().toxml()), |
250 | '<?xml version="1.0" ?><manifest>' + | 296 | '<?xml version="1.0" ?><manifest>' |
251 | '<remote name="test-remote" fetch="http://localhost"/>' + | 297 | '<remote fetch="http://localhost" name="test-remote"/>' |
252 | '<default remote="test-remote" revision="refs/heads/main"/>' + | 298 | '<default remote="test-remote" revision="refs/heads/main"/>' |
253 | '<superproject name="superproject"/>' + | 299 | '<superproject name="superproject"/>' |
300 | '</manifest>') | ||
301 | |||
302 | def test_remote_annotations(self): | ||
303 | """Check remote settings.""" | ||
304 | manifest = self.getXmlManifest(""" | ||
305 | <manifest> | ||
306 | <remote name="test-remote" fetch="http://localhost"> | ||
307 | <annotation name="foo" value="bar"/> | ||
308 | </remote> | ||
309 | </manifest> | ||
310 | """) | ||
311 | self.assertEqual(manifest.remotes['test-remote'].annotations[0].name, 'foo') | ||
312 | self.assertEqual(manifest.remotes['test-remote'].annotations[0].value, 'bar') | ||
313 | self.assertEqual( | ||
314 | sort_attributes(manifest.ToXml().toxml()), | ||
315 | '<?xml version="1.0" ?><manifest>' | ||
316 | '<remote fetch="http://localhost" name="test-remote">' | ||
317 | '<annotation name="foo" value="bar"/>' | ||
318 | '</remote>' | ||
254 | '</manifest>') | 319 | '</manifest>') |
255 | 320 | ||
256 | 321 | ||
@@ -303,6 +368,7 @@ class IncludeElementTests(ManifestParseTestCase): | |||
303 | def test_allow_bad_name_from_user(self): | 368 | def test_allow_bad_name_from_user(self): |
304 | """Check handling of bad name attribute from the user's input.""" | 369 | """Check handling of bad name attribute from the user's input.""" |
305 | def parse(name): | 370 | def parse(name): |
371 | name = self.encodeXmlAttr(name) | ||
306 | manifest = self.getXmlManifest(f""" | 372 | manifest = self.getXmlManifest(f""" |
307 | <manifest> | 373 | <manifest> |
308 | <remote name="default-remote" fetch="http://localhost" /> | 374 | <remote name="default-remote" fetch="http://localhost" /> |
@@ -327,6 +393,7 @@ class IncludeElementTests(ManifestParseTestCase): | |||
327 | def test_bad_name_checks(self): | 393 | def test_bad_name_checks(self): |
328 | """Check handling of bad name attribute.""" | 394 | """Check handling of bad name attribute.""" |
329 | def parse(name): | 395 | def parse(name): |
396 | name = self.encodeXmlAttr(name) | ||
330 | # Setup target of the include. | 397 | # Setup target of the include. |
331 | with open(os.path.join(self.manifest_dir, 'target.xml'), 'w') as fp: | 398 | with open(os.path.join(self.manifest_dir, 'target.xml'), 'w') as fp: |
332 | fp.write(f'<manifest><include name="{name}"/></manifest>') | 399 | fp.write(f'<manifest><include name="{name}"/></manifest>') |
@@ -398,16 +465,18 @@ class ProjectElementTests(ManifestParseTestCase): | |||
398 | project = manifest.projects[0] | 465 | project = manifest.projects[0] |
399 | project.SetRevisionId('ABCDEF') | 466 | project.SetRevisionId('ABCDEF') |
400 | self.assertEqual( | 467 | self.assertEqual( |
401 | manifest.ToXml().toxml(), | 468 | sort_attributes(manifest.ToXml().toxml()), |
402 | '<?xml version="1.0" ?><manifest>' + | 469 | '<?xml version="1.0" ?><manifest>' |
403 | '<remote name="default-remote" fetch="http://localhost"/>' + | 470 | '<remote fetch="http://localhost" name="default-remote"/>' |
404 | '<default remote="default-remote" revision="refs/heads/main"/>' + | 471 | '<default remote="default-remote" revision="refs/heads/main"/>' |
405 | '<project name="test-name" revision="ABCDEF"/>' + | 472 | '<project name="test-name" revision="ABCDEF" upstream="refs/heads/main"/>' |
406 | '</manifest>') | 473 | '</manifest>') |
407 | 474 | ||
408 | def test_trailing_slash(self): | 475 | def test_trailing_slash(self): |
409 | """Check handling of trailing slashes in attributes.""" | 476 | """Check handling of trailing slashes in attributes.""" |
410 | def parse(name, path): | 477 | def parse(name, path): |
478 | name = self.encodeXmlAttr(name) | ||
479 | path = self.encodeXmlAttr(path) | ||
411 | return self.getXmlManifest(f""" | 480 | return self.getXmlManifest(f""" |
412 | <manifest> | 481 | <manifest> |
413 | <remote name="default-remote" fetch="http://localhost" /> | 482 | <remote name="default-remote" fetch="http://localhost" /> |
@@ -437,6 +506,8 @@ class ProjectElementTests(ManifestParseTestCase): | |||
437 | def test_toplevel_path(self): | 506 | def test_toplevel_path(self): |
438 | """Check handling of path=. specially.""" | 507 | """Check handling of path=. specially.""" |
439 | def parse(name, path): | 508 | def parse(name, path): |
509 | name = self.encodeXmlAttr(name) | ||
510 | path = self.encodeXmlAttr(path) | ||
440 | return self.getXmlManifest(f""" | 511 | return self.getXmlManifest(f""" |
441 | <manifest> | 512 | <manifest> |
442 | <remote name="default-remote" fetch="http://localhost" /> | 513 | <remote name="default-remote" fetch="http://localhost" /> |
@@ -453,6 +524,8 @@ class ProjectElementTests(ManifestParseTestCase): | |||
453 | def test_bad_path_name_checks(self): | 524 | def test_bad_path_name_checks(self): |
454 | """Check handling of bad path & name attributes.""" | 525 | """Check handling of bad path & name attributes.""" |
455 | def parse(name, path): | 526 | def parse(name, path): |
527 | name = self.encodeXmlAttr(name) | ||
528 | path = self.encodeXmlAttr(path) | ||
456 | manifest = self.getXmlManifest(f""" | 529 | manifest = self.getXmlManifest(f""" |
457 | <manifest> | 530 | <manifest> |
458 | <remote name="default-remote" fetch="http://localhost" /> | 531 | <remote name="default-remote" fetch="http://localhost" /> |
@@ -499,12 +572,79 @@ class SuperProjectElementTests(ManifestParseTestCase): | |||
499 | self.assertEqual(manifest.superproject['name'], 'superproject') | 572 | self.assertEqual(manifest.superproject['name'], 'superproject') |
500 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') | 573 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') |
501 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') | 574 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') |
575 | self.assertEqual(manifest.superproject['revision'], 'refs/heads/main') | ||
502 | self.assertEqual( | 576 | self.assertEqual( |
503 | manifest.ToXml().toxml(), | 577 | sort_attributes(manifest.ToXml().toxml()), |
504 | '<?xml version="1.0" ?><manifest>' + | 578 | '<?xml version="1.0" ?><manifest>' |
505 | '<remote name="test-remote" fetch="http://localhost"/>' + | 579 | '<remote fetch="http://localhost" name="test-remote"/>' |
506 | '<default remote="test-remote" revision="refs/heads/main"/>' + | 580 | '<default remote="test-remote" revision="refs/heads/main"/>' |
507 | '<superproject name="superproject"/>' + | 581 | '<superproject name="superproject"/>' |
582 | '</manifest>') | ||
583 | |||
584 | def test_superproject_revision(self): | ||
585 | """Check superproject settings with a different revision attribute""" | ||
586 | self.maxDiff = None | ||
587 | manifest = self.getXmlManifest(""" | ||
588 | <manifest> | ||
589 | <remote name="test-remote" fetch="http://localhost" /> | ||
590 | <default remote="test-remote" revision="refs/heads/main" /> | ||
591 | <superproject name="superproject" revision="refs/heads/stable" /> | ||
592 | </manifest> | ||
593 | """) | ||
594 | self.assertEqual(manifest.superproject['name'], 'superproject') | ||
595 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') | ||
596 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') | ||
597 | self.assertEqual(manifest.superproject['revision'], 'refs/heads/stable') | ||
598 | self.assertEqual( | ||
599 | sort_attributes(manifest.ToXml().toxml()), | ||
600 | '<?xml version="1.0" ?><manifest>' | ||
601 | '<remote fetch="http://localhost" name="test-remote"/>' | ||
602 | '<default remote="test-remote" revision="refs/heads/main"/>' | ||
603 | '<superproject name="superproject" revision="refs/heads/stable"/>' | ||
604 | '</manifest>') | ||
605 | |||
606 | def test_superproject_revision_default_negative(self): | ||
607 | """Check superproject settings with a same revision attribute""" | ||
608 | self.maxDiff = None | ||
609 | manifest = self.getXmlManifest(""" | ||
610 | <manifest> | ||
611 | <remote name="test-remote" fetch="http://localhost" /> | ||
612 | <default remote="test-remote" revision="refs/heads/stable" /> | ||
613 | <superproject name="superproject" revision="refs/heads/stable" /> | ||
614 | </manifest> | ||
615 | """) | ||
616 | self.assertEqual(manifest.superproject['name'], 'superproject') | ||
617 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') | ||
618 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') | ||
619 | self.assertEqual(manifest.superproject['revision'], 'refs/heads/stable') | ||
620 | self.assertEqual( | ||
621 | sort_attributes(manifest.ToXml().toxml()), | ||
622 | '<?xml version="1.0" ?><manifest>' | ||
623 | '<remote fetch="http://localhost" name="test-remote"/>' | ||
624 | '<default remote="test-remote" revision="refs/heads/stable"/>' | ||
625 | '<superproject name="superproject"/>' | ||
626 | '</manifest>') | ||
627 | |||
628 | def test_superproject_revision_remote(self): | ||
629 | """Check superproject settings with a same revision attribute""" | ||
630 | self.maxDiff = None | ||
631 | manifest = self.getXmlManifest(""" | ||
632 | <manifest> | ||
633 | <remote name="test-remote" fetch="http://localhost" revision="refs/heads/main" /> | ||
634 | <default remote="test-remote" /> | ||
635 | <superproject name="superproject" revision="refs/heads/stable" /> | ||
636 | </manifest> | ||
637 | """) | ||
638 | self.assertEqual(manifest.superproject['name'], 'superproject') | ||
639 | self.assertEqual(manifest.superproject['remote'].name, 'test-remote') | ||
640 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') | ||
641 | self.assertEqual(manifest.superproject['revision'], 'refs/heads/stable') | ||
642 | self.assertEqual( | ||
643 | sort_attributes(manifest.ToXml().toxml()), | ||
644 | '<?xml version="1.0" ?><manifest>' | ||
645 | '<remote fetch="http://localhost" name="test-remote" revision="refs/heads/main"/>' | ||
646 | '<default remote="test-remote"/>' | ||
647 | '<superproject name="superproject" revision="refs/heads/stable"/>' | ||
508 | '</manifest>') | 648 | '</manifest>') |
509 | 649 | ||
510 | def test_remote(self): | 650 | def test_remote(self): |
@@ -520,13 +660,14 @@ class SuperProjectElementTests(ManifestParseTestCase): | |||
520 | self.assertEqual(manifest.superproject['name'], 'platform/superproject') | 660 | self.assertEqual(manifest.superproject['name'], 'platform/superproject') |
521 | self.assertEqual(manifest.superproject['remote'].name, 'superproject-remote') | 661 | self.assertEqual(manifest.superproject['remote'].name, 'superproject-remote') |
522 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject') | 662 | self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject') |
663 | self.assertEqual(manifest.superproject['revision'], 'refs/heads/main') | ||
523 | self.assertEqual( | 664 | self.assertEqual( |
524 | manifest.ToXml().toxml(), | 665 | sort_attributes(manifest.ToXml().toxml()), |
525 | '<?xml version="1.0" ?><manifest>' + | 666 | '<?xml version="1.0" ?><manifest>' |
526 | '<remote name="default-remote" fetch="http://localhost"/>' + | 667 | '<remote fetch="http://localhost" name="default-remote"/>' |
527 | '<remote name="superproject-remote" fetch="http://localhost"/>' + | 668 | '<remote fetch="http://localhost" name="superproject-remote"/>' |
528 | '<default remote="default-remote" revision="refs/heads/main"/>' + | 669 | '<default remote="default-remote" revision="refs/heads/main"/>' |
529 | '<superproject name="platform/superproject" remote="superproject-remote"/>' + | 670 | '<superproject name="platform/superproject" remote="superproject-remote"/>' |
530 | '</manifest>') | 671 | '</manifest>') |
531 | 672 | ||
532 | def test_defalut_remote(self): | 673 | def test_defalut_remote(self): |
@@ -540,10 +681,165 @@ class SuperProjectElementTests(ManifestParseTestCase): | |||
540 | """) | 681 | """) |
541 | self.assertEqual(manifest.superproject['name'], 'superproject') | 682 | self.assertEqual(manifest.superproject['name'], 'superproject') |
542 | self.assertEqual(manifest.superproject['remote'].name, 'default-remote') | 683 | self.assertEqual(manifest.superproject['remote'].name, 'default-remote') |
684 | self.assertEqual(manifest.superproject['revision'], 'refs/heads/main') | ||
685 | self.assertEqual( | ||
686 | sort_attributes(manifest.ToXml().toxml()), | ||
687 | '<?xml version="1.0" ?><manifest>' | ||
688 | '<remote fetch="http://localhost" name="default-remote"/>' | ||
689 | '<default remote="default-remote" revision="refs/heads/main"/>' | ||
690 | '<superproject name="superproject"/>' | ||
691 | '</manifest>') | ||
692 | |||
693 | |||
694 | class ContactinfoElementTests(ManifestParseTestCase): | ||
695 | """Tests for <contactinfo>.""" | ||
696 | |||
697 | def test_contactinfo(self): | ||
698 | """Check contactinfo settings.""" | ||
699 | bugurl = 'http://localhost/contactinfo' | ||
700 | manifest = self.getXmlManifest(f""" | ||
701 | <manifest> | ||
702 | <contactinfo bugurl="{bugurl}"/> | ||
703 | </manifest> | ||
704 | """) | ||
705 | self.assertEqual(manifest.contactinfo.bugurl, bugurl) | ||
543 | self.assertEqual( | 706 | self.assertEqual( |
544 | manifest.ToXml().toxml(), | 707 | manifest.ToXml().toxml(), |
545 | '<?xml version="1.0" ?><manifest>' + | 708 | '<?xml version="1.0" ?><manifest>' |
546 | '<remote name="default-remote" fetch="http://localhost"/>' + | 709 | f'<contactinfo bugurl="{bugurl}"/>' |
547 | '<default remote="default-remote" revision="refs/heads/main"/>' + | ||
548 | '<superproject name="superproject"/>' + | ||
549 | '</manifest>') | 710 | '</manifest>') |
711 | |||
712 | |||
713 | class DefaultElementTests(ManifestParseTestCase): | ||
714 | """Tests for <default>.""" | ||
715 | |||
716 | def test_default(self): | ||
717 | """Check default settings.""" | ||
718 | a = manifest_xml._Default() | ||
719 | a.revisionExpr = 'foo' | ||
720 | a.remote = manifest_xml._XmlRemote(name='remote') | ||
721 | b = manifest_xml._Default() | ||
722 | b.revisionExpr = 'bar' | ||
723 | self.assertEqual(a, a) | ||
724 | self.assertNotEqual(a, b) | ||
725 | self.assertNotEqual(b, a.remote) | ||
726 | self.assertNotEqual(a, 123) | ||
727 | self.assertNotEqual(a, None) | ||
728 | |||
729 | |||
730 | class RemoteElementTests(ManifestParseTestCase): | ||
731 | """Tests for <remote>.""" | ||
732 | |||
733 | def test_remote(self): | ||
734 | """Check remote settings.""" | ||
735 | a = manifest_xml._XmlRemote(name='foo') | ||
736 | a.AddAnnotation('key1', 'value1', 'true') | ||
737 | b = manifest_xml._XmlRemote(name='foo') | ||
738 | b.AddAnnotation('key2', 'value1', 'true') | ||
739 | c = manifest_xml._XmlRemote(name='foo') | ||
740 | c.AddAnnotation('key1', 'value2', 'true') | ||
741 | d = manifest_xml._XmlRemote(name='foo') | ||
742 | d.AddAnnotation('key1', 'value1', 'false') | ||
743 | self.assertEqual(a, a) | ||
744 | self.assertNotEqual(a, b) | ||
745 | self.assertNotEqual(a, c) | ||
746 | self.assertNotEqual(a, d) | ||
747 | self.assertNotEqual(a, manifest_xml._Default()) | ||
748 | self.assertNotEqual(a, 123) | ||
749 | self.assertNotEqual(a, None) | ||
750 | |||
751 | |||
752 | class RemoveProjectElementTests(ManifestParseTestCase): | ||
753 | """Tests for <remove-project>.""" | ||
754 | |||
755 | def test_remove_one_project(self): | ||
756 | manifest = self.getXmlManifest(""" | ||
757 | <manifest> | ||
758 | <remote name="default-remote" fetch="http://localhost" /> | ||
759 | <default remote="default-remote" revision="refs/heads/main" /> | ||
760 | <project name="myproject" /> | ||
761 | <remove-project name="myproject" /> | ||
762 | </manifest> | ||
763 | """) | ||
764 | self.assertEqual(manifest.projects, []) | ||
765 | |||
766 | def test_remove_one_project_one_remains(self): | ||
767 | manifest = self.getXmlManifest(""" | ||
768 | <manifest> | ||
769 | <remote name="default-remote" fetch="http://localhost" /> | ||
770 | <default remote="default-remote" revision="refs/heads/main" /> | ||
771 | <project name="myproject" /> | ||
772 | <project name="yourproject" /> | ||
773 | <remove-project name="myproject" /> | ||
774 | </manifest> | ||
775 | """) | ||
776 | |||
777 | self.assertEqual(len(manifest.projects), 1) | ||
778 | self.assertEqual(manifest.projects[0].name, 'yourproject') | ||
779 | |||
780 | def test_remove_one_project_doesnt_exist(self): | ||
781 | with self.assertRaises(manifest_xml.ManifestParseError): | ||
782 | manifest = self.getXmlManifest(""" | ||
783 | <manifest> | ||
784 | <remote name="default-remote" fetch="http://localhost" /> | ||
785 | <default remote="default-remote" revision="refs/heads/main" /> | ||
786 | <remove-project name="myproject" /> | ||
787 | </manifest> | ||
788 | """) | ||
789 | manifest.projects | ||
790 | |||
791 | def test_remove_one_optional_project_doesnt_exist(self): | ||
792 | manifest = self.getXmlManifest(""" | ||
793 | <manifest> | ||
794 | <remote name="default-remote" fetch="http://localhost" /> | ||
795 | <default remote="default-remote" revision="refs/heads/main" /> | ||
796 | <remove-project name="myproject" optional="true" /> | ||
797 | </manifest> | ||
798 | """) | ||
799 | self.assertEqual(manifest.projects, []) | ||
800 | |||
801 | |||
802 | class ExtendProjectElementTests(ManifestParseTestCase): | ||
803 | """Tests for <extend-project>.""" | ||
804 | |||
805 | def test_extend_project_dest_path_single_match(self): | ||
806 | manifest = self.getXmlManifest(""" | ||
807 | <manifest> | ||
808 | <remote name="default-remote" fetch="http://localhost" /> | ||
809 | <default remote="default-remote" revision="refs/heads/main" /> | ||
810 | <project name="myproject" /> | ||
811 | <extend-project name="myproject" dest-path="bar" /> | ||
812 | </manifest> | ||
813 | """) | ||
814 | self.assertEqual(len(manifest.projects), 1) | ||
815 | self.assertEqual(manifest.projects[0].relpath, 'bar') | ||
816 | |||
817 | def test_extend_project_dest_path_multi_match(self): | ||
818 | with self.assertRaises(manifest_xml.ManifestParseError): | ||
819 | manifest = self.getXmlManifest(""" | ||
820 | <manifest> | ||
821 | <remote name="default-remote" fetch="http://localhost" /> | ||
822 | <default remote="default-remote" revision="refs/heads/main" /> | ||
823 | <project name="myproject" path="x" /> | ||
824 | <project name="myproject" path="y" /> | ||
825 | <extend-project name="myproject" dest-path="bar" /> | ||
826 | </manifest> | ||
827 | """) | ||
828 | manifest.projects | ||
829 | |||
830 | def test_extend_project_dest_path_multi_match_path_specified(self): | ||
831 | manifest = self.getXmlManifest(""" | ||
832 | <manifest> | ||
833 | <remote name="default-remote" fetch="http://localhost" /> | ||
834 | <default remote="default-remote" revision="refs/heads/main" /> | ||
835 | <project name="myproject" path="x" /> | ||
836 | <project name="myproject" path="y" /> | ||
837 | <extend-project name="myproject" path="x" dest-path="bar" /> | ||
838 | </manifest> | ||
839 | """) | ||
840 | self.assertEqual(len(manifest.projects), 2) | ||
841 | if manifest.projects[0].relpath == 'y': | ||
842 | self.assertEqual(manifest.projects[1].relpath, 'bar') | ||
843 | else: | ||
844 | self.assertEqual(manifest.projects[0].relpath, 'bar') | ||
845 | self.assertEqual(manifest.projects[1].relpath, 'y') | ||