import numpy as np
import pytest
import scirs2
class TestGraphCreation:
def test_graph_from_edges_basic(self):
edges = [(0, 1), (1, 2), (2, 3)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
assert graph["num_nodes"] == 4
assert graph["num_edges"] == 3
assert graph["directed"] is False
assert "adjacency" in graph
def test_graph_from_edges_weighted(self):
edges = [(0, 1, 1.5), (1, 2, 2.0), (2, 3, 0.5)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
assert graph["num_nodes"] == 4
assert graph["num_edges"] == 3
adj = graph["adjacency"]
assert len(adj[0]) > 0 assert len(adj[1]) > 0
def test_digraph_from_edges_basic(self):
edges = [(0, 1), (1, 2), (2, 0)]
graph = scirs2.digraph_from_edges_py(edges, num_nodes=3)
assert graph["num_nodes"] == 3
assert graph["num_edges"] == 3
assert graph["directed"] is True
def test_graph_from_edges_auto_nodes(self):
edges = [(0, 5), (1, 3), (2, 4)]
graph = scirs2.graph_from_edges_py(edges)
assert graph["num_nodes"] >= 6
class TestGraphGenerators:
def test_complete_graph(self):
graph = scirs2.complete_graph_py(5)
assert graph["num_nodes"] == 5
assert graph["num_edges"] == 10
def test_path_graph(self):
graph = scirs2.path_graph_py(6)
assert graph["num_nodes"] == 6
assert graph["num_edges"] == 5
def test_cycle_graph(self):
graph = scirs2.cycle_graph_py(5)
assert graph["num_nodes"] == 5
assert graph["num_edges"] == 5
def test_star_graph(self):
graph = scirs2.star_graph_py(4)
assert graph["num_nodes"] == 5 assert graph["num_edges"] == 4
def test_erdos_renyi_graph(self):
graph = scirs2.erdos_renyi_graph_py(10, 0.3, seed=42)
assert graph["num_nodes"] == 10
assert 0 <= graph["num_edges"] <= 45
def test_barabasi_albert_graph(self):
graph = scirs2.barabasi_albert_graph_py(20, 2, seed=42)
assert graph["num_nodes"] == 20
assert graph["num_edges"] >= 18
def test_watts_strogatz_graph(self):
graph = scirs2.watts_strogatz_graph_py(10, 4, 0.1, seed=42)
assert graph["num_nodes"] == 10
assert 15 <= graph["num_edges"] <= 25
class TestShortestPaths:
def test_dijkstra_path_simple(self):
edges = [(0, 1, 1.0), (1, 2, 1.0), (0, 2, 5.0)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=3)
result = scirs2.dijkstra_path_py(graph, 0, 2)
assert result["success"]
assert result["distance"] == pytest.approx(2.0, abs=1e-10)
assert result["path"] == [0, 1, 2]
def test_dijkstra_path_no_path(self):
edges = [(0, 1), (2, 3)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
result = scirs2.dijkstra_path_py(graph, 0, 3)
assert result["success"] is False or result["distance"] == float('inf')
def test_floyd_warshall_basic(self):
edges = [(0, 1, 1.0), (1, 2, 2.0), (0, 2, 5.0)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=3)
result = scirs2.floyd_warshall_py(graph)
assert "distances" in result
distances = result["distances"]
assert distances.shape == (3, 3)
assert np.allclose(np.diag(distances), [0, 0, 0])
assert distances[0, 2] == pytest.approx(3.0, abs=1e-10)
class TestConnectivity:
def test_connected_components_single(self):
edges = [(0, 1), (1, 2), (2, 3)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
result = scirs2.connected_components_py(graph)
assert result["num_components"] == 1
assert len(result["components"]) == 1
def test_connected_components_multiple(self):
edges = [(0, 1), (2, 3), (4, 5)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=6)
result = scirs2.connected_components_py(graph)
assert result["num_components"] == 3
def test_strongly_connected_components(self):
edges = [(0, 1), (1, 2), (2, 0), (3, 4)]
graph = scirs2.digraph_from_edges_py(edges, num_nodes=5)
result = scirs2.strongly_connected_components_py(graph)
assert result["num_components"] >= 2
assert len(result["components"]) >= 2
def test_is_bipartite_true(self):
graph = scirs2.path_graph_py(4)
result = scirs2.is_bipartite_py(graph)
assert result["is_bipartite"] is True
def test_is_bipartite_false(self):
graph = scirs2.cycle_graph_py(5)
result = scirs2.is_bipartite_py(graph)
assert result["is_bipartite"] is False
def test_articulation_points(self):
edges = [(0, 1), (1, 2)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=3)
result = scirs2.articulation_points_py(graph)
assert 1 in result["points"]
def test_bridges(self):
edges = [(0, 1), (1, 2), (2, 3)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
result = scirs2.bridges_py(graph)
assert len(result["bridges"]) >= 1
class TestTraversal:
def test_breadth_first_search(self):
edges = [(0, 1), (0, 2), (1, 3), (2, 4)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=5)
result = scirs2.breadth_first_search_py(graph, 0)
assert "order" in result
assert len(result["order"]) == 5
assert result["order"][0] == 0
def test_depth_first_search(self):
edges = [(0, 1), (0, 2), (1, 3), (2, 4)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=5)
result = scirs2.depth_first_search_py(graph, 0)
assert "order" in result
assert len(result["order"]) == 5
assert result["order"][0] == 0
class TestCentrality:
def test_betweenness_centrality(self):
graph = scirs2.star_graph_py(4)
result = scirs2.betweenness_centrality_py(graph)
assert "centrality" in result
centrality = result["centrality"]
assert centrality[0] > 0
def test_closeness_centrality(self):
edges = [(0, 1), (1, 2), (2, 3)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
result = scirs2.closeness_centrality_py(graph)
assert "centrality" in result
centrality = result["centrality"]
assert all(c >= 0 for c in centrality)
def test_pagerank_centrality(self):
edges = [(0, 1), (1, 2), (2, 0), (1, 3)]
graph = scirs2.digraph_from_edges_py(edges, num_nodes=4)
result = scirs2.pagerank_centrality_py(graph)
assert "pagerank" in result
pagerank = result["pagerank"]
assert 0.9 <= sum(pagerank) <= 1.1
assert all(p > 0 for p in pagerank)
class TestSpanningTree:
def test_minimum_spanning_tree(self):
edges = [(0, 1, 1.0), (1, 2, 2.0), (0, 2, 5.0), (2, 3, 1.5)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=4)
result = scirs2.minimum_spanning_tree_py(graph)
assert "edges" in result
assert "total_weight" in result
assert len(result["edges"]) == 3
assert result["total_weight"] < 10.0
class TestCommunityDetection:
def test_louvain_communities(self):
edges = [
(0, 1), (1, 2), (0, 2), (3, 4), (4, 5), (3, 5), (2, 3), ]
graph = scirs2.graph_from_edges_py(edges, num_nodes=6)
result = scirs2.louvain_communities_py(graph)
assert "communities" in result
assert "num_communities" in result
assert result["num_communities"] >= 1
def test_label_propagation(self):
edges = [
(0, 1), (1, 2), (0, 2), (3, 4), (4, 5), (3, 5), ]
graph = scirs2.graph_from_edges_py(edges, num_nodes=6)
result = scirs2.label_propagation_py(graph, seed=42)
assert "communities" in result
assert len(result["communities"]) == 6
def test_modularity(self):
edges = [(0, 1), (1, 2), (3, 4)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=5)
communities = [0, 0, 0, 1, 1]
result = scirs2.modularity_py(graph, communities)
assert "modularity" in result
assert -1.0 <= result["modularity"] <= 1.0
class TestGraphMeasures:
def test_clustering_coefficient(self):
edges = [(0, 1), (1, 2), (2, 0)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=3)
result = scirs2.clustering_coefficient_py(graph)
assert "average" in result or "clustering" in result
if "average" in result:
assert result["average"] > 0.5
def test_diameter(self):
graph = scirs2.path_graph_py(4)
result = scirs2.diameter_py(graph)
assert "diameter" in result
assert result["diameter"] == 3
class TestEdgeCases:
def test_empty_graph(self):
graph = scirs2.graph_from_edges_py([], num_nodes=0)
assert graph["num_nodes"] == 0
assert graph["num_edges"] == 0
def test_single_node_graph(self):
graph = scirs2.graph_from_edges_py([], num_nodes=1)
assert graph["num_nodes"] == 1
assert graph["num_edges"] == 0
def test_self_loop(self):
edges = [(0, 0), (0, 1)]
graph = scirs2.graph_from_edges_py(edges, num_nodes=2)
assert graph["num_nodes"] == 2
if __name__ == "__main__":
pytest.main([__file__, "-v"])