111 lines
2.9 KiB
Go
111 lines
2.9 KiB
Go
|
|
package d2sequence
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"oss.terrastruct.com/d2/d2graph"
|
||
|
|
"oss.terrastruct.com/d2/lib/geo"
|
||
|
|
"oss.terrastruct.com/d2/lib/log"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestLayout(t *testing.T) {
|
||
|
|
g := d2graph.NewGraph(nil)
|
||
|
|
g.Objects = []*d2graph.Object{
|
||
|
|
{
|
||
|
|
ID: "Alice",
|
||
|
|
Box: geo.NewBox(nil, 100, 100),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
ID: "Bob",
|
||
|
|
Box: geo.NewBox(nil, 30, 30),
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
g.Edges = []*d2graph.Edge{
|
||
|
|
{
|
||
|
|
Src: g.Objects[0],
|
||
|
|
Dst: g.Objects[1],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
Src: g.Objects[1],
|
||
|
|
Dst: g.Objects[0],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
Src: g.Objects[0],
|
||
|
|
Dst: g.Objects[1],
|
||
|
|
},
|
||
|
|
{
|
||
|
|
Src: g.Objects[1],
|
||
|
|
Dst: g.Objects[0],
|
||
|
|
},
|
||
|
|
}
|
||
|
|
nEdges := len(g.Edges)
|
||
|
|
|
||
|
|
ctx := log.WithTB(context.Background(), t, nil)
|
||
|
|
Layout(ctx, g)
|
||
|
|
|
||
|
|
// asserts that objects were placed in the expected x order and at y=0
|
||
|
|
objectsOrder := []*d2graph.Object{
|
||
|
|
g.Objects[0],
|
||
|
|
g.Objects[1],
|
||
|
|
}
|
||
|
|
for i := 1; i < len(objectsOrder); i++ {
|
||
|
|
if objectsOrder[i].TopLeft.X < objectsOrder[i-1].TopLeft.X {
|
||
|
|
t.Fatalf("expected object[%d].TopLeft.X > object[%d].TopLeft.X", i, i-1)
|
||
|
|
}
|
||
|
|
if objectsOrder[i].Center().Y != objectsOrder[i-1].Center().Y {
|
||
|
|
t.Fatalf("expected object[%d] and object[%d] to be at the same center y", i, i-1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
nExpectedEdges := nEdges + len(objectsOrder)
|
||
|
|
if len(g.Edges) != nExpectedEdges {
|
||
|
|
t.Fatalf("expected %d edges, got %d", nExpectedEdges, len(g.Edges))
|
||
|
|
}
|
||
|
|
|
||
|
|
// assert that edges were placed in y order and have the endpoints at their objects
|
||
|
|
// uses `nEdges` because Layout creates some vertical edges to represent the object lifeline
|
||
|
|
for i := 0; i < nEdges; i++ {
|
||
|
|
edge := g.Edges[i]
|
||
|
|
if len(edge.Route) != 2 {
|
||
|
|
t.Fatalf("expected edge[%d] to have only 2 points", i)
|
||
|
|
}
|
||
|
|
if edge.Route[0].Y != edge.Route[1].Y {
|
||
|
|
t.Fatalf("expected edge[%d] to be a horizontal line", i)
|
||
|
|
}
|
||
|
|
if edge.Route[0].X != edge.Src.Center().X {
|
||
|
|
t.Fatalf("expected edge[%d] source endpoint to be at the middle of the source object", i)
|
||
|
|
}
|
||
|
|
if edge.Route[1].X != edge.Dst.Center().X {
|
||
|
|
t.Fatalf("expected edge[%d] target endpoint to be at the middle of the target object", i)
|
||
|
|
}
|
||
|
|
if i > 0 {
|
||
|
|
prevEdge := g.Edges[i-1]
|
||
|
|
if edge.Route[0].Y < prevEdge.Route[0].Y {
|
||
|
|
t.Fatalf("expected edge[%d].TopLeft.Y > edge[%d].TopLeft.Y", i, i-1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
lastSequenceEdge := g.Edges[nEdges-1]
|
||
|
|
for i := nEdges; i < nExpectedEdges; i++ {
|
||
|
|
edge := g.Edges[i]
|
||
|
|
if len(edge.Route) != 2 {
|
||
|
|
t.Fatalf("expected edge[%d] to have only 2 points", i)
|
||
|
|
}
|
||
|
|
if edge.Route[0].X != edge.Route[1].X {
|
||
|
|
t.Fatalf("expected edge[%d] to be a vertical line", i)
|
||
|
|
}
|
||
|
|
if edge.Route[0].X != edge.Src.Center().X {
|
||
|
|
t.Fatalf("expected edge[%d] x to be at the object center", i)
|
||
|
|
}
|
||
|
|
if edge.Route[0].Y != edge.Src.Height+edge.Src.TopLeft.Y {
|
||
|
|
t.Fatalf("expected edge[%d] to start at the bottom of the source object", i)
|
||
|
|
}
|
||
|
|
if edge.Route[1].Y < lastSequenceEdge.Route[0].Y {
|
||
|
|
t.Fatalf("expected edge[%d] to end after the last sequence edge", i)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|