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)