diff --git a/tests/data/testfile.rsrc b/tests/data/testfile.rsrc new file mode 100755 index 0000000..aa9f694 Binary files /dev/null and b/tests/data/testfile.rsrc differ diff --git a/tests/test_rsrcfork.py b/tests/test_rsrcfork.py index a3d8cd9..9cebbdb 100644 --- a/tests/test_rsrcfork.py +++ b/tests/test_rsrcfork.py @@ -8,6 +8,12 @@ import rsrcfork DATA_DIR = pathlib.Path(__file__).parent / "data" EMPTY_RSRC_FILE = DATA_DIR / "empty.rsrc" TEXTCLIPPING_RSRC_FILE = DATA_DIR / "unicode.textClipping.rsrc" +TESTFILE_RSRC_FILE = DATA_DIR / "testfile.rsrc" + + +def make_pascal_string(s): + return bytes([len(s)]) + s + UNICODE_TEXT = "Here is some text, including Üñïçø∂é!" DRAG_DATA = ( @@ -31,6 +37,37 @@ TEXTCLIPPING_RESOURCES = collections.OrderedDict([ ])) ]) +TESTFILE_HEADER_SYSTEM_DATA = ( + b"\xa7F$\x08 <\x00\x00\xab\x03\xa7F <\x00\x00" + b"\x01\x00\xb4\x88f\x06`\np\x00`\x06 <\x00\x00" + b"\x08testfile\x00\x02\x00\x02\x00rs" + b"rcRSED\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + b"\x02\x00rsrcRSED\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + b"\x00\x00\xdaIp~\x00\x00\x00\x00\x00\x00\x02.\xfe\x84" +) +TESTFILE_HEADER_APPLICATION_DATA = b"This is the application-specific header data section. Apparently I can write whatever nonsense I want here. A few more bytes...." +TESTFILE_RESOURCES = collections.OrderedDict([ + (b"STR ", collections.OrderedDict([ + (128, ( + None, rsrcfork.ResourceAttrs(0), + make_pascal_string(b"The String, without name or attributes"), + )), + (129, ( + b"The Name", rsrcfork.ResourceAttrs(0), + make_pascal_string(b"The String, with name and no attributes"), + )), + (130, ( + None, rsrcfork.ResourceAttrs.resProtected | rsrcfork.ResourceAttrs.resPreload, + make_pascal_string(b"The String, without name but with attributes"), + )), + (131, ( + b"The Name with Attributes", rsrcfork.ResourceAttrs.resSysHeap, + make_pascal_string(b"The String, with both name and attributes"), + )), + ])), +]) + class ResourceFileReadTests(unittest.TestCase): def test_empty(self) -> None: @@ -61,6 +98,28 @@ class ResourceFileReadTests(unittest.TestCase): self.assertEqual(actual_res.attributes, rsrcfork.ResourceAttrs(0)) self.assertEqual(actual_res.data, expected_data) self.assertEqual(actual_res.compressed_info, None) + + def test_testfile(self) -> None: + with rsrcfork.open(TESTFILE_RSRC_FILE, fork="data") as rf: + self.assertEqual(rf.header_system_data, TESTFILE_HEADER_SYSTEM_DATA) + self.assertEqual(rf.header_application_data, TESTFILE_HEADER_APPLICATION_DATA) + self.assertEqual(rf.file_attributes, rsrcfork.ResourceFileAttrs.mapPrinterDriverMultiFinderCompatible | rsrcfork.ResourceFileAttrs.mapReadOnly) + self.assertEqual(list(rf), list(TESTFILE_RESOURCES)) + + for (actual_type, actual_reses), (expected_type, expected_reses) in zip(rf.items(), TESTFILE_RESOURCES.items()): + with self.subTest(type=expected_type): + self.assertEqual(actual_type, expected_type) + self.assertEqual(list(actual_reses), list(expected_reses)) + + for (actual_id, actual_res), (expected_id, (expected_name, expected_attrs, expected_data)) in zip(actual_reses.items(), expected_reses.items()): + with self.subTest(id=expected_id): + self.assertEqual(actual_res.type, expected_type) + self.assertEqual(actual_id, expected_id) + self.assertEqual(actual_res.id, expected_id) + self.assertEqual(actual_res.name, expected_name) + self.assertEqual(actual_res.attributes, expected_attrs) + self.assertEqual(actual_res.data, expected_data) + self.assertEqual(actual_res.compressed_info, None) if __name__ == "__main__":