"""Tests for Tools/ue_common.py — the shared Unreal commandlet helpers. Pure stdlib: these helpers exist to turn two silent failures into loud ones, so they are tested without starting Unreal. """ import os import stat import sys import tempfile import unittest ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) sys.path.insert(0, os.path.join(ROOT, "Tools")) import ue_common # noqa: E402 class MakeWritableTest(unittest.TestCase): def test_read_only_file_is_made_writable(self): # Exactly how an LFS-tracked .umap checks out: 0o444. with tempfile.NamedTemporaryFile(delete=False) as handle: path = handle.name try: os.chmod(path, 0o444) self.assertFalse(os.access(path, os.W_OK)) note = ue_common.make_writable(path) self.assertIsNotNone(note) self.assertIn("chmod u+w", note) self.assertTrue(os.access(path, os.W_OK)) finally: os.chmod(path, 0o644) os.unlink(path) def test_writable_file_reports_nothing(self): with tempfile.NamedTemporaryFile(delete=False) as handle: path = handle.name try: os.chmod(path, 0o644) self.assertIsNone(ue_common.make_writable(path)) finally: os.unlink(path) def test_missing_file_raises(self): # A typo must not look like a permissions problem. with tempfile.TemporaryDirectory() as tmp: with self.assertRaises(FileNotFoundError): ue_common.make_writable(os.path.join(tmp, "absent.umap")) def test_read_bits_are_preserved(self): with tempfile.NamedTemporaryFile(delete=False) as handle: path = handle.name try: os.chmod(path, 0o400) ue_common.make_writable(path) mode = os.stat(path).st_mode self.assertTrue(mode & stat.S_IRUSR) finally: os.chmod(path, 0o644) os.unlink(path) class RequireSavedTest(unittest.TestCase): def test_passes_the_save_result_through(self): self.assertTrue(ue_common.require_saved(True, "/Game/X")) self.assertFalse(ue_common.require_saved(False, "/Game/X")) if __name__ == "__main__": unittest.main()