github.com/ipld/go-ipld-prime@v0.21.0/codec/raw/codec_test.go (about)

     1  package raw
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"testing"
     8  
     9  	qt "github.com/frankban/quicktest"
    10  	"github.com/ipfs/go-cid"
    11  	"github.com/ipld/go-ipld-prime/datamodel"
    12  	"github.com/ipld/go-ipld-prime/linking"
    13  	cidlink "github.com/ipld/go-ipld-prime/linking/cid"
    14  	"github.com/ipld/go-ipld-prime/node/basicnode"
    15  	nodetests "github.com/ipld/go-ipld-prime/node/tests"
    16  )
    17  
    18  var tests = []struct {
    19  	name string
    20  	data []byte
    21  }{
    22  	{"Empty", nil},
    23  	{"Plaintext", []byte("hello there")},
    24  	{"JSON", []byte(`{"foo": "bar"}`)},
    25  	{"NullBytes", []byte("\x00\x00")},
    26  }
    27  
    28  func TestRoundtrip(t *testing.T) {
    29  	t.Parallel()
    30  
    31  	for _, test := range tests {
    32  		t.Run(test.name, func(t *testing.T) {
    33  			nb := basicnode.Prototype.Bytes.NewBuilder()
    34  			r := bytes.NewBuffer(test.data)
    35  
    36  			err := Decode(nb, r)
    37  			qt.Assert(t, err, qt.IsNil)
    38  			node := nb.Build()
    39  
    40  			buf := new(bytes.Buffer)
    41  			err = Encode(node, buf)
    42  			qt.Assert(t, err, qt.IsNil)
    43  
    44  			qt.Assert(t, buf.Bytes(), qt.DeepEquals, test.data)
    45  		})
    46  	}
    47  }
    48  
    49  func TestRoundtripCidlink(t *testing.T) {
    50  	t.Parallel()
    51  
    52  	lp := cidlink.LinkPrototype{Prefix: cid.Prefix{
    53  		Version:  1,
    54  		Codec:    rawMulticodec,
    55  		MhType:   0x13,
    56  		MhLength: 4,
    57  	}}
    58  	node := basicnode.NewBytes([]byte("hello there"))
    59  
    60  	lsys := cidlink.DefaultLinkSystem()
    61  
    62  	buf := bytes.Buffer{}
    63  	lsys.StorageWriteOpener = func(lnkCtx linking.LinkContext) (io.Writer, linking.BlockWriteCommitter, error) {
    64  		return &buf, func(lnk datamodel.Link) error { return nil }, nil
    65  	}
    66  	lsys.StorageReadOpener = func(lnkCtx linking.LinkContext, lnk datamodel.Link) (io.Reader, error) {
    67  		return bytes.NewReader(buf.Bytes()), nil
    68  	}
    69  	lnk, err := lsys.Store(linking.LinkContext{}, lp, node)
    70  
    71  	qt.Assert(t, err, qt.IsNil)
    72  
    73  	newNode, err := lsys.Load(linking.LinkContext{}, lnk, basicnode.Prototype.Any)
    74  	qt.Assert(t, err, qt.IsNil)
    75  	qt.Assert(t, newNode, nodetests.NodeContentEquals, node)
    76  }
    77  
    78  // mustOnlyUseRead only exposes Read, hiding Bytes.
    79  type mustOnlyUseRead struct {
    80  	buf *bytes.Buffer
    81  }
    82  
    83  func (r mustOnlyUseRead) Read(p []byte) (int, error) {
    84  	return r.buf.Read(p)
    85  }
    86  
    87  // mustNotUseRead exposes Bytes and makes Read always error.
    88  type mustNotUseRead struct {
    89  	buf *bytes.Buffer
    90  }
    91  
    92  func (r mustNotUseRead) Read(p []byte) (int, error) {
    93  	return 0, fmt.Errorf("must not call Read")
    94  }
    95  
    96  func (r mustNotUseRead) Bytes() []byte {
    97  	return r.buf.Bytes()
    98  }
    99  
   100  func TestDecodeBuffer(t *testing.T) {
   101  	t.Parallel()
   102  
   103  	var err error
   104  	buf := bytes.NewBuffer([]byte("hello there"))
   105  
   106  	err = Decode(
   107  		basicnode.Prototype.Bytes.NewBuilder(),
   108  		mustOnlyUseRead{buf},
   109  	)
   110  	qt.Assert(t, err, qt.IsNil)
   111  
   112  	err = Decode(
   113  		basicnode.Prototype.Bytes.NewBuilder(),
   114  		mustNotUseRead{buf},
   115  	)
   116  	qt.Assert(t, err, qt.IsNil)
   117  }