Spaces:
Paused
Paused
| import pytest | |
| import networkx as nx | |
| from networkx.utils import BinaryHeap, PairingHeap | |
| class X: | |
| def __eq__(self, other): | |
| raise self is other | |
| def __ne__(self, other): | |
| raise self is not other | |
| def __lt__(self, other): | |
| raise TypeError("cannot compare") | |
| def __le__(self, other): | |
| raise TypeError("cannot compare") | |
| def __ge__(self, other): | |
| raise TypeError("cannot compare") | |
| def __gt__(self, other): | |
| raise TypeError("cannot compare") | |
| def __hash__(self): | |
| return hash(id(self)) | |
| x = X() | |
| data = [ # min should not invent an element. | |
| ("min", nx.NetworkXError), | |
| # Popping an empty heap should fail. | |
| ("pop", nx.NetworkXError), | |
| # Getting nonexisting elements should return None. | |
| ("get", 0, None), | |
| ("get", x, None), | |
| ("get", None, None), | |
| # Inserting a new key should succeed. | |
| ("insert", x, 1, True), | |
| ("get", x, 1), | |
| ("min", (x, 1)), | |
| # min should not pop the top element. | |
| ("min", (x, 1)), | |
| # Inserting a new key of different type should succeed. | |
| ("insert", 1, -2.0, True), | |
| # int and float values should interop. | |
| ("min", (1, -2.0)), | |
| # pop removes minimum-valued element. | |
| ("insert", 3, -(10**100), True), | |
| ("insert", 4, 5, True), | |
| ("pop", (3, -(10**100))), | |
| ("pop", (1, -2.0)), | |
| # Decrease-insert should succeed. | |
| ("insert", 4, -50, True), | |
| ("insert", 4, -60, False, True), | |
| # Decrease-insert should not create duplicate keys. | |
| ("pop", (4, -60)), | |
| ("pop", (x, 1)), | |
| # Popping all elements should empty the heap. | |
| ("min", nx.NetworkXError), | |
| ("pop", nx.NetworkXError), | |
| # Non-value-changing insert should fail. | |
| ("insert", x, 0, True), | |
| ("insert", x, 0, False, False), | |
| ("min", (x, 0)), | |
| ("insert", x, 0, True, False), | |
| ("min", (x, 0)), | |
| # Failed insert should not create duplicate keys. | |
| ("pop", (x, 0)), | |
| ("pop", nx.NetworkXError), | |
| # Increase-insert should succeed when allowed. | |
| ("insert", None, 0, True), | |
| ("insert", 2, -1, True), | |
| ("min", (2, -1)), | |
| ("insert", 2, 1, True, False), | |
| ("min", (None, 0)), | |
| # Increase-insert should fail when disallowed. | |
| ("insert", None, 2, False, False), | |
| ("min", (None, 0)), | |
| # Failed increase-insert should not create duplicate keys. | |
| ("pop", (None, 0)), | |
| ("pop", (2, 1)), | |
| ("min", nx.NetworkXError), | |
| ("pop", nx.NetworkXError), | |
| ] | |
| def _test_heap_class(cls, *args, **kwargs): | |
| heap = cls(*args, **kwargs) | |
| # Basic behavioral test | |
| for op in data: | |
| if op[-1] is not nx.NetworkXError: | |
| assert op[-1] == getattr(heap, op[0])(*op[1:-1]) | |
| else: | |
| pytest.raises(op[-1], getattr(heap, op[0]), *op[1:-1]) | |
| # Coverage test. | |
| for i in range(99, -1, -1): | |
| assert heap.insert(i, i) | |
| for i in range(50): | |
| assert heap.pop() == (i, i) | |
| for i in range(100): | |
| assert heap.insert(i, i) == (i < 50) | |
| for i in range(100): | |
| assert not heap.insert(i, i + 1) | |
| for i in range(50): | |
| assert heap.pop() == (i, i) | |
| for i in range(100): | |
| assert heap.insert(i, i + 1) == (i < 50) | |
| for i in range(49): | |
| assert heap.pop() == (i, i + 1) | |
| assert sorted([heap.pop(), heap.pop()]) == [(49, 50), (50, 50)] | |
| for i in range(51, 100): | |
| assert not heap.insert(i, i + 1, True) | |
| for i in range(51, 70): | |
| assert heap.pop() == (i, i + 1) | |
| for i in range(100): | |
| assert heap.insert(i, i) | |
| for i in range(100): | |
| assert heap.pop() == (i, i) | |
| pytest.raises(nx.NetworkXError, heap.pop) | |
| def test_PairingHeap(): | |
| _test_heap_class(PairingHeap) | |
| def test_BinaryHeap(): | |
| _test_heap_class(BinaryHeap) | |