Skip to content

Commit

Permalink
fix(datamodel): add tests to Copy, make it complain on nil
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Feb 10, 2023
1 parent 7b00b14 commit f4bb2da
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 1 deletion.
6 changes: 5 additions & 1 deletion datamodel/copy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package datamodel

import (
"errors"
"fmt"
)

Expand All @@ -20,10 +21,13 @@ import (
// faster shortcuts they might prefer to employ, such as direct struct copying
// if they share internal memory layouts, etc, have been tried already).
func Copy(n Node, na NodeAssembler) error {
if n == nil {
return errors.New("cannot copy a nil node")
}
switch n.Kind() {
case Kind_Null:
if n.IsAbsent() {
return fmt.Errorf("copying an absent node makes no sense")
return errors.New("copying an absent node makes no sense")
}
return na.AssignNull()
case Kind_Bool:
Expand Down
92 changes: 92 additions & 0 deletions datamodel/copy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package datamodel_test

import (
"testing"

"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/fluent/qp"
basic "github.com/ipld/go-ipld-prime/node/basicnode"
)

var copyTests = []struct {
name string
na datamodel.NodeBuilder
n datamodel.Node
err string
}{
{name: "Null / Any", na: basic.Prototype.Any.NewBuilder(), n: datamodel.Null},
{name: "Int / Any", na: basic.Prototype.Any.NewBuilder(), n: basic.NewInt(100)},
{name: "Int / Int", na: basic.Prototype.Int.NewBuilder(), n: basic.NewInt(1000)},
{name: "Bool / Any", na: basic.Prototype.Any.NewBuilder(), n: basic.NewBool(true)},
{name: "Bool / Bool", na: basic.Prototype.Bool.NewBuilder(), n: basic.NewBool(false)},
{name: "Float / Any", na: basic.Prototype.Any.NewBuilder(), n: basic.NewFloat(1.1)},
{name: "Float / Float", na: basic.Prototype.Float.NewBuilder(), n: basic.NewFloat(1.2)},
{name: "String / Any", na: basic.Prototype.Any.NewBuilder(), n: basic.NewString("mary had")},
{name: "String / String", na: basic.Prototype.String.NewBuilder(), n: basic.NewString("a little lamb")},
{name: "Bytes / Any", na: basic.Prototype.Any.NewBuilder(), n: basic.NewBytes([]byte("mary had"))},
{name: "Bytes / Bytes", na: basic.Prototype.Bytes.NewBuilder(), n: basic.NewBytes([]byte("a little lamb"))},
{name: "Link / Any", na: basic.Prototype.Any.NewBuilder(), n: basic.NewLink(globalLink)},
{name: "Link / Link", na: basic.Prototype.Link.NewBuilder(), n: basic.NewLink(globalLink2)},
{
name: "List / Any",
na: basic.Prototype.Any.NewBuilder(),
n: qpMust(qp.BuildList(basic.Prototype.Any, -1, func(am datamodel.ListAssembler) {
qp.ListEntry(am, qp.Int(7))
qp.ListEntry(am, qp.Int(8))
})),
},
{
name: "List / List",
na: basic.Prototype.List.NewBuilder(),
n: qpMust(qp.BuildList(basic.Prototype.List, -1, func(am datamodel.ListAssembler) {
qp.ListEntry(am, qp.String("yep"))
qp.ListEntry(am, qp.Int(8))
qp.ListEntry(am, qp.String("nope"))
})),
},
{
name: "Map / Any",
na: basic.Prototype.Any.NewBuilder(),
n: qpMust(qp.BuildMap(basic.Prototype.Any, -1, func(am datamodel.MapAssembler) {
qp.MapEntry(am, "foo", qp.Int(7))
qp.MapEntry(am, "bar", qp.Int(8))
})),
},
{
name: "Map / Map",
na: basic.Prototype.Map.NewBuilder(),
n: qpMust(qp.BuildMap(basic.Prototype.Map, -1, func(am datamodel.MapAssembler) {
qp.MapEntry(am, "foo", qp.Int(7))
qp.MapEntry(am, "bar", qp.Int(8))
qp.MapEntry(am, "bang", qp.Link(globalLink))
})),
},
{name: "nil", na: basic.Prototype.Any.NewBuilder(), n: nil, err: "cannot copy a nil node"},
{name: "absent", na: basic.Prototype.Any.NewBuilder(), n: datamodel.Absent, err: "copying an absent node makes no sense"},
}

func TestCopy(t *testing.T) {
for _, tt := range copyTests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := datamodel.Copy(tt.n, tt.na)
if err != nil {
if tt.err != "" {
if err.Error() != tt.err {
t.Fatalf("expected error %q, got %q", tt.err, err.Error())
}
} else {
t.Fatal(err)
}
return
} else if tt.err != "" {
t.Fatalf("expected error %q, got nil", tt.err)
return
}
out := tt.na.Build()
if !datamodel.DeepEqual(tt.n, out) {
t.Fatalf("deep equal failed")
}
})
}
}

0 comments on commit f4bb2da

Please sign in to comment.