1# Some tests that verify that object identity is correctly retained 2# accross the bridge 3# 4# TODO: 5# - Add unittests here for every class that is treated specially by 6# the bridge. 7# - Add unittests that test for "real-world" scenarios (writing stuff 8# to plists, ...) 9# - Implement the required functionality 10 11import sys, os 12import objc 13from PyObjCTest.identity import * 14from PyObjCTools.TestSupport import * 15 16class TestPythonRoundTrip (TestCase): 17 # TODO: verify 18 19 def testBasicPython(self): 20 21 container = OC_TestIdentity.alloc().init() 22 23 for v in (self, object(), list, sum): 24 container.setStoredObject_(v) 25 self.assert_(v is container.storedObject(), repr(v)) 26 27 28 def testPythonContainer(self): 29 30 container = OC_TestIdentity.alloc().init() 31 32 for v in ( [1, 2,3], (1,2,3), {1:2, 3:4} ): 33 container.setStoredObject_(v) 34 self.assert_(v is container.storedObject(), repr(v)) 35 36 def dont_testPythonStrings(self): 37 # XXX: this test would always fail, this is by design. 38 39 container = OC_TestIdentity.alloc().init() 40 41 for v in ( u"Hello world", "Hello world" ): 42 container.setStoredObject_(v) 43 self.assert_(v is container.storedObject(), repr(v)) 44 45 def dont_testPythonNumber(self): 46 # XXX: this test would always fail, need to move some code to C 47 # to fix (but not now) 48 container = OC_TestIdentity.alloc().init() 49 50 for v in (99999, 99999L, 10.0): 51 container.setStoredObject_(v) 52 self.assert_(v is container.storedObject, repr(v)) 53 54 55class ObjCRoundTrip (TestCase): 56 # TODO: NSProxy 57 58 def testNSObject(self): 59 container = OC_TestIdentity.alloc().init() 60 61 cls = objc.lookUpClass("NSObject") 62 container.setStoredObjectToResultOf_on_("new", cls) 63 64 v = container.storedObject() 65 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 66 67 container.setStoredObjectToResultOf_on_("class", cls) 68 v = container.storedObject() 69 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 70 71 def testNSString(self): 72 73 container = OC_TestIdentity.alloc().init() 74 75 cls = objc.lookUpClass("NSObject") 76 container.setStoredObjectToResultOf_on_("description", cls) 77 v = container.storedObject() 78 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 79 self.assert_(isinstance(v, unicode)) 80 81 cls = objc.lookUpClass("NSMutableString") 82 container.setStoredObjectToResultOf_on_("new", cls) 83 v = container.storedObject() 84 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 85 self.assert_(isinstance(v, unicode)) 86 87 def testProtocol(self): 88 container = OC_TestIdentity.alloc().init() 89 90 container.setStoredObjectToAProtocol() 91 v = container.storedObject() 92 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 93 self.assert_(isinstance(v, objc.formal_protocol)) 94 95 if sys.maxint < 2 ** 32: 96 def testObject(self): 97 container = OC_TestIdentity.alloc().init() 98 cls = objc.lookUpClass("Object") 99 container.setStoredObjectAnInstanceOfClassic_(cls) 100 v = container.storedObject() 101 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 102 self.assert_(isinstance(v, cls)) 103 104 def testNSNumber(self): 105 container = OC_TestIdentity.alloc().init() 106 107 container.setStoredObjectToInteger_(10) 108 v = container.storedObject() 109 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 110 111 container.setStoredObjectToInteger_(-40) 112 v = container.storedObject() 113 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 114 115 container.setStoredObjectToUnsignedInteger_(40) 116 v = container.storedObject() 117 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 118 119 container.setStoredObjectToUnsignedInteger_(2 ** 32 - 4) 120 v = container.storedObject() 121 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 122 123 if sys.maxint < 2 ** 32: 124 container.setStoredObjectToLongLong_(sys.maxint * 2) 125 v = container.storedObject() 126 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 127 128 container.setStoredObjectToLongLong_(-sys.maxint) 129 v = container.storedObject() 130 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 131 132 container.setStoredObjectToUnsignedLongLong_(sys.maxint * 2) 133 v = container.storedObject() 134 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 135 136 container.setStoredObjectToFloat_(10.0) 137 v = container.storedObject() 138 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 139 140 container.setStoredObjectToDouble_(9999.0) 141 v = container.storedObject() 142 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 143 144 def testNSDecimalNumber(self): 145 container = OC_TestIdentity.alloc().init() 146 cls = objc.lookUpClass("NSDecimalNumber") 147 container.setStoredObjectToResultOf_on_("zero", cls) 148 v = container.storedObject() 149 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 150 151 152class ObjCtoPython (TestCase): 153 # TODO: NSProxy 154 155 def assertFetchingTwice(self, container, message = None): 156 v1 = container.storedObject() 157 v2 = container.storedObject() 158 159 self.assert_(v1 is v2, message) 160 161 def testNSObject(self): 162 container = OC_TestIdentity.alloc().init() 163 164 cls = objc.lookUpClass("NSObject") 165 container.setStoredObjectToResultOf_on_("new", cls) 166 167 self.assertFetchingTwice(container, repr(cls)) 168 169 container.setStoredObjectToResultOf_on_("new", cls) 170 v1 = container.storedObject() 171 container.setStoredObjectToResultOf_on_("new", cls) 172 v2 = container.storedObject() 173 self.assert_(v1 is not v2, "different objects") 174 175 def dont_testNSString(self): 176 # This would always fail, NSStrings get a new proxy everytime 177 # they cross the bridge, otherwise it would be unnecessarily hard 178 # to get at the current value of NSMutableStrings. 179 180 container = OC_TestIdentity.alloc().init() 181 182 cls = objc.lookUpClass("NSObject") 183 container.setStoredObjectToResultOf_on_("description", cls) 184 self.assertFetchingTwice(container, "string") 185 186 cls = objc.lookUpClass("NSMutableString") 187 container.setStoredObjectToResultOf_on_("new", cls) 188 self.assertFetchingTwice(container, "mutable string") 189 190 def testProtocol(self): 191 container = OC_TestIdentity.alloc().init() 192 193 container.setStoredObjectToAProtocol() 194 v = container.storedObject() 195 self.assertFetchingTwice(container, "protocol") 196 197 if sys.maxint < 2**32: 198 def testObject(self): 199 container = OC_TestIdentity.alloc().init() 200 201 cls = objc.lookUpClass("Object") 202 container.setStoredObjectAnInstanceOfClassic_(cls) 203 self.assertFetchingTwice(container, "object") 204 205 def dont_testNSNumber(self): 206 # No unique proxies yet, due to the way these proxies are 207 # implemented. This needs to be fixed, but that does not have 208 # a high priority. 209 container = OC_TestIdentity.alloc().init() 210 211 container.setStoredObjectToInteger_(10) 212 self.assertFetchingTwice(container, "int 10") 213 214 container.setStoredObjectToInteger_(-40) 215 self.assertFetchingTwice(container, "int -40") 216 217 container.setStoredObjectToUnsignedInteger_(40) 218 self.assertFetchingTwice(container, "unsigned int 40") 219 220 container.setStoredObjectToUnsignedInteger_(sys.maxint * 2) 221 self.assertFetchingTwice(container, "unsigned int sys.maxint*2") 222 223 container.setStoredObjectToLongLong_(sys.maxint * 2) 224 self.assertFetchingTwice(container, "long long sys.maxint*2") 225 226 container.setStoredObjectToLongLong_(-sys.maxint) 227 self.assertFetchingTwice(container, "long long -sys.maxint") 228 229 container.setStoredObjectToUnsignedLongLong_(sys.maxint * 2) 230 self.assertFetchingTwice(container, "unsigned long long sys.maxint*2") 231 232 container.setStoredObjectToFloat_(10.0) 233 self.assertFetchingTwice(container, "float") 234 235 container.setStoredObjectToDouble_(9999.0) 236 self.assertFetchingTwice(container, "double") 237 238 def testNSDecimalNumber(self): 239 container = OC_TestIdentity.alloc().init() 240 241 cls = objc.lookUpClass("NSDecimalNumber") 242 container.setStoredObjectToResultOf_on_("zero", cls) 243 self.assertFetchingTwice(container, "decimal") 244 245class PythonToObjC (TestCase): 246 # TODO: verify 247 248 def testPlainObjects(self): 249 container = OC_TestIdentity.alloc().init() 250 251 for v in (self, object(), list, sum): 252 container.setStoredObject_(v) 253 254 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 255 256 257 def testContainers(self): 258 container = OC_TestIdentity.alloc().init() 259 260 for v in ([1,2,3], (1,2,3), {1:2, 3:4}): 261 container.setStoredObject_(v) 262 263 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 264 265 def dont_testStrings(self): 266 # These get converted, not proxied 267 container = OC_TestIdentity.alloc().init() 268 269 for v in ("hello world", u"a unicode string"): 270 container.setStoredObject_(v) 271 272 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 273 274 def dont_testNumbers(self): 275 # These get converted, not proxied 276 container = OC_TestIdentity.alloc().init() 277 278 for v in (1, 666666, 1L, 66666L, 1.0,): 279 container.setStoredObject_(v) 280 281 self.assert_(container.isSameObjectAsStored_(v), repr(v)) 282 283class TestSerializingDataStructures (TestCase): 284 # OC_Python{Array,Dictionary} used to contain specialized 285 # identity-preservation code. It is unclear why this was added, it might 286 # have to do with writing data to plist files. 287 # This TestCase tries to trigger the problem that caused the addition of 288 # said code, although unsuccesfully... 289 290 def tearDown(self): 291 if os.path.exists("/tmp/pyPyObjCTest.identity"): 292 os.unlink("/tmp/pyPyObjCTest.identity") 293 294 def testMakePlist(self): 295 container = OC_TestIdentity.alloc().init() 296 297 value = [ 1, 2, 3, [ u"hello", [u"world", (u"in", 9 ) ], True, {u"aap":3}]] 298 value.append(value[3]) 299 300 container.setStoredObject_(value) 301 container.writeStoredObjectToFile_(u"/tmp/pyPyObjCTest.identity") 302 303 value = { 304 u"hello": [ 1, 2, 3], 305 u"world": { 306 u"nl": u"wereld", 307 u"de": u"Welt", 308 } 309 } 310 container.setStoredObject_(value) 311 container.writeStoredObjectToFile_(u"/tmp/pyPyObjCTest.identity") 312 313 314 315if __name__ == "__main__": 316 main() 317