mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			216 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Copyright (C) 2003 Python Software Foundation
 | |
| 
 | |
| import unittest
 | |
| import plistlib
 | |
| import os
 | |
| import datetime
 | |
| from test import support
 | |
| 
 | |
| 
 | |
| # This test data was generated through Cocoa's NSDictionary class
 | |
| TESTDATA = b"""<?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>anEmptyDict</key>
 | |
|         <dict/>
 | |
|         <key>anEmptyList</key>
 | |
|         <array/>
 | |
|         <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(b" " * 8, b"\t")  # Apple as well as plistlib.py output hard tabs
 | |
| 
 | |
| 
 | |
| class TestPlistlib(unittest.TestCase):
 | |
| 
 | |
|     def tearDown(self):
 | |
|         try:
 | |
|             os.unlink(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='M\xe4ssig, Ma\xdf',
 | |
|                 aTrueValue=True,
 | |
|                 aFalseValue=False,
 | |
|                 deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]),
 | |
|             ),
 | |
|             someData = plistlib.Data(b"<binary gunk>"),
 | |
|             someMoreData = plistlib.Data(b"<lots of binary gunk>\0\1\2\3" * 10),
 | |
|             nestedData = [plistlib.Data(b"<lots of binary gunk>\0\1\2\3" * 10)],
 | |
|             aDate = datetime.datetime(2004, 10, 26, 10, 33, 33),
 | |
|             anEmptyDict = dict(),
 | |
|             anEmptyList = list()
 | |
|         )
 | |
|         pl['\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, support.TESTFN)
 | |
|         pl2 = plistlib.readPlist(support.TESTFN)
 | |
|         self.assertEqual(dict(pl), dict(pl2))
 | |
| 
 | |
|     def test_bytes(self):
 | |
|         pl = self._create()
 | |
|         data = plistlib.writePlistToBytes(pl)
 | |
|         pl2 = plistlib.readPlistFromBytes(data)
 | |
|         self.assertEqual(dict(pl), dict(pl2))
 | |
|         data2 = plistlib.writePlistToBytes(pl2)
 | |
|         self.assertEqual(data, data2)
 | |
| 
 | |
|     def test_appleformatting(self):
 | |
|         pl = plistlib.readPlistFromBytes(TESTDATA)
 | |
|         data = plistlib.writePlistToBytes(pl)
 | |
|         self.assertEqual(data, TESTDATA,
 | |
|                          "generated data was not identical to Apple's output")
 | |
| 
 | |
|     def test_appleformattingfromliteral(self):
 | |
|         pl = self._create()
 | |
|         pl2 = plistlib.readPlistFromBytes(TESTDATA)
 | |
|         self.assertEqual(dict(pl), dict(pl2),
 | |
|                          "generated data was not identical to Apple's output")
 | |
| 
 | |
|     def test_bytesio(self):
 | |
|         from io import BytesIO
 | |
|         b = BytesIO()
 | |
|         pl = self._create()
 | |
|         plistlib.writePlist(pl, b)
 | |
|         pl2 = plistlib.readPlist(BytesIO(b.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.writePlistToBytes(testString)
 | |
|             else:
 | |
|                 self.assertRaises(ValueError,
 | |
|                                   plistlib.writePlistToBytes,
 | |
|                                   testString)
 | |
| 
 | |
|     def test_nondictroot(self):
 | |
|         test1 = "abc"
 | |
|         test2 = [1, 2, 3, "abc"]
 | |
|         result1 = plistlib.readPlistFromBytes(plistlib.writePlistToBytes(test1))
 | |
|         result2 = plistlib.readPlistFromBytes(plistlib.writePlistToBytes(test2))
 | |
|         self.assertEqual(test1, result1)
 | |
|         self.assertEqual(test2, result2)
 | |
| 
 | |
|     def test_invalidarray(self):
 | |
|         for i in ["<key>key inside an array</key>",
 | |
|                   "<key>key inside an array2</key><real>3</real>",
 | |
|                   "<true/><key>key inside an array3</key>"]:
 | |
|             self.assertRaises(ValueError, plistlib.readPlistFromBytes,
 | |
|                               ("<plist><array>%s</array></plist>"%i).encode())
 | |
| 
 | |
|     def test_invaliddict(self):
 | |
|         for i in ["<key><true/>k</key><string>compound key</string>",
 | |
|                   "<key>single key</key>",
 | |
|                   "<string>missing key</string>",
 | |
|                   "<key>k1</key><string>v1</string><real>5.3</real>"
 | |
|                   "<key>k1</key><key>k2</key><string>double key</string>"]:
 | |
|             self.assertRaises(ValueError, plistlib.readPlistFromBytes,
 | |
|                               ("<plist><dict>%s</dict></plist>"%i).encode())
 | |
|             self.assertRaises(ValueError, plistlib.readPlistFromBytes,
 | |
|                               ("<plist><array><dict>%s</dict></array></plist>"%i).encode())
 | |
| 
 | |
|     def test_invalidinteger(self):
 | |
|         self.assertRaises(ValueError, plistlib.readPlistFromBytes,
 | |
|                           b"<plist><integer>not integer</integer></plist>")
 | |
| 
 | |
|     def test_invalidreal(self):
 | |
|         self.assertRaises(ValueError, plistlib.readPlistFromBytes,
 | |
|                           b"<plist><integer>not real</integer></plist>")
 | |
| 
 | |
| 
 | |
| def test_main():
 | |
|     support.run_unittest(TestPlistlib)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     test_main()
 | 
