mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
149 lines
6.0 KiB
Python
149 lines
6.0 KiB
Python
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
import check_conventions
|
|
from check_conventions import Check
|
|
|
|
DOC = "docs/dev/ENVIRONMENT.md"
|
|
SAMPLE = "core/libs/prx/libSceExample/Sample.cpp"
|
|
DOC_TEXT = "| `APS5_DOCUMENTED` | presence |\n| `APS5_GONE` | presence |\n"
|
|
|
|
|
|
def repository(root, base, head):
|
|
def git(*args):
|
|
subprocess.run(["git", "-c", f"safe.directory={root}", "-c", "user.name=Conventions Test",
|
|
"-c", "user.email=test@example.com", "-c", "commit.gpgsign=false", *args],
|
|
cwd=root, capture_output=True, check=True)
|
|
|
|
def apply(files):
|
|
for path, text in files.items():
|
|
target = root / path
|
|
if text is None:
|
|
target.unlink()
|
|
continue
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text(text, encoding="utf-8")
|
|
|
|
git("init", "-q")
|
|
apply(base)
|
|
git("add", ".")
|
|
git("commit", "-qm", "docs: add base")
|
|
git("tag", "base")
|
|
apply(head)
|
|
git("add", "-A")
|
|
git("commit", "-qm", "feat: read a new name")
|
|
|
|
|
|
def findings_of(root, base, head):
|
|
previous = os.getcwd()
|
|
os.chdir(root)
|
|
try:
|
|
check = Check("base", "HEAD")
|
|
check.env_reference()
|
|
return check.findings
|
|
finally:
|
|
os.chdir(previous)
|
|
|
|
|
|
class EnvReferenceDiffTests(unittest.TestCase):
|
|
def run_case(self, base, head):
|
|
directory = tempfile.TemporaryDirectory()
|
|
self.addCleanup(directory.cleanup)
|
|
root = Path(directory.name)
|
|
repository(root, base, head)
|
|
return findings_of(root, base, head)
|
|
|
|
def test_only_a_name_the_pull_request_adds_is_reported_at_its_line(self):
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n'
|
|
'static bool b = std::getenv("APS5_OLD_UNDOCUMENTED") != nullptr;\n',
|
|
}
|
|
added = 'static bool c = std::getenv("APS5_NEW_READ") != nullptr;\n'
|
|
head = {SAMPLE: base[SAMPLE] + added}
|
|
findings = self.run_case(base, head)
|
|
self.assertEqual(findings, [("env-reference", SAMPLE, 3,
|
|
f"APS5_NEW_READ is read here but has no row in {DOC}")])
|
|
|
|
def test_a_branch_without_the_document_still_reports_its_new_reads(self):
|
|
base = {SAMPLE: "int unrelated;\n"}
|
|
head = {SAMPLE: 'static bool a = std::getenv("APS5_NEW_READ") != nullptr;\n'}
|
|
findings = self.run_case(base, head)
|
|
self.assertEqual([(rule, detail) for rule, _, _, detail in findings],
|
|
[("env-reference", f"APS5_NEW_READ is read here but has no row in {DOC}")])
|
|
|
|
def test_a_row_is_reported_when_the_pull_request_removes_its_last_read(self):
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n'
|
|
'static bool b = std::getenv("APS5_GONE") != nullptr;\n',
|
|
}
|
|
head = {SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n'}
|
|
findings = self.run_case(base, head)
|
|
self.assertEqual(findings, [("env-reference", DOC, 0,
|
|
"APS5_GONE has a row but the code no longer reads it")])
|
|
|
|
def test_removing_one_of_two_reads_keeps_the_row(self):
|
|
other = "core/libs/prx/libSceExample/Other.cpp"
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n',
|
|
other: 'static bool b = std::getenv("APS5_DOCUMENTED") != nullptr;\n',
|
|
}
|
|
head = {other: None}
|
|
self.assertEqual(self.run_case(base, head), [])
|
|
|
|
def test_a_name_the_pull_request_does_not_touch_is_not_reported(self):
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: 'static bool b = std::getenv("APS5_OLD_UNDOCUMENTED") != nullptr;\n',
|
|
}
|
|
head = {SAMPLE: base[SAMPLE] + "int unrelated;\n"}
|
|
self.assertEqual(self.run_case(base, head), [])
|
|
|
|
def test_a_row_the_pull_request_removes_is_reported_while_the_code_still_reads_it(self):
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n',
|
|
}
|
|
head = {DOC: "| `APS5_GONE` | presence |\n"}
|
|
self.assertEqual(self.run_case(base, head), [("env-reference", DOC, 0,
|
|
"APS5_DOCUMENTED is still read by the code but this pull request removes its row")])
|
|
|
|
def test_a_removed_row_is_kept_quiet_when_the_code_stops_reading_it_too(self):
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n'
|
|
'static bool b = std::getenv("APS5_GONE") != nullptr;\n',
|
|
}
|
|
head = {
|
|
DOC: "| `APS5_DOCUMENTED` | presence |\n",
|
|
SAMPLE: 'static bool a = std::getenv("APS5_DOCUMENTED") != nullptr;\n',
|
|
}
|
|
self.assertEqual(self.run_case(base, head), [])
|
|
|
|
def test_an_added_line_starting_with_plus_does_not_shift_the_reported_line(self):
|
|
base = {DOC: DOC_TEXT, SAMPLE: "int a;\n"}
|
|
head = {SAMPLE: "int a;\n+++x;\n" 'static bool b = std::getenv("APS5_NEW_READ") != nullptr;\n'}
|
|
findings = self.run_case(base, head)
|
|
self.assertEqual(findings, [("env-reference", SAMPLE, 3,
|
|
f"APS5_NEW_READ is read here but has no row in {DOC}")])
|
|
|
|
def test_a_removed_line_starting_with_minus_still_counts_as_a_removed_read(self):
|
|
base = {
|
|
DOC: DOC_TEXT,
|
|
SAMPLE: '--x; std::getenv("APS5_GONE") != nullptr;\n',
|
|
}
|
|
head = {SAMPLE: "int unrelated;\n"}
|
|
self.assertEqual(self.run_case(base, head), [("env-reference", DOC, 0,
|
|
"APS5_GONE has a row but the code no longer reads it")])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|