mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-16 08:23:28 -05:00
feat: refuse a profile check with no value
This commit is contained in:
1 parent
d3d83d0116
commit
276588485a
2 files changed
+92
No files matched your search
@@ -57,6 +57,43 @@ def _validate_yaml_directory(
|
||||
continue
|
||||
out.extend(_errors(validator, data, str(path.relative_to(ROOT))))
|
||||
out.extend(_unreachable_citations(path, data))
|
||||
if schema_name == "emulator.schema.json":
|
||||
out.extend(_checks_without_values(path, data))
|
||||
return out
|
||||
|
||||
|
||||
_CHECK_FIELDS = {
|
||||
"crc32": ("crc32",),
|
||||
"md5": ("md5",),
|
||||
"sha1": ("sha1",),
|
||||
"sha256": ("sha256",),
|
||||
"size": ("size", "min_size", "max_size"),
|
||||
}
|
||||
|
||||
|
||||
def _checks_without_values(path: Path, document: object) -> list[str]:
|
||||
"""A check an entry declares with nothing to compare against.
|
||||
|
||||
validation: [crc32] with no crc32 runs nothing: the file passes whatever
|
||||
it holds, and the report reads as checked. Fourteen profiles carried
|
||||
one, the code they describe either refusing or warning on a value the
|
||||
entry never wrote down.
|
||||
"""
|
||||
out: list[str] = []
|
||||
files = document.get("files") if isinstance(document, dict) else None
|
||||
for index, entry in enumerate(files or []):
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
declared = entry.get("validation") or []
|
||||
if isinstance(declared, dict):
|
||||
declared = [check for checks in declared.values() for check in checks or []]
|
||||
for check in declared:
|
||||
fields = _CHECK_FIELDS.get(check)
|
||||
if fields and not any(entry.get(field) not in (None, "", []) for field in fields):
|
||||
out.append(
|
||||
f"{path.relative_to(ROOT)}: files[{index}] ({entry.get('name')}) "
|
||||
f"declares a {check} check with no {'/'.join(fields)} value"
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
"""A check a profile declares has a value to compare against.
|
||||
|
||||
validation: [crc32] with no crc32 ran nothing, and fourteen profiles carried
|
||||
one. validate_schemas now refuses it.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
|
||||
class ChecksHaveValues(unittest.TestCase):
|
||||
def setUp(self):
|
||||
try:
|
||||
import validate_schemas
|
||||
except ImportError as exc:
|
||||
self.skipTest(f"validate_schemas needs jsonschema: {exc}")
|
||||
self.check = validate_schemas._checks_without_values
|
||||
|
||||
def test_a_valueless_check_is_named(self):
|
||||
path = REPO_ROOT / "emulators" / "x.yml"
|
||||
document = {"files": [
|
||||
{"name": "a.bin", "validation": ["crc32"]},
|
||||
{"name": "b.bin", "validation": ["size"], "min_size": 4},
|
||||
{"name": "c.bin", "validation": {"core": ["size"], "upstream": ["sha1"]},
|
||||
"size": 4},
|
||||
]}
|
||||
found = self.check(path, document)
|
||||
self.assertEqual(len(found), 2)
|
||||
self.assertIn("a.bin", found[0])
|
||||
self.assertIn("c.bin", found[1])
|
||||
|
||||
def test_every_tracked_profile(self):
|
||||
tracked = subprocess.run(
|
||||
["git", "ls-files", "emulators/*.yml"], cwd=REPO_ROOT,
|
||||
capture_output=True, text=True, check=True,
|
||||
).stdout.split()
|
||||
found = []
|
||||
for name in tracked:
|
||||
path = REPO_ROOT / name
|
||||
with path.open(encoding="utf-8") as fh:
|
||||
found.extend(self.check(path, yaml.safe_load(fh)))
|
||||
self.assertEqual(found, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user