1""" 2test.test_dict from python 2.7 adapted for testing NSMutableDictionary 3""" 4from PyObjCTools.TestSupport import * 5 6import objc 7import operator 8NSDictionary = objc.lookUpClass('NSDictionary') 9NSMutableDictionary = objc.lookUpClass('NSMutableDictionary') 10 11import test.test_dict 12 13 14class TestDict (test.test_dict.DictTest, TestCase): 15 def setUp(self): 16 test.test_dict.dict = NSMutableDictionary 17 18 def tearDown(self): 19 del test.test_dict.dict 20 21 def test_literal_constructor(self): pass 22 23 def test_bool(self): 24 self.assertIs(not NSMutableDictionary(), True) 25 self.assertTrue(NSMutableDictionary({1: 2})) 26 self.assertIs(bool(NSMutableDictionary()), False) 27 self.assertIs(bool(NSMutableDictionary({1: 2})), True) 28 29 def test_keys(self): 30 d = NSMutableDictionary() 31 self.assertEqual(d.keys(), []) 32 d = NSMutableDictionary({'a': 1, 'b': 2}) 33 k = d.keys() 34 self.assertTrue(d.has_key('a')) 35 self.assertTrue(d.has_key('b')) 36 37 self.assertRaises(TypeError, d.keys, None) 38 39 def test_values(self): 40 d = NSMutableDictionary({}) 41 self.assertEqual(d.values(), []) 42 d = NSMutableDictionary({1:2}) 43 self.assertEqual(d.values(), [2]) 44 45 self.assertRaises(TypeError, d.values, None) 46 47 def test_items(self): 48 d = NSMutableDictionary({}) 49 self.assertEqual(d.items(), []) 50 51 d = NSMutableDictionary({1:2}) 52 self.assertEqual(d.items(), [(1, 2)]) 53 54 self.assertRaises(TypeError, d.items, None) 55 56 def test_has_key(self): 57 d = NSMutableDictionary({}) 58 self.assertFalse(d.has_key('a')) 59 d = NSMutableDictionary({'a': 1, 'b': 2}) 60 k = list(d.keys()) 61 k.sort() 62 self.assertEqual(k, ['a', 'b']) 63 64 self.assertRaises(TypeError, d.has_key) 65 66 def test_contains(self): 67 d = NSMutableDictionary({}) 68 self.assertNotIn('a', d) 69 self.assertFalse('a' in d) 70 self.assertTrue('a' not in d) 71 d = NSMutableDictionary({'a': 1, 'b': 2}) 72 self.assertIn('a', d) 73 self.assertIn('b', d) 74 self.assertNotIn('c', d) 75 76 self.assertRaises(TypeError, d.__contains__) 77 78 def test_len(self): 79 d = NSMutableDictionary({}) 80 self.assertEqual(len(d), 0) 81 d = NSMutableDictionary({'a': 1, 'b': 2}) 82 self.assertEqual(len(d), 2) 83 84 def test_getitem(self): 85 d = NSMutableDictionary({'a': 1, 'b': 2}) 86 self.assertEqual(d['a'], 1) 87 self.assertEqual(d['b'], 2) 88 d['c'] = 3 89 d['a'] = 4 90 self.assertEqual(d['c'], 3) 91 self.assertEqual(d['a'], 4) 92 del d['b'] 93 self.assertEqual(d, {'a': 4, 'c': 3}) 94 95 self.assertRaises(TypeError, d.__getitem__) 96 97 class BadEq(object): 98 def __eq__(self, other): 99 raise Exc() 100 def __hash__(self): 101 return 24 102 103 d = NSMutableDictionary({}) 104 d[BadEq()] = 42 105 self.assertRaises(KeyError, d.__getitem__, 23) 106 107 class Exc(Exception): pass 108 109 class BadHash(object): 110 fail = False 111 def __hash__(self): 112 if self.fail: 113 raise Exc() 114 else: 115 return 42 116 117 #x = BadHash() 118 #d[x] = 42 119 #x.fail = True 120 #self.assertRaises(Exc, d.__getitem__, x) 121 122 def test_clear(self): 123 d = NSMutableDictionary({1:1, 2:2, 3:3}) 124 d.clear() 125 self.assertEqual(d, {}) 126 127 self.assertRaises(TypeError, d.clear, None) 128 129 def test_update(self): 130 d = NSMutableDictionary({}) 131 d.update({1:100}) 132 d.update({2:20}) 133 d.update({1:1, 2:2, 3:3}) 134 self.assertEqual(d, {1:1, 2:2, 3:3}) 135 136 d.update() 137 self.assertEqual(d, {1:1, 2:2, 3:3}) 138 139 self.assertRaises((TypeError, AttributeError), d.update, None) 140 141 class SimpleUserDict: 142 def __init__(self): 143 self.d = {1:1, 2:2, 3:3} 144 def keys(self): 145 return self.d.keys() 146 def __getitem__(self, i): 147 return self.d[i] 148 d.clear() 149 d.update(SimpleUserDict()) 150 self.assertEqual(d, {1:1, 2:2, 3:3}) 151 152 class Exc(Exception): pass 153 154 d.clear() 155 class FailingUserDict: 156 def keys(self): 157 raise Exc 158 self.assertRaises(Exc, d.update, FailingUserDict()) 159 160 class FailingUserDict: 161 def keys(self): 162 class BogonIter: 163 def __init__(self): 164 self.i = 1 165 def __iter__(self): 166 return self 167 def next(self): 168 if self.i: 169 self.i = 0 170 return 'a' 171 raise Exc 172 return BogonIter() 173 def __getitem__(self, key): 174 return key 175 self.assertRaises(Exc, d.update, FailingUserDict()) 176 177 class FailingUserDict: 178 def keys(self): 179 class BogonIter: 180 def __init__(self): 181 self.i = ord('a') 182 def __iter__(self): 183 return self 184 def next(self): 185 if self.i <= ord('z'): 186 rtn = chr(self.i) 187 self.i += 1 188 return rtn 189 raise StopIteration 190 return BogonIter() 191 def __getitem__(self, key): 192 raise Exc 193 self.assertRaises(Exc, d.update, FailingUserDict()) 194 195 class badseq(object): 196 def __iter__(self): 197 return self 198 def next(self): 199 raise Exc() 200 201 self.assertRaises(Exc, NSMutableDictionary({}).update, badseq()) 202 203 self.assertRaises(ValueError, NSMutableDictionary({}).update, [(1, 2, 3)]) 204 205 def test_fromkeys(self): 206 self.assertEqual(NSMutableDictionary.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) 207 d = NSMutableDictionary({}) 208 self.assertIsNot(d.fromkeys('abc'), d) 209 self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) 210 self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0}) 211 self.assertEqual(d.fromkeys([]), {}) 212 def g(): 213 yield 1 214 self.assertEqual(d.fromkeys(g()), {1:None}) 215 self.assertRaises(TypeError, NSMutableDictionary({}).fromkeys, 3) 216 #class dictlike(dict): pass 217 #self.assertEqual(dictlike.fromkeys('a'), {'a':None}) 218 #self.assertEqual(dictlike().fromkeys('a'), {'a':None}) 219 #self.assertIsInstance(dictlike.fromkeys('a'), dictlike) 220 #self.assertIsInstance(dictlike().fromkeys('a'), dictlike) 221 #class mydict(dict): 222 # def __new__(cls): 223 # return UserDict.UserDict() 224 #ud = mydict.fromkeys('ab') 225 #self.assertEqual(ud, {'a':None, 'b':None}) 226 #self.assertIsInstance(ud, UserDict.UserDict) 227 #self.assertRaises(TypeError, dict.fromkeys) 228 229 class Exc(Exception): pass 230 231 #class baddict1(dict): 232 # def __init__(self): 233 # raise Exc() 234 235 #self.assertRaises(Exc, baddict1.fromkeys, [1]) 236 237 class BadSeq(object): 238 def __iter__(self): 239 return self 240 def next(self): 241 raise Exc() 242 243 self.assertRaises(Exc, NSMutableDictionary.fromkeys, BadSeq()) 244 245 #class baddict2(dict): 246 # def __setitem__(self, key, value): 247 # raise Exc() 248 249 #self.assertRaises(Exc, baddict2.fromkeys, [1]) 250 251 # test fast path for dictionary inputs 252 d = NSMutableDictionary(zip(range(6), range(6))) 253 self.assertEqual(NSMutableDictionary.fromkeys(d, 0), NSMutableDictionary(zip(range(6), [0]*6))) 254 255 def test_copy(self): 256 d = NSMutableDictionary({1:1, 2:2, 3:3}) 257 self.assertEqual(d.copy(), {1:1, 2:2, 3:3}) 258 self.assertEqual(NSMutableDictionary({}).copy(), {}) 259 self.assertRaises(TypeError, d.copy, None) 260 261 def test_get(self): 262 d = NSMutableDictionary({}) 263 self.assertIs(d.get('c'), None) 264 self.assertEqual(d.get('c', 3), 3) 265 d = NSMutableDictionary({'a': 1, 'b': 2}) 266 self.assertIs(d.get('c'), None) 267 self.assertEqual(d.get('c', 3), 3) 268 self.assertEqual(d.get('a'), 1) 269 self.assertEqual(d.get('a', 3), 1) 270 self.assertRaises(TypeError, d.get) 271 self.assertRaises(TypeError, d.get, None, None, None) 272 273 def test_setdefault(self): 274 # dict.setdefault() 275 d = NSMutableDictionary({}) 276 self.assertIs(d.setdefault('key0'), None) 277 d.setdefault('key0', []) 278 self.assertIs(d.setdefault('key0'), None) 279 d.setdefault('key', []).append(3) 280 self.assertEqual(d['key'][0], 3) 281 d.setdefault('key', []).append(4) 282 self.assertEqual(len(d['key']), 2) 283 self.assertRaises(TypeError, d.setdefault) 284 285 class Exc(Exception): pass 286 287 class BadHash(object): 288 fail = False 289 def __hash__(self): 290 if self.fail: 291 raise Exc() 292 else: 293 return 42 294 295 #x = BadHash() 296 #d[x] = 42 297 #x.fail = True 298 #self.assertRaises(Exc, d.setdefault, x, []) 299 300 def test_popitem(self): 301 # dict.popitem() 302 for copymode in -1, +1: 303 # -1: b has same structure as a 304 # +1: b is a.copy() 305 for log2size in range(12): 306 size = 2**log2size 307 a = NSMutableDictionary({}) 308 b = NSMutableDictionary({}) 309 for i in range(size): 310 a[repr(i)] = i 311 if copymode < 0: 312 b[repr(i)] = i 313 if copymode > 0: 314 b = a.mutableCopy() 315 for i in range(size): 316 ka, va = ta = a.popitem() 317 self.assertEqual(va, int(ka)) 318 kb, vb = tb = b.popitem() 319 self.assertEqual(vb, int(kb)) 320 self.assertFalse(copymode < 0 and ta != tb) 321 self.assertFalse(a) 322 self.assertFalse(b) 323 324 d = NSMutableDictionary({}) 325 self.assertRaises(KeyError, d.popitem) 326 327 def test_pop(self): 328 # Tests for pop with specified key 329 d = NSMutableDictionary({}) 330 k, v = 'abc', 'def' 331 d[k] = v 332 self.assertRaises(KeyError, d.pop, 'ghi') 333 334 self.assertEqual(d.pop(k), v) 335 self.assertEqual(len(d), 0) 336 337 self.assertRaises(KeyError, d.pop, k) 338 339 # verify longs/ints get same value when key > 32 bits 340 # (for 64-bit archs). See SF bug #689659. 341 x = 4503599627370496L 342 y = 4503599627370496 343 h = NSMutableDictionary({x: 'anything', y: 'something else'}) 344 self.assertEqual(h[x], h[y]) 345 346 self.assertEqual(d.pop(k, v), v) 347 d[k] = v 348 self.assertEqual(d.pop(k, 1), v) 349 350 self.assertRaises(TypeError, d.pop) 351 352 class Exc(Exception): pass 353 354 class BadHash(object): 355 fail = False 356 def __hash__(self): 357 if self.fail: 358 raise Exc() 359 else: 360 return 42 361 362 #x = BadHash() 363 #d[x] = 42 364 #x.fail = True 365 #self.assertRaises(Exc, d.pop, x) 366 367 def test_mutatingiteration(self): 368 # XXX: Reimplement iteration using NSFastIteration, 369 return 370 371 # changing dict size during iteration 372 d = NSMutableDictionary({}) 373 d[1] = 1 374 try: 375 for i in d: 376 d[i+1] = 1 377 except RuntimeError: 378 pass 379 else: 380 self.fail("RuntimeError not raised") 381 382 def test_repr(self): pass 383 def test_le(self): pass 384 def test_missing(self): pass 385 def test_tuple_keyerror(self): 386 # SF #1576657 387 d = NSMutableDictionary() 388 try: 389 d[(1,)] 390 except KeyError as exc: 391 pass 392 else: 393 fail("KeyError not raised") 394 self.assertEqual(exc.args, ((1,),)) 395 396 def test_bad_key(self): pass 397 def test_resize1(self): pass 398 def test_resize2(self): pass 399 def test_empty_presized_dict_in_freelist(self): pass 400 def test_container_iterator(self): pass 401 def test_track_literals(self): pass 402 def test_track_dynamic(self): pass 403 def test_track_subtypes(self): pass 404 405class GeneralMappingTests (test.test_dict.GeneralMappingTests): 406 type2test = NSMutableDictionary 407 408 409if __name__ == "__main__": 410 main() 411