| OLD | NEW |
| 1 """Unittests for heapq.""" | 1 """Unittests for heapq.""" |
| 2 | 2 |
| 3 import random | 3 import random |
| 4 import unittest | 4 import unittest |
| 5 from test import test_support | 5 from test import test_support |
| 6 import sys | 6 import sys |
| 7 | 7 |
| 8 # We do a bit of trickery here to be able to test both the C implementation | 8 # We do a bit of trickery here to be able to test both the C implementation |
| 9 # and the Python implementation of the module. | 9 # and the Python implementation of the module. |
| 10 | 10 |
| 11 # Make it impossible to import the C implementation anymore. | 11 # Make it impossible to import the C implementation anymore. |
| 12 sys.modules['_heapq'] = 0 | 12 sys.modules['_heapq'] = 0 |
| 13 # We must also handle the case that heapq was imported before. | 13 # We must also handle the case that heapq was imported before. |
| 14 if 'heapq' in sys.modules: | 14 if 'heapq' in sys.modules: |
| 15 del sys.modules['heapq'] | 15 del sys.modules['heapq'] |
| 16 | 16 |
| 17 # Now we can import the module and get the pure Python implementation. | 17 # Now we can import the module and get the pure Python implementation. |
| 18 import heapq as py_heapq | 18 import heapq as py_heapq |
| 19 | 19 |
| 20 # Restore everything to normal. | 20 # Restore everything to normal. |
| 21 del sys.modules['_heapq'] | 21 del sys.modules['_heapq'] |
| 22 del sys.modules['heapq'] | 22 del sys.modules['heapq'] |
| 23 | 23 |
| 24 # This is now the module with the C implementation. | 24 # This is now the module with the C implementation. |
| 25 import heapq as c_heapq | 25 import heapq as c_heapq |
| 26 | 26 |
| 27 | 27 |
| 28 class TestHeap(unittest.TestCase): | 28 class TestHeap(unittest.TestCase): |
| 29 module = None | 29 module = None |
| 30 | 30 |
| 31 def test_push_pop(self): | 31 def test_push_pop(self): |
| 32 # 1) Push 256 random numbers and pop them off, verifying all's OK. | 32 # 1) Push 256 random numbers and pop them off, verifying all's OK. |
| 33 heap = [] | 33 heap = [] |
| 34 data = [] | 34 data = [] |
| 35 self.check_invariant(heap) | 35 self.check_invariant(heap) |
| 36 for i in range(256): | 36 for i in range(256): |
| 37 item = random.random() | 37 item = random.random() |
| 38 data.append(item) | 38 data.append(item) |
| 39 self.module.heappush(heap, item) | 39 self.module.heappush(heap, item) |
| 40 self.check_invariant(heap) | 40 self.check_invariant(heap) |
| 41 results = [] | 41 results = [] |
| 42 while heap: | 42 while heap: |
| 43 item = self.module.heappop(heap) | 43 item = self.module.heappop(heap) |
| 44 self.check_invariant(heap) | 44 self.check_invariant(heap) |
| 45 results.append(item) | 45 results.append(item) |
| 46 data_sorted = data[:] | 46 data_sorted = data[:] |
| 47 data_sorted.sort() | 47 data_sorted.sort() |
| 48 self.assertEqual(data_sorted, results) | 48 self.assertEqual(data_sorted, results) |
| 49 # 2) Check that the invariant holds for a sorted array | 49 # 2) Check that the invariant holds for a sorted array |
| 50 self.check_invariant(results) | 50 self.check_invariant(results) |
| (...skipping 239 matching lines...) Show 10 above Show 10 below |
| 290 | 290 |
| 291 from itertools import chain | 291 from itertools import chain |
| 292 def L(seqn): | 292 def L(seqn): |
| 293 'Test multiple tiers of iterators' | 293 'Test multiple tiers of iterators' |
| 294 return chain(map(lambda x:x, R(Ig(G(seqn))))) | 294 return chain(map(lambda x:x, R(Ig(G(seqn))))) |
| 295 | 295 |
| 296 class TestErrorHandling(unittest.TestCase): | 296 class TestErrorHandling(unittest.TestCase): |
| 297 # only for C implementation | 297 # only for C implementation |
| 298 module = c_heapq | 298 module = c_heapq |
| 299 | 299 |
| 300 def test_non_sequence(self): | 300 def test_non_sequence(self): |
| 301 for f in (self.module.heapify, self.module.heappop): | 301 for f in (self.module.heapify, self.module.heappop): |
| 302 self.assertRaises(TypeError, f, 10) | 302 self.assertRaises(TypeError, f, 10) |
| 303 for f in (self.module.heappush, self.module.heapreplace, | 303 for f in (self.module.heappush, self.module.heapreplace, |
| 304 self.module.nlargest, self.module.nsmallest): | 304 self.module.nlargest, self.module.nsmallest): |
| 305 self.assertRaises(TypeError, f, 10, 10) | 305 self.assertRaises(TypeError, f, 10, 10) |
| 306 | 306 |
| 307 def test_len_only(self): | 307 def test_len_only(self): |
| 308 for f in (self.module.heapify, self.module.heappop): | 308 for f in (self.module.heapify, self.module.heappop): |
| 309 self.assertRaises(TypeError, f, LenOnly()) | 309 self.assertRaises(TypeError, f, LenOnly()) |
| 310 for f in (self.module.heappush, self.module.heapreplace): | 310 for f in (self.module.heappush, self.module.heapreplace): |
| 311 self.assertRaises(TypeError, f, LenOnly(), 10) | 311 self.assertRaises(TypeError, f, LenOnly(), 10) |
| 312 for f in (self.module.nlargest, self.module.nsmallest): | 312 for f in (self.module.nlargest, self.module.nsmallest): |
| 313 self.assertRaises(TypeError, f, 2, LenOnly()) | 313 self.assertRaises(TypeError, f, 2, LenOnly()) |
| 314 | 314 |
| 315 def test_get_only(self): | 315 def test_get_only(self): |
| 316 for f in (self.module.heapify, self.module.heappop): | 316 for f in (self.module.heapify, self.module.heappop): |
| 317 self.assertRaises(TypeError, f, GetOnly()) | 317 self.assertRaises(TypeError, f, GetOnly()) |
| 318 for f in (self.module.heappush, self.module.heapreplace): | 318 for f in (self.module.heappush, self.module.heapreplace): |
| 319 self.assertRaises(TypeError, f, GetOnly(), 10) | 319 self.assertRaises(TypeError, f, GetOnly(), 10) |
| 320 for f in (self.module.nlargest, self.module.nsmallest): | 320 for f in (self.module.nlargest, self.module.nsmallest): |
| 321 self.assertRaises(TypeError, f, 2, GetOnly()) | 321 self.assertRaises(TypeError, f, 2, GetOnly()) |
| 322 | 322 |
| 323 def test_get_only(self): | 323 def test_get_only(self): |
| 324 seq = [CmpErr(), CmpErr(), CmpErr()] | 324 seq = [CmpErr(), CmpErr(), CmpErr()] |
| 325 for f in (self.module.heapify, self.module.heappop): | 325 for f in (self.module.heapify, self.module.heappop): |
| 326 self.assertRaises(ZeroDivisionError, f, seq) | 326 self.assertRaises(ZeroDivisionError, f, seq) |
| 327 for f in (self.module.heappush, self.module.heapreplace): | 327 for f in (self.module.heappush, self.module.heapreplace): |
| 328 self.assertRaises(ZeroDivisionError, f, seq, 10) | 328 self.assertRaises(ZeroDivisionError, f, seq, 10) |
| 329 for f in (self.module.nlargest, self.module.nsmallest): | 329 for f in (self.module.nlargest, self.module.nsmallest): |
| 330 self.assertRaises(ZeroDivisionError, f, 2, seq) | 330 self.assertRaises(ZeroDivisionError, f, 2, seq) |
| 331 | 331 |
| 332 def test_arg_parsing(self): | 332 def test_arg_parsing(self): |
| 333 for f in (self.module.heapify, self.module.heappop, | 333 for f in (self.module.heapify, self.module.heappop, |
| 334 self.module.heappush, self.module.heapreplace, | 334 self.module.heappush, self.module.heapreplace, |
| 335 self.module.nlargest, self.module.nsmallest): | 335 self.module.nlargest, self.module.nsmallest): |
| 336 self.assertRaises(TypeError, f, 10) | 336 self.assertRaises(TypeError, f, 10) |
| 337 | 337 |
| 338 def test_iterable_args(self): | 338 def test_iterable_args(self): |
| 339 for f in (self.module.nlargest, self.module.nsmallest): | 339 for f in (self.module.nlargest, self.module.nsmallest): |
| 340 for s in ("123", "", range(1000), (1, 1.2), range(2000,2200,5)): | 340 for s in ("123", "", (1, 1.2)): |
| 341 for g in (G, I, Ig, L, R): | 341 for g in (G, I, Ig, L, R): |
| 342 self.assertEqual(list(f(2, g(s))), list(f(2,s))) | 342 self.assertEqual(list(f(2, g(s))), list(f(2,s))) |
| 343 self.assertEqual(list(f(2, S(s))), []) | 343 self.assertEqual(list(f(2, S(s))), []) |
| 344 self.assertRaises(TypeError, f, 2, X(s)) | 344 self.assertRaises(TypeError, f, 2, X(s)) |
| 345 self.assertRaises(TypeError, f, 2, N(s)) | 345 self.assertRaises(TypeError, f, 2, N(s)) |
| 346 self.assertRaises(ZeroDivisionError, f, 2, E(s)) | 346 self.assertRaises(ZeroDivisionError, f, 2, E(s)) |
| 347 | 347 |
| 348 | 348 |
| 349 #============================================================================== | 349 #============================================================================== |
| 350 | 350 |
| 351 | 351 |
| 352 def test_main(verbose=None): | 352 def test_main(verbose=None): |
| 353 from types import BuiltinFunctionType | 353 from types import BuiltinFunctionType |
| 354 | 354 |
| 355 test_classes = [TestHeapPython, TestHeapC, TestErrorHandling] | 355 test_classes = [TestHeapPython, TestHeapC, TestErrorHandling] |
| 356 test_support.run_unittest(*test_classes) | 356 test_support.run_unittest(*test_classes) |
| 357 | 357 |
| 358 # verify reference counting | 358 # verify reference counting |
| 359 if verbose and hasattr(sys, "gettotalrefcount"): | 359 if verbose and hasattr(sys, "gettotalrefcount"): |
| 360 import gc | 360 import gc |
| 361 counts = [None] * 5 | 361 counts = [None] * 5 |
| 362 for i in range(len(counts)): | 362 for i in range(len(counts)): |
| 363 test_support.run_unittest(*test_classes) | 363 test_support.run_unittest(*test_classes) |
| 364 gc.collect() | 364 gc.collect() |
| 365 counts[i] = sys.gettotalrefcount() | 365 counts[i] = sys.gettotalrefcount() |
| 366 print(counts) | 366 print(counts) |
| 367 | 367 |
| 368 if __name__ == "__main__": | 368 if __name__ == "__main__": |
| 369 test_main(verbose=True) | 369 test_main(verbose=True) |
| OLD | NEW |