Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests #147

Merged
merged 16 commits into from
Aug 2, 2022
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ The XGI package has been supported by NSF Grant 2121905, ["HNDS-I: Using Hypergr
## Other resources
This library may not meet your needs and if this is this case, consider checking out these other resources:
* [HyperNetX](https://pnnl.github.io/HyperNetX): A package in Python for representing, analyzing, and visualizing hypergraphs.
* [Reticula](https://docs.reticula.network/): A package with a Python wrapper of C++ functions for representing, analyzing, and visualizing temporal and static graphs and hypergraphs.
* [SimpleHypergraphs.jl](https://pszufe.github.io/SimpleHypergraphs.jl/v0.1/): A package in Julia for representing, analyzing, and generating hypergraphs.
* [HyperGraphs.jl](https://github.com/lpmdiaz/HyperGraphs.jl): A package in Julia for representing, analyzing, and generating hypergraphs which may be oriented and weighted.
* [hyperG](https://cran.r-project.org/package=HyperG): A package in R for storing and analyzing hypergraphs
* [NetworkX](https://networkx.org/): A package in Python for representing, analyzing, and visualizing networks.
4 changes: 2 additions & 2 deletions docs/source/api/readwrite/xgi.readwrite.json.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ xgi.readwrite.json

.. rubric:: Functions

.. autofunction:: read_hypergraph_json
.. autofunction:: write_hypergraph_json
.. autofunction:: read_json
.. autofunction:: write_json



Expand Down
15 changes: 13 additions & 2 deletions tests/algorithms/test_assortativity.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,37 @@ def test_dynamical_assortativity(edgelist1, edgelist6):
assert abs(xgi.dynamical_assortativity(H1) - -0.0526) < 1e-3


def test_degree_assortativity(edgelist1, edgelist6):
def test_degree_assortativity(edgelist1, edgelist5):
H1 = xgi.Hypergraph(edgelist1)
assert -1 <= xgi.degree_assortativity(H1, kind="uniform") <= 1
assert -1 <= xgi.degree_assortativity(H1, kind="top-2") <= 1
assert -1 <= xgi.degree_assortativity(H1, kind="top-bottom") <= 1

H2 = xgi.Hypergraph(edgelist6)
H2 = xgi.Hypergraph(edgelist5)
assert -1 <= xgi.degree_assortativity(H2, kind="uniform") <= 1
assert -1 <= xgi.degree_assortativity(H2, kind="top-2") <= 1
assert -1 <= xgi.degree_assortativity(H2, kind="top-bottom") <= 1

# test "exact" keyword
assert -1 <= xgi.degree_assortativity(H1, kind="uniform", exact=True) <= 1
assert -1 <= xgi.degree_assortativity(H1, kind="top-2", exact=True) <= 1
assert -1 <= xgi.degree_assortativity(H1, kind="top-bottom", exact=True) <= 1


def test_choose_degrees(edgelist1, edgelist6):
H1 = xgi.Hypergraph(edgelist1)
k = H1.degree()

# test singleton edges
with pytest.raises(XGIError):
e = H1.edges.members(1)
choose_degrees(e, k)

# invalid choice function
with pytest.raises(XGIError):
e = H1.edges.members(0)
choose_degrees(e, k, "test")

e = H1.edges.members(0)
assert np.all(np.array(choose_degrees(e, k)) == 1)

Expand Down
3 changes: 2 additions & 1 deletion tests/classes/test_hypergraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def test_contains(edgelist1):
for node in unique_nodes:
assert node in H

assert 0 not in H
# test TypeError handling
assert [1, 2, 3] not in H


def test_string():
Expand Down
13 changes: 12 additions & 1 deletion tests/classes/test_iddict.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest

import xgi
from xgi.exception import IDNotFound
from xgi.exception import IDNotFound, XGIError


def test_iddict(edgelist1):
Expand All @@ -17,6 +17,17 @@ def test_iddict(edgelist1):
with pytest.raises(IDNotFound):
H.edges[4]

assert H.edges[0] == dict()

with pytest.raises(XGIError):
H._edge[None] = [1, 2, 3]

with pytest.raises(IDNotFound):
del H._node["test"]

with pytest.raises(TypeError):
H._node[[0, 1, 2]] = [0, 1]


def test_neighbors():
H = xgi.Hypergraph()
Expand Down
34 changes: 34 additions & 0 deletions tests/linalg/test_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ def test_multiorder_laplacian(edgelist2, edgelist6):
L1, node_dict1 = xgi.multiorder_laplacian(
H1, orders=[1, 2], weights=[1, 1], index=True
)

# different order and weight lengths
with pytest.raises(ValueError):
L1, node_dict1 = xgi.multiorder_laplacian(
H2, orders=[1, 2], weights=[1, 1, 1], index=True
)
node_dict1 = {k: v for v, k in node_dict1.items()}
assert L1.shape == (5, 5)
assert np.all((L1.T == L1))
Expand All @@ -343,6 +349,9 @@ def test_multiorder_laplacian(edgelist2, edgelist6):
assert L2[node_dict2[3], node_dict2[5]] == 0
assert L2[node_dict2[3], node_dict2[6]] == 0

L2 = xgi.multiorder_laplacian(H2, orders=[1, 2], weights=[1, 1])
assert np.shape(L2) == (6, 6)


def test_intersection_profile(edgelist2):
el1 = edgelist2
Expand Down Expand Up @@ -370,6 +379,10 @@ def test_intersection_profile(edgelist2):

assert P2[edge_dict2[2], edge_dict2[2]] == 3

P2 = xgi.intersection_profile(H1, order=2)
assert np.shape(P2) == (1, 1)
assert P2[0, 0] == 3


def test_clique_motif_matrix(edgelist4):
H1 = xgi.Hypergraph(edgelist4)
Expand Down Expand Up @@ -407,3 +420,24 @@ def test_empty():
assert xgi.adjacency_matrix(H).shape == (0, 0)
assert xgi.laplacian(H).shape == (0, 0)
assert xgi.clique_motif_matrix(H).shape == (0,)

# with indices
data = xgi.incidence_matrix(H, index=True)
assert len(data) == 3
assert data[0].shape == (0,)
assert type(data[1]) == dict and type(data[2]) == dict

data = xgi.adjacency_matrix(H, index=True)
assert len(data) == 2
assert data[0].shape == (0, 0)
assert type(data[1]) == dict

data = xgi.laplacian(H, index=True)
assert len(data) == 2
assert data[0].shape == (0, 0)
assert type(data[1]) == dict

data = xgi.clique_motif_matrix(H, index=True)
assert len(data) == 2
assert data[0].shape == (0,)
assert type(data[1]) == dict
40 changes: 40 additions & 0 deletions tests/readwrite/test_bipartite_edgelist.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import tempfile
from typing import Type
nwlandry marked this conversation as resolved.
Show resolved Hide resolved

import pytest

import xgi
from xgi.exception import XGIError

bipartite_edgelist_spaces_string = """0 0
# Comment
Expand Down Expand Up @@ -56,6 +58,32 @@ def test_read_bipartite_edgelist(file_string, extra_kwargs):

def test_parse_bipartite_edgelist():
lines = ["0 0", "1 0", "2 0", "3 0", "4 1", "5 2", "6 2", "6 3", "7 3", "8 3"]
bad_lines1 = ["0", "1 0", "2 0", "3 0", "4 1", "5 2", "6 2", "6 3", "7 3", "8 3"]
bad_lines2 = [
"test 0",
"1 0",
"2 0",
"3 0",
"4 1",
"5 test",
"6 test",
"6 3",
"7 3",
"8 3",
]
bad_lines3 = [
"0 0",
"1 0",
"2 0",
"3 0",
"4 1",
"5 test",
"6 test",
"6 3",
"7 3",
"8 3",
]

H = xgi.parse_bipartite_edgelist(lines, nodetype=int)
assert list(H.nodes) == [0, 1, 2, 3, 4, 5, 6, 7, 8]
assert list(H.edges) == ["0", "1", "2", "3"]
Expand Down Expand Up @@ -89,6 +117,18 @@ def test_parse_bipartite_edgelist():
[3],
]

# test less than two entries per line
with pytest.raises(XGIError):
xgi.parse_bipartite_edgelist(bad_lines1)

# test failed nodetype conversion
with pytest.raises(TypeError):
xgi.parse_bipartite_edgelist(bad_lines2, nodetype=int)

# test failed edgetype conversion
with pytest.raises(TypeError):
xgi.parse_bipartite_edgelist(bad_lines3, edgetype=int)


def test_write_bipartite_edgelist(edgelist1):
_, filename = tempfile.mkstemp()
Expand Down
2 changes: 2 additions & 0 deletions tests/readwrite/test_edgelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def test_parse_edgelist():
[1, 4, 7, 8],
[2, 3],
]
with pytest.raises(TypeError):
xgi.parse_edgelist(["test 2", "2 3 4", "test 4 7 8", "2 3"], nodetype=int)
nwlandry marked this conversation as resolved.
Show resolved Hide resolved


def test_write_edgelist(edgelist1):
Expand Down
114 changes: 0 additions & 114 deletions tests/readwrite/test_hypergraph_json.py

This file was deleted.

Loading