mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-25 05:09:03 -05:00
The test skeleton indexed verify_platform's dict result as a list and stopped on KeyError: 0. The verification discipline and the profiling guide hedged rules the project holds as firm. The profile field table marked as required fields the schema does not require, and now names the pin that profile_sync --strict needs.
120 lines
4.1 KiB
Python
120 lines
4.1 KiB
Python
"""What the wiki and the generated README state holds against the code.
|
|
|
|
Each class reads a page and the code it describes. A page that quotes a
|
|
function's return shape, a resolution order or a field list drifts when the
|
|
code moves, and nothing else notices.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ast
|
|
import hashlib
|
|
import inspect
|
|
import io
|
|
import json
|
|
import re
|
|
import sys
|
|
import unittest
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
WIKI = ROOT / "wiki"
|
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
|
|
from tests.test_prose_style import _python_prose, _sentence_case # noqa: E402
|
|
|
|
FENCED = re.compile(r"^```.*?^```", re.S | re.M)
|
|
PUBLISHED = sorted(WIKI.glob("*.md")) + [ROOT / "README.md", ROOT / "CONTRIBUTING.md"]
|
|
|
|
|
|
def _page(name: str) -> str:
|
|
return (WIKI / name).read_text(encoding="utf-8")
|
|
|
|
|
|
def _section(text: str, heading: str) -> str:
|
|
"""Body of a markdown section, up to the next heading of any level."""
|
|
start = re.search(rf"(?m)^#+ {re.escape(heading)}\n", text)
|
|
if start is None:
|
|
raise AssertionError(f"no section {heading!r}")
|
|
rest = text[start.end():]
|
|
blanked = FENCED.sub(lambda m: re.sub(r"[^\n]", " ", m.group(0)), rest)
|
|
end = re.search(r"(?m)^#+ ", blanked)
|
|
return rest[: end.start()] if end else rest
|
|
|
|
|
|
def _table_rows(text: str) -> list[list[str]]:
|
|
rows = []
|
|
for line in text.splitlines():
|
|
if line.startswith("|") and not re.match(r"\|\s*-", line):
|
|
rows.append([cell.strip() for cell in line.strip().strip("|").split(" | ")])
|
|
return rows[1:]
|
|
|
|
|
|
class TestSkeletonReadsTheResultShape(unittest.TestCase):
|
|
"""The skeleton indexed verify_platform's result as a list, and a test
|
|
copied from it stopped on KeyError: 0 before any assertion."""
|
|
|
|
def test_every_key_it_reads_is_one_verify_platform_returns(self):
|
|
from verify import verify_platform
|
|
|
|
result = verify_platform(
|
|
{"platform": "x", "verification_mode": "existence", "systems": {}},
|
|
{"files": {}, "indexes": {}},
|
|
emu_profiles={},
|
|
)
|
|
text = _page("testing-guide.md").split("Example skeleton:", 1)[1]
|
|
code = re.search(r"```python\n(.*?)```", text, re.S).group(1)
|
|
read = [
|
|
node.slice
|
|
for node in ast.walk(ast.parse(code))
|
|
if isinstance(node, ast.Subscript)
|
|
and isinstance(node.value, ast.Name)
|
|
and node.value.id == "result"
|
|
]
|
|
self.assertTrue(read, "the skeleton no longer reads the result")
|
|
for key in read:
|
|
self.assertIsInstance(key, ast.Constant)
|
|
self.assertIn(key.value, result)
|
|
|
|
|
|
class NoHedgedRules(unittest.TestCase):
|
|
"""The profiling guide and the verification discipline turned rules into
|
|
wishes ("it's worth", "Ideally", "something to look into")."""
|
|
|
|
FILLER = re.compile(
|
|
r"(?i)\bit'?s worth\b|\bworth noting\b|\bit helps to\b|^Ideally\b"
|
|
r"|\bsomething to look into\b|\busually indicate\b"
|
|
)
|
|
|
|
def test_published_pages(self):
|
|
offenders = [
|
|
f"{page.name}: {line[:80]}"
|
|
for page in PUBLISHED
|
|
for line in FENCED.sub("", page.read_text(encoding="utf-8")).splitlines()
|
|
if self.FILLER.search(line)
|
|
]
|
|
self.assertEqual(offenders, [], "\n".join(offenders))
|
|
|
|
|
|
class ProfileFieldsRequired(unittest.TestCase):
|
|
"""The table marked source, profiled_date, core_version and systems as
|
|
required and called the schema authoritative, which requires none."""
|
|
|
|
def test_yes_matches_the_schema(self):
|
|
schema = json.loads((ROOT / "schemas" / "emulator.schema.json").read_text(encoding="utf-8"))
|
|
required = set(schema["required"])
|
|
for rule in schema.get("allOf", []):
|
|
for branch in ("then", "else"):
|
|
required |= set(rule.get(branch, {}).get("required", []))
|
|
section = _section(_page("profiling.md"), "Profile fields")
|
|
marked = {
|
|
row[0].strip("`") for row in _table_rows(section)
|
|
if row[1].startswith(("yes", "for `type"))
|
|
}
|
|
self.assertEqual(marked, required)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|