|
1 | 1 | # Copyright (C) 2003-2013 Python Software Foundation |
2 | | - |
| 2 | +import copy |
| 3 | +import operator |
| 4 | +import pickle |
3 | 5 | import unittest |
4 | 6 | import plistlib |
5 | 7 | import os |
|
10 | 12 | from test import support |
11 | 13 | from io import BytesIO |
12 | 14 |
|
| 15 | +from plistlib import UID |
| 16 | + |
13 | 17 | ALL_FORMATS=(plistlib.FMT_XML, plistlib.FMT_BINARY) |
14 | 18 |
|
15 | 19 | # The testdata is generated using Mac/Tools/plistlib_generate_testdata.py |
|
88 | 92 | ZwB0AHwAiACUAJoApQCuALsAygDTAOQA7QD4AQQBDwEdASsBNgE3ATgBTwFn |
89 | 93 | AW4BcAFyAXQBdgF/AYMBhQGHAYwBlQGbAZ0BnwGhAaUBpwGwAbkBwAHBAcIB |
90 | 94 | xQHHAsQC0gAAAAAAAAIBAAAAAAAAADkAAAAAAAAAAAAAAAAAAALs'''), |
| 95 | + 'KEYED_ARCHIVE': binascii.a2b_base64(b''' |
| 96 | + YnBsaXN0MDDUAQIDBAUGHB1YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVy |
| 97 | + VCR0b3ASAAGGoKMHCA9VJG51bGzTCQoLDA0OVnB5dHlwZVYkY2xhc3NZTlMu |
| 98 | + c3RyaW5nEAGAAl8QE0tleUFyY2hpdmUgVUlEIFRlc3TTEBESExQZWiRjbGFz |
| 99 | + c25hbWVYJGNsYXNzZXNbJGNsYXNzaGludHNfEBdPQ19CdWlsdGluUHl0aG9u |
| 100 | + VW5pY29kZaQVFhcYXxAXT0NfQnVpbHRpblB5dGhvblVuaWNvZGVfEBBPQ19Q |
| 101 | + eXRob25Vbmljb2RlWE5TU3RyaW5nWE5TT2JqZWN0ohobXxAPT0NfUHl0aG9u |
| 102 | + U3RyaW5nWE5TU3RyaW5nXxAPTlNLZXllZEFyY2hpdmVy0R4fVHJvb3SAAQAI |
| 103 | + ABEAGgAjAC0AMgA3ADsAQQBIAE8AVgBgAGIAZAB6AIEAjACVAKEAuwDAANoA |
| 104 | + 7QD2AP8BAgEUAR0BLwEyATcAAAAAAAACAQAAAAAAAAAgAAAAAAAAAAAAAAAA |
| 105 | + AAABOQ=='''), |
91 | 106 | } |
92 | 107 |
|
93 | 108 |
|
@@ -151,6 +166,14 @@ def test_invalid_type(self): |
151 | 166 | with self.subTest(fmt=fmt): |
152 | 167 | self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt) |
153 | 168 |
|
| 169 | + def test_invalid_uid(self): |
| 170 | + with self.assertRaises(TypeError): |
| 171 | + UID("not an int") |
| 172 | + with self.assertRaises(ValueError): |
| 173 | + UID(2 ** 64) |
| 174 | + with self.assertRaises(ValueError): |
| 175 | + UID(-19) |
| 176 | + |
154 | 177 | def test_int(self): |
155 | 178 | for pl in [0, 2**8-1, 2**8, 2**16-1, 2**16, 2**32-1, 2**32, |
156 | 179 | 2**63-1, 2**64-1, 1, -2**63]: |
@@ -200,6 +223,45 @@ def test_indentation_dict_mix(self): |
200 | 223 | data = {'1': {'2': [{'3': [[[[[{'test': b'aaaaaa'}]]]]]}]}} |
201 | 224 | self.assertEqual(plistlib.loads(plistlib.dumps(data)), data) |
202 | 225 |
|
| 226 | + def test_uid(self): |
| 227 | + data = UID(1) |
| 228 | + self.assertEqual(plistlib.loads(plistlib.dumps(data, fmt=plistlib.FMT_BINARY)), data) |
| 229 | + dict_data = { |
| 230 | + 'uid0': UID(0), |
| 231 | + 'uid2': UID(2), |
| 232 | + 'uid8': UID(2 ** 8), |
| 233 | + 'uid16': UID(2 ** 16), |
| 234 | + 'uid32': UID(2 ** 32), |
| 235 | + 'uid63': UID(2 ** 63) |
| 236 | + } |
| 237 | + self.assertEqual(plistlib.loads(plistlib.dumps(dict_data, fmt=plistlib.FMT_BINARY)), dict_data) |
| 238 | + |
| 239 | + def test_uid_data(self): |
| 240 | + uid = UID(1) |
| 241 | + self.assertEqual(uid.data, 1) |
| 242 | + |
| 243 | + def test_uid_eq(self): |
| 244 | + self.assertEqual(UID(1), UID(1)) |
| 245 | + self.assertNotEqual(UID(1), UID(2)) |
| 246 | + self.assertNotEqual(UID(1), "not uid") |
| 247 | + |
| 248 | + def test_uid_hash(self): |
| 249 | + self.assertEqual(hash(UID(1)), hash(UID(1))) |
| 250 | + |
| 251 | + def test_uid_repr(self): |
| 252 | + self.assertEqual(repr(UID(1)), "UID(1)") |
| 253 | + |
| 254 | + def test_uid_index(self): |
| 255 | + self.assertEqual(operator.index(UID(1)), 1) |
| 256 | + |
| 257 | + def test_uid_pickle(self): |
| 258 | + for proto in range(pickle.HIGHEST_PROTOCOL + 1): |
| 259 | + self.assertEqual(pickle.loads(pickle.dumps(UID(19), protocol=proto)), UID(19)) |
| 260 | + |
| 261 | + def test_uid_copy(self): |
| 262 | + self.assertEqual(copy.copy(UID(1)), UID(1)) |
| 263 | + self.assertEqual(copy.deepcopy(UID(1)), UID(1)) |
| 264 | + |
203 | 265 | def test_appleformatting(self): |
204 | 266 | for use_builtin_types in (True, False): |
205 | 267 | for fmt in ALL_FORMATS: |
@@ -648,14 +710,46 @@ def test_dataobject_deprecated(self): |
648 | 710 | self.assertEqual(cur, in_data) |
649 | 711 |
|
650 | 712 |
|
| 713 | +class TestKeyedArchive(unittest.TestCase): |
| 714 | + def test_keyed_archive_data(self): |
| 715 | + # This is the structure of a NSKeyedArchive packed plist |
| 716 | + data = { |
| 717 | + '$version': 100000, |
| 718 | + '$objects': [ |
| 719 | + '$null', { |
| 720 | + 'pytype': 1, |
| 721 | + '$class': UID(2), |
| 722 | + 'NS.string': 'KeyArchive UID Test' |
| 723 | + }, |
| 724 | + { |
| 725 | + '$classname': 'OC_BuiltinPythonUnicode', |
| 726 | + '$classes': [ |
| 727 | + 'OC_BuiltinPythonUnicode', |
| 728 | + 'OC_PythonUnicode', |
| 729 | + 'NSString', |
| 730 | + 'NSObject' |
| 731 | + ], |
| 732 | + '$classhints': [ |
| 733 | + 'OC_PythonString', 'NSString' |
| 734 | + ] |
| 735 | + } |
| 736 | + ], |
| 737 | + '$archiver': 'NSKeyedArchiver', |
| 738 | + '$top': { |
| 739 | + 'root': UID(1) |
| 740 | + } |
| 741 | + } |
| 742 | + self.assertEqual(plistlib.loads(TESTDATA["KEYED_ARCHIVE"]), data) |
| 743 | + |
| 744 | + |
651 | 745 | class MiscTestCase(unittest.TestCase): |
652 | 746 | def test__all__(self): |
653 | 747 | blacklist = {"PlistFormat", "PLISTHEADER"} |
654 | 748 | support.check__all__(self, plistlib, blacklist=blacklist) |
655 | 749 |
|
656 | 750 |
|
657 | 751 | def test_main(): |
658 | | - support.run_unittest(TestPlistlib, TestPlistlibDeprecated, MiscTestCase) |
| 752 | + support.run_unittest(TestPlistlib, TestPlistlibDeprecated, TestKeyedArchive, MiscTestCase) |
659 | 753 |
|
660 | 754 |
|
661 | 755 | if __name__ == '__main__': |
|
0 commit comments