1 # Copyright (C) 2003 Python Software Foundation 2 3 import unittest 4 import plistlib 5 import os 6 import datetime 7 from test import test_support 8 9 10 # This test data was generated through Cocoa's NSDictionary class 11 TESTDATA = """<?xml version="1.0" encoding="UTF-8"?> 12 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" \ 13 "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 14 <plist version="1.0"> 15 <dict> 16 <key>aDate</key> 17 <date>2004-10-26T10:33:33Z</date> 18 <key>aDict</key> 19 <dict> 20 <key>aFalseValue</key> 21 <false/> 22 <key>aTrueValue</key> 23 <true/> 24 <key>aUnicodeValue</key> 25 <string>M\xc3\xa4ssig, Ma\xc3\x9f</string> 26 <key>anotherString</key> 27 <string><hello & 'hi' there!></string> 28 <key>deeperDict</key> 29 <dict> 30 <key>a</key> 31 <integer>17</integer> 32 <key>b</key> 33 <real>32.5</real> 34 <key>c</key> 35 <array> 36 <integer>1</integer> 37 <integer>2</integer> 38 <string>text</string> 39 </array> 40 </dict> 41 </dict> 42 <key>aFloat</key> 43 <real>0.5</real> 44 <key>aList</key> 45 <array> 46 <string>A</string> 47 <string>B</string> 48 <integer>12</integer> 49 <real>32.5</real> 50 <array> 51 <integer>1</integer> 52 <integer>2</integer> 53 <integer>3</integer> 54 </array> 55 </array> 56 <key>aString</key> 57 <string>Doodah</string> 58 <key>anInt</key> 59 <integer>728</integer> 60 <key>nestedData</key> 61 <array> 62 <data> 63 PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5r 64 PgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5 65 IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBi 66 aW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3Rz 67 IG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQID 68 PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAw== 69 </data> 70 </array> 71 <key>someData</key> 72 <data> 73 PGJpbmFyeSBndW5rPg== 74 </data> 75 <key>someMoreData</key> 76 <data> 77 PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8 78 bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxs 79 b3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxv 80 dHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90 81 cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAw== 82 </data> 83 <key>\xc3\x85benraa</key> 84 <string>That was a unicode key.</string> 85 </dict> 86 </plist> 87 """.replace(" " * 8, "\t") # Apple as well as plistlib.py output hard tabs 88 89 90 class TestPlistlib(unittest.TestCase): 91 92 def tearDown(self): 93 try: 94 os.unlink(test_support.TESTFN) 95 except: 96 pass 97 98 def _create(self): 99 pl = dict( 100 aString="Doodah", 101 aList=["A", "B", 12, 32.5, [1, 2, 3]], 102 aFloat = 0.5, 103 anInt = 728, 104 aDict=dict( 105 anotherString="<hello & 'hi' there!>", 106 aUnicodeValue=u'M\xe4ssig, Ma\xdf', 107 aTrueValue=True, 108 aFalseValue=False, 109 deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]), 110 ), 111 someData = plistlib.Data("<binary gunk>"), 112 someMoreData = plistlib.Data("<lots of binary gunk>\0\1\2\3" * 10), 113 nestedData = [plistlib.Data("<lots of binary gunk>\0\1\2\3" * 10)], 114 aDate = datetime.datetime(2004, 10, 26, 10, 33, 33), 115 ) 116 pl[u'\xc5benraa'] = "That was a unicode key." 117 return pl 118 119 def test_create(self): 120 pl = self._create() 121 self.assertEqual(pl["aString"], "Doodah") 122 self.assertEqual(pl["aDict"]["aFalseValue"], False) 123 124 def test_io(self): 125 pl = self._create() 126 plistlib.writePlist(pl, test_support.TESTFN) 127 pl2 = plistlib.readPlist(test_support.TESTFN) 128 self.assertEqual(dict(pl), dict(pl2)) 129 130 def test_string(self): 131 pl = self._create() 132 data = plistlib.writePlistToString(pl) 133 pl2 = plistlib.readPlistFromString(data) 134 self.assertEqual(dict(pl), dict(pl2)) 135 data2 = plistlib.writePlistToString(pl2) 136 self.assertEqual(data, data2) 137 138 def test_indentation_array(self): 139 data = [[[[[[[[{'test': plistlib.Data(b'aaaaaa')}]]]]]]]] 140 self.assertEqual(plistlib.readPlistFromString(plistlib.writePlistToString(data)), data) 141 142 def test_indentation_dict(self): 143 data = {'1': {'2': {'3': {'4': {'5': {'6': {'7': {'8': {'9': plistlib.Data(b'aaaaaa')}}}}}}}}} 144 self.assertEqual(plistlib.readPlistFromString(plistlib.writePlistToString(data)), data) 145 146 def test_indentation_dict_mix(self): 147 data = {'1': {'2': [{'3': [[[[[{'test': plistlib.Data(b'aaaaaa')}]]]]]}]}} 148 self.assertEqual(plistlib.readPlistFromString(plistlib.writePlistToString(data)), data) 149 150 def test_appleformatting(self): 151 pl = plistlib.readPlistFromString(TESTDATA) 152 data = plistlib.writePlistToString(pl) 153 self.assertEqual(data, TESTDATA, 154 "generated data was not identical to Apple's output") 155 156 def test_appleformattingfromliteral(self): 157 pl = self._create() 158 pl2 = plistlib.readPlistFromString(TESTDATA) 159 self.assertEqual(dict(pl), dict(pl2), 160 "generated data was not identical to Apple's output") 161 162 def test_stringio(self): 163 from StringIO import StringIO 164 f = StringIO() 165 pl = self._create() 166 plistlib.writePlist(pl, f) 167 pl2 = plistlib.readPlist(StringIO(f.getvalue())) 168 self.assertEqual(dict(pl), dict(pl2)) 169 170 def test_cstringio(self): 171 from cStringIO import StringIO 172 f = StringIO() 173 pl = self._create() 174 plistlib.writePlist(pl, f) 175 pl2 = plistlib.readPlist(StringIO(f.getvalue())) 176 self.assertEqual(dict(pl), dict(pl2)) 177 178 def test_controlcharacters(self): 179 for i in range(128): 180 c = chr(i) 181 testString = "string containing %s" % c 182 if i >= 32 or c in "\r\n\t": 183 # \r, \n and \t are the only legal control chars in XML 184 plistlib.writePlistToString(testString) 185 else: 186 self.assertRaises(ValueError, 187 plistlib.writePlistToString, 188 testString) 189 190 def test_nondictroot(self): 191 test1 = "abc" 192 test2 = [1, 2, 3, "abc"] 193 result1 = plistlib.readPlistFromString(plistlib.writePlistToString(test1)) 194 result2 = plistlib.readPlistFromString(plistlib.writePlistToString(test2)) 195 self.assertEqual(test1, result1) 196 self.assertEqual(test2, result2) 197 198 199 def test_main(): 200 test_support.run_unittest(TestPlistlib) 201 202 203 if __name__ == '__main__': 204 test_main() 205