def test_save(self): g = Graph.Graph([ (1,2), (1,3), (1,4), (2,4), (2,6), (2,7), (7,4), (6,1), ] ) dot = Dot.Dot(g) dot.style(graph="foobar") dot.node_style(1, key='value') dot.node_style(2, key='another', key2='world') dot.edge_style(1,4, key1='value1', key2='value2') dot.edge_style(2,4, key1='valueA') fn = 'test_dot.dot' self.assertTrue(not os.path.exists(fn)) try: dot.save_dot(fn) fp = open(fn, 'r') data = fp.read() fp.close() self.assertEqual(data, ''.join(dot)) finally: if os.path.exists(fn): os.unlink(fn)
def test_constructor(self): o = modulegraph.ModuleGraph() self.assertTrue(o.path is sys.path) self.assertEqual(o.lazynodes, {}) self.assertEqual(o.replace_paths, ()) self.assertEqual(o.debug, 0) # Stricter tests would be nice, but that requires # better control over what's on sys.path self.assertIsInstance(o.nspackages, dict) g = Graph.Graph() o = modulegraph.ModuleGraph(['a', 'b', 'c'], ['modA'], [ ('fromA', 'toB'), ('fromC', 'toD')], { 'modA': ['modB', 'modC'], 'modC': ['modE', 'modF'], }, g, 1) self.assertEqual(o.path, ['a', 'b', 'c']) self.assertEqual(o.lazynodes, { 'modA': None, 'modC': ['modE', 'modF'], }) self.assertEqual(o.replace_paths, [('fromA', 'toB'), ('fromC', 'toD')]) self.assertEqual(o.nspackages, {}) self.assertTrue(o.graph is g) self.assertEqual(o.debug, 1)
def test_node_style(self): g = Graph.Graph([ (1,2), (1,3), (1,4), (2,4), (2,6), (2,7), (7,4), (6,1), ] ) dot = Dot.Dot(g) self.assertEqual(dot.nodes[1], {}) dot.node_style(1, key='value') self.assertEqual(dot.nodes[1], {'key': 'value'}) dot.node_style(1, key2='value2') self.assertEqual(dot.nodes[1], {'key2': 'value2'}) self.assertEqual(dot.nodes[2], {}) dot.all_node_style(key3='value3') for n in g: self.assertEqual(dot.nodes[n], {'key3': 'value3'}) self.assertTrue(9 not in dot.nodes) dot.node_style(9, key='value') self.assertEqual(dot.nodes[9], {'key': 'value'})
def test_edge_style(self): g = Graph.Graph([ (1,2), (1,3), (1,4), (2,4), (2,6), (2,7), (7,4), (6,1), ] ) dot = Dot.Dot(g) self.assertEqual(dot.edges[1][2], {}) dot.edge_style(1,2, foo='bar') self.assertEqual(dot.edges[1][2], {'foo': 'bar'}) dot.edge_style(1,2, foo2='2bar') self.assertEqual(dot.edges[1][2], {'foo2': '2bar'}) self.assertEqual(dot.edges[1][3], {}) self.assertFalse(6 in dot.edges[1]) dot.edge_style(1,6, foo2='2bar') self.assertEqual(dot.edges[1][6], {'foo2': '2bar'}) self.assertRaises(GraphError, dot.edge_style, 1, 9, a=1) self.assertRaises(GraphError, dot.edge_style, 9, 1, a=1)
def test_simple(self): a = Graph.Graph() self.assertEqual(GraphStat.degree_dist(a), []) a.add_node(1) a.add_node(2) a.add_node(3) self.assertEqual(GraphStat.degree_dist(a), GraphStat._binning([0, 0, 0])) for x in range(100): a.add_node(x) for x in range(1, 100): for y in range(1, 50): if x % y == 0: a.add_edge(x, y) counts_inc = [] counts_out = [] for n in a: counts_inc.append(a.inc_degree(n)) counts_out.append(a.out_degree(n)) self.assertEqual(GraphStat.degree_dist(a), GraphStat._binning(counts_out)) self.assertEqual(GraphStat.degree_dist(a, mode='inc'), GraphStat._binning(counts_inc))
def test_style(self): g = Graph.Graph([]) dot = Dot.Dot(g) self.assertEqual(dot.attr, {}) dot.style(key='value') self.assertEqual(dot.attr, {'key': 'value'}) dot.style(key2='value2') self.assertEqual(dot.attr, {'key2': 'value2'})
def setUp(self): self.edges = [(1, 2), (2, 4), (1, 3), (2, 4), (3, 4), (4, 5), (6, 5), (6, 14), (14, 15), (6, 15), (5, 7), (7, 8), (7, 13), (12, 8), (8, 13), (11, 12), (11, 9), (13, 11), (9, 13), (13, 10)] # these are the edges self.store = {} self.g = Graph.Graph() for head, tail in self.edges: self.store[head] = self.store[tail] = None self.g.add_edge(head, tail)
def test_filter_stack(self): g = Graph.Graph() g.add_node("1", "N.1") g.add_node("1.1", "N.1.1") g.add_node("1.1.1", "N.1.1.1") g.add_node("1.1.2", "N.1.1.2") g.add_node("1.1.3", "N.1.1.3") g.add_node("1.1.1.1", "N.1.1.1.1") g.add_node("1.1.1.2", "N.1.1.1.2") g.add_node("1.1.2.1", "N.1.1.2.1") g.add_node("1.1.2.2", "N.1.1.2.2") g.add_node("1.1.2.3", "N.1.1.2.3") g.add_node("2", "N.2") g.add_edge("1", "1.1") g.add_edge("1.1", "1.1.1") g.add_edge("1.1", "1.1.2") g.add_edge("1.1", "1.1.3") g.add_edge("1.1.1", "1.1.1.1") g.add_edge("1.1.1", "1.1.1.2") g.add_edge("1.1.2", "1.1.2.1") g.add_edge("1.1.2", "1.1.2.2") g.add_edge("1.1.2", "1.1.2.3") v, r, o = GraphUtil.filter_stack( g, "1", [lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.2.3"]) self.assertEqual( v, set([ "1", "1.1", "1.1.1", "1.1.2", "1.1.3", "1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2", "1.1.2.3" ])) self.assertEqual(r, set(["1.1.1", "1.1.2.3"])) o.sort() self.assertEqual(o, [("1.1", "1.1.1.1"), ("1.1", "1.1.1.2")]) v, r, o = GraphUtil.filter_stack( g, "1", [lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.1.2"]) self.assertEqual( v, set([ "1", "1.1", "1.1.1", "1.1.2", "1.1.3", "1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2", "1.1.2.3" ])) self.assertEqual(r, set(["1.1.1", "1.1.1.2"])) self.assertEqual(o, [ ("1.1", "1.1.1.1"), ])
def generate_scale_free_graph(steps, growth_num, self_loops=False, multi_edges=False): ''' Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that will have *steps* \* *growth_num* nodes and a scale free (powerlaw) connectivity. Starting with a fully connected graph with *growth_num* nodes at every step *growth_num* nodes are added to the graph and are connected to existing nodes with a probability proportional to the degree of these existing nodes. ''' # FIXME: The code doesn't seem to do what the documentation claims. graph = Graph.Graph() # initialize the graph store = [] for i in range(growth_num): #store += [ i ] * (growth_num - 1) for j in range(i + 1, growth_num): store.append(i) store.append(j) graph.add_edge(i,j) # generate for node in range(growth_num, steps * growth_num): graph.add_node(node) while ( graph.out_degree(node) < growth_num ): nbr = random.choice(store) # loop defense if node == nbr and not self_loops: continue # multi edge defense if graph.edge_by_node(node, nbr) and not multi_edges: continue graph.add_edge(node, nbr) for nbr in graph.out_nbrs(node): store.append(node) store.append(nbr) return graph
def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=False): ''' Generates and returns a :py:class:`~altgraph.Graph.Graph` instance with *node_num* nodes randomly connected by *edge_num* edges. ''' g = Graph.Graph() if not multi_edges: if self_loops: max_edges = node_num * node_num else: max_edges = node_num * (node_num-1) if edge_num > max_edges: raise GraphError("inconsistent arguments to 'generate_random_graph'") nodes = range(node_num) for node in nodes: g.add_node(node) while 1: head = random.choice(nodes) tail = random.choice(nodes) # loop defense if head == tail and not self_loops: continue # multiple edge defense if g.edge_by_node(head,tail) is not None and not multi_edges: continue # add the edge g.add_edge(head, tail) if g.number_of_edges() >= edge_num: break return g
def test_img(self): g = Graph.Graph([ (1,2), (1,3), (1,4), (2,4), (2,6), (2,7), (7,4), (6,1), ] ) dot = Dot.Dot(g, dot='/usr/local/bin/!!dot', dotty='/usr/local/bin/!!dotty', neato='/usr/local/bin/!!neato') dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75) dot.node_style(1, label='BASE_NODE',shape='box', color='blue') dot.node_style(2, style='filled', fillcolor='red') dot.edge_style(1,4, style='dotted') dot.edge_style(2,4, arrowhead='dot', label='binds', labelangle='90') system_cmds = [] def fake_system(cmd): system_cmds.append(cmd) return None try: real_system = os.system os.system = fake_system system_cmds = [] dot.save_img('foo') self.assertEqual(system_cmds, ['/usr/local/bin/!!dot -Tgif tmp_dot.dot -o foo.gif']) system_cmds = [] dot.save_img('foo', file_type='jpg') self.assertEqual(system_cmds, ['/usr/local/bin/!!dot -Tjpg tmp_dot.dot -o foo.jpg']) system_cmds = [] dot.save_img('bar', file_type='jpg', mode='neato') self.assertEqual(system_cmds, [ '/usr/local/bin/!!neato -o tmp_dot.dot tmp_neo.dot', '/usr/local/bin/!!dot -Tjpg tmp_dot.dot -o bar.jpg', ]) system_cmds = [] dot.display() self.assertEqual(system_cmds, [ '/usr/local/bin/!!dotty tmp_dot.dot' ]) system_cmds = [] dot.display(mode='neato') self.assertEqual(system_cmds, [ '/usr/local/bin/!!neato -o tmp_dot.dot tmp_neo.dot', '/usr/local/bin/!!dotty tmp_dot.dot' ]) finally: if os.path.exists(dot.temp_dot): os.unlink(dot.temp_dot) if os.path.exists(dot.temp_neo): os.unlink(dot.temp_neo) os.system = real_system if os.path.exists('/usr/local/bin/dot') and os.path.exists('/usr/local/bin/neato'): try: dot.dot='/usr/local/bin/dot' dot.neato='/usr/local/bin/neato' self.assertFalse(os.path.exists('foo.gif')) dot.save_img('foo') self.assertTrue(os.path.exists('foo.gif')) os.unlink('foo.gif') self.assertFalse(os.path.exists('foo.gif')) dot.save_img('foo', mode='neato') self.assertTrue(os.path.exists('foo.gif')) os.unlink('foo.gif') finally: if os.path.exists(dot.temp_dot): os.unlink(dot.temp_dot) if os.path.exists(dot.temp_neo): os.unlink(dot.temp_neo)
def test_iter(self): g = Graph.Graph([ (1,2), (1,3), (1,4), (2,4), (2,6), (2,7), (7,4), (6,1), ] ) dot = Dot.Dot(g) dot.style(graph="foobar") dot.node_style(1, key='value') dot.node_style(2, key='another', key2='world') dot.edge_style(1,4, key1='value1', key2='value2') dot.edge_style(2,4, key1='valueA') self.assertEqual(list(iter(dot)), list(dot.iterdot())) for item in dot.iterdot(): self.assertTrue(isinstance(item, str)) first = list(dot.iterdot())[0] self.assertEqual(first, "digraph %s {\n"%(dot.name,)) dot.type = 'graph' first = list(dot.iterdot())[0] self.assertEqual(first, "graph %s {\n"%(dot.name,)) dot.type = 'foo' self.assertRaises(GraphError, list, dot.iterdot()) dot.type = 'digraph' self.assertEqual(list(dot), [ 'digraph G {\n', 'graph="foobar";', '\n', '\t"1" [', 'key="value",', '];\n', '\t"2" [', 'key="another",', 'key2="world",', '];\n', '\t"3" [', '];\n', '\t"4" [', '];\n', '\t"6" [', '];\n', '\t"7" [', '];\n', '\t"1" -> "2" [', '];\n', '\t"1" -> "3" [', '];\n', '\t"1" -> "4" [', 'key1="value1",', 'key2="value2",', '];\n', '\t"2" -> "4" [', 'key1="valueA",', '];\n', '\t"2" -> "6" [', '];\n', '\t"2" -> "7" [', '];\n', '\t"6" -> "1" [', '];\n', '\t"7" -> "4" [', '];\n', '}\n'])
def test_constructor(self): g = Graph.Graph([ (1,2), (1,3), (1,4), (2,4), (2,6), (2,7), (7,4), (6,1), ] ) dot = Dot.Dot(g) self.assertEqual(dot.name, 'G') self.assertEqual(dot.attr, {}) self.assertEqual(dot.temp_dot, 'tmp_dot.dot') self.assertEqual(dot.temp_neo, 'tmp_neo.dot') self.assertEqual(dot.dot, 'dot') self.assertEqual(dot.dotty, 'dotty') self.assertEqual(dot.neato, 'neato') self.assertEqual(dot.type, 'digraph') self.assertEqual(dot.nodes, dict([(x, {}) for x in g])) edges = {} for head in g: edges[head] = {} for tail in g.out_nbrs(head): edges[head][tail] = {} self.assertEqual(dot.edges[1], edges[1]) self.assertEqual(dot.edges, edges) dot = Dot.Dot(g, nodes=[1,2], edgefn=lambda node: list(sorted(g.out_nbrs(node)))[:-1], nodevisitor=lambda node: {'label': node}, edgevisitor=lambda head, tail: {'label': (head, tail) }, name="testgraph", dot='/usr/local/bin/dot', dotty='/usr/local/bin/dotty', neato='/usr/local/bin/neato', graphtype="graph") self.assertEqual(dot.name, 'testgraph') self.assertEqual(dot.attr, {}) self.assertEqual(dot.temp_dot, 'tmp_dot.dot') self.assertEqual(dot.temp_neo, 'tmp_neo.dot') self.assertEqual(dot.dot, '/usr/local/bin/dot') self.assertEqual(dot.dotty, '/usr/local/bin/dotty') self.assertEqual(dot.neato, '/usr/local/bin/neato') self.assertEqual(dot.type, 'graph') self.assertEqual(dot.nodes, dict([(x, {'label': x}) for x in [1,2]])) edges = {} for head in [1,2]: edges[head] = {} for tail in list(sorted(g.out_nbrs(head)))[:-1]: if tail not in [1,2]: continue edges[head][tail] = {'label': (head, tail) } self.assertEqual(dot.edges[1], edges[1]) self.assertEqual(dot.edges, edges) self.assertRaises(GraphError, Dot.Dot, g, nodes=[1,2, 9])