1from PyObjCTools.TestSupport import * 2from PyObjCTest import structargs 3from PyObjCTest import testbndl 4from PyObjCTest import copying 5 6import objc, sys 7from PyObjCTest.fnd import NSObject, NSAutoreleasePool 8 9rct = structargs.StructArgClass.someRect.__metadata__()['retval']['type'] 10 11class OCTestRegrWithGetItem (NSObject): 12 def objectForKey_(self, k): 13 return "ofk: %s"%(k,) 14 15 def __getitem__(self, k): 16 return "gi: %s"%(k,) 17 18class OCTestRegrWithGetItem2 (OCTestRegrWithGetItem): 19 def objectForKey_(self, k): 20 return "ofk2: %s"%(k,) 21 22class ReturnAStruct (NSObject): 23 def someRectWithRect_(self, aRect): 24 ((x, y), (h, w)) = aRect 25 return ((x,y),(h,w)) 26 someRectWithRect_ = objc.selector(someRectWithRect_, signature=rct + b'@:' + rct) 27 28 29class TestRegressions(TestCase): 30 def testNSObjectRespondsToCommonMethods(self): 31 self.assertTrue(NSObject.pyobjc_classMethods.respondsToSelector_('alloc')) 32 self.assertTrue(NSObject.instancesRespondToSelector_('init')) 33 self.assertFalse(NSObject.instancesRespondToSelector_('frodel')) 34 35 36 def testDeallocUninit(self): 37 import objc 38 39 import warnings 40 warnings.filterwarnings('ignore', 41 category=objc.UninitializedDeallocWarning) 42 43 try: 44 for clsName in [ 'NSURL', 'NSObject', 'NSArray' ]: 45 d = objc.lookUpClass(clsName).alloc() 46 del d 47 48 finally: 49 del warnings.filters[0] 50 51 # Check that we generate a warning for unitialized objects that 52 # get deallocated 53 import sys 54 import StringIO 55 warnings.filterwarnings('always', 56 category=objc.UninitializedDeallocWarning) 57 sys.stderr = io = StringIO.StringIO() 58 try: 59 d = NSObject.alloc() 60 del d 61 62 finally: 63 del warnings.filters[0] 64 sys.stderr = sys.__stderr__ 65 66 # A warning is three lines: location info, source code, empty line 67 self.assertEquals(len(io.getvalue().split('\n')), 3) 68 69 def testOneWayMethods(self): 70 # This one should be in test_methods*.py 71 from PyObjCTest.initialize import OC_TestInitialize 72 73 o = OC_TestInitialize.alloc().init() 74 self.assertEquals(objc.splitSignature(o.onewayVoidMethod.signature), (objc._C_ONEWAY + objc._C_VOID, objc._C_ID, objc._C_SEL)) 75 76 # Make sure we can call the method 77 o.onewayVoidMethod() 78 self.assertEquals(o.isInitialized(), -1) 79 80 81 def testNoneAsSelf (self): 82 class SelfIsNone (NSObject): 83 def f(x): 84 pass 85 86 self.assertRaises(TypeError, NSObject.pyobjc_instanceMethods.description, None) 87 self.assertRaises(TypeError, SelfIsNone.pyobjc_instanceMethods.f, None) 88 89 def testOneArgumentTooMany (self): 90 class ClsIsNone (NSObject): 91 @classmethod 92 def f(cls): 93 pass 94 95 object = NSObject.alloc().init() 96 97 self.assertRaises(TypeError, object.description, None) 98 self.assertRaises(TypeError, object.description, "twelf") 99 self.assertRaises(TypeError, NSObject.description, None) 100 self.assertRaises(TypeError, ClsIsNone.f, None) 101 102 103 def testStructArgs (self): 104 # Like AppKit.test.test_nsimage.TestNSImage.test_compositePoint 105 # unlike that this one doesn't crash on darwin/x86, makeing it less 106 # likely that libffi is at fault 107 108 o = structargs.StructArgClass.alloc().init() 109 v = o.compP_aRect_anOp_((1,2), ((3,4),(5,6)), 7) 110 self.assertEquals(v, u"aP:{1, 2} aR:{{3, 4}, {5, 6}} anO:7") 111 112 def testInitialize(self): 113 calls=[] 114 self.assertEquals(len(calls), 0) 115 116 class InitializeTestClass (NSObject): 117 @classmethod 118 def initialize(cls): 119 calls.append(repr(cls)) 120 121 o = InitializeTestClass.new() 122 self.assertEquals(len(calls), 1) 123 o = InitializeTestClass.new() 124 self.assertEquals(len(calls), 1) 125 126 def testPrivateIntrospection(self): 127 o = testbndl.PyObjC_TestClass4.alloc().init() 128 self.assertEquals(o._privateMethodWithArg_(1.5), 1) 129 self.assertEquals(o._privateMethodWithArg_(-2.5), -2) 130 131 imp = testbndl.PyObjC_TestClass4.instanceMethodForSelector_('_privateMethodWithArg:') 132 self.assertEquals(imp.signature, b'i@:f') 133 134 sel = testbndl.PyObjC_TestClass4._privateMethodWithArg_ 135 self.assertEquals(sel.signature, b'i@:f') 136 137 def testStructReturnPy(self): 138 o = ReturnAStruct.alloc().init() 139 p = structargs.StructArgClass.alloc().init() 140 141 v = p.someRectWithObject_X_Y_H_W_(o, 1, 2, 3, 4) 142 self.assertEquals(v, ((1,2),(3,4))) 143 144 def testStructReturn(self): 145 o = structargs.StructArgClass.alloc().init() 146 v = o.someRect() 147 self.assertEquals(v, ((1,2),(3,4))) 148 149 150 151if sys.byteorder == 'little': 152 # i386 has specific stack alignment requirements. 153 154 class AlignmentTestClass(NSObject): 155 def testWithObject_(self, obj): 156 return obj.stackPtr() 157 158 159 def testStackPtr(self): 160 o = structargs.StructArgClass.alloc().init() 161 162 p = self.AlignmentTestClass.alloc().init() 163 self.assertEquals(p.testWithObject_(o) % 16, o.stackPtr() % 16) 164 165 166 167# 168# Regression in retainCount management when a Python object 169# is created from Objective-C. This only happened when the 170# Python class has an implementation of the designated initializer. 171# 172# Mentioned by Dirk Stoop on the Pyobjc-dev mailing-list. 173# 174 175gDeallocCounter = 0 176class OC_LeakTest_20090704_init (NSObject): 177 def init(self): 178 #self = super(OC_LeakTest_20090704_init, self).init() 179 return self 180 181 def dealloc(self): 182 global gDeallocCounter 183 gDeallocCounter += 1 184 185class OC_LeakTest_20090704_noinit (NSObject): 186 def dealloc(self): 187 global gDeallocCounter 188 gDeallocCounter += 1 189 190 191class TestInitMemoryLeak (TestCase): 192 def testNoPythonInit(self): 193 # This test is basicly a self-test of the test-case, the 194 # test even passed before the regression was fixed. 195 196 global gDeallocCounter 197 198 pool = NSAutoreleasePool.alloc().init() 199 try: 200 v = copying.OC_CopyHelper.newObjectOfClass_(OC_LeakTest_20090704_noinit) 201 self.assertIsInstance(v, OC_LeakTest_20090704_noinit) 202 203 gDeallocCounter = 0 204 del v 205 206 finally: 207 del pool 208 209 self.assertNotEqual(gDeallocCounter, 0) 210 211 def testWithPythonInit(self): 212 global gDeallocCounter 213 214 pool = NSAutoreleasePool.alloc().init() 215 try: 216 v = copying.OC_CopyHelper.newObjectOfClass_(OC_LeakTest_20090704_init) 217 self.assertIsInstance(v, OC_LeakTest_20090704_init) 218 219 gDeallocCounter = 0 220 del v 221 222 finally: 223 del pool 224 225 self.assertNotEqual(gDeallocCounter, 0) 226 227 def testInitFailureLeaks(self): 228 NSData = objc.lookUpClass('NSData') 229 import warnings 230 warnings.filterwarnings('error', 231 category=objc.UninitializedDeallocWarning) 232 233 try: 234 try: 235 v = NSData.alloc().initWithContentsOfFile_("/etc/no-such-file.txt") 236 finally: 237 del warnings.filters[0] 238 239 except objc.UninitializedDeallocWarning: 240 self.fail("Unexpected raising of UninitializedDeallocWarning") 241 242 self.assertFalse(v is not None) 243 244 def testExplicitGetItem(self): 245 v = OCTestRegrWithGetItem.alloc().init() 246 247 self.assertEqual(v.objectForKey_("foo"), "ofk: foo") 248 self.assertEqual(v["foo"], "gi: foo") 249 250 v = OCTestRegrWithGetItem2.alloc().init() 251 self.assertEqual(v.objectForKey_("foo"), "ofk2: foo") 252 self.assertEqual(v["foo"], "gi: foo") 253 254 255if __name__ == '__main__': 256 main() 257