Skip to content

Instantly share code, notes, and snippets.

@rik0
Forked from anonymous/test_graph.py
Created April 21, 2012 18:05
Show Gist options
  • Save rik0/2438870 to your computer and use it in GitHub Desktop.
Save rik0/2438870 to your computer and use it in GitHub Desktop.
Simple test for a Graph class
import unittest
from graph import Graph
class TestGraph(unittest.TestCase):
def test_init(self):
# Graph(iterable: nodes, iterable of nodes couples: edges)
graph = Graph()
self.assertEqual(graph.number_of_nodes, 0)
self.assertEqual(graph.number_of_edges, 0)
self.assertEqual(list(graph.nodes), [])
self.assertEqual(list(graph.edges), [])
graph = Graph(range(5))
self.assertEqual(graph.number_of_nodes, 5)
self.assertEqual(graph.number_of_edges, 0)
self.assertEqual(sorted(graph.nodes), list(range(5)))
self.assertEqual(list(graph.edges), [])
graph = Graph(range(5), ((0,1), (3,2), (4,0)))
self.assertEqual(graph.number_of_nodes, 5)
self.assertEqual(graph.number_of_edges, 3)
self.assertEqual(sorted(graph.nodes), list(range(5)))
self.assertEqual(sorted(graph.edges), [(0, 1), (3, 2), (4, 0)])
graph = Graph([0,3,7], ((0,3), (7,3)))
self.assertEqual(graph.number_of_nodes, 3)
self.assertEqual(graph.number_of_edges, 2)
self.assertEqual(sorted(graph.nodes), [0,3,7])
self.assertEqual(sorted(graph.edges), [(0,3), (7,3)])
def test_equals(self):
# A == B <=> set(A.nodes) == set(B.nodes) and set(A.edges) == (B.edges)
graph = Graph(range(7), ((1,2), (3,6), (4,5)))
graph2 = Graph(range(7), ((1,2), (4,5), (3,6)))
self.assertEqual(graph, graph2)
self.assertNotEqual(graph, Graph(range(8), ((1,2), (3,6), (4,5))))
self.assertNotEqual(graph, Graph(range(7), ((1,2), (5,4))))
def test_contains(self):
graph = Graph(range(4), ((0,1), (1,2)))
# Graph contains the node?
self.assertTrue(2 in graph)
self.assertTrue(0 in graph)
self.assertFalse(4 in graph)
# Graph contains the edge?
self.assertTrue((0,1) in graph)
self.assertTrue((1,2) in graph)
self.assertFalse((0,2) in graph)
subgraph = Graph(range(2), ((0,1),))
# Graph contains subgraph?
self.assertTrue(subgraph in graph)
subgraph = Graph(range(2), ((1,0),))
self.assertFalse(subgraph in graph)
path = [(0,1)]
# Graph contains the path? (sequence of edges)
self.assertTrue(path in graph)
path = [(0,1), (1,3)]
self.assertFalse(path in graph)
def test_is_connected(self):
self.assertTrue(Graph().is_connected())
self.assertTrue(Graph(range(1)).is_connected())
self.assertFalse(Graph(range(2), ((0,1),)).is_connected())
self.assertTrue(Graph(range(2),((0,1),(1,0))).is_connected())
# strongly=True -> takes into account orientation of edges
# strongly=False returns True if the underneath, not oriented, graph
# is connected.
self.assertTrue(Graph(range(2), ((0,1),)).is_connected(strongly=False))
def test_induce(self):
graph = Graph(range(10), ((0,1), (0,3), (0,9), (2,1), (2,5), (2,8),
(3,4), (4,1), (4,3), (5,6), (5,9), (7,8)))
# subgraph containing only the given subset of nodes
# and removing all edges containg other nodes
subgraph = graph.induce(nodes=(0,1,2,3))
self.assertEqual(subgraph, Graph(range(4), ((0,1), (0,3), (2,1))))
# Raises ValueError if a node which does not belong to the
# graph is in the set of nodes.
self.assertRaises(ValueError, graph.induce, (0,1,2,10))
subgraph = graph.induce(edges=((0,1), (0,9), (5,6), (7,8), (3,4)))
self.assertEqual(subgraph, Graph(range(10), ((0,1), (0,9), (5,6), (7,8), (3,4))))
# Raises ValueError if an edge which does not belong to the
# graph is in the set of edges.
self.assertRaises(ValueError, graph.induce,((0,1), (4,5)))
subgraph = graph.induce(nodes=(0,1,3,4,5,6,7,8,9),
edges=((0,1), (0,9), (5,6), (7,8),(3,4)))
self.assertEqual(subgraph, Graph([0,1,3,4,5,6,7,8,9],
((0,1),(0,9),(5,6),(7,8),(3,4))))
self.assertRaises(ValueError, graph.induce, (0,1,2), ((0,1),(0,3),(2,1),(5,9)))
def test_add_edge(self):
graph = Graph(range(4))
graph.add_edge((2,3))
self.assertEqual(graph, Graph(range(4), ((2,3),)))
# Can't add an edge referring to a node which does not
# belong to the graph.
self.assertRaises(ValueError, graph.add_edge, (1,4))
def test_remove_edge(self):
graph = Graph(range(4), ((0,1), (1,0), (2,1), (2,3)))
graph.remove_edge((0,1))
self.assertEqual(graph, Graph(range(4), ((1,0), (2,1), (2,3))))
self.assertRaises(ValueError, graph.remove_edge,(1,2))
def test_add_node(self):
graph = Graph(range(7), ((4,5), (5,7), (7,6), (7,5)))
graph.add_node(10)
self.assertEqual(graph, Graph(range(7) + [10], ((4,5),(5,7),(7,6),(7,5))))
# Raise an error if the node is already in the graph
self.assertRaises(ValueError, graph.add_node, 6)
def test_remove_node(self):
graph = Graph(range(9), ((2,3), (2,6), (4,7), (5,8)))
graph.remove_node(4)
self.assertEqual(graph, Graph((0,1,2,3,5,6,7,8), ((2,3), (2,6), (5,8))))
# Raise an error if the node is not in the graph.
self.assertRaises(ValueError, graph.remove_node, 10)
def test_connected_components(self):
graph = Graph(range(10), ((0,1), (0,2), (2,1),
(0,3), (3,4), (3,5), (4,3), (4,5), (5,3), (5,4),
(5,7), (8,9), (6,8)))
# Return a sequence of strongly-connected components
components = graph.connected_components()
self.assertEqual(len(components), 1)
self.assertEqual(components[0],
Graph((3,4,5), ((3,4), (3,5), (4,3), (4,5), (5,3), (5,4))))
# Return a sequence of weakly-connected components
components = graph.connected_components(strongly=False)
self.assertEqual(len(components), 2)
first_comp = Graph(range(6), ((0,1), (0,2), (2,1), (0,3), (3,4), (3,5),
(4,3), (4,5), (5,3), (5,4)))
second_comp = Graph((6,8,9), ((8,9), (6,8)))
if components[0] == first_comp:
self.assertEqual(components[1], second_comp)
elif components[0] == second_comp:
self.assertEqual(components[1], first_comp)
else:
self.fail('Bad components: %s' % components)
def test_is_eulerian(self):
graph = Graph(range(3), ((0,1), (1,0), (0,2), (2,0), (1,2), (2,1)))
# Return True if the graph contains an eulerian-cycle
self.assertTrue(graph.is_eulerian())
# Return True if the graph contains an eulerian-cycle,
# without considering edge orientation.
self.assertTrue(graph.is_eulerian(strongly=False))
graph = Graph(range(3), ((0,1), (1,2), (2,0)))
self.assertFalse(graph.is_eulerian())
self.assertTrue(graph.is_eulerian(strongly=False))
graph = Graph(range(2), ((0,1),))
self.assertFalse(graph.is_eulerian())
self.assertFalse(graph.is_eulerian(strongly=False))
graph = Graph(range(2), ((0,1), (1,0)))
self.assertTrue(graph.is_eulerian())
self.assertFalse(graph.is_eulerian(strongly=False))
def test_get_eulerian_cycle(self):
graph = Graph(range(4), ((0,1), (1,3), (3,2), (2, 0)))
cycle = graph.get_eulerian_cycle()
self.assertEqual(list(cycle), [(0,1), (1,3), (3,2), (2,0)])
cycle = graph.get_eulerian_cycle(strongly=False)
self.assertEqual(list(cycle), [(0,1), (1,3), (3,2), (2,0)])
graph = Graph(range(4), ((0,1), (1,3), (3,2), (0,2)))
self.assertRaises(ValueError, graph.get_eulerian_cycle)
cycle = graph.get_eulerian_cycle(strongly=False)
self.assertTrue(list(cycle) in ([(0,1), (1,3), (3,2), (0,2)],
[(0,2), (2,3), (1,3), (0,1)]))
def test_get_eulerian_cycle2(self):
graph = Graph(range(6), ((0,1), (0, 4),
(1,2), (1,3), (1,5),
(2,3), (2,5), (2,4),
(3,4), (3,5),
(4,5)))
self.assertRaises(ValueError, graph.get_eulerian_cycle)
cycle = graph.get_eulerian_cycle(strongly=False)
# is made from all and only the 11 edges?
self.assertEqual(len(cycle), 11)
self.assertEqual(len(set(cycle)), 11)
for edge in cycle:
self.assertTrue(edge in graph)
# if each edge is adjacent to the next and the last is adjacent
# to the first, than the cycle is an eulerian one.
for i,edge in enumerate(cycle[1:]):
if not set(cycle[i]).intersection(edge):
self.fail('Edges %s and %s are not adjacent.' % (cycle[i], edge))
self.assertTrue(set(cycle[0]).intersection(cycle[-1]))
def test_get_eulerian_cycle3(self):
graph = Graph(range(4), ((0,1), (1,0), (1,3), (3,2), (2,1)))
cycle = graph.get_eulerian_cycle()
self.assertEqual(cycle, [(0,1), (1,3), (3,2), (2,1), (1,0)])
self.assertRaises(ValueError, graph.get_eulerian_cycle, False)
graph = Graph(range(5), ((0,1), (4,0), (2,1), (1,3), (1,4), (3,2)))
cycle = graph.get_eulerian_cycle(strongly=False)
self.assertEqual(len(cycle), 6)
self.assertEqual(len(set(cycle)), 6)
for edge in cycle:
self.assertTrue(cycle in graph)
for i,edge in enumerate(cycle[1:]):
if not set(cycle[i]).intersection(edge):
self.fail('Edges %s and %s are not adjacent.' % (cycle[i], edge))
self.assertTrue(set(cycle[0]).intersection(cycle[-1]))
cycle = graph.get_eulerian_cycle()
self.assertEqual(cycle, [(0,1), (1,3), (3,2), (2,1), (1,4), (4,0)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment