diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dcb86d6..d0f0003 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: - name: Install dependencies run: | conda install -c conda-forge python-graphblas scipy pandas \ - pytest-cov pytest-randomly black flake8-comprehensions flake8-bugbear + pytest-cov pytest-randomly black flake8-comprehensions flake8-bugbear hypothesis # matplotlib lxml pygraphviz pydot sympy # Extra networkx deps we don't need yet pip install git+https://github.com/networkx/networkx.git@main --no-deps pip install -e . --no-deps diff --git a/graphblas_algorithms/algorithms/link_analysis/tests/test_pagerank.py b/graphblas_algorithms/algorithms/link_analysis/tests/test_pagerank.py index 3c44f3c..f5687e0 100644 --- a/graphblas_algorithms/algorithms/link_analysis/tests/test_pagerank.py +++ b/graphblas_algorithms/algorithms/link_analysis/tests/test_pagerank.py @@ -1,3 +1,14 @@ +import pytest +from hypothesis import given, settings + from graphblas_algorithms import pagerank +from graphblas_algorithms.utils import custom_graph_generators + + +@settings(deadline=None, max_examples=500) +@given(custom_graph_generators()) +def test_pagerank_gen(graph): + assert pagerank(graph) == pytest.approx(nx.pagerank(graph)) + from networkx.algorithms.link_analysis.tests.test_pagerank import * # isort:skip diff --git a/graphblas_algorithms/algorithms/tests/test_reciprocity.py b/graphblas_algorithms/algorithms/tests/test_reciprocity.py index 64f36b2..d4e3f89 100644 --- a/graphblas_algorithms/algorithms/tests/test_reciprocity.py +++ b/graphblas_algorithms/algorithms/tests/test_reciprocity.py @@ -1,3 +1,22 @@ from graphblas_algorithms import overall_reciprocity, reciprocity +import pytest +from hypothesis import given, settings +from graphblas_algorithms.utils import custom_graph_generators + + +@settings(deadline=None, max_examples=500) +@given(custom_graph_generators()) +def test_overall_reciprocity_gen(graph): + # TODO: Fix the graph gen to not produce empty graphs and control directions + if len(graph) > 0 and graph.is_directed(): + assert overall_reciprocity(graph) == pytest.approx(nx.overall_reciprocity(graph)) + + +@settings(deadline=None, max_examples=500) +@given(custom_graph_generators()) +def test_reciprocity_gen(graph): + if len(graph) > 0 and graph.is_directed(): + assert reciprocity(graph) == pytest.approx(nx.reciprocity(graph)) + from networkx.algorithms.tests.test_reciprocity import * # isort:skip diff --git a/graphblas_algorithms/utils/__init__.py b/graphblas_algorithms/utils/__init__.py index 345b7ef..2c2458c 100644 --- a/graphblas_algorithms/utils/__init__.py +++ b/graphblas_algorithms/utils/__init__.py @@ -1,2 +1,3 @@ from ._misc import * from .decorators import * +from .graph_gen import * diff --git a/graphblas_algorithms/utils/graph_gen.py b/graphblas_algorithms/utils/graph_gen.py new file mode 100644 index 0000000..51a2026 --- /dev/null +++ b/graphblas_algorithms/utils/graph_gen.py @@ -0,0 +1,30 @@ +import networkx as nx +from hypothesis.strategies import booleans, composite, integers, lists, tuples + + +@composite +def custom_graph_generators( + draw, + directed=booleans(), + self_loops=booleans(), + sym_digraph=booleans(), + edges=tuples(integers(0, 100), integers(0, 100), integers(-100, 100)), + edge_data=booleans(), +): + G = nx.DiGraph() if draw(directed) else nx.Graph() + self_loop = draw(self_loops) + edges = draw(lists(edges, max_size=1000)) + edge_data = draw(edge_data) + for u, v, d in edges: + if not self_loop and u == v: + continue + if edge_data: + G.add_edge(u, v, data=d) + else: + G.add_edge(u, v) + if G.is_directed(): + sym_digraph = draw(sym_digraph) + if sym_digraph: + G = G.to_undirected() + G = G.to_directed() + return G