diff --git a/cgraph/cgraph.go b/cgraph/cgraph.go index 4a44d71..fa9ace5 100644 --- a/cgraph/cgraph.go +++ b/cgraph/cgraph.go @@ -905,6 +905,9 @@ func (g *Graph) IsSimple() bool { return ccall.Agissimple(g.Agraph) } +// Creates a new node with the given name in the graph, and returns the new node. +// +// Note: The name is not automatically used as the node's label. func (g *Graph) CreateNode(name string) (*Node, error) { node, err := ccall.Agnodef(g.Agraph, name, 1) if err != nil { @@ -913,6 +916,8 @@ func (g *Graph) CreateNode(name string) (*Node, error) { return toNode(node), nil } +// Returns the node with the given name in the graph. +// If no node with the given name exists in the graph, nil is returned. func (g *Graph) Node(name string) (*Node, error) { node, err := ccall.Agnodef(g.Agraph, name, 0) if err != nil { @@ -959,6 +964,9 @@ func (g *Graph) SubRep(n *Node) *SubNode { } } +// Creates a new edge with the given name in the graph, and returns the new edge. +// +// Note: The name is not automatically used as the edge's label. func (g *Graph) CreateEdge(name string, start *Node, end *Node) (*Edge, error) { edge, err := ccall.Agedgef(g.Agraph, start.Agnode, end.Agnode, name, 1) if err != nil { @@ -967,6 +975,16 @@ func (g *Graph) CreateEdge(name string, start *Node, end *Node) (*Edge, error) { return toEdge(edge), nil } +// Returns the edge with the given name in the graph. +// If no edge with the given name exists in the graph, nil is returned. +func (g *Graph) Edge(name string, start *Node, end *Node) (*Edge, error) { + edge, err := ccall.Agedgef(g.Agraph, start.Agnode, end.Agnode, name, 0) + if err != nil { + return nil, err + } + return toEdge(edge), nil +} + func (g *Graph) IDEdge(t *Node, h *Node, id IDTYPE, createFlag int) (*Edge, error) { edge, err := ccall.Agidedge(g.Agraph, t.Agnode, h.Agnode, uint64(id), createFlag) if err != nil { diff --git a/graphviz_test.go b/graphviz_test.go index c43c2b4..040620a 100644 --- a/graphviz_test.go +++ b/graphviz_test.go @@ -150,6 +150,93 @@ func TestParseFile(t *testing.T) { } } +func TestGetNode(t *testing.T) { + g := graphviz.New() + graph, err := g.Graph() + if err != nil { + t.Fatalf("%+v", err) + } + defer func() { + graph.Close() + g.Close() + }() + + _, err = graph.CreateNode("n") + if err != nil { + t.Fatalf("%+v", err) + } + + n, err := graph.Node("n") + if err != nil { + t.Fatalf("%+v", err) + } + if n == nil { + t.Fatal("failed to get node 'n'. Got `nil` instead.") + } + if name := n.Name(); name != "n" { + t.Fatalf("failed to get node 'n'. Got node '%s' instead.", name) + } + + m, err := graph.Node("m") + if err != nil { + t.Fatalf("%+v", err) + } + if m != nil { + t.Fatal("got unexpected node 'm'") + } + if nodes := graph.NumberNodes(); nodes != 1 { + t.Fatalf("expected graph to have 1 node, but found %d", nodes) + } +} + +func TestGetEdge(t *testing.T) { + g := graphviz.New() + graph, err := g.Graph() + if err != nil { + t.Fatalf("%+v", err) + } + defer func() { + graph.Close() + g.Close() + }() + + n, err := graph.CreateNode("n") + if err != nil { + t.Fatalf("%+v", err) + } + m, err := graph.CreateNode("m") + if err != nil { + t.Fatalf("%+v", err) + } + + _, err = graph.CreateEdge("e1", n, m) + if err != nil { + t.Fatalf("%+v", err) + } + + e1, err := graph.Edge("e1", n, m) + if err != nil { + t.Fatalf("%+v", err) + } + if e1 == nil { + t.Fatal("failed to get edge 'e1'. Got `nil` instead.") + } + if name := e1.Name(); name != "e1" { + t.Fatalf("failed to get node 'n'. Got node '%s' instead.", name) + } + + e2, err := graph.Edge("e2", m, n) + if err != nil { + t.Fatalf("%+v", err) + } + if e2 != nil { + t.Fatal("got unexpected edge 'e2'") + } + if edges := graph.NumberEdges(); edges != 1 { + t.Fatalf("expected graph to have 1 edge, but found %d", edges) + } +} + func TestNodeDegree(t *testing.T) { type test struct { node_name string