import pytest import networkx as nx from networkx.utils import * class X(object): 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)