From 1cfa2c3acab25c78264a62309d29cba255feac87 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 4 Mar 2020 00:47:20 +0530 Subject: unit tests: Rewrite documentation table parsing code The old logic was completely broken, and didn't even assert that the specified section was found at all. The CPU families test was broken because of this. Luckily, the table didn't go out of sync with the code. It now also doesn't assume that each section has only one table. This fixes the test now that we document the buildtype/optimization/debug mapping in a second table inside the `Universal options` section. --- run_unittests.py | 76 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index b9dcd41..0249183 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1274,39 +1274,54 @@ class DataTests(unittest.TestCase): self.assertIn(opt, md) self.assertNotIn('b_unknown', md) + @staticmethod + def _get_section_content(name, sections, md): + for section in sections: + if section and section.group(1) == name: + try: + next_section = next(sections) + end = next_section.start() + except StopIteration: + end = len(md) + # Extract the content for this section + return md[section.end():end] + raise RuntimeError('Could not find "{}" heading'.format(name)) + def test_builtin_options_documented(self): ''' Test that universal options and base options are documented in Builtin-Options.md. ''' + from itertools import tee md = None with open('docs/markdown/Builtin-options.md', encoding='utf-8') as f: md = f.read() self.assertIsNotNone(md) found_entries = set() - sections = list(re.finditer(r"^## (.+)$", md, re.MULTILINE)) + [None] - - for s1, s2 in zip(sections[:], sections[1:]): - if s1.group(1) == "Universal options": - # Extract the content for this section - end = s2.start() if s2 is not None else len(md) - content = md[s1.end():end] - subsections = list(re.finditer(r"^### (.+)$", content, re.MULTILINE)) + [None] - - for sub1, sub2 in zip(subsections[:], subsections[1:]): - if sub1.group(1) == "Directories" or sub1.group(1) == "Core options": - # Extract the content for this subsection - sub_end = sub2.start() if sub2 is not None else len(content) - subcontent = content[sub1.end():sub_end] - # Find the list entries - arches = [m.group(1) for m in re.finditer(r"^\| (\w+) .* \|", subcontent, re.MULTILINE)] - # Drop the header - arches = set(arches[1:]) - - self.assertEqual(len(found_entries & arches), 0) - found_entries |= arches - break + sections = re.finditer(r"^## (.+)$", md, re.MULTILINE) + # Extract the content for this section + content = self._get_section_content("Universal options", sections, md) + subsections = tee(re.finditer(r"^### (.+)$", content, re.MULTILINE)) + subcontent1 = self._get_section_content("Directories", subsections[0], content) + subcontent2 = self._get_section_content("Core options", subsections[1], content) + for subcontent in (subcontent1, subcontent2): + # Find the option names + options = set() + # Match either a table row or a table heading separator: | ------ | + rows = re.finditer(r"^\|(?: (\w+) .* | *-+ *)\|", subcontent, re.MULTILINE) + # Skip the header of the first table + next(rows) + # Skip the heading separator of the first table + next(rows) + for m in rows: + value = m.group(1) + # End when the `buildtype` table starts + if value is None: + break + options.add(value) + self.assertEqual(len(found_entries & options), 0) + found_entries |= options self.assertEqual(found_entries, set([ *mesonbuild.coredata.builtin_options.keys(), @@ -1318,16 +1333,13 @@ class DataTests(unittest.TestCase): md = f.read() self.assertIsNotNone(md) - sections = list(re.finditer(r"^## (.+)$", md, re.MULTILINE)) - for s1, s2 in zip(sections[::2], sections[1::2]): - if s1.group(1) == "CPU families": - # Extract the content for this section - content = md[s1.end():s2.start()] - # Find the list entries - arches = [m.group(1) for m in re.finditer(r"^\| (\w+) +\|", content, re.MULTILINE)] - # Drop the header - arches = set(arches[1:]) - self.assertEqual(arches, set(mesonbuild.environment.known_cpu_families)) + sections = re.finditer(r"^## (.+)$", md, re.MULTILINE) + content = self._get_section_content("CPU families", sections, md) + # Find the list entries + arches = [m.group(1) for m in re.finditer(r"^\| (\w+) +\|", content, re.MULTILINE)] + # Drop the header + arches = set(arches[1:]) + self.assertEqual(arches, set(mesonbuild.environment.known_cpu_families)) def test_markdown_files_in_sitemap(self): ''' -- cgit v1.1