# Copyright (C) 2003 Python Software Foundation | |
import unittest | |
import plistlib | |
import os | |
import datetime | |
from test import test_support | |
# This test data was generated through Cocoa's NSDictionary class | |
TESTDATA = """<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" \ | |
"http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>aDate</key> | |
<date>2004-10-26T10:33:33Z</date> | |
<key>aDict</key> | |
<dict> | |
<key>aFalseValue</key> | |
<false/> | |
<key>aTrueValue</key> | |
<true/> | |
<key>aUnicodeValue</key> | |
<string>M\xc3\xa4ssig, Ma\xc3\x9f</string> | |
<key>anotherString</key> | |
<string><hello & 'hi' there!></string> | |
<key>deeperDict</key> | |
<dict> | |
<key>a</key> | |
<integer>17</integer> | |
<key>b</key> | |
<real>32.5</real> | |
<key>c</key> | |
<array> | |
<integer>1</integer> | |
<integer>2</integer> | |
<string>text</string> | |
</array> | |
</dict> | |
</dict> | |
<key>aFloat</key> | |
<real>0.5</real> | |
<key>aList</key> | |
<array> | |
<string>A</string> | |
<string>B</string> | |
<integer>12</integer> | |
<real>32.5</real> | |
<array> | |
<integer>1</integer> | |
<integer>2</integer> | |
<integer>3</integer> | |
</array> | |
</array> | |
<key>aString</key> | |
<string>Doodah</string> | |
<key>anInt</key> | |
<integer>728</integer> | |
<key>nestedData</key> | |
<array> | |
<data> | |
PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5r | |
PgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5 | |
IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBi | |
aW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3Rz | |
IG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQID | |
PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAw== | |
</data> | |
</array> | |
<key>someData</key> | |
<data> | |
PGJpbmFyeSBndW5rPg== | |
</data> | |
<key>someMoreData</key> | |
<data> | |
PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8 | |
bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxs | |
b3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxv | |
dHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90 | |
cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAw== | |
</data> | |
<key>\xc3\x85benraa</key> | |
<string>That was a unicode key.</string> | |
</dict> | |
</plist> | |
""".replace(" " * 8, "\t") # Apple as well as plistlib.py output hard tabs | |
class TestPlistlib(unittest.TestCase): | |
def tearDown(self): | |
try: | |
os.unlink(test_support.TESTFN) | |
except: | |
pass | |
def _create(self): | |
pl = dict( | |
aString="Doodah", | |
aList=["A", "B", 12, 32.5, [1, 2, 3]], | |
aFloat = 0.5, | |
anInt = 728, | |
aDict=dict( | |
anotherString="<hello & 'hi' there!>", | |
aUnicodeValue=u'M\xe4ssig, Ma\xdf', | |
aTrueValue=True, | |
aFalseValue=False, | |
deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]), | |
), | |
someData = plistlib.Data("<binary gunk>"), | |
someMoreData = plistlib.Data("<lots of binary gunk>\0\1\2\3" * 10), | |
nestedData = [plistlib.Data("<lots of binary gunk>\0\1\2\3" * 10)], | |
aDate = datetime.datetime(2004, 10, 26, 10, 33, 33), | |
) | |
pl[u'\xc5benraa'] = "That was a unicode key." | |
return pl | |
def test_create(self): | |
pl = self._create() | |
self.assertEqual(pl["aString"], "Doodah") | |
self.assertEqual(pl["aDict"]["aFalseValue"], False) | |
def test_io(self): | |
pl = self._create() | |
plistlib.writePlist(pl, test_support.TESTFN) | |
pl2 = plistlib.readPlist(test_support.TESTFN) | |
self.assertEqual(dict(pl), dict(pl2)) | |
def test_string(self): | |
pl = self._create() | |
data = plistlib.writePlistToString(pl) | |
pl2 = plistlib.readPlistFromString(data) | |
self.assertEqual(dict(pl), dict(pl2)) | |
data2 = plistlib.writePlistToString(pl2) | |
self.assertEqual(data, data2) | |
def test_appleformatting(self): | |
pl = plistlib.readPlistFromString(TESTDATA) | |
data = plistlib.writePlistToString(pl) | |
self.assertEqual(data, TESTDATA, | |
"generated data was not identical to Apple's output") | |
def test_appleformattingfromliteral(self): | |
pl = self._create() | |
pl2 = plistlib.readPlistFromString(TESTDATA) | |
self.assertEqual(dict(pl), dict(pl2), | |
"generated data was not identical to Apple's output") | |
def test_stringio(self): | |
from StringIO import StringIO | |
f = StringIO() | |
pl = self._create() | |
plistlib.writePlist(pl, f) | |
pl2 = plistlib.readPlist(StringIO(f.getvalue())) | |
self.assertEqual(dict(pl), dict(pl2)) | |
def test_cstringio(self): | |
from cStringIO import StringIO | |
f = StringIO() | |
pl = self._create() | |
plistlib.writePlist(pl, f) | |
pl2 = plistlib.readPlist(StringIO(f.getvalue())) | |
self.assertEqual(dict(pl), dict(pl2)) | |
def test_controlcharacters(self): | |
for i in range(128): | |
c = chr(i) | |
testString = "string containing %s" % c | |
if i >= 32 or c in "\r\n\t": | |
# \r, \n and \t are the only legal control chars in XML | |
plistlib.writePlistToString(testString) | |
else: | |
self.assertRaises(ValueError, | |
plistlib.writePlistToString, | |
testString) | |
def test_nondictroot(self): | |
test1 = "abc" | |
test2 = [1, 2, 3, "abc"] | |
result1 = plistlib.readPlistFromString(plistlib.writePlistToString(test1)) | |
result2 = plistlib.readPlistFromString(plistlib.writePlistToString(test2)) | |
self.assertEqual(test1, result1) | |
self.assertEqual(test2, result2) | |
def test_main(): | |
test_support.run_unittest(TestPlistlib) | |
if __name__ == '__main__': | |
test_main() |