move comparison to serde

This commit is contained in:
Júlio César Batista 2023-02-18 13:56:17 -03:00
parent 92f774ba53
commit 8d7dadd2ea
No known key found for this signature in database
GPG key ID: 10C4B861BF314878
3 changed files with 316 additions and 314 deletions

View file

@ -1582,316 +1582,3 @@ func (g *Graph) SortEdgesByAST() {
})
g.Edges = edges
}
func (g *Graph) Compare(other *Graph) error {
if len(g.Objects) != len(other.Objects) {
return fmt.Errorf("object count differs: g=%d, other=%d", len(g.Objects), len(other.Objects))
}
if len(g.Edges) != len(other.Edges) {
return fmt.Errorf("edge count differs: g=%d, other=%d", len(g.Edges), len(other.Edges))
}
if err := g.Root.Compare(other.Root); err != nil {
return fmt.Errorf("root differs: %v", err)
}
for i := 0; i < len(g.Objects); i++ {
if err := g.Objects[i].Compare(other.Objects[i]); err != nil {
return fmt.Errorf(
"objects differ at %d [g=%s, other=%s]: %v",
i,
g.Objects[i].ID,
other.Objects[i].ID,
err,
)
}
}
for i := 0; i < len(g.Edges); i++ {
if err := g.Edges[i].Compare(other.Edges[i]); err != nil {
return fmt.Errorf(
"edges differ at %d [g=%s, other=%s]: %v",
i,
g.Edges[i].AbsID(),
other.Edges[i].AbsID(),
err,
)
}
}
return nil
}
func (obj *Object) Compare(other *Object) error {
if obj != nil && other == nil {
return fmt.Errorf("other is nil")
} else if obj == nil && other != nil {
return fmt.Errorf("obj is nil")
} else if obj == nil {
// both are nil
return nil
}
if obj.ID != other.ID {
return fmt.Errorf("ids differ: obj=%s, other=%s", obj.ID, other.ID)
}
if obj.AbsID() != other.AbsID() {
return fmt.Errorf("absolute ids differ: obj=%s, other=%s", obj.AbsID(), other.AbsID())
}
if obj.Box != nil && other.Box == nil {
return fmt.Errorf("other should have a box")
} else if obj.Box == nil && other.Box != nil {
return fmt.Errorf("other should not have a box")
} else if obj.Box != nil {
if obj.Width != other.Width {
return fmt.Errorf("widths differ: obj=%f, other=%f", obj.Width, other.Width)
}
if obj.Height != other.Height {
return fmt.Errorf("heights differ: obj=%f, other=%f", obj.Height, other.Height)
}
}
if obj.Parent != nil && other.Parent == nil {
return fmt.Errorf("other should have a parent")
} else if obj.Parent == nil && other.Parent != nil {
return fmt.Errorf("other should not have a parent")
} else if obj.Parent != nil && obj.Parent.ID != other.Parent.ID {
return fmt.Errorf("parent differs: obj=%s, other=%s", obj.Parent.ID, other.Parent.ID)
}
if len(obj.Children) != len(other.Children) {
return fmt.Errorf("children count differs: obj=%d, other=%d", len(obj.Children), len(other.Children))
}
for childID, objChild := range obj.Children {
if otherChild, exists := other.Children[childID]; exists {
if err := objChild.Compare(otherChild); err != nil {
return fmt.Errorf("children differ at key %s: %v", childID, err)
}
} else {
return fmt.Errorf("child %s does not exist in other", childID)
}
}
if len(obj.ChildrenArray) != len(other.ChildrenArray) {
return fmt.Errorf("childrenArray count differs: obj=%d, other=%d", len(obj.ChildrenArray), len(other.ChildrenArray))
}
for i := 0; i < len(obj.ChildrenArray); i++ {
if err := obj.ChildrenArray[i].Compare(other.ChildrenArray[i]); err != nil {
return fmt.Errorf("childrenArray differs at %d: %v", i, err)
}
}
if obj.Attributes != nil && other.Attributes == nil {
return fmt.Errorf("other should have attributes")
} else if obj.Attributes == nil && other.Attributes != nil {
return fmt.Errorf("other should not have attributes")
} else if obj.Attributes != nil {
if d2target.IsShape(obj.Attributes.Shape.Value) != d2target.IsShape(other.Attributes.Shape.Value) {
return fmt.Errorf(
"shapes differ: obj=%s, other=%s",
obj.Attributes.Shape.Value,
other.Attributes.Shape.Value,
)
}
if obj.Attributes.Icon == nil && other.Attributes.Icon != nil {
return fmt.Errorf("other does not have an icon")
} else if obj.Attributes.Icon != nil && other.Attributes.Icon == nil {
return fmt.Errorf("obj does not have an icon")
}
if obj.Attributes.Direction.Value != other.Attributes.Direction.Value {
return fmt.Errorf(
"directions differ: obj=%s, other=%s",
obj.Attributes.Direction.Value,
other.Attributes.Direction.Value,
)
}
if obj.Attributes.Label.Value != other.Attributes.Label.Value {
return fmt.Errorf(
"labels differ: obj=%s, other=%s",
obj.Attributes.Label.Value,
other.Attributes.Label.Value,
)
}
if obj.Attributes.NearKey != nil {
if other.Attributes.NearKey == nil {
return fmt.Errorf("other does not have near")
}
objKey := strings.Join(Key(obj.Attributes.NearKey), ".")
deserKey := strings.Join(Key(other.Attributes.NearKey), ".")
if objKey != deserKey {
return fmt.Errorf(
"near differs: obj=%s, other=%s",
objKey,
deserKey,
)
}
} else if other.Attributes.NearKey != nil {
return fmt.Errorf("other should not have near")
}
}
if obj.SQLTable == nil && other.SQLTable != nil {
return fmt.Errorf("other is not a sql table")
} else if obj.SQLTable != nil && other.SQLTable == nil {
return fmt.Errorf("obj is not a sql table")
}
if obj.SQLTable != nil {
if len(obj.SQLTable.Columns) != len(other.SQLTable.Columns) {
return fmt.Errorf(
"table columns count differ: obj=%d, other=%d",
len(obj.SQLTable.Columns),
len(other.SQLTable.Columns),
)
}
}
if obj.LabelWidth != nil {
if other.LabelWidth == nil {
return fmt.Errorf("other does not have a label width")
}
if *obj.LabelWidth != *other.LabelWidth {
return fmt.Errorf(
"label widths differ: obj=%d, other=%d",
*obj.LabelWidth,
*other.LabelWidth,
)
}
} else if other.LabelWidth != nil {
return fmt.Errorf("other should not have label width")
}
if obj.LabelHeight != nil {
if other.LabelHeight == nil {
return fmt.Errorf("other does not have a label height")
}
if *obj.LabelHeight != *other.LabelHeight {
return fmt.Errorf(
"label heights differ: obj=%d, other=%d",
*obj.LabelHeight,
*other.LabelHeight,
)
}
} else if other.LabelHeight != nil {
return fmt.Errorf("other should not have label height")
}
return nil
}
func (edge *Edge) Compare(other *Edge) error {
if edge.AbsID() != other.AbsID() {
return fmt.Errorf(
"absolute ids differ: edge=%s, other=%s",
edge.AbsID(),
other.AbsID(),
)
}
if edge.Src.AbsID() != other.Src.AbsID() {
return fmt.Errorf(
"sources differ: edge=%s, other=%s",
edge.Src.AbsID(),
other.Src.AbsID(),
)
}
if edge.Dst.AbsID() != other.Dst.AbsID() {
return fmt.Errorf(
"targets differ: edge=%s, other=%s",
edge.Dst.AbsID(),
other.Dst.AbsID(),
)
}
if edge.SrcArrow != other.SrcArrow {
return fmt.Errorf(
"source arrows differ: edge=%t, other=%t",
edge.SrcArrow,
other.SrcArrow,
)
}
if edge.DstArrow != other.DstArrow {
return fmt.Errorf(
"target arrows differ: edge=%t, other=%t",
edge.DstArrow,
other.DstArrow,
)
}
if edge.MinWidth != other.MinWidth {
return fmt.Errorf(
"min width differs: edge=%d, other=%d",
edge.MinWidth,
other.MinWidth,
)
}
if edge.MinHeight != other.MinHeight {
return fmt.Errorf(
"min height differs: edge=%d, other=%d",
edge.MinHeight,
other.MinHeight,
)
}
if edge.Attributes.Label.Value != other.Attributes.Label.Value {
return fmt.Errorf(
"labels differ: edge=%s, other=%s",
edge.Attributes.Label.Value,
other.Attributes.Label.Value,
)
}
if edge.LabelDimensions.Width != other.LabelDimensions.Width {
return fmt.Errorf(
"label width differs: edge=%d, other=%d",
edge.LabelDimensions.Width,
other.LabelDimensions.Width,
)
}
if edge.LabelDimensions.Height != other.LabelDimensions.Height {
return fmt.Errorf(
"label hieght differs: edge=%d, other=%d",
edge.LabelDimensions.Height,
other.LabelDimensions.Height,
)
}
if edge.SrcTableColumnIndex != nil && other.SrcTableColumnIndex == nil {
return fmt.Errorf("other should have src column index")
} else if other.SrcTableColumnIndex != nil && edge.SrcTableColumnIndex == nil {
return fmt.Errorf("other should not have src column index")
} else if other.SrcTableColumnIndex != nil {
edgeColumn := *edge.SrcTableColumnIndex
otherColumn := *other.SrcTableColumnIndex
if edgeColumn != otherColumn {
return fmt.Errorf("src column differs: edge=%d, other=%d", edgeColumn, otherColumn)
}
}
if edge.DstTableColumnIndex != nil && other.DstTableColumnIndex == nil {
return fmt.Errorf("other should have dst column index")
} else if other.DstTableColumnIndex != nil && edge.DstTableColumnIndex == nil {
return fmt.Errorf("other should not have dst column index")
} else if other.DstTableColumnIndex != nil {
edgeColumn := *edge.DstTableColumnIndex
otherColumn := *other.DstTableColumnIndex
if edgeColumn != otherColumn {
return fmt.Errorf("dst column differs: edge=%d, other=%d", edgeColumn, otherColumn)
}
}
return nil
}

View file

@ -2,8 +2,10 @@ package d2graph
import (
"encoding/json"
"fmt"
"strings"
"oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/util-go/go2"
)
@ -158,3 +160,316 @@ func convert[T, Q any](from T, to *Q) error {
}
return nil
}
func CompareSerializedGraph(g, other *Graph) error {
if len(g.Objects) != len(other.Objects) {
return fmt.Errorf("object count differs: g=%d, other=%d", len(g.Objects), len(other.Objects))
}
if len(g.Edges) != len(other.Edges) {
return fmt.Errorf("edge count differs: g=%d, other=%d", len(g.Edges), len(other.Edges))
}
if err := CompareSerializedObject(g.Root, other.Root); err != nil {
return fmt.Errorf("root differs: %v", err)
}
for i := 0; i < len(g.Objects); i++ {
if err := CompareSerializedObject(g.Objects[i], other.Objects[i]); err != nil {
return fmt.Errorf(
"objects differ at %d [g=%s, other=%s]: %v",
i,
g.Objects[i].ID,
other.Objects[i].ID,
err,
)
}
}
for i := 0; i < len(g.Edges); i++ {
if err := CompareSerializedEdge(g.Edges[i], other.Edges[i]); err != nil {
return fmt.Errorf(
"edges differ at %d [g=%s, other=%s]: %v",
i,
g.Edges[i].AbsID(),
other.Edges[i].AbsID(),
err,
)
}
}
return nil
}
func CompareSerializedObject(obj, other *Object) error {
if obj != nil && other == nil {
return fmt.Errorf("other is nil")
} else if obj == nil && other != nil {
return fmt.Errorf("obj is nil")
} else if obj == nil {
// both are nil
return nil
}
if obj.ID != other.ID {
return fmt.Errorf("ids differ: obj=%s, other=%s", obj.ID, other.ID)
}
if obj.AbsID() != other.AbsID() {
return fmt.Errorf("absolute ids differ: obj=%s, other=%s", obj.AbsID(), other.AbsID())
}
if obj.Box != nil && other.Box == nil {
return fmt.Errorf("other should have a box")
} else if obj.Box == nil && other.Box != nil {
return fmt.Errorf("other should not have a box")
} else if obj.Box != nil {
if obj.Width != other.Width {
return fmt.Errorf("widths differ: obj=%f, other=%f", obj.Width, other.Width)
}
if obj.Height != other.Height {
return fmt.Errorf("heights differ: obj=%f, other=%f", obj.Height, other.Height)
}
}
if obj.Parent != nil && other.Parent == nil {
return fmt.Errorf("other should have a parent")
} else if obj.Parent == nil && other.Parent != nil {
return fmt.Errorf("other should not have a parent")
} else if obj.Parent != nil && obj.Parent.ID != other.Parent.ID {
return fmt.Errorf("parent differs: obj=%s, other=%s", obj.Parent.ID, other.Parent.ID)
}
if len(obj.Children) != len(other.Children) {
return fmt.Errorf("children count differs: obj=%d, other=%d", len(obj.Children), len(other.Children))
}
for childID, objChild := range obj.Children {
if otherChild, exists := other.Children[childID]; exists {
if err := CompareSerializedObject(objChild, otherChild); err != nil {
return fmt.Errorf("children differ at key %s: %v", childID, err)
}
} else {
return fmt.Errorf("child %s does not exist in other", childID)
}
}
if len(obj.ChildrenArray) != len(other.ChildrenArray) {
return fmt.Errorf("childrenArray count differs: obj=%d, other=%d", len(obj.ChildrenArray), len(other.ChildrenArray))
}
for i := 0; i < len(obj.ChildrenArray); i++ {
if err := CompareSerializedObject(obj.ChildrenArray[i], other.ChildrenArray[i]); err != nil {
return fmt.Errorf("childrenArray differs at %d: %v", i, err)
}
}
if obj.Attributes != nil && other.Attributes == nil {
return fmt.Errorf("other should have attributes")
} else if obj.Attributes == nil && other.Attributes != nil {
return fmt.Errorf("other should not have attributes")
} else if obj.Attributes != nil {
if d2target.IsShape(obj.Attributes.Shape.Value) != d2target.IsShape(other.Attributes.Shape.Value) {
return fmt.Errorf(
"shapes differ: obj=%s, other=%s",
obj.Attributes.Shape.Value,
other.Attributes.Shape.Value,
)
}
if obj.Attributes.Icon == nil && other.Attributes.Icon != nil {
return fmt.Errorf("other does not have an icon")
} else if obj.Attributes.Icon != nil && other.Attributes.Icon == nil {
return fmt.Errorf("obj does not have an icon")
}
if obj.Attributes.Direction.Value != other.Attributes.Direction.Value {
return fmt.Errorf(
"directions differ: obj=%s, other=%s",
obj.Attributes.Direction.Value,
other.Attributes.Direction.Value,
)
}
if obj.Attributes.Label.Value != other.Attributes.Label.Value {
return fmt.Errorf(
"labels differ: obj=%s, other=%s",
obj.Attributes.Label.Value,
other.Attributes.Label.Value,
)
}
if obj.Attributes.NearKey != nil {
if other.Attributes.NearKey == nil {
return fmt.Errorf("other does not have near")
}
objKey := strings.Join(Key(obj.Attributes.NearKey), ".")
deserKey := strings.Join(Key(other.Attributes.NearKey), ".")
if objKey != deserKey {
return fmt.Errorf(
"near differs: obj=%s, other=%s",
objKey,
deserKey,
)
}
} else if other.Attributes.NearKey != nil {
return fmt.Errorf("other should not have near")
}
}
if obj.SQLTable == nil && other.SQLTable != nil {
return fmt.Errorf("other is not a sql table")
} else if obj.SQLTable != nil && other.SQLTable == nil {
return fmt.Errorf("obj is not a sql table")
}
if obj.SQLTable != nil {
if len(obj.SQLTable.Columns) != len(other.SQLTable.Columns) {
return fmt.Errorf(
"table columns count differ: obj=%d, other=%d",
len(obj.SQLTable.Columns),
len(other.SQLTable.Columns),
)
}
}
if obj.LabelWidth != nil {
if other.LabelWidth == nil {
return fmt.Errorf("other does not have a label width")
}
if *obj.LabelWidth != *other.LabelWidth {
return fmt.Errorf(
"label widths differ: obj=%d, other=%d",
*obj.LabelWidth,
*other.LabelWidth,
)
}
} else if other.LabelWidth != nil {
return fmt.Errorf("other should not have label width")
}
if obj.LabelHeight != nil {
if other.LabelHeight == nil {
return fmt.Errorf("other does not have a label height")
}
if *obj.LabelHeight != *other.LabelHeight {
return fmt.Errorf(
"label heights differ: obj=%d, other=%d",
*obj.LabelHeight,
*other.LabelHeight,
)
}
} else if other.LabelHeight != nil {
return fmt.Errorf("other should not have label height")
}
return nil
}
func CompareSerializedEdge(edge, other *Edge) error {
if edge.AbsID() != other.AbsID() {
return fmt.Errorf(
"absolute ids differ: edge=%s, other=%s",
edge.AbsID(),
other.AbsID(),
)
}
if edge.Src.AbsID() != other.Src.AbsID() {
return fmt.Errorf(
"sources differ: edge=%s, other=%s",
edge.Src.AbsID(),
other.Src.AbsID(),
)
}
if edge.Dst.AbsID() != other.Dst.AbsID() {
return fmt.Errorf(
"targets differ: edge=%s, other=%s",
edge.Dst.AbsID(),
other.Dst.AbsID(),
)
}
if edge.SrcArrow != other.SrcArrow {
return fmt.Errorf(
"source arrows differ: edge=%t, other=%t",
edge.SrcArrow,
other.SrcArrow,
)
}
if edge.DstArrow != other.DstArrow {
return fmt.Errorf(
"target arrows differ: edge=%t, other=%t",
edge.DstArrow,
other.DstArrow,
)
}
if edge.MinWidth != other.MinWidth {
return fmt.Errorf(
"min width differs: edge=%d, other=%d",
edge.MinWidth,
other.MinWidth,
)
}
if edge.MinHeight != other.MinHeight {
return fmt.Errorf(
"min height differs: edge=%d, other=%d",
edge.MinHeight,
other.MinHeight,
)
}
if edge.Attributes.Label.Value != other.Attributes.Label.Value {
return fmt.Errorf(
"labels differ: edge=%s, other=%s",
edge.Attributes.Label.Value,
other.Attributes.Label.Value,
)
}
if edge.LabelDimensions.Width != other.LabelDimensions.Width {
return fmt.Errorf(
"label width differs: edge=%d, other=%d",
edge.LabelDimensions.Width,
other.LabelDimensions.Width,
)
}
if edge.LabelDimensions.Height != other.LabelDimensions.Height {
return fmt.Errorf(
"label hieght differs: edge=%d, other=%d",
edge.LabelDimensions.Height,
other.LabelDimensions.Height,
)
}
if edge.SrcTableColumnIndex != nil && other.SrcTableColumnIndex == nil {
return fmt.Errorf("other should have src column index")
} else if other.SrcTableColumnIndex != nil && edge.SrcTableColumnIndex == nil {
return fmt.Errorf("other should not have src column index")
} else if other.SrcTableColumnIndex != nil {
edgeColumn := *edge.SrcTableColumnIndex
otherColumn := *other.SrcTableColumnIndex
if edgeColumn != otherColumn {
return fmt.Errorf("src column differs: edge=%d, other=%d", edgeColumn, otherColumn)
}
}
if edge.DstTableColumnIndex != nil && other.DstTableColumnIndex == nil {
return fmt.Errorf("other should have dst column index")
} else if other.DstTableColumnIndex != nil && edge.DstTableColumnIndex == nil {
return fmt.Errorf("other should not have dst column index")
} else if other.DstTableColumnIndex != nil {
edgeColumn := *edge.DstTableColumnIndex
otherColumn := *other.DstTableColumnIndex
if edgeColumn != otherColumn {
return fmt.Errorf("dst column differs: edge=%d, other=%d", edgeColumn, otherColumn)
}
}
return nil
}

View file

@ -115,7 +115,7 @@ func serde(t *testing.T, tc testCase, ruler *textmeasure.Ruler) {
var newG d2graph.Graph
err = d2graph.DeserializeGraph(b, &newG)
trequire.Nil(t, err)
trequire.Nil(t, g.Compare(&newG))
trequire.Nil(t, d2graph.CompareSerializedGraph(g, &newG))
}
func run(t *testing.T, tc testCase) {