Skip to content

Commit

Permalink
Port codec package tests to quicktest
Browse files Browse the repository at this point in the history
Implement `NodeContentEquals` quicktest checker that checks two given
nodes have equal content by comparing their printout using `printer`.
This simplifies the tests that use `datamode.DeepEqual` by performing
an equivalent check while producing a human-readable error when nodes
are not equal. The naming for this check is inspired by a similar
equality check in quicktest, named `ContentEquals`.

Port the tests in `codec` package to quicktest; use:
 - `qt.Assert` for `wish.Require`
 - `qt.Check` for `wish.Wish`
 - `qt.IsTrue` for ShouldEqual` over `true`
 - `qt.IsFalse` for `ShouldEqual` over `false`
 - `qt.IsNil` for `ShouldEqual` over `nil`
 - `NodeContentEquals` for `ShouldEqual` over nodes

Address TODO in node tests by using `NodeContentEquals` to check node
equality.

Relates to:
 - #219
  • Loading branch information
masih committed Nov 10, 2021
1 parent a3cb8e9 commit 3c062db
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 61 deletions.
21 changes: 11 additions & 10 deletions codec/cbor/roundtrip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"strings"
"testing"

. "github.com/warpfork/go-wish"
qt "github.com/frankban/quicktest"

"github.com/ipld/go-ipld-prime/fluent"
"github.com/ipld/go-ipld-prime/node/basicnode"
nt "github.com/ipld/go-ipld-prime/node/tests"
)

var n = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) {
Expand All @@ -34,15 +35,15 @@ func TestRoundtrip(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(n, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, serial)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, serial)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(serial)
nb := basicnode.Prototype.Map.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, n)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, n)
})
}

Expand All @@ -53,14 +54,14 @@ func TestRoundtripScalar(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(simple, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, `japplesauce`)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, `japplesauce`)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(`japplesauce`)
buf := strings.NewReader(`djapplesauce`)
nb := basicnode.Prototype__String{}.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, simple)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, simple)
})
}
9 changes: 5 additions & 4 deletions codec/dagcbor/roundtripCidlink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"io"
"testing"

. "github.com/warpfork/go-wish"
qt "github.com/frankban/quicktest"

cid "github.com/ipfs/go-cid"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/linking"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/node/basicnode"
nt "github.com/ipld/go-ipld-prime/node/tests"
)

func TestRoundtripCidlink(t *testing.T) {
Expand All @@ -32,9 +33,9 @@ func TestRoundtripCidlink(t *testing.T) {
}

lnk, err := lsys.Store(linking.LinkContext{}, lp, n)
Require(t, err, ShouldEqual, nil)
qt.Assert(t, err, qt.IsNil)

n2, err := lsys.Load(linking.LinkContext{}, lnk, basicnode.Prototype.Any)
Require(t, err, ShouldEqual, nil)
Wish(t, n2, ShouldEqual, nSorted)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, n2, nt.NodeContentEquals, nSorted)
}
25 changes: 13 additions & 12 deletions codec/dagcbor/roundtrip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (
"strings"
"testing"

qt "github.com/frankban/quicktest"
cid "github.com/ipfs/go-cid"
. "github.com/warpfork/go-wish"

"github.com/ipld/go-ipld-prime/fluent"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/node/basicnode"
nt "github.com/ipld/go-ipld-prime/node/tests"
)

var n = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) {
Expand Down Expand Up @@ -52,15 +53,15 @@ func TestRoundtrip(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(n, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, serial)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, serial)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(serial)
nb := basicnode.Prototype.Map.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, nSorted)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, nSorted)
})
}

Expand All @@ -71,15 +72,15 @@ func TestRoundtripScalar(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(simple, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, `japplesauce`)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, `japplesauce`)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(`japplesauce`)
nb := basicnode.Prototype__String{}.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, simple)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, simple)
})
}

Expand All @@ -102,10 +103,10 @@ func TestRoundtripLinksAndBytes(t *testing.T) {

buf := bytes.Buffer{}
err := Encode(linkByteNode, &buf)
Require(t, err, ShouldEqual, nil)
qt.Assert(t, err, qt.IsNil)
nb := basicnode.Prototype.Map.NewBuilder()
err = Decode(nb, &buf)
Require(t, err, ShouldEqual, nil)
qt.Assert(t, err, qt.IsNil)
reconstructed := nb.Build()
Wish(t, reconstructed, ShouldEqual, linkByteNode)
qt.Check(t, reconstructed, nt.NodeContentEquals, linkByteNode)
}
10 changes: 5 additions & 5 deletions codec/dagcbor/unmarshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"strings"
"testing"

. "github.com/warpfork/go-wish"
qt "github.com/frankban/quicktest"

"github.com/ipld/go-ipld-prime/node/basicnode"
)
Expand All @@ -15,27 +15,27 @@ func TestFunBlocks(t *testing.T) {
buf := strings.NewReader("\x8d\x8d\x97\xd8*@")
nb := basicnode.Prototype.Any.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, ErrInvalidMultibase)
qt.Assert(t, err, qt.Equals, ErrInvalidMultibase)
})
t.Run("fuzz001", func(t *testing.T) {
// This fixture might cause an overly large allocation if you aren't careful to have resource budgets.
buf := strings.NewReader("\x9a\xff000")
nb := basicnode.Prototype.Any.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, ErrAllocationBudgetExceeded)
qt.Assert(t, err, qt.Equals, ErrAllocationBudgetExceeded)
})
t.Run("fuzz002", func(t *testing.T) {
// This fixture might cause an overly large allocation if you aren't careful to have resource budgets.
buf := strings.NewReader("\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9a\xff000")
nb := basicnode.Prototype.Any.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, ErrAllocationBudgetExceeded)
qt.Assert(t, err, qt.Equals, ErrAllocationBudgetExceeded)
})
t.Run("fuzz003", func(t *testing.T) {
// This fixture might cause an overly large allocation if you aren't careful to have resource budgets.
buf := strings.NewReader("\x9f\x9f\x9f\x9f\x9f\x9f\x9f\xbb00000000")
nb := basicnode.Prototype.Any.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, ErrAllocationBudgetExceeded)
qt.Assert(t, err, qt.Equals, ErrAllocationBudgetExceeded)
})
}
19 changes: 10 additions & 9 deletions codec/dagjson/roundtripBytes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"strings"
"testing"

. "github.com/warpfork/go-wish"
qt "github.com/frankban/quicktest"

"github.com/ipld/go-ipld-prime/fluent"
"github.com/ipld/go-ipld-prime/node/basicnode"
nt "github.com/ipld/go-ipld-prime/node/tests"
)

var byteNode = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) {
Expand All @@ -25,15 +26,15 @@ func TestRoundtripBytes(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(byteNode, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, byteSerial)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, byteSerial)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(byteSerial)
nb := basicnode.Prototype.Map.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, byteNodeSorted)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, byteNodeSorted)
})
}

Expand All @@ -48,14 +49,14 @@ func TestEncapsulatedBytes(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(encapsulatedNode, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, encapsulatedSerial)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, encapsulatedSerial)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(encapsulatedSerial)
nb := basicnode.Prototype.Map.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, encapsulatedNode)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, encapsulatedNode)
})
}
17 changes: 9 additions & 8 deletions codec/dagjson/roundtripCidlink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"strings"
"testing"

. "github.com/warpfork/go-wish"
qt "github.com/frankban/quicktest"

cid "github.com/ipfs/go-cid"
"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/linking"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/node/basicnode"
nt "github.com/ipld/go-ipld-prime/node/tests"
)

func TestRoundtripCidlink(t *testing.T) {
Expand All @@ -33,11 +34,11 @@ func TestRoundtripCidlink(t *testing.T) {
}

lnk, err := lsys.Store(linking.LinkContext{}, lp, n)
Require(t, err, ShouldEqual, nil)
qt.Assert(t, err, qt.IsNil)

n2, err := lsys.Load(linking.LinkContext{}, lnk, basicnode.Prototype.Any)
Require(t, err, ShouldEqual, nil)
Wish(t, n2, ShouldEqual, nSorted)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, n2, nt.NodeContentEquals, nSorted)
}

// Make sure that a map that *almost* looks like a link is handled safely.
Expand All @@ -59,10 +60,10 @@ func TestUnmarshalTrickyMapContainingLink(t *testing.T) {
// Unmarshal. Hopefully we get a map with a link in it.
nb := basicnode.Prototype.Any.NewBuilder()
err := Decode(nb, strings.NewReader(tricky))
Require(t, err, ShouldEqual, nil)
qt.Assert(t, err, qt.IsNil)
n := nb.Build()
Wish(t, n.Kind(), ShouldEqual, datamodel.Kind_Map)
qt.Check(t, n.Kind(), qt.Equals, datamodel.Kind_Map)
n2, err := n.LookupByString("/")
Require(t, err, ShouldEqual, nil)
Wish(t, n2.Kind(), ShouldEqual, datamodel.Kind_Link)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, n2.Kind(), qt.Equals, datamodel.Kind_Link)
}
19 changes: 10 additions & 9 deletions codec/dagjson/roundtrip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"strings"
"testing"

. "github.com/warpfork/go-wish"
qt "github.com/frankban/quicktest"

"github.com/ipld/go-ipld-prime/fluent"
"github.com/ipld/go-ipld-prime/node/basicnode"
nt "github.com/ipld/go-ipld-prime/node/tests"
)

var n = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) {
Expand Down Expand Up @@ -49,15 +50,15 @@ func TestRoundtrip(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(n, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, serial)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, serial)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(serial)
nb := basicnode.Prototype.Map.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, nSorted)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), nt.NodeContentEquals, nSorted)
})
}

Expand All @@ -68,14 +69,14 @@ func TestRoundtripScalar(t *testing.T) {
t.Run("encoding", func(t *testing.T) {
var buf bytes.Buffer
err := Encode(simple, &buf)
Require(t, err, ShouldEqual, nil)
Wish(t, buf.String(), ShouldEqual, `"applesauce"`)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, buf.String(), qt.Equals, `"applesauce"`)
})
t.Run("decoding", func(t *testing.T) {
buf := strings.NewReader(`"applesauce"`)
nb := basicnode.Prototype__String{}.NewBuilder()
err := Decode(nb, buf)
Require(t, err, ShouldEqual, nil)
Wish(t, nb.Build(), ShouldEqual, simple)
qt.Assert(t, err, qt.IsNil)
qt.Check(t, nb.Build(), qt.DeepEquals, simple)
})
}
41 changes: 41 additions & 0 deletions node/tests/checkers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package tests

import (
"errors"

qt "github.com/frankban/quicktest"

"github.com/ipld/go-ipld-prime/datamodel"
"github.com/ipld/go-ipld-prime/printer"
)

// NodeContentEquals prints the content of the actual and expected nodes using printer.Sprint, and
// checks that the generated strings are identical.
//
// See: printer.Sprint.
var NodeContentEquals = &nodeContentEqualsChecker{}

type nodeContentEqualsChecker struct{}

func (n *nodeContentEqualsChecker) Check(got interface{}, args []interface{}, note func(key string, value interface{})) error {
want := args[0]
if want == nil {
return qt.IsNil.Check(got, args, note)
}
wantNode, ok := want.(datamodel.Node)
if !ok {
return errors.New("this checker only supports checking datamodel.Node values")
}
wantPrint := printer.Sprint(wantNode)

gotNode, ok := got.(datamodel.Node)
if !ok {
return errors.New("this checker only supports checking datamodel.Node values")
}
gotPrint := printer.Sprint(gotNode)
return qt.Equals.Check(gotPrint, []interface{}{wantPrint}, note)
}

func (n *nodeContentEqualsChecker) ArgNames() []string {
return []string{"got", "want node"}
}
Loading

0 comments on commit 3c062db

Please sign in to comment.