mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-28 00:35:47 +00:00
114 lines
4.4 KiB
Python
114 lines
4.4 KiB
Python
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
import pr_overlap
|
|
|
|
|
|
def run(*args):
|
|
return subprocess.run(["git", "-c", "user.name=t", "-c", "user.email=t@t", *args],
|
|
capture_output=True, text=True, check=True).stdout.strip()
|
|
|
|
|
|
def write(path, text):
|
|
Path(path).parent.mkdir(parents=True, exist_ok=True)
|
|
with open(path, "w", encoding="utf-8", newline="\n") as handle:
|
|
handle.write(text)
|
|
|
|
|
|
def export(name):
|
|
return f"int APS5_VABI {name}(int value) {{ return value; }}\n"
|
|
|
|
|
|
class ExportCacheTests(unittest.TestCase):
|
|
def setUp(self):
|
|
self.old = os.getcwd()
|
|
self.tmp = tempfile.TemporaryDirectory()
|
|
os.chdir(self.tmp.name)
|
|
run("init", "-q")
|
|
write("core/libs/prx/libOne/One.cpp", export("sceOneFirst"))
|
|
write("core/libs/prx/libTwo/Two.cpp", export("sceTwoFirst"))
|
|
write("core/libs/prx/libTwo/Copy.cpp", export("sceTwoFirst"))
|
|
write("core/libs/prx/libTwo/tests/Test.cpp", export("sceTestOnly"))
|
|
write("core/libs/prx/libTwo/Header.hpp", export("sceHeaderOnly"))
|
|
run("add", "-A")
|
|
run("commit", "-q", "-m", "base")
|
|
self.first = run("rev-parse", "HEAD")
|
|
write("core/libs/prx/libTwo/Two.cpp", export("sceTwoSecond"))
|
|
run("commit", "-qam", "change two")
|
|
self.second = run("rev-parse", "HEAD")
|
|
self.cache = Path(run("rev-parse", "--absolute-git-dir")) / "pr_overlap-exports.json"
|
|
self.parsed = []
|
|
real = pr_overlap.source_exports
|
|
|
|
def counting(text, library=""):
|
|
self.parsed.append(library)
|
|
return real(text, library)
|
|
|
|
patcher = patch.object(pr_overlap, "source_exports", side_effect=counting)
|
|
patcher.start()
|
|
self.addCleanup(patcher.stop)
|
|
|
|
def tearDown(self):
|
|
os.chdir(self.old)
|
|
self.tmp.cleanup()
|
|
|
|
def names(self, found):
|
|
return {name for names in found.values() for name in names}
|
|
|
|
def test_matches_the_sources_without_tests_or_headers(self):
|
|
found = pr_overlap.base_exports(self.first)
|
|
self.assertEqual(self.names(found), {"sceOneFirst", "sceTwoFirst"})
|
|
self.assertEqual({library for library, _ in found}, {"core/libs/prx/libOne", "core/libs/prx/libTwo"})
|
|
|
|
def test_a_second_run_on_the_same_base_parses_nothing(self):
|
|
first = pr_overlap.base_exports(self.first)
|
|
self.assertEqual(len(self.parsed), 2)
|
|
self.assertEqual(pr_overlap.base_exports(self.first), first)
|
|
self.assertEqual(len(self.parsed), 2)
|
|
|
|
def test_a_moved_base_parses_only_the_changed_sources(self):
|
|
pr_overlap.base_exports(self.first)
|
|
self.parsed.clear()
|
|
found = pr_overlap.base_exports(self.second)
|
|
self.assertEqual(self.parsed, ["core/libs/prx/libTwo"])
|
|
self.assertEqual(self.names(found), {"sceOneFirst", "sceTwoFirst", "sceTwoSecond"})
|
|
|
|
def test_switching_back_to_an_older_base_reuses_its_entries(self):
|
|
pr_overlap.base_exports(self.first)
|
|
pr_overlap.base_exports(self.second)
|
|
self.parsed.clear()
|
|
pr_overlap.base_exports(self.first)
|
|
self.assertEqual(self.parsed, [])
|
|
|
|
def test_a_cache_from_other_parsers_is_ignored(self):
|
|
pr_overlap.base_exports(self.first)
|
|
cache = json.loads(self.cache.read_text(encoding="utf-8"))
|
|
cache["version"] = "older parsers"
|
|
self.cache.write_text(json.dumps(cache), encoding="utf-8")
|
|
self.parsed.clear()
|
|
pr_overlap.base_exports(self.first)
|
|
self.assertEqual(len(self.parsed), 2)
|
|
|
|
def test_an_unreadable_cache_is_rebuilt(self):
|
|
self.cache.write_text("{not json", encoding="utf-8")
|
|
found = pr_overlap.base_exports(self.first)
|
|
self.assertEqual(self.names(found), {"sceOneFirst", "sceTwoFirst"})
|
|
self.assertEqual(json.loads(self.cache.read_text(encoding="utf-8"))["version"], pr_overlap.export_cache_version())
|
|
|
|
def test_a_cache_that_cannot_be_written_does_not_fail_the_run(self):
|
|
with patch.object(pr_overlap.os, "replace", side_effect=PermissionError("read-only")):
|
|
found = pr_overlap.base_exports(self.first)
|
|
self.assertEqual(self.names(found), {"sceOneFirst", "sceTwoFirst"})
|
|
self.assertEqual([path.name for path in self.cache.parent.glob("pr_overlap-exports.json*")], [])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|