chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
import pytest
|
||||
|
||||
from easygraph import biconnected_components
|
||||
from easygraph import generator_articulation_points
|
||||
from easygraph import generator_biconnected_components_edges
|
||||
from easygraph import generator_biconnected_components_nodes
|
||||
from easygraph import is_biconnected
|
||||
|
||||
|
||||
class Test_biconnected(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.edges = [(1, 2), (2, 3), ("String", "Bool"), (2, 1), (0, 0), (-99, 256)]
|
||||
self.test_graphs = [eg.Graph(), eg.MultiGraph(), eg.DiGraph()]
|
||||
self.test_graphs.append(eg.classes.DiGraph(self.edges))
|
||||
|
||||
def test_is_biconnected(self):
|
||||
for i in self.test_graphs:
|
||||
print(eg.is_biconnected(i))
|
||||
|
||||
def test_biconnected_components(self):
|
||||
for i in self.test_graphs:
|
||||
eg.biconnected_components(i)
|
||||
|
||||
def test_generator_biconnected_components_nodes(self):
|
||||
for i in self.test_graphs:
|
||||
eg.generator_biconnected_components_nodes(i)
|
||||
|
||||
def test_generator_biconnected_components_edges(self):
|
||||
for i in self.test_graphs:
|
||||
eg.generator_biconnected_components_edges(i)
|
||||
|
||||
def test_generator_articulation_points(self):
|
||||
for i in self.test_graphs:
|
||||
eg.generator_articulation_points(i)
|
||||
|
||||
|
||||
class TestBiconnectedFunctions(unittest.TestCase):
|
||||
def test_single_node(self):
|
||||
G = eg.Graph()
|
||||
G.add_node(1)
|
||||
self.assertFalse(is_biconnected(G))
|
||||
self.assertEqual(list(biconnected_components(G)), [])
|
||||
self.assertEqual(list(generator_articulation_points(G)), [])
|
||||
|
||||
def test_disconnected_graph(self):
|
||||
G = eg.Graph()
|
||||
G.add_edges_from([(0, 1), (2, 3)])
|
||||
self.assertFalse(is_biconnected(G))
|
||||
self.assertGreaterEqual(len(list(generator_biconnected_components_edges(G))), 1)
|
||||
|
||||
def test_triangle(self):
|
||||
G = eg.Graph([(0, 1), (1, 2), (2, 0)])
|
||||
self.assertTrue(is_biconnected(G))
|
||||
comps = list(biconnected_components(G))
|
||||
self.assertEqual(len(comps), 1)
|
||||
self.assertEqual(set(comps[0]), {(0, 1), (1, 2), (2, 0)})
|
||||
self.assertEqual(list(generator_articulation_points(G)), [])
|
||||
|
||||
def test_with_articulation_point(self):
|
||||
G = eg.Graph([(0, 1), (1, 2), (1, 3)])
|
||||
self.assertFalse(is_biconnected(G))
|
||||
arts = list(generator_articulation_points(G))
|
||||
self.assertIn(1, arts)
|
||||
self.assertEqual(len(arts), 1)
|
||||
|
||||
def test_cycle_plus_leaf(self):
|
||||
G = eg.Graph([(0, 1), (1, 2), (2, 0), (2, 3)])
|
||||
self.assertFalse(is_biconnected(G))
|
||||
arts = list(generator_articulation_points(G))
|
||||
self.assertIn(2, arts)
|
||||
|
||||
def test_multiple_biconnected_components(self):
|
||||
G = eg.Graph()
|
||||
G.add_edges_from([(1, 2), (2, 3), (3, 1)]) # triangle
|
||||
G.add_edges_from([(3, 4), (4, 5)]) # path
|
||||
components = list(generator_biconnected_components_edges(G))
|
||||
self.assertEqual(len(components), 3)
|
||||
nodes_comps = list(generator_biconnected_components_nodes(G))
|
||||
self.assertTrue(any({1, 2, 3}.issubset(comp) for comp in nodes_comps))
|
||||
self.assertTrue(any({4, 5}.issubset(comp) for comp in nodes_comps))
|
||||
|
||||
def test_articulation_points_multiple(self):
|
||||
G = eg.Graph([(0, 1), (1, 2), (2, 3), (3, 4)])
|
||||
aps = list(generator_articulation_points(G))
|
||||
self.assertEqual(aps, [3, 2, 1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,112 @@
|
||||
import inspect
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
from easygraph import connected_component_of_node
|
||||
from easygraph import connected_components
|
||||
from easygraph import connected_components_directed
|
||||
from easygraph import is_connected
|
||||
from easygraph import number_connected_components
|
||||
from easygraph.utils.exception import EasyGraphNotImplemented
|
||||
|
||||
|
||||
class TestConnected(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.edges = [(1, 2), (2, 3), (0, 4), (2, 1), (0, 0), (-99, 256)]
|
||||
self.test_graphs = [eg.Graph([(4, -4)]), eg.DiGraph([(4, -4)])]
|
||||
self.test_graphs.append(eg.classes.DiGraph(self.edges))
|
||||
|
||||
def test_is_connected(self):
|
||||
for i in self.test_graphs:
|
||||
print(eg.is_connected(i))
|
||||
|
||||
def test_number_connected_components(self):
|
||||
for i in self.test_graphs:
|
||||
print(eg.number_connected_components(i))
|
||||
|
||||
def test_connected_components(self):
|
||||
for i in self.test_graphs:
|
||||
print(eg.connected_components(i))
|
||||
|
||||
def test_connected_components_directed(self):
|
||||
for i in self.test_graphs:
|
||||
print(eg.connected_components_directed(i))
|
||||
|
||||
def test_connected_component_of_node(self):
|
||||
for i in self.test_graphs:
|
||||
print(eg.connected_component_of_node(i, 4))
|
||||
|
||||
def test_empty_graph(self):
|
||||
G = eg.Graph()
|
||||
with self.assertRaises(AssertionError):
|
||||
is_connected(G)
|
||||
self.assertEqual(number_connected_components(G), 0)
|
||||
self.assertEqual(list(connected_components(G)), [])
|
||||
|
||||
def test_single_node(self):
|
||||
G = eg.Graph()
|
||||
G.add_node(1)
|
||||
self.assertTrue(is_connected(G))
|
||||
self.assertEqual(number_connected_components(G), 1)
|
||||
self.assertEqual(list(connected_components(G)), [{1}])
|
||||
self.assertEqual(connected_component_of_node(G, 1), {1})
|
||||
|
||||
def test_disconnected_graph(self):
|
||||
G = eg.Graph()
|
||||
G.add_edges_from([(0, 1), (2, 3)])
|
||||
self.assertFalse(is_connected(G))
|
||||
self.assertEqual(number_connected_components(G), 2)
|
||||
comps = list(connected_components(G))
|
||||
self.assertTrue({0, 1} in comps and {2, 3} in comps)
|
||||
|
||||
def test_connected_graph(self):
|
||||
G = eg.path_graph(5)
|
||||
self.assertTrue(is_connected(G))
|
||||
self.assertEqual(number_connected_components(G), 1)
|
||||
comps = list(connected_components(G))
|
||||
self.assertEqual(len(comps), 1)
|
||||
self.assertEqual(comps[0], set(range(5)))
|
||||
|
||||
def test_node_component_lookup(self):
|
||||
G = eg.Graph()
|
||||
G.add_edges_from([(0, 1), (2, 3)])
|
||||
comp = connected_component_of_node(G, 0)
|
||||
self.assertEqual(comp, {0, 1})
|
||||
with self.assertRaises(KeyError):
|
||||
connected_component_of_node(G, 999) # non-existent node
|
||||
|
||||
def test_undirected_with_self_loops(self):
|
||||
G = eg.Graph()
|
||||
G.add_edges_from([(1, 1), (2, 2), (1, 2)])
|
||||
self.assertTrue(is_connected(G))
|
||||
self.assertEqual(number_connected_components(G), 1)
|
||||
self.assertEqual(list(connected_components(G))[0], {1, 2})
|
||||
|
||||
def test_directed_components(self):
|
||||
G = eg.DiGraph()
|
||||
G.add_edges_from([(0, 1), (2, 3)])
|
||||
self.assertEqual(number_connected_components(G), 2)
|
||||
components = list(connected_components_directed(G))
|
||||
self.assertTrue({0, 1} in components and {2, 3} in components)
|
||||
|
||||
def test_directed_strong_vs_weak(self):
|
||||
G = eg.DiGraph([(0, 1), (1, 0), (2, 3)])
|
||||
comps = list(connected_components_directed(G))
|
||||
self.assertTrue({0, 1} in comps)
|
||||
self.assertTrue({2, 3} in comps)
|
||||
|
||||
def test_multigraph_blocked(self):
|
||||
G = eg.MultiGraph([(1, 2), (2, 3)])
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
is_connected(G)
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
number_connected_components(G)
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
list(connected_components(G))
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
connected_component_of_node(G, 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,121 @@
|
||||
import inspect
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
from easygraph import condensation
|
||||
from easygraph import is_strongly_connected
|
||||
from easygraph import number_strongly_connected_components
|
||||
from easygraph import strongly_connected_components
|
||||
from easygraph.utils.exception import EasyGraphNotImplemented
|
||||
from easygraph.utils.exception import EasyGraphPointlessConcept
|
||||
|
||||
|
||||
class Test_strongly_connected(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.edges = [(1, 2), (2, 3), ("String", "Bool"), (2, 1), (0, 0), (-99, 256)]
|
||||
self.test_graphs = [eg.Graph([(4, -4)]), eg.DiGraph([(4, False)])]
|
||||
self.test_graphs.append(eg.classes.DiGraph(self.edges))
|
||||
|
||||
def test_empty_graph(self):
|
||||
G = eg.DiGraph()
|
||||
with self.assertRaises(EasyGraphPointlessConcept):
|
||||
is_strongly_connected(G)
|
||||
self.assertEqual(number_strongly_connected_components(G), 0)
|
||||
self.assertEqual(list(strongly_connected_components(G)), [])
|
||||
|
||||
def test_single_node(self):
|
||||
G = eg.DiGraph()
|
||||
G.add_node(1)
|
||||
self.assertTrue(is_strongly_connected(G))
|
||||
self.assertEqual(number_strongly_connected_components(G), 1)
|
||||
scc = list(strongly_connected_components(G))
|
||||
self.assertEqual(scc, [{1}])
|
||||
|
||||
def test_cycle_graph(self):
|
||||
G = eg.DiGraph([(1, 2), (2, 3), (3, 1)])
|
||||
self.assertTrue(is_strongly_connected(G))
|
||||
self.assertEqual(number_strongly_connected_components(G), 1)
|
||||
scc = list(strongly_connected_components(G))
|
||||
self.assertEqual(scc, [{1, 2, 3}])
|
||||
|
||||
def test_disconnected_scc(self):
|
||||
G = eg.DiGraph([(0, 1), (1, 0), (2, 3), (3, 2), (4, 5)])
|
||||
scc = list(strongly_connected_components(G))
|
||||
self.assertEqual(len(scc), 4)
|
||||
self.assertIn({0, 1}, scc)
|
||||
self.assertIn({2, 3}, scc)
|
||||
self.assertIn({4}, scc)
|
||||
self.assertIn({5}, scc)
|
||||
self.assertFalse(is_strongly_connected(G))
|
||||
self.assertEqual(number_strongly_connected_components(G), 4)
|
||||
|
||||
def test_scc_with_self_loops(self):
|
||||
G = eg.DiGraph([(1, 1), (2, 2), (3, 4), (4, 3)])
|
||||
scc = list(strongly_connected_components(G))
|
||||
self.assertEqual(len(scc), 3)
|
||||
self.assertIn({1}, scc)
|
||||
self.assertIn({2}, scc)
|
||||
self.assertIn({3, 4}, scc)
|
||||
|
||||
def test_condensation_structure(self):
|
||||
G = eg.DiGraph(
|
||||
[(0, 1), (1, 2), (2, 0), (2, 3), (4, 5), (3, 4), (5, 6), (6, 3), (6, 7)]
|
||||
)
|
||||
cond = condensation(G)
|
||||
self.assertTrue(cond.is_directed())
|
||||
self.assertIn("mapping", cond.graph)
|
||||
self.assertEqual(len(cond), number_strongly_connected_components(G))
|
||||
|
||||
def has_cycle(G):
|
||||
visited = set()
|
||||
temp_mark = set()
|
||||
|
||||
def visit(node):
|
||||
if node in temp_mark:
|
||||
return True
|
||||
if node in visited:
|
||||
return False
|
||||
temp_mark.add(node)
|
||||
for neighbor in G[node]:
|
||||
if visit(neighbor):
|
||||
return True
|
||||
temp_mark.remove(node)
|
||||
visited.add(node)
|
||||
return False
|
||||
|
||||
return any(visit(v) for v in G)
|
||||
|
||||
self.assertFalse(has_cycle(cond))
|
||||
|
||||
def test_condensation_empty_graph(self):
|
||||
G = eg.DiGraph()
|
||||
C = condensation(G)
|
||||
self.assertEqual(len(C), 0)
|
||||
|
||||
def test_undirected_raises(self):
|
||||
G = eg.Graph([(1, 2), (2, 3)])
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
list(strongly_connected_components(G))
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
is_strongly_connected(G)
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
number_strongly_connected_components(G)
|
||||
|
||||
def test_condensation_on_undirected_graph_raises(self):
|
||||
G = eg.Graph([(1, 2), (2, 3)])
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
condensation(G)
|
||||
|
||||
def test_condensation_manual_scc_input(self):
|
||||
G = eg.DiGraph([(1, 2), (2, 1), (3, 4)])
|
||||
scc = list(strongly_connected_components(G))
|
||||
C = condensation(G, scc=scc)
|
||||
self.assertEqual(len(C.nodes), len(scc))
|
||||
# Check if mapping is consistent
|
||||
all_mapped = set(C.graph["mapping"].keys())
|
||||
self.assertEqual(all_mapped, set(G.nodes))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,82 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
from easygraph import is_weakly_connected
|
||||
from easygraph import number_weakly_connected_components
|
||||
from easygraph import weakly_connected_components
|
||||
from easygraph.utils.exception import EasyGraphNotImplemented
|
||||
from easygraph.utils.exception import EasyGraphPointlessConcept
|
||||
|
||||
|
||||
class Test_weakly_connected(unittest.TestCase):
|
||||
def test_empty_graph(self):
|
||||
G = eg.DiGraph()
|
||||
with self.assertRaises(EasyGraphPointlessConcept):
|
||||
is_weakly_connected(G)
|
||||
self.assertEqual(number_weakly_connected_components(G), 0)
|
||||
self.assertEqual(list(weakly_connected_components(G)), [])
|
||||
|
||||
def test_single_node(self):
|
||||
G = eg.DiGraph()
|
||||
G.add_node(1)
|
||||
self.assertTrue(is_weakly_connected(G))
|
||||
self.assertEqual(number_weakly_connected_components(G), 1)
|
||||
self.assertEqual(list(weakly_connected_components(G)), [{1}])
|
||||
|
||||
def test_connected_graph(self):
|
||||
G = eg.DiGraph([(1, 2), (2, 3), (3, 4)])
|
||||
self.assertTrue(is_weakly_connected(G))
|
||||
self.assertEqual(number_weakly_connected_components(G), 1)
|
||||
self.assertEqual(list(weakly_connected_components(G)), [{1, 2, 3, 4}])
|
||||
|
||||
def test_disconnected_graph(self):
|
||||
G = eg.DiGraph([(1, 2), (3, 4)])
|
||||
self.assertFalse(is_weakly_connected(G))
|
||||
wcc = list(weakly_connected_components(G))
|
||||
self.assertEqual(len(wcc), 2)
|
||||
self.assertIn({1, 2}, wcc)
|
||||
self.assertIn({3, 4}, wcc)
|
||||
|
||||
def test_self_loops(self):
|
||||
G = eg.DiGraph([(1, 1), (2, 2)])
|
||||
wcc = list(weakly_connected_components(G))
|
||||
self.assertEqual(len(wcc), 2)
|
||||
self.assertIn({1}, wcc)
|
||||
self.assertIn({2}, wcc)
|
||||
self.assertFalse(is_weakly_connected(G))
|
||||
|
||||
def test_multiple_components(self):
|
||||
G = eg.DiGraph([(1, 2), (3, 4), (5, 6), (6, 5)])
|
||||
wcc = list(weakly_connected_components(G))
|
||||
self.assertEqual(number_weakly_connected_components(G), 3)
|
||||
self.assertIn({1, 2}, wcc)
|
||||
self.assertIn({3, 4}, wcc)
|
||||
self.assertIn({5, 6}, wcc)
|
||||
|
||||
def test_unconnected_nodes(self):
|
||||
G = eg.DiGraph([(1, 2), (3, 4)])
|
||||
G.add_node(99) # isolated node
|
||||
wcc = list(weakly_connected_components(G))
|
||||
self.assertEqual(len(wcc), 3)
|
||||
self.assertIn({99}, wcc)
|
||||
|
||||
def test_is_weakly_connected_after_adding_edge(self):
|
||||
G = eg.DiGraph([(0, 1), (2, 1)])
|
||||
G.add_node(3)
|
||||
self.assertFalse(is_weakly_connected(G))
|
||||
G.add_edge(2, 3)
|
||||
self.assertTrue(is_weakly_connected(G))
|
||||
|
||||
def test_undirected_raises(self):
|
||||
G = eg.Graph([(1, 2), (2, 3)])
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
is_weakly_connected(G)
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
number_weakly_connected_components(G)
|
||||
with self.assertRaises(EasyGraphNotImplemented):
|
||||
list(weakly_connected_components(G))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user