1""" 2Tests for the new-style metadata format interface. 3 4Note: Tests for calling from python into ObjC are in test_metadata.py 5 6TODO: 7-> OutputOptional version for TestByReference 8-> Testcode might need changes, C code definitely needs changes 9 10- Add more testcases: python methods that return the wrong value 11- The python->C interface (that is the contents of the metadata object) is 12 likely to change when the bridge is feature-complete. 13- Probably need special-casing for arrays (numarray and array.array)! 14""" 15import objc 16from PyObjCTools.TestSupport import * 17 18from PyObjCTest.metadata import * 19 20# To ensure we have the right metadata 21import PyObjCTest.test_metadata 22from PyObjCTest.test_metadata_py import Py_MetaDataTest_AllArgs 23 24if 0: 25 from PyObjCTest.test_metadata_py2 import Py_MetaDataTest_OutputOptional 26 27class TestArraysOut_AllArgs (TestCase): 28 def testFixedSize(self): 29 o = Py_MetaDataTest_AllArgs.new() 30 31 v = o.fill4Tuple_() 32 self.assertEqual(list(v), list(range(9, 13))) 33 34 v = o.fill4Tuple_(None) 35 self.assertEqual(list(v), list(range(9, 13))) 36 37 self.assertRaises(ValueError, OC_MetaDataTest.fill4Tuple_on_, objc.NULL, o) 38 39 n, v = o.nullfill4Tuple_() 40 self.assertEqual(n, 1) 41 self.assertEqual(list(v), list(range(1, 5))) 42 43 n, v = o.nullfill4Tuple_(None) 44 self.assertEqual(n, 1) 45 self.assertEqual(list(v), list(range(1, 5))) 46 47 n, v = o.nullfill4Tuple_(objc.NULL) 48 self.assertEqual(n, 2) 49 #self.assertIs(v, objc.NULL ) 50 51 def testNullTerminated(self): 52 o = Py_MetaDataTest_AllArgs.new() 53 54 # Output only arrays of null-terminated arrays cannot be 55 # wrapped automaticly. How is the bridge supposed to know 56 # how much memory it should allocate for the C-array? 57 58 #self.assertRaises(TypeError, o.fillStringArray_) 59 #self.assertRaises(TypeError, o.fillStringArray_, None) 60 #self.assertRaises(ValueError, o.fillStringArray_, objc.NULL) 61 62 #self.assertRaises(TypeError, o.nullfillStringArray_) 63 #self.assertRaises(TypeError, o.nullfillStringArray_, None) 64 n, v = o.nullfillStringArray_(objc.NULL) 65 self.assertEqual(n, 9) 66 self.assertIs(v, objc.NULL) 67 68 def testWithCount(self): 69 o = Py_MetaDataTest_AllArgs.new() 70 71 v = o.fillArray_count_(3) 72 self.assertEqual(list(v), [10, 11, 12]) 73 74 v = o.fillArray_count_(None, 3) 75 self.assertEqual(list(v), [10, 11, 12]) 76 77 v = o.fillArray_count_(5) 78 self.assertEqual(list(v), [10, 11, 12, 13, 14]) 79 80 v = o.fillArray_count_(0) 81 self.assertEqual(list(v), []) 82 83 #self.assertRaises(ValueError, o.fillArray_count_, objc.NULL, 0) 84 85 n, v = o.nullfillArray_count_(3) 86 self.assertEqual(n, 2) 87 self.assertEqual(list(v), [30,31,32]) 88 n, v = o.nullfillArray_count_(None, 3) 89 self.assertEqual(n, 2) 90 self.assertEqual(list(v), [30,31,32]) 91 92 n, v = o.nullfillArray_count_(objc.NULL, 3) 93 self.assertEqual(n, 1) 94 #self.assertIs(v, objc.NULL ) 95 96 def testWithCountInResult(self): 97 o = Py_MetaDataTest_AllArgs.new() 98 99 c, v = o.fillArray_uptoCount_(20) 100 self.assertEqual(c, 10) 101 self.assertEqual(list(v), [i+10 for i in range(10)]) 102 103 c, v = o.maybeFillArray_() 104 self.assertEqual(c, 2) 105 self.assertEqual(list(v), [0, 1]) 106 107if 0: 108 class TestArraysOut_OutputOptional (TestCase): 109 def testFixedSize(self): 110 o = Py_MetaDataTest_OutputOptional.new() 111 112 v = o.fill4Tuple_() 113 self.assertEqual(list(v), list(range(9, 13))) 114 115 v = o.fill4Tuple_(None) 116 self.assertEqual(list(v), list(range(9, 13))) 117 118 self.assertRaises(ValueError, OC_MetaDataTest.fill4Tuple_on_, objc.NULL, o) 119 120 n, v = o.nullfill4Tuple_() 121 self.assertEqual(n, 1) 122 self.assertEqual(list(v), list(range(1, 5))) 123 124 n, v = o.nullfill4Tuple_(None) 125 self.assertEqual(n, 1) 126 self.assertEqual(list(v), list(range(1, 5))) 127 128 n, v = o.nullfill4Tuple_(objc.NULL) 129 #self.assertEqual(n, 2) 130 #self.assertIs(v, objc.NULL) 131 132 def testNullTerminated(self): 133 o = Py_MetaDataTest_OutputOptional.new() 134 135 # Output only arrays of null-terminated arrays cannot be 136 # wrapped automaticly. How is the bridge supposed to know 137 # how much memory it should allocate for the C-array? 138 139 #self.assertRaises(TypeError, o.fillStringArray_) 140 #self.assertRaises(TypeError, o.fillStringArray_, None) 141 #self.assertRaises(ValueError, o.fillStringArray_, objc.NULL) 142 143 #self.assertRaises(TypeError, o.nullfillStringArray_) 144 #self.assertRaises(TypeError, o.nullfillStringArray_, None) 145 #n, v = o.nullfillStringArray_(objc.NULL) 146 #self.assertEqual(n, 9) 147 #self.assertIs(v, objc.NULL) 148 149 def testWithCount(self): 150 o = Py_MetaDataTest_OutputOptional.new() 151 152 v = o.fillArray_count_(3) 153 self.assertEqual(list(v), [10, 11, 12]) 154 155 v = o.fillArray_count_(None, 3) 156 self.assertEqual(list(v), [10, 11, 12]) 157 158 v = o.fillArray_count_(5) 159 self.assertEqual(list(v), [10, 11, 12, 13, 14]) 160 161 v = o.fillArray_count_(0) 162 self.assertEqual(list(v), []) 163 164 #self.assertRaises(ValueError, o.fillArray_count_, objc.NULL, 0) 165 166 n, v = o.nullfillArray_count_(3) 167 self.assertEqual(n, 2) 168 self.assertEqual(list(v), [30,31,32]) 169 n, v = o.nullfillArray_count_(None, 3) 170 self.assertEqual(n, 2) 171 self.assertEqual(list(v), [30,31,32]) 172 173 n, v = o.nullfillArray_count_(objc.NULL, 3) 174 #self.assertEqual(n, 1) 175 #self.assertIs(v, objc.NULL) 176 177 def testWithCountInResult(self): 178 o = Py_MetaDataTest_OutputOptional.new() 179 180 c, v = o.fillArray_uptoCount_(20) 181 self.assertEqual(c, 10) 182 self.assertEqual(list(v), [i+10 for i in range(10)]) 183 184 c, v = o.maybeFillArray_() 185 self.assertEqual(c, 2) 186 self.assertEqual(list(v), [0, 1]) 187 188class TestArraysInOut_AllArgs (TestCase): 189 def testFixedSize(self): 190 o = Py_MetaDataTest_AllArgs.new() 191 192 a = (1,2,3,4) 193 v = o.reverse4Tuple_(a) 194 self.assertEqual(a, (1,2,3,4)) 195 self.assertEqual(list(v), [43, 44, 45, 46]) 196 197 #self.assertRaises(ValueError, o.reverse4Tuple_, (1,2,3)) 198 #self.assertRaises(ValueError, o.reverse4Tuple_, (1,2,3,4,5)) 199 #self.assertRaises(ValueError, o.reverse4Tuple_, objc.NULL) 200 201 a = (1,2,3,4) 202 n, v = o.nullreverse4Tuple_(a) 203 self.assertEqual(n, 1) 204 self.assertEqual(a, (1,2,3,4)) 205 self.assertEqual(list(v), [43, 44, 45, 46]) 206 207 n, v = o.nullreverse4Tuple_(objc.NULL) 208 self.assertEqual(n, -1) 209 self.assertIs(v, objc.NULL) 210 211 def testNullTerminated(self): 212 o = Py_MetaDataTest_AllArgs.new() 213 214 a = ('aap', 'boot', 'cello') 215 v = o.reverseStrings_(a) 216 self.assertEqual(a, ('aap', 'boot', 'cello')) 217 self.assertEqual(list(v), ['paa', 'toob', 'ollec']) 218 219 #self.assertRaises(ValueError, o.reverseStrings_, (1,2)) 220 #self.assertRaises(ValueError, o.reverseStrings_, objc.NULL) 221 222 a = ('aap', 'boot', 'cello') 223 n, v = o.nullreverseStrings_(a) 224 self.assertEqual(n, 10) 225 self.assertEqual(a, ('aap', 'boot', 'cello')) 226 self.assertEqual(list(v), ['paa', 'toob', 'ollec']) 227 228 n, v = o.nullreverseStrings_(objc.NULL) 229 self.assertEqual(n, 9) 230 self.assertIs(v, objc.NULL) 231 232 def testWithCount(self): 233 o = Py_MetaDataTest_AllArgs.new() 234 235 a = (1.0, 2.0, 3.0, 4.0, 5.0) 236 v = o.reverseArray_count_(a, 4) 237 self.assertEqual(a, (1.0, 2.0, 3.0, 4.0, 5.0)) 238 239 # Python->python: same semantics as normal python calls, therefore 240 # the result is 5 long, and there is 2 added to the result (that is 241 # the method sees the actual argument array instead of a truncated one) 242 self.assertEqual(list(v[:4]), [3.0, 4.0, 5.0, 6.0]) 243 244 a = (1.0, 2.0, 3.0, 4.0, 5.0) 245 v = o.reverseArray_count_(a, 5) 246 self.assertEqual(a, (1.0, 2.0, 3.0, 4.0, 5.0)) 247 self.assertEqual(list(v), [2.0, 3.0, 4.0, 5.0, 6.0]) 248 249 # Nice to have, but doesn't work without major 250 # surgery: 251 #a = (1.0, 2.0, 3.0, 4.0, 5.0) 252 #v = o.reverseArray_count_(a, None) 253 #self.assertEqual(a, (1.0, 2.0, 3.0, 4.0, 5.0)) 254 #self.assertEqual(v, (2.0, 3.0, 4.0, 5.0, 6.0)) 255 256 #self.assertRaises(ValueError, o.reverseArray_count_, (1.0, 2.0), 5) 257 #self.assertRaises(ValueError, o.reverseArray_count_, objc.NULL, 0) 258 259 a = (1.0, 2.0, 3.0, 4.0, 5.0) 260 n, v = o.nullreverseArray_count_(a, 5) 261 self.assertEqual(n, 9) 262 self.assertEqual(a, (1.0, 2.0, 3.0, 4.0, 5.0)) 263 self.assertEqual(list(v), [43.0, 44.0, 45.0, 46.0, 47.0]) 264 265 n, v = o.nullreverseArray_count_(objc.NULL, 0) 266 self.assertEqual(n, 2) 267 self.assertIs(v, objc.NULL) 268 269 def testWithCountInResult(self): 270 o = Py_MetaDataTest_AllArgs.new() 271 272 # XXX: caling python->python has the usual python semantics, hence 273 # the argument won't be truncated! 274 c, v = o.reverseArray_uptoCount_(range(10), 10) 275 self.assertEqual(c, 5) 276 self.assertEqual(len(v), 10) 277 self.assertEqual(list(v)[:int(c)], [0, 10, 20, 30, 40]) 278 279 c, v = o.maybeReverseArray_([1,2,3,4]) 280 self.assertEqual(c, 2) 281 self.assertEqual(len(v), 2) 282 self.assertEqual(list(v), [45, 51]) 283 284class TestArraysIn_AllArgs (TestCase): 285 def testFixedSize(self): 286 o = Py_MetaDataTest_AllArgs.new() 287 288 v, = o.make4Tuple_((1.0, 4.0, 8.0, 12.5)) 289 self.assertEqual(len(v), 4) 290 self.assertEqual(list(v), [1.0, 4.0, 8.0, 12.5]) 291 292 v, = o.make4Tuple_((1, 2, 3, 4)) 293 self.assertEqual(len(v), 4) 294 self.assertEqual(list(v), [1.0, 2.0, 3.0, 4.0]) 295 296 # XXX: Calling python->python has a the same semantics as a normal 297 # python call. 298 #self.assertRaises(ValueError, o.make4Tuple_, (1, 2, 3)) 299 #self.assertRaises(ValueError, o.make4Tuple_, (1, 2, 3, 4, 5)) 300 #self.assertRaises(ValueError, o.make4Tuple_, objc.NULL) 301 302 v, = o.null4Tuple_(objc.NULL) 303 self.assertIs(v, objc.NULL) 304 305 def testNullTerminated(self): 306 o = Py_MetaDataTest_AllArgs.new() 307 308 v, = OC_MetaDataTest.makeStringArray_on_((b"hello", b"world", b"there"), o) 309 self.assertEqual(len(v), 3) 310 self.assertEqual(list(v), ["hello", "world", "there"]) 311 312 NSObject = objc.lookUpClass('NSObject') 313 p, q = NSObject.new(), NSObject.new() 314 v, = o.makeObjectArray_((p, q)) 315 self.assertEqual(len(v), 2) 316 self.assertIs(v[0], p) 317 self.assertIs(v[1], q) 318 319 v, = OC_MetaDataTest.makeStringArray_on_((), o) 320 self.assertEqual(len(v), 0) 321 322 self.assertRaises(ValueError, OC_MetaDataTest.makeStringArray_on_, [1,2], o) 323 self.assertRaises(ValueError, OC_MetaDataTest.makeStringArray_on_, objc.NULL, o) 324 325 v, = OC_MetaDataTest.nullStringArray_on_(objc.NULL, o) 326 self.assertEqual(v, objc.NULL) 327 328 def testWithCount(self): 329 o = Py_MetaDataTest_AllArgs.new() 330 331 v, c = o.makeIntArray_count_((1,2,3,4), 3) 332 self.assertEqual(c, 3) 333 334 # Calling python -> python doesn't pass through C, hence the usual 335 # python semantics are used which are slightly different from calling 336 # into C or from C. 337 self.assertEqual(len(v), 4) 338 self.assertEqual(list(v)[:c], [1,2,3]) 339 340 # XXX: This one would be nice to have, but not entirely trivial 341 #v, c = o.makeIntArray_count_((1,2,3,4), None) 342 #self.assertEqual(c, 3) 343 #self.assertEqual(len(v), 3) 344 #self.assertEqual(list(v), [1,2,3,4]) 345 346 # See above 347 #self.assertRaises(ValueError, o.makeIntArray_count_, [1,2,3], 4) 348 #self.assertRaises(ValueError, o.makeIntArray_count_, objc.NULL, 0) 349 #self.assertRaises(ValueError, o.makeIntArray_count_, objc.NULL, 1) 350 351 v, c = o.nullIntArray_count_(objc.NULL, 0) 352 self.assertEqual(c, 0) 353 self.assertEqual(v, objc.NULL) 354 355 # See above 356 #self.assertRaises(ValueError, o.makeIntArray_count_, objc.NULL, 1) 357 358 # Make sure this also works when the length is in a pass-by-reference argument 359 v, c = o.makeIntArray_countPtr_((1,2,3,4), 4) 360 self.assertEqual(c, 4) 361 self.assertEqual(len(v), 4) 362 self.assertEqual(list(v), [1,2,3,4]) 363 364class TestArrayReturns_AllArgs (TestCase): 365 # TODO: 366 # - Add null-terminated arrays of various supported types: 367 # -> integers 368 # -> CF-types 369 def testFixedSize(self): 370 o = Py_MetaDataTest_AllArgs.new() 371 372 v = o.makeIntArrayOf5() 373 self.assertEqual( len(v), 5 ) 374 self.assertEqual( list(v), [100, 200, 300, 400, 500] ) 375 376 v = o.nullIntArrayOf5() 377 self.assertEqual(v, objc.NULL) 378 379 def testSizeInArgument(self): 380 o = Py_MetaDataTest_AllArgs.new() 381 v = o.makeIntArrayOf_(3) 382 self.assertEqual(len(v), 3) 383 self.assertEqual(list(v), [20, 21, 22]) 384 385 v = o.makeIntArrayOf_(10) 386 self.assertEqual(len(v), 10) 387 self.assertEqual(list(v), list(range(20, 30))) 388 389 v = o.nullIntArrayOf_(100) 390 self.assertEqual(v, objc.NULL) 391 392 def testNULLterminated(self): 393 o = Py_MetaDataTest_AllArgs.new() 394 395 v = o.makeStringArray() 396 self.assertEqual(len(v), 3) 397 self.assertEqual(list(v), [ b"jaap", b"pieter", b"hans" ]) 398 399 v = o.nullStringArray() 400 self.assertEqual(v, objc.NULL) 401 402class TestByReference_AllArgs (TestCase): 403 # Pass by reference arguments. 404 # Note that these tests aren't exhaustive, we have test_methods and 405 # test_methods2 for that :-) 406 407 def testInput(self): 408 o = Py_MetaDataTest_AllArgs.new() 409 410 r = o.sumX_andY_(1, 2) 411 self.assertEqual(r, 1**2+2**2) 412 413 r = o.sumX_andY_(2535, 5325) 414 self.assertEqual(r, 2535**2 + 5325**2) 415 416 #self.assertRaises(ValueError, o.sumX_andY_, 42, objc.NULL) 417 418 def testOutput(self): 419 o = Py_MetaDataTest_AllArgs.new() 420 421 div, rem = o.divBy5_remainder_(55) 422 self.assertEqual(div, 55 / 7) 423 self.assertEqual(rem, 55 % 7) 424 425 div, rem = o.divBy5_remainder_(13) 426 self.assertEqual(div, 13 / 7) 427 self.assertEqual(rem, 13 % 7) 428 429 # XXX: To be fixed: 430 #self.assertRaises(ValueError, o.divBy5_remainder_, 42, objc.NULL) 431 432 def testInputOutput(self): 433 o = Py_MetaDataTest_AllArgs.new() 434 x, y = o.swapX_andY_(42, 284) 435 self.assertEqual(x, 284*2) 436 self.assertEqual(y, 42*2) 437 438 #self.assertRaises(ValueError, o.swapX_andY_, 42, objc.NULL) 439 440 def testNullAccepted(self): 441 # Note: the commented-out test-cases require a change in the pyobjc-core 442 o = Py_MetaDataTest_AllArgs.new(); 443 444 def makeNum(value): 445 return int(value, 0) 446 447 # All arguments present 448 r, y, z = o.input_output_inputAndOutput_(1, 2) 449 self.assertEqual(len(r), 3) 450 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 3) 451 self.assertEqual(y, 9) 452 self.assertEqual(z, 10) 453 454 r, y, z = o.input_output_inputAndOutput_(1, None, 2) 455 self.assertEqual(len(r), 3) 456 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 3) 457 self.assertEqual(y, 9) 458 self.assertEqual(z, 10) 459 460 # Argument 1 is NULL 461 r, y, z = o.input_output_inputAndOutput_(objc.NULL, 2) 462 self.assertEqual(len(r), 3) 463 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 2) 464 self.assertEqual(y, 11) 465 self.assertEqual(z, 12) 466 467 r, y, z = o.input_output_inputAndOutput_(objc.NULL, None, 2) 468 self.assertEqual(len(r), 3) 469 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 2) 470 self.assertEqual(y, 11) 471 self.assertEqual(z, 12) 472 473 # Argument 2 is NULL 474 r, y, z = o.input_output_inputAndOutput_(1, objc.NULL, 2) 475 self.assertEqual(len(r), 3) 476 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 2) 477 self.assertEqual(y, 13) # objc.NULL ... 478 self.assertEqual(z, 14) 479 480 # Argument 3 is NULL 481 r, y, z = o.input_output_inputAndOutput_(1, objc.NULL) 482 self.assertEqual(len(r), 3) 483 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 2) 484 self.assertEqual(y, 15) 485 self.assertEqual(z, 16) # objc.NULL ... 486 487 r, y, z = o.input_output_inputAndOutput_(1, None, objc.NULL) 488 self.assertEqual(len(r), 3) 489 self.assertEqual(len(list(filter(lambda x: x is not objc.NULL, r))), 2) 490 self.assertEqual(y, 15) 491 self.assertEqual(z, 16) # , objc.NULL) 492 493if __name__ == "__main__": 494 main() 495