120 lines
6.8 KiB
Python
120 lines
6.8 KiB
Python
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 progress
|
|
|
|
|
|
class ProgressTests(unittest.TestCase):
|
|
def test_nonvoid_stub_wrappers_keep_callers_unimplemented(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
library = Path(directory) / "libSceExample"
|
|
library.mkdir()
|
|
(library / "Export.cpp").write_text(
|
|
"static int SupportFormat() { NotImplemented_nid_no_patch(__func__); return 0; }\n"
|
|
"int APS5_VABI sceExampleSupportFormat() { return SupportFormat(); }\n")
|
|
group = progress.scan_library(library)
|
|
self.assertEqual(group["done_names"], [])
|
|
self.assertEqual(group["todo_names"], ["sceExampleSupportFormat"])
|
|
|
|
def test_test_sources_do_not_change_library_progress(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
root = Path(directory) / "tests" / "prx"
|
|
library = root / "libSceExample"
|
|
source = library / "src"
|
|
source.mkdir(parents=True)
|
|
(source / "Export.cpp").write_text(
|
|
"int APS5_VABI Ready() { return 0; }\n"
|
|
"int APS5_VABI Pending() { NotImplemented_nid_no_patch(__func__); }\n")
|
|
alias = root / "libSceExample.native"
|
|
alias.mkdir()
|
|
(alias / "CMakeLists.txt").write_text('include("${CMAKE_CURRENT_SOURCE_DIR}/../libSceExample/Library.cmake")\n')
|
|
with patch.object(progress, "PRX", root):
|
|
base = progress.collect_libraries()
|
|
self.assertEqual(base["groups"][0]["done_names"], ["Ready"])
|
|
self.assertEqual(base["groups"][0]["todo_names"], ["Pending"])
|
|
tests = library / "tests"
|
|
nested = tests / "fixtures"
|
|
nested.mkdir(parents=True)
|
|
(tests / "Callbacks.cpp").write_text(
|
|
"int APS5_VABI FixtureReady() { return 0; }\n"
|
|
"int APS5_VABI Pending() { return 0; }\n"
|
|
"int APS5_VABI FixturePending() { NotImplemented_nid_no_patch(__func__); }\n")
|
|
(nested / "Callbacks.cpp").write_text("int APS5_VABI NestedFixture() { return 0; }\n")
|
|
(alias / "tests").mkdir()
|
|
(alias / "tests" / "Callbacks.cpp").write_text("int APS5_VABI AliasFixture() { return 0; }\n")
|
|
head = progress.collect_libraries()
|
|
self.assertEqual(head, base)
|
|
self.assertEqual(progress.compare("Libraries", "Library", "functions", base, head), [])
|
|
|
|
def test_shared_source_refactor_preserves_functions(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
root = Path(directory)
|
|
owner = root / "libSceExample"
|
|
alias = root / "libSceExample.native"
|
|
empty = root / "libSceEmpty"
|
|
for path in (owner, alias, empty):
|
|
path.mkdir()
|
|
source = "int APS5_VABI Ready() { return 0; }\nint APS5_VABI Pending() { NotImplemented_nid_no_patch(__func__); }\n"
|
|
(owner / "Export.cpp").write_text(source)
|
|
(alias / "Export.cpp").write_text(source)
|
|
(owner / "Library.cmake").write_text("add_library(example SHARED Export.cpp)\n")
|
|
(empty / "CMakeLists.txt").write_text('# include(${CMAKE_CURRENT_SOURCE_DIR}/../libSceExample/Library.cmake)\n')
|
|
with patch.object(progress, "PRX", root):
|
|
base = progress.collect_libraries()
|
|
self.assertEqual((base["done"], base["total"]), (2, 4))
|
|
(alias / "Export.cpp").unlink()
|
|
(alias / "CMakeLists.txt").write_text('include("${CMAKE_CURRENT_SOURCE_DIR}/../libSceExample/Library.cmake")\n')
|
|
head = progress.collect_libraries()
|
|
self.assertEqual((head["done"], head["total"]), (1, 2))
|
|
groups = {group["name"]: group for group in head["groups"]}
|
|
self.assertEqual(groups[alias.name]["shared_sources"], owner.name)
|
|
self.assertNotIn("shared_sources", groups[empty.name])
|
|
html = progress.table("Libraries", "Library", head)
|
|
self.assertIn('colspan="3">Shared sources:', html)
|
|
self.assertIn("shared by " + alias.name, "\n".join(progress.treemap("Libraries", head, 0)))
|
|
report = "\n".join(progress.compare("Libraries", "Library", "functions", base, head))
|
|
self.assertIn("sharing sources", report)
|
|
self.assertNotIn("removed", report)
|
|
self.assertNotIn("implemented", report)
|
|
self.assertEqual(progress.compare("Libraries", "Library", "functions", head, head), [])
|
|
(owner / "Export.cpp").write_text(source.replace("return 0;", "NotImplemented_nid_no_patch(__func__);"))
|
|
regressed = progress.collect_libraries()
|
|
report = "\n".join(progress.compare("Libraries", "Library", "functions", base, regressed))
|
|
self.assertIn("-1 reverted", report)
|
|
self.assertIn("Ready", report)
|
|
(owner / "Export.cpp").write_text("int APS5_VABI Ready() { return 0; }\n")
|
|
removed = progress.collect_libraries()
|
|
report = "\n".join(progress.compare("Libraries", "Library", "functions", base, removed))
|
|
self.assertIn("-1 removed", report)
|
|
self.assertIn("Pending", report)
|
|
|
|
def test_empty_libraries(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
root = Path(directory)
|
|
owner = root / "libSceExample"
|
|
alias = root / "libSceExampleBackend"
|
|
dummy = root / "libSceDummy"
|
|
for path in (owner, alias, dummy):
|
|
path.mkdir()
|
|
(owner / "Export.cpp").write_text("int APS5_VABI Ready() { return 0; }\n")
|
|
(alias / "Export.cpp").write_text('#include "prx/libSceExample/Export.cpp"\n')
|
|
(dummy / "Export.cpp").write_text('#include "prx/libc/include/General.hpp"\nextern "C" {\nAPS5_DUMMY_FUN\n}\n')
|
|
with patch.object(progress, "PRX", root):
|
|
data = progress.collect_libraries()
|
|
groups = {group["name"]: group for group in data["groups"]}
|
|
self.assertEqual(groups[alias.name]["shared_sources"], owner.name)
|
|
self.assertNotIn("shared_sources", groups[dummy.name])
|
|
self.assertEqual((data["done"], data["total"]), (1, 1))
|
|
html = progress.table("Libraries", "Library", data)
|
|
self.assertIn(f'<td>{alias.name}</td><td colspan="3">Shared sources:', html)
|
|
self.assertIn(f'<td>{dummy.name}</td><td colspan="3">No exports</td>', html)
|
|
self.assertNotIn("<td>0</td>", html)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|