mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 15:47:01 +08:00
graph/encoding/dot: don't propagate edge-setting panics when unmarshaling DOT
This commit is contained in:
@@ -275,6 +275,16 @@ func applyPortsToEdge(from ast.Vertex, to *ast.Edge, edge basicEdge) {
|
||||
func (gen *simpleGraph) addEdgeStmt(dst encoding.Builder, stmt *ast.EdgeStmt) {
|
||||
fs := gen.addVertex(dst, stmt.From)
|
||||
ts := gen.addEdge(dst, stmt.To, stmt.Attrs)
|
||||
defer func() {
|
||||
switch e := recover().(type) {
|
||||
case nil:
|
||||
// Do nothing.
|
||||
case error:
|
||||
panic(e)
|
||||
default:
|
||||
panic(fmt.Errorf("panic setting edge: %v", e))
|
||||
}
|
||||
}()
|
||||
for _, f := range fs {
|
||||
for _, t := range ts {
|
||||
edge := dst.NewEdge(f, t)
|
||||
|
@@ -644,3 +644,60 @@ func (a *attributes) SetAttribute(attr encoding.Attribute) error {
|
||||
*a = append(*a, attr)
|
||||
return nil
|
||||
}
|
||||
|
||||
const undirectedSelfLoopGraph = `graph {
|
||||
// Node definitions.
|
||||
0;
|
||||
1;
|
||||
|
||||
// Edge definitions.
|
||||
0 -- 0;
|
||||
1 -- 1;
|
||||
}`
|
||||
|
||||
const directedSelfLoopGraph = `digraph {
|
||||
// Node definitions.
|
||||
0;
|
||||
1;
|
||||
|
||||
// Edge definitions.
|
||||
0 -> 0;
|
||||
1 -> 1;
|
||||
}`
|
||||
|
||||
func TestSelfLoopSimple(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
dst func() encoding.Builder
|
||||
src string
|
||||
}{
|
||||
{
|
||||
dst: func() encoding.Builder { return simple.NewUndirectedGraph() },
|
||||
src: undirectedSelfLoopGraph,
|
||||
},
|
||||
{
|
||||
dst: func() encoding.Builder { return simple.NewDirectedGraph() },
|
||||
src: directedSelfLoopGraph,
|
||||
},
|
||||
} {
|
||||
dst := test.dst()
|
||||
message, panicked := panics(func() {
|
||||
err := Unmarshal([]byte(test.src), dst)
|
||||
if err == nil {
|
||||
t.Errorf("expected error for self loop addition to %T", dst)
|
||||
}
|
||||
})
|
||||
if panicked {
|
||||
t.Errorf("unexpected panic for self loop addition to %T: %s", dst, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func panics(fn func()) (message string, ok bool) {
|
||||
defer func() {
|
||||
r := recover()
|
||||
message = fmt.Sprint(r)
|
||||
ok = r != nil
|
||||
}()
|
||||
fn()
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user