1from PyObjCTools.TestSupport import * 2import objc 3 4from Foundation import * 5from PyObjCTest.testhelper import PyObjC_TestClass4 6 7class TestNSCoderUsage(TestCase): 8 if not hasattr(TestCase, 'assertAlmostEquals'): 9 # XXX Move to a PyObjC unittest module? 10 def assertAlmostEquals(self, val1, val2): 11 self.assert_ (abs(val1 - val2) < 0.000001) 12 13 def testUsage(self): 14 class CoderClass1 (NSObject): 15 def encodeWithCoder_(self, coder): 16 # NSObject does not implement NSCoding, no need to 17 # call superclass implementation: 18 # super(CoderClass1, self).encodeWithCoder_(coder) 19 coder.encodeValueOfObjCType_at_(objc._C_INT, 2) 20 coder.encodeValueOfObjCType_at_(objc._C_DBL, 2.0) 21 coder.encodeArrayOfObjCType_count_at_(objc._C_DBL, 4, (1.0, 2.0, 3.0, 4.0)) 22 coder.encodeBytes_length_("hello world!", 5) 23 24 def initWithCoder_(self, coder): 25 # NSObject does not implement NSCoding, no need to 26 # call superclass implementation: 27 # self = super(CodeClass1, self).initWithCoder_(coder) 28 self = self.init() 29 self.intVal = coder.decodeValueOfObjCType_at_(objc._C_INT) 30 self.dblVal = coder.decodeValueOfObjCType_at_(objc._C_DBL) 31 self.dblArray = coder.decodeArrayOfObjCType_count_at_(objc._C_DBL, 4) 32 self.decodedBytes = coder.decodeBytesWithReturnedLength_() 33 return self 34 35 origObj = CoderClass1.alloc().init() 36 data = NSMutableData.data() 37 archiver = NSArchiver.alloc().initForWritingWithMutableData_(data) 38 archiver.encodeObject_(origObj) 39 40 archiver = NSUnarchiver.alloc().initForReadingWithData_(data) 41 newObj = archiver.decodeObject() 42 43 self.assertEquals(newObj.intVal, 2) 44 self.assertAlmostEquals(newObj.dblVal, 2.0) 45 self.assertEquals(len(newObj.dblArray), 4) 46 self.assertAlmostEquals(newObj.dblArray[0], 1.0) 47 self.assertAlmostEquals(newObj.dblArray[1], 2.0) 48 self.assertAlmostEquals(newObj.dblArray[2], 3.0) 49 self.assertAlmostEquals(newObj.dblArray[3], 4.0) 50 self.assertEquals(newObj.decodedBytes[0], "hello") 51 self.assertEquals(newObj.decodedBytes[1], 5) 52 53 54class MyCoder (NSCoder): 55 def init(self): 56 self = super(MyCoder, self).init() 57 if self is None: return None 58 self.coded = [] 59 return self 60 61 def encodeValueOfObjCType_at_(self, tp, value): 62 self.coded.append( ("value", tp, value) ) 63 64 def encodeArrayOfObjCType_count_at_(self, tp, cnt, value): 65 self.coded.append( ("array", tp, cnt, value) ) 66 67 def encodeBytes_length_(self, bytes, length): 68 self.coded.append( ("bytes", bytes, length) ) 69 70 def decodeValueOfObjCType_at_(self, tp): 71 if tp == 'i': 72 return 42 73 elif tp == 'd': 74 return 1.5 75 76 def decodeArrayOfObjCType_count_at_(self, tp, cnt): 77 return range(cnt) 78 79 def decodeBytesWithReturnedLength_(self): 80 return ("ABCDEabcde", 10) 81 82class TestPythonCoder(TestCase): 83 # 84 # This test accesses a NSCoder implemented in Python from Objective-C 85 # 86 # The tests only use those methods that require a custom IMP-stub. 87 # 88 def testEncoding(self): 89 coder = MyCoder.alloc().init() 90 o = PyObjC_TestClass4.alloc().init() 91 o.encodeWithCoder_(coder) 92 self.assertEquals(coder.coded, 93 [ 94 ("value", "d", 1.5), 95 ("array", "i", 4, (3,4,5,6)), 96 ("bytes", "hello world", 11), 97 ]) 98 99 def testDecoding(self): 100 coder = MyCoder.alloc().init() 101 o = PyObjC_TestClass4 102 103 self.assertEquals(o.fetchInt_(coder), 42) 104 self.assertEquals(o.fetchDouble_(coder), 1.5) 105 106 d = o.fetchData_(coder) 107 self.assertEquals(d.length(), 10) 108 self.assertEquals(str(d.bytes()), "ABCDEabcde") 109 110 d = o.fetchArray_(coder) 111 self.assertEquals(tuple(range(10)), tuple(d)) 112 113 def testMethods(self): 114 self.failUnlessResultIsBOOL(NSCoder.allowsKeyedCoding) 115 self.failUnlessArgIsBOOL(NSCoder.encodeBool_forKey_, 0) 116 self.failUnlessResultIsBOOL(NSCoder.containsValueForKey_) 117 self.failUnlessResultIsBOOL(NSCoder.decodeBoolForKey_) 118 119 self.failUnlessResultHasType(NSCoder.decodeBytesForKey_returnedLength_, '^v') 120 self.failUnlessResultSizeInArg(NSCoder.decodeBytesForKey_returnedLength_, 1) 121 self.failUnlessArgIsOut(NSCoder.decodeBytesForKey_returnedLength_, 1) 122 123 124if __name__ == '__main__': 125 main( ) 126