diff --git a/tests/test_git_superproject.py b/tests/test_git_superproject.py index 5c1455f5..b1ae3576 100644 --- a/tests/test_git_superproject.py +++ b/tests/test_git_superproject.py @@ -23,6 +23,7 @@ from unittest import mock import git_superproject import manifest_xml import platform_utils +from test_manifest_xml import sort_attributes class SuperprojectTestCase(unittest.TestCase): @@ -140,12 +141,12 @@ class SuperprojectTestCase(unittest.TestCase): with open(manifest_path, 'r') as fp: manifest_xml = fp.read() self.assertEqual( - manifest_xml, + sort_attributes(manifest_xml), '' - '' + '' '' - '' + '' '' '') @@ -167,13 +168,13 @@ class SuperprojectTestCase(unittest.TestCase): with open(manifest_path, 'r') as fp: manifest_xml = fp.read() self.assertEqual( - manifest_xml, + sort_attributes(manifest_xml), '' - '' + '' '' - '' + '' '' '') @@ -208,16 +209,17 @@ class SuperprojectTestCase(unittest.TestCase): with open(manifest_path, 'r') as fp: manifest_xml = fp.read() self.assertEqual( - manifest_xml, + sort_attributes(manifest_xml), '' - '' - '' + '' + '' '' - '' - '' + '' + '' '' '') diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py index 99848e57..bd74780d 100644 --- a/tests/test_manifest_xml.py +++ b/tests/test_manifest_xml.py @@ -16,6 +16,7 @@ import os import platform +import re import shutil import tempfile import unittest @@ -63,6 +64,30 @@ if os.path.sep != '/': INVALID_FS_PATHS += tuple(x.replace('/', os.path.sep) for x in INVALID_FS_PATHS) +def sort_attributes(manifest): + """Sort the attributes of all elements alphabetically. + + This is needed because different versions of the toxml() function from + xml.dom.minidom outputs the attributes of elements in different orders. + Before Python 3.8 they were output alphabetically, later versions preserve + the order specified by the user. + + Args: + manifest: String containing an XML manifest. + + Returns: + The XML manifest with the attributes of all elements sorted alphabetically. + """ + new_manifest = '' + # This will find every element in the XML manifest, whether they have + # attributes or not. This simplifies recreating the manifest below. + matches = re.findall(r'(<[/?]?[a-z-]+\s*)((?:\S+?="[^"]+"\s*?)*)(\s*[/?]?>)', manifest) + for head, attrs, tail in matches: + m = re.findall(r'\S+?="[^"]+"', attrs) + new_manifest += head + ' '.join(sorted(m)) + tail + return new_manifest + + class ManifestParseTestCase(unittest.TestCase): """TestCase for parsing manifests.""" @@ -254,9 +279,9 @@ class XmlManifestTests(ManifestParseTestCase): self.assertEqual(manifest.superproject['name'], 'superproject') self.assertEqual(manifest.superproject['remote'].name, 'test-remote') self.assertEqual( - manifest.ToXml().toxml(), + sort_attributes(manifest.ToXml().toxml()), '' - '' + '' '' '' '') @@ -408,9 +433,9 @@ class ProjectElementTests(ManifestParseTestCase): project = manifest.projects[0] project.SetRevisionId('ABCDEF') self.assertEqual( - manifest.ToXml().toxml(), + sort_attributes(manifest.ToXml().toxml()), '' - '' + '' '' '' '') @@ -516,9 +541,9 @@ class SuperProjectElementTests(ManifestParseTestCase): self.assertEqual(manifest.superproject['remote'].name, 'test-remote') self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/superproject') self.assertEqual( - manifest.ToXml().toxml(), + sort_attributes(manifest.ToXml().toxml()), '' - '' + '' '' '' '') @@ -537,10 +562,10 @@ class SuperProjectElementTests(ManifestParseTestCase): self.assertEqual(manifest.superproject['remote'].name, 'superproject-remote') self.assertEqual(manifest.superproject['remote'].url, 'http://localhost/platform/superproject') self.assertEqual( - manifest.ToXml().toxml(), + sort_attributes(manifest.ToXml().toxml()), '' - '' - '' + '' + '' '' '' '') @@ -557,9 +582,9 @@ class SuperProjectElementTests(ManifestParseTestCase): self.assertEqual(manifest.superproject['name'], 'superproject') self.assertEqual(manifest.superproject['remote'].name, 'default-remote') self.assertEqual( - manifest.ToXml().toxml(), + sort_attributes(manifest.ToXml().toxml()), '' - '' + '' '' '' '')