Skip to content

Commit 41d52ed

Browse files
committed
add approximatly a million more tests
1 parent 38e2b66 commit 41d52ed

12 files changed

Lines changed: 602 additions & 53 deletions

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ repository = "https://github.com/reticula-network/reticula-python"
3535
bug-tracker= "https://github.com/reticula-network/reticula-python/issues"
3636

3737
[project.optional-dependencies]
38-
test = ["pytest", "hypothesis", "pytest-xdist"]
38+
test = ["pytest", "hypothesis", "pytest-xdist", "networkx"]
3939

4040
[build-system]
4141
requires = [

tests/network_strategies.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,44 @@ def directed_temporal_hypernetwork(draw: st.DrawFn,
145145
st.floats(min_value=0, max_value=10))
146146
edges = st.lists(hyperedge, min_size=0, max_size=max_edges)
147147
return ret.directed_temporal_hypernetwork[VERT, TIME](draw(edges), verts)
148+
149+
150+
any_network = st.one_of(
151+
undirected_network(),
152+
directed_network(),
153+
undirected_hypernetwork(),
154+
directed_hypernetwork(),
155+
undirected_temporal_network(),
156+
directed_temporal_network(),
157+
undirected_temporal_hypernetwork(),
158+
directed_temporal_hypernetwork(),
159+
)
160+
161+
any_directed_network = st.one_of(
162+
directed_network(),
163+
directed_temporal_network(),
164+
directed_hypernetwork(),
165+
directed_temporal_hypernetwork(),
166+
)
167+
168+
169+
any_undirected_network = st.one_of(
170+
undirected_network(),
171+
undirected_temporal_network(),
172+
undirected_hypernetwork(),
173+
undirected_temporal_hypernetwork(),
174+
)
175+
176+
177+
static_network = st.one_of(
178+
undirected_network(),
179+
directed_network(),
180+
undirected_hypernetwork(),
181+
directed_hypernetwork(),
182+
)
183+
184+
any_dyadic_network = st.one_of(
185+
undirected_network(),
186+
directed_network(),
187+
undirected_temporal_network(),
188+
directed_temporal_network())

tests/test_algorithms.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import math
22

3-
import pytest
43
import reticula as ret
4+
5+
import pytest
56
from hypothesis import given
6-
from network_strategies import undirected_network, directed_network
7+
from network_strategies import any_network, any_undirected_network
78

89

910
def test_density():
@@ -152,21 +153,34 @@ def test_degree_sequence():
152153
assert set(inc_deg_seq) == {2, 2, 2}
153154

154155

155-
@given(undirected_network())
156+
@given(any_undirected_network)
156157
def test_degree_properties(net):
157158
for v in net.vertices():
158159
deg = ret.degree(net, v)
159-
assert deg >= 0
160160
assert deg == len([e for e in net.edges() if v in e.incident_verts()])
161161

162162

163-
@given(directed_network())
163+
@given(any_network)
164164
def test_directed_degree_properties(net):
165165
for v in net.vertices():
166166
in_deg = ret.in_degree(net, v)
167+
assert in_deg == len([
168+
e for e in net.edges()
169+
if v in e.mutated_verts()])
170+
167171
out_deg = ret.out_degree(net, v)
168-
assert in_deg >= 0
169-
assert out_deg >= 0
172+
assert out_deg == len([
173+
e for e in net.edges()
174+
if v in e.mutator_verts()])
175+
176+
inc_deg = ret.incident_degree(net, v)
177+
assert inc_deg == len([
178+
e for e in net.edges()
179+
if v in e.incident_verts()])
180+
181+
for v in net.vertices():
182+
assert ret.in_degree(net, v) >= 0
183+
assert ret.out_degree(net, v) >= 0
170184

171185

172186
def test_attribute_assortativity():

tests/test_distributions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,12 @@ def test_residual_power_law_with_specified_mean():
7575

7676
values = [dist(gen) for _ in range(100)]
7777
assert all(v >= 0.0 for v in values)
78+
79+
80+
def test_hawkes_univariate_exponential():
81+
gen = ret.mersenne_twister(42)
82+
hawkes_dist = ret.hawkes_univariate_exponential[ret.double](
83+
mu=1.0, alpha=0.5, theta=2.0)
84+
85+
values = [hawkes_dist(gen) for _ in range(100)]
86+
assert all(v >= 0.0 for v in values)

tests/test_event_graphs.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import reticula as ret
2+
3+
4+
def test_event_graph_creation():
5+
edges = [(0, 1, 1.0), (1, 2, 2.0), (0, 2, 3.0)]
6+
net = ret.directed_temporal_network[ret.int64, ret.double](edges)
7+
8+
adj = ret.temporal_adjacency.limited_waiting_time[net.edge_type()](2.0)
9+
eg = ret.event_graph(net, adj)
10+
assert eg.successors((1, 2, 2.0)) == []
11+
assert eg.successors((0, 1, 1.0)) == [net.edge_type()(1, 2, 2.0)]
12+
assert eg.predecessors((1, 2, 2.0)) == [net.edge_type()(0, 1, 1.0)]
13+
14+
adj = ret.temporal_adjacency.limited_waiting_time[net.edge_type()](0.5)
15+
eg = ret.event_graph(net, adj)
16+
assert eg.successors((1, 2, 2.0)) == []
17+
assert eg.predecessors((1, 2, 2.0)) == []
18+
19+
20+
def test_implicit_event_graph():
21+
edges = [(0, 1, 1.0), (1, 2, 2.0), (0, 2, 3.0)]
22+
net = ret.directed_temporal_network[ret.int64, ret.double](edges)
23+
24+
adj = ret.temporal_adjacency.limited_waiting_time[net.edge_type()](2.0)
25+
ieg = ret.implicit_event_graph[net.edge_type(), type(adj)](net, adj)
26+
assert ieg.successors((1, 2, 2.0)) == []
27+
assert ieg.successors((0, 1, 1.0)) == [net.edge_type()(1, 2, 2.0)]
28+
assert ieg.predecessors((1, 2, 2.0)) == [net.edge_type()(0, 1, 1.0)]
29+
30+
ieg = ret.make_implicit_event_graph(net, adj)
31+
assert ieg.successors((1, 2, 2.0)) == []
32+
assert ieg.successors((0, 1, 1.0)) == [net.edge_type()(1, 2, 2.0)]
33+
assert ieg.predecessors((1, 2, 2.0)) == [net.edge_type()(0, 1, 1.0)]
34+
35+
adj = ret.temporal_adjacency.limited_waiting_time[net.edge_type()](0.5)
36+
ieg = ret.implicit_event_graph[net.edge_type(), type(adj)](net, adj)
37+
assert ieg.successors((1, 2, 2.0)) == []
38+
assert ieg.predecessors((1, 2, 2.0)) == []
39+
40+
ieg = ret.make_implicit_event_graph(net, adj)
41+
assert ieg.successors((1, 2, 2.0)) == []
42+
assert ieg.predecessors((1, 2, 2.0)) == []

tests/test_generation_operations.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,142 @@ def test_graph_union():
7979
u = ret.graph_union(g1, g2)
8080
assert len(u.edges()) == len(g1.edges()) + 1
8181
assert set(u.vertices()) == set(g2.vertices())
82+
83+
84+
def test_square_grid_graph():
85+
g = ret.square_grid_graph[ret.int64](side=3, dims=2)
86+
assert len(g.vertices()) == 9
87+
assert len(g.edges()) == 12
88+
89+
90+
def test_regular_ring_lattice():
91+
g = ret.regular_ring_lattice[ret.int64](size=6, degree=2)
92+
assert len(g.vertices()) == 6
93+
assert all(ret.degree(g, v) == 2 for v in g.vertices())
94+
95+
96+
def test_random_barabasi_albert_graph():
97+
gen = ret.mersenne_twister(42)
98+
g = ret.random_barabasi_albert_graph[ret.int64](
99+
n=10, m=2, random_state=gen)
100+
assert len(g.vertices()) == 10
101+
assert len(g.edges()) == 2*(10-2)
102+
103+
104+
def test_random_degree_sequence_graph():
105+
gen = ret.mersenne_twister(42)
106+
degree_seq = [2, 2, 2, 2]
107+
g = ret.random_degree_sequence_graph[ret.int64](
108+
degree_sequence=degree_seq, random_state=gen)
109+
assert len(g.vertices()) == 4
110+
assert all(ret.degree(g, v) == 2 for v in g.vertices())
111+
112+
113+
def test_random_directed_degree_sequence_graph():
114+
gen = ret.mersenne_twister(42)
115+
in_out_seq = [(1, 1), (1, 1), (1, 1)]
116+
g = ret.random_directed_degree_sequence_graph[ret.int64](
117+
in_out_degree_sequence=in_out_seq, random_state=gen)
118+
assert len(g.vertices()) == 3
119+
for v in g.vertices():
120+
assert ret.in_degree(g, v) == 1
121+
assert ret.out_degree(g, v) == 1
122+
123+
124+
def test_random_expected_degree_sequence_graph():
125+
gen = ret.mersenne_twister(42)
126+
weight_seq = [2.0, 2.0, 2.0, 2.0]
127+
g = ret.random_expected_degree_sequence_graph[ret.int64](
128+
weight_sequence=weight_seq, random_state=gen)
129+
assert len(g.vertices()) == 4
130+
131+
132+
def test_random_directed_expected_degree_sequence_graph():
133+
gen = ret.mersenne_twister(42)
134+
in_out_weight_seq = [(1.0, 1.0), (1.0, 1.0), (1.0, 1.0)]
135+
g = ret.random_directed_expected_degree_sequence_graph[ret.int64](
136+
in_out_weight_sequence=in_out_weight_seq, random_state=gen)
137+
assert len(g.vertices()) == 3
138+
139+
140+
def test_random_uniform_hypergraph():
141+
gen = ret.mersenne_twister(42)
142+
g = ret.random_uniform_hypergraph[ret.int64](
143+
size=5, edge_degree=3, edge_prob=0.5, random_state=gen)
144+
assert len(g.vertices()) == 5
145+
for e in g.edges():
146+
assert len(e.incident_verts()) == 3
147+
148+
149+
def test_random_directed_uniform_hypergraph():
150+
gen = ret.mersenne_twister(42)
151+
g = ret.random_directed_uniform_hypergraph[ret.int64](
152+
size=5, edge_in_degree=2, edge_out_degree=2,
153+
edge_prob=0.5, random_state=gen)
154+
assert len(g.vertices()) == 5
155+
156+
157+
def test_random_expected_degree_sequence_hypergraph():
158+
gen = ret.mersenne_twister(42)
159+
vertex_weights = [3.0, 3.0, 3.0, 3.0]
160+
edge_weights = [4.0, 4.0, 4.0]
161+
g = ret.random_expected_degree_sequence_hypergraph[ret.int64](
162+
vertex_weight_sequence=vertex_weights,
163+
edge_weight_sequence=edge_weights, random_state=gen)
164+
assert len(g.vertices()) == 4
165+
166+
167+
def test_random_directed_expected_degree_sequence_hypergraph():
168+
gen = ret.mersenne_twister(42)
169+
vertex_in_out_weights = [(1.0, 1.0), (1.0, 1.0),
170+
(1.0, 1.0)]
171+
edge_in_out_weights = [(3.0, 3.0)]
172+
g = ret.random_directed_expected_degree_sequence_hypergraph[ret.int64](
173+
vertex_in_out_weight_sequence=vertex_in_out_weights,
174+
edge_in_out_weight_sequence=edge_in_out_weights,
175+
random_state=gen)
176+
assert len(g.vertices()) == 3
177+
178+
179+
def test_random_fully_mixed_temporal_network():
180+
gen = ret.mersenne_twister(42)
181+
g = ret.random_fully_mixed_temporal_network[ret.int64](
182+
size=4, rate=1.0, max_t=10.0, random_state=gen)
183+
assert len(g.vertices()) == 4
184+
t0, t1 = ret.time_window(g)
185+
assert t0 >= 0.0
186+
assert t1 <= 10.0
187+
188+
189+
def test_random_directed_fully_mixed_temporal_network():
190+
gen = ret.mersenne_twister(42)
191+
g = ret.random_directed_fully_mixed_temporal_network[ret.int64](
192+
size=4, rate=1.0, max_t=10.0, random_state=gen)
193+
assert len(g.vertices()) == 4
194+
t0, t1 = ret.time_window(g)
195+
assert t0 >= 0.0
196+
assert t1 <= 10.0
197+
198+
199+
def test_random_link_activation_temporal_network():
200+
gen = ret.mersenne_twister(42)
201+
static_net = ret.complete_graph[ret.int64](size=3)
202+
iet_dist = ret.exponential_distribution[ret.double](lmbda=1.0)
203+
g = ret.random_link_activation_temporal_network(
204+
base_net=static_net, max_t=5.0, iet_dist=iet_dist, random_state=gen)
205+
assert len(g.vertices()) == 3
206+
t0, t1 = ret.time_window(g)
207+
assert t0 >= 0.0
208+
assert t1 <= 5.0
209+
210+
211+
def test_random_node_activation_temporal_network():
212+
gen = ret.mersenne_twister(42)
213+
base_net = ret.complete_graph[ret.int64](size=4)
214+
iet_dist = ret.exponential_distribution[ret.double](lmbda=1.0)
215+
g = ret.random_node_activation_temporal_network(
216+
base_net=base_net, max_t=5.0, iet_dist=iet_dist, random_state=gen)
217+
assert len(g.vertices()) == 4
218+
t0, t1 = ret.time_window(g)
219+
assert t0 >= 0.0
220+
assert t1 <= 5.0

tests/test_graph_operations.py

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,15 @@
1-
from hypothesis import given, assume
21
import math
32
import statistics
43

4+
from hypothesis import given, assume
55
from hypothesis import strategies as st
66
import pytest
77

88
import reticula as ret
99

1010
from network_strategies import (
11-
undirected_network,
12-
directed_network,
13-
undirected_temporal_network,
14-
directed_temporal_network,
15-
undirected_hypernetwork,
16-
directed_hypernetwork,
17-
undirected_temporal_hypernetwork,
18-
directed_temporal_hypernetwork
19-
)
20-
21-
22-
any_network = st.one_of(
23-
undirected_network(),
24-
directed_network(),
25-
undirected_hypernetwork(),
26-
directed_hypernetwork(),
27-
undirected_temporal_network(),
28-
directed_temporal_network(),
29-
undirected_temporal_hypernetwork(),
30-
directed_temporal_hypernetwork(),
31-
)
32-
33-
any_directed_network = st.one_of(
34-
directed_network(),
35-
directed_temporal_network(),
36-
directed_hypernetwork(),
37-
directed_temporal_hypernetwork(),
38-
)
39-
40-
41-
any_undirected_network = st.one_of(
42-
undirected_network(),
43-
undirected_temporal_network(),
44-
undirected_hypernetwork(),
45-
undirected_temporal_hypernetwork(),
46-
)
47-
48-
49-
static_network = st.one_of(
50-
undirected_network(),
51-
directed_network(),
52-
undirected_hypernetwork(),
53-
directed_hypernetwork(),
54-
)
11+
undirected_network, undirected_hypernetwork,
12+
directed_network, any_network)
5513

5614

5715
@given(any_network)

0 commit comments

Comments
 (0)