From bc9537389cfde21124b81eca79c8e5cc31899c9c Mon Sep 17 00:00:00 2001 From: "Masih H. Derkani" Date: Tue, 9 Nov 2021 16:43:19 +0000 Subject: [PATCH] Port `codec` package tests to quicktest Implement `NodeContentEquals` quicktest checker that checks two given nodes have equal content by comparing their printout using `printer.Sprint`. 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 - `NodeContentEquals` for `datamodel.DeepEqual` over nodes Update `NodeContentEquals` for `datamodel.DeepEqual` over nodes in `node` package while at it. Port `node/mixins/TestSplitExact` over to quicktest missed out in earlier PRs. Note, to assert equality `CmpEqual` is used with an `Exporter` that exports all unexpored fields. Address TODO in node tests by using `NodeContentEquals` to check node equality. Relates to: - https://github.com/ipld/go-ipld-prime/issues/219 Depends on: - https://github.com/ipld/go-ipld-prime/pull/294 --- codec/cbor/roundtrip_test.go | 19 ++++--- codec/dagcbor/roundtripCidlink_test.go | 9 +-- codec/dagcbor/roundtrip_test.go | 25 +++++---- codec/dagcbor/unmarshal_test.go | 10 ++-- codec/dagjson/roundtripBytes_test.go | 30 +++++----- codec/dagjson/roundtripCidlink_test.go | 22 ++++---- codec/dagjson/roundtrip_test.go | 30 +++++----- codec/raw/codec_test.go | 3 +- node/mixins/delim_test.go | 6 +- node/tests/checkers.go | 41 ++++++++++++++ node/tests/checkers_test.go | 70 ++++++++++++++++++++++++ node/tests/schemaLists.go | 6 +- node/tests/schemaMaps.go | 10 ++-- node/tests/schemaStruct.go | 10 ++-- node/tests/schemaStructReprStringjoin.go | 8 +-- node/tests/schemaStructReprTuple.go | 6 +- node/tests/testcase.go | 9 +-- 17 files changed, 217 insertions(+), 97 deletions(-) create mode 100644 node/tests/checkers.go create mode 100644 node/tests/checkers_test.go diff --git a/codec/cbor/roundtrip_test.go b/codec/cbor/roundtrip_test.go index 1ae817f2..80c1d778 100644 --- a/codec/cbor/roundtrip_test.go +++ b/codec/cbor/roundtrip_test.go @@ -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" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) var n = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) { @@ -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(), nodetests.NodeContentEquals, n) }) } @@ -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`) 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(), nodetests.NodeContentEquals, simple) }) } diff --git a/codec/dagcbor/roundtripCidlink_test.go b/codec/dagcbor/roundtripCidlink_test.go index 2da7edee..6510242b 100644 --- a/codec/dagcbor/roundtripCidlink_test.go +++ b/codec/dagcbor/roundtripCidlink_test.go @@ -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" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) func TestRoundtripCidlink(t *testing.T) { @@ -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, nodetests.NodeContentEquals, nSorted) } diff --git a/codec/dagcbor/roundtrip_test.go b/codec/dagcbor/roundtrip_test.go index 64b4a0b6..fef0f5a6 100644 --- a/codec/dagcbor/roundtrip_test.go +++ b/codec/dagcbor/roundtrip_test.go @@ -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" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) var n = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) { @@ -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(), nodetests.NodeContentEquals, nSorted) }) } @@ -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(), nodetests.NodeContentEquals, simple) }) } @@ -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, nodetests.NodeContentEquals, linkByteNode) } diff --git a/codec/dagcbor/unmarshal_test.go b/codec/dagcbor/unmarshal_test.go index b19d91e5..7d6557df 100644 --- a/codec/dagcbor/unmarshal_test.go +++ b/codec/dagcbor/unmarshal_test.go @@ -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" ) @@ -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) }) } diff --git a/codec/dagjson/roundtripBytes_test.go b/codec/dagjson/roundtripBytes_test.go index 18814f70..7da6a317 100644 --- a/codec/dagjson/roundtripBytes_test.go +++ b/codec/dagjson/roundtripBytes_test.go @@ -1,14 +1,16 @@ -package dagjson +package dagjson_test import ( "bytes" "strings" "testing" - . "github.com/warpfork/go-wish" + qt "github.com/frankban/quicktest" + "github.com/ipld/go-ipld-prime/codec/dagjson" "github.com/ipld/go-ipld-prime/fluent" "github.com/ipld/go-ipld-prime/node/basicnode" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) var byteNode = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) { @@ -24,16 +26,16 @@ var byteSerial = `{"bytes":{"/":{"bytes":"ZGVhZGJlZWY"}},"plain":"olde string"}` 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) + err := dagjson.Encode(byteNode, &buf) + 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) + err := dagjson.Decode(nb, buf) + qt.Assert(t, err, qt.IsNil) + qt.Check(t, nb.Build(), nodetests.NodeContentEquals, byteNodeSorted) }) } @@ -47,15 +49,15 @@ var encapsulatedSerial = `{"/":{"bytes":{"/":{"bytes":"ZGVhZGJlZWY"}}}}` 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) + err := dagjson.Encode(encapsulatedNode, &buf) + 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) + err := dagjson.Decode(nb, buf) + qt.Assert(t, err, qt.IsNil) + qt.Check(t, nb.Build(), nodetests.NodeContentEquals, encapsulatedNode) }) } diff --git a/codec/dagjson/roundtripCidlink_test.go b/codec/dagjson/roundtripCidlink_test.go index 03e25fd0..43e0c403 100644 --- a/codec/dagjson/roundtripCidlink_test.go +++ b/codec/dagjson/roundtripCidlink_test.go @@ -1,4 +1,4 @@ -package dagjson +package dagjson_test import ( "bytes" @@ -6,13 +6,15 @@ 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/codec/dagjson" "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" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) func TestRoundtripCidlink(t *testing.T) { @@ -33,11 +35,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, nodetests.NodeContentEquals, nSorted) } // Make sure that a map that *almost* looks like a link is handled safely. @@ -58,11 +60,11 @@ 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) + err := dagjson.Decode(nb, strings.NewReader(tricky)) + 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) } diff --git a/codec/dagjson/roundtrip_test.go b/codec/dagjson/roundtrip_test.go index 8b88a1bb..f995151c 100644 --- a/codec/dagjson/roundtrip_test.go +++ b/codec/dagjson/roundtrip_test.go @@ -1,14 +1,16 @@ -package dagjson +package dagjson_test import ( "bytes" "strings" "testing" - . "github.com/warpfork/go-wish" + qt "github.com/frankban/quicktest" + "github.com/ipld/go-ipld-prime/codec/dagjson" "github.com/ipld/go-ipld-prime/fluent" "github.com/ipld/go-ipld-prime/node/basicnode" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) var n = fluent.MustBuildMap(basicnode.Prototype.Map, 4, func(na fluent.MapAssembler) { @@ -48,16 +50,16 @@ var serial = `{"list":["three","four"],"map":{"one":1,"two":2},"nested":{"deeper 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) + err := dagjson.Encode(n, &buf) + 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) + err := dagjson.Decode(nb, buf) + qt.Assert(t, err, qt.IsNil) + qt.Check(t, nb.Build(), nodetests.NodeContentEquals, nSorted) }) } @@ -67,15 +69,15 @@ func TestRoundtripScalar(t *testing.T) { simple := nb.Build() 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"`) + err := dagjson.Encode(simple, &buf) + 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) + err := dagjson.Decode(nb, buf) + qt.Assert(t, err, qt.IsNil) + qt.Check(t, nb.Build(), nodetests.NodeContentEquals, simple) }) } diff --git a/codec/raw/codec_test.go b/codec/raw/codec_test.go index 1403d2e9..d9b39c65 100644 --- a/codec/raw/codec_test.go +++ b/codec/raw/codec_test.go @@ -12,6 +12,7 @@ import ( "github.com/ipld/go-ipld-prime/linking" cidlink "github.com/ipld/go-ipld-prime/linking/cid" "github.com/ipld/go-ipld-prime/node/basicnode" + nodetests "github.com/ipld/go-ipld-prime/node/tests" ) var tests = []struct { @@ -71,7 +72,7 @@ func TestRoundtripCidlink(t *testing.T) { newNode, err := lsys.Load(linking.LinkContext{}, lnk, basicnode.Prototype.Any) qt.Assert(t, err, qt.IsNil) - qt.Assert(t, newNode, qt.DeepEquals, node) + qt.Assert(t, newNode, nodetests.NodeContentEquals, node) } // mustOnlyUseRead only exposes Read, hiding Bytes. diff --git a/node/mixins/delim_test.go b/node/mixins/delim_test.go index e4bde075..86bf02ce 100644 --- a/node/mixins/delim_test.go +++ b/node/mixins/delim_test.go @@ -2,9 +2,11 @@ package mixins import ( "fmt" + "github.com/google/go-cmp/cmp" + "reflect" "testing" - . "github.com/warpfork/go-wish" + qt "github.com/frankban/quicktest" ) func TestSplitExact(t *testing.T) { @@ -29,6 +31,6 @@ func TestSplitExact(t *testing.T) { } { value, err := SplitExact(ent.s, ent.sep, ent.count) ent2 := tcase{ent.s, ent.sep, ent.count, expect{value, err}} - Wish(t, ent2, ShouldEqual, ent) + qt.Check(t, ent2, qt.CmpEquals(cmp.Exporter(func(reflect.Type) bool { return true })), ent) } } diff --git a/node/tests/checkers.go b/node/tests/checkers.go new file mode 100644 index 00000000..58c6f468 --- /dev/null +++ b/node/tests/checkers.go @@ -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 checks whether two nodes have equal content by first encoding them via +// printer.Sprint, then checking that the generated encodings 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"} +} diff --git a/node/tests/checkers_test.go b/node/tests/checkers_test.go new file mode 100644 index 00000000..7def275d --- /dev/null +++ b/node/tests/checkers_test.go @@ -0,0 +1,70 @@ +package tests + +import ( + "testing" + + qt "github.com/frankban/quicktest" + + "github.com/ipld/go-ipld-prime/node/basicnode" +) + +func Test_nodeContentEqualsChecker_Check(t *testing.T) { + someNode := basicnode.Prototype__String{}.NewBuilder().Build() + nb := basicnode.Prototype__String{}.NewBuilder() + err := nb.AssignString("fish") + qt.Assert(t, err, qt.IsNil) + someOtherNode := nb.Build() + + tests := []struct { + name string + got interface{} + want interface{} + wantErr string + }{ + { + name: "nilWantIsError", + got: "not a node", + want: nil, + wantErr: "got non-nil value", + }, + { + name: "nonNodeAsWantIsError", + got: "not a node", + want: someNode, + wantErr: "this checker only supports checking datamodel.Node values", + }, + { + name: "nonNodeAsGotIsError", + got: someNode, + want: "not a node", + wantErr: "this checker only supports checking datamodel.Node values", + }, + { + name: "nilWantAndGotAreEqual", + got: nil, + want: nil, + }, + { + name: "equivalentNodesAreEqual", + got: someNode, + want: someNode, + }, + { + name: "differentNodesAreNotEqual", + got: someNode, + want: someOtherNode, + wantErr: "values are not equal", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := NodeContentEquals.Check(tt.got, []interface{}{tt.want}, nil) + if tt.wantErr == "" { + qt.Assert(t, err, qt.IsNil) + } else { + qt.Assert(t, err, qt.Not(qt.IsNil)) + qt.Assert(t, err.Error(), qt.Equals, tt.wantErr) + } + }) + } +} diff --git a/node/tests/schemaLists.go b/node/tests/schemaLists.go index b06624f9..adca7ac4 100644 --- a/node/tests/schemaLists.go +++ b/node/tests/schemaLists.go @@ -64,7 +64,7 @@ func SchemaTestListsContainingMaybe(t *testing.T, engine Engine) { la.AssembleValue().AssignString("1") la.AssembleValue().AssignString("2") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) t.Run("nullable", func(t *testing.T) { @@ -99,7 +99,7 @@ func SchemaTestListsContainingMaybe(t *testing.T, engine Engine) { la.AssembleValue().AssignString("1") la.AssembleValue().AssignNull() }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) } @@ -186,6 +186,6 @@ func SchemaTestListsContainingLists(t *testing.T, engine Engine) { la.AssembleValue().CreateMap(1, func(ma fluent.MapAssembler) { ma.AssembleEntry("encoded").AssignString("32") }) }) }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) } diff --git a/node/tests/schemaMaps.go b/node/tests/schemaMaps.go index 74c6c711..6890e71c 100644 --- a/node/tests/schemaMaps.go +++ b/node/tests/schemaMaps.go @@ -53,7 +53,7 @@ func SchemaTestMapsContainingMaybe(t *testing.T, engine Engine) { ma.AssembleEntry("one").AssignString("1") ma.AssembleEntry("two").AssignString("2") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) t.Run("nullable", func(t *testing.T) { @@ -88,7 +88,7 @@ func SchemaTestMapsContainingMaybe(t *testing.T, engine Engine) { ma.AssembleEntry("one").AssignString("1") ma.AssembleEntry("none").AssignNull() }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) } @@ -156,7 +156,7 @@ func SchemaTestMapsContainingMaps(t *testing.T, engine Engine) { }) }) withNode(must.Node(n.LookupByString("none")), func(n datamodel.Node) { - qt.Check(t, datamodel.DeepEqual(n, datamodel.Null), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, datamodel.Null) }) _, err := n.LookupByString("miss") qt.Check(t, err, qt.ErrorAs, &datamodel.ErrNotExists{}) @@ -174,7 +174,7 @@ func SchemaTestMapsContainingMaps(t *testing.T, engine Engine) { }) t.Run("repr-create", func(t *testing.T) { nr := creation(t, nrp, "encoded") - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) } @@ -236,6 +236,6 @@ func SchemaTestMapsWithComplexKeys(t *testing.T, engine Engine) { ma.AssembleEntry("c:d").AssignString("2") ma.AssembleEntry("e:f").AssignString("3") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) } diff --git a/node/tests/schemaStruct.go b/node/tests/schemaStruct.go index ddb20664..c614fdf8 100644 --- a/node/tests/schemaStruct.go +++ b/node/tests/schemaStruct.go @@ -107,10 +107,10 @@ func SchemaTestStructNesting(t *testing.T, engine Engine) { qt.Assert(t, n2.Kind(), qt.Equals, datamodel.Kind_Map) n2Seg := must.Node(n.LookupBySegment(datamodel.PathSegmentOfString("x"))) - qt.Check(t, datamodel.DeepEqual(n2, n2Seg), qt.IsTrue) + qt.Check(t, n2, NodeContentEquals, n2Seg) n2Node := must.Node(n.LookupByNode(basicnode.NewString("x"))) - qt.Check(t, datamodel.DeepEqual(n2, n2Node), qt.IsTrue) + qt.Check(t, n2, NodeContentEquals, n2Node) qt.Check(t, must.String(must.Node(n2.LookupByString("s"))), qt.Equals, "woo") }) @@ -123,10 +123,10 @@ func SchemaTestStructNesting(t *testing.T, engine Engine) { qt.Assert(t, n2.Kind(), qt.Equals, datamodel.Kind_Map) n2Seg := must.Node(nr.LookupBySegment(datamodel.PathSegmentOfString("r"))) - qt.Check(t, datamodel.DeepEqual(n2, n2Seg), qt.IsTrue) + qt.Check(t, n2, NodeContentEquals, n2Seg) n2Node := must.Node(nr.LookupByNode(basicnode.NewString("r"))) - qt.Check(t, datamodel.DeepEqual(n2, n2Node), qt.IsTrue) + qt.Check(t, n2, NodeContentEquals, n2Node) qt.Check(t, must.String(must.Node(n2.LookupByString("q"))), qt.Equals, "woo") }) @@ -137,6 +137,6 @@ func SchemaTestStructNesting(t *testing.T, engine Engine) { ma.AssembleEntry("q").AssignString("woo") }) }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) } diff --git a/node/tests/schemaStructReprStringjoin.go b/node/tests/schemaStructReprStringjoin.go index c56d7b29..7684ca7d 100644 --- a/node/tests/schemaStructReprStringjoin.go +++ b/node/tests/schemaStructReprStringjoin.go @@ -65,7 +65,7 @@ func SchemaTestStructReprStringjoin(t *testing.T, engine Engine) { nr := fluent.MustBuild(nrp, func(na fluent.NodeAssembler) { na.AssignString("valoo") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) @@ -94,7 +94,7 @@ func SchemaTestStructReprStringjoin(t *testing.T, engine Engine) { nr := fluent.MustBuild(nrp, func(na fluent.NodeAssembler) { na.AssignString("v1:v2") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) @@ -123,7 +123,7 @@ func SchemaTestStructReprStringjoin(t *testing.T, engine Engine) { nr := fluent.MustBuild(nrp, func(na fluent.NodeAssembler) { na.AssignString(":v2") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) @@ -160,7 +160,7 @@ func SchemaTestStructReprStringjoin(t *testing.T, engine Engine) { nr := fluent.MustBuild(nrp, func(na fluent.NodeAssembler) { na.AssignString("v1-v2:v3-v4") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) } diff --git a/node/tests/schemaStructReprTuple.go b/node/tests/schemaStructReprTuple.go index 33bfbf4f..e57cae7c 100644 --- a/node/tests/schemaStructReprTuple.go +++ b/node/tests/schemaStructReprTuple.go @@ -56,7 +56,7 @@ func SchemaTestStructReprTuple(t *testing.T, engine Engine) { nr := fluent.MustBuildList(nrp, 1, func(la fluent.ListAssembler) { la.AssembleValue().AssignString("valoo") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) @@ -96,7 +96,7 @@ func SchemaTestStructReprTuple(t *testing.T, engine Engine) { la.AssembleValue().AssignString("2") la.AssembleValue().AssignString("3") }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) @@ -130,7 +130,7 @@ func SchemaTestStructReprTuple(t *testing.T, engine Engine) { la.AssembleValue().AssignString("0") la.AssembleValue().AssignNull() }) - qt.Check(t, datamodel.DeepEqual(n, nr), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, nr) }) }) } diff --git a/node/tests/testcase.go b/node/tests/testcase.go index 81087ff4..18bd90e1 100644 --- a/node/tests/testcase.go +++ b/node/tests/testcase.go @@ -126,7 +126,7 @@ func (tcase testcase) Test(t *testing.T, np, npr datamodel.NodePrototype) { } if n2 != nil { t.Run("type-create and repr-create match", func(t *testing.T) { - qt.Check(t, datamodel.DeepEqual(n, n2), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, n2) }) } @@ -189,7 +189,7 @@ func (tcase testcase) Test(t *testing.T, np, npr datamodel.NodePrototype) { t.Run("type-create with AK+AV", func(t *testing.T) { n3, err := shallowCopyMap(np, n) qt.Check(t, err, qt.IsNil) - qt.Check(t, datamodel.DeepEqual(n, n3), qt.IsTrue) + qt.Check(t, n, NodeContentEquals, n3) }) } @@ -199,10 +199,7 @@ func (tcase testcase) Test(t *testing.T, np, npr datamodel.NodePrototype) { t.Run("repr-create with AK+AV", func(t *testing.T) { n3, err := shallowCopyMap(npr, n.(schema.TypedNode).Representation()) qt.Check(t, err, qt.IsNil) - // TODO: Improve checking mechanism; hits: - // - expose datamodel.DeepEqual as a go-cmp Comparer, or - // - use the printer package and then do string diff on the results - qt.Check(t, datamodel.DeepEqual(n, n3), qt.IsTrue) + qt.Check(t, n3, NodeContentEquals, n) }) }