package msgpack_test
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
. "gopkg.in/check.v1"
|
|
|
|
"github.com/vmihailenco/msgpack"
|
|
)
|
|
|
|
type nameStruct struct {
|
|
Name string
|
|
}
|
|
|
|
func TestGocheck(t *testing.T) { TestingT(t) }
|
|
|
|
type MsgpackTest struct {
|
|
buf *bytes.Buffer
|
|
enc *msgpack.Encoder
|
|
dec *msgpack.Decoder
|
|
}
|
|
|
|
var _ = Suite(&MsgpackTest{})
|
|
|
|
func (t *MsgpackTest) SetUpTest(c *C) {
|
|
t.buf = &bytes.Buffer{}
|
|
t.enc = msgpack.NewEncoder(t.buf)
|
|
t.dec = msgpack.NewDecoder(bufio.NewReader(t.buf))
|
|
}
|
|
|
|
func (t *MsgpackTest) TestDecodeNil(c *C) {
|
|
c.Assert(t.dec.Decode(nil), NotNil)
|
|
}
|
|
|
|
func (t *MsgpackTest) TestTime(c *C) {
|
|
in := time.Now()
|
|
var out time.Time
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Equal(in), Equals, true)
|
|
|
|
var zero time.Time
|
|
c.Assert(t.enc.Encode(zero), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Equal(zero), Equals, true)
|
|
c.Assert(out.IsZero(), Equals, true)
|
|
}
|
|
|
|
func (t *MsgpackTest) TestLargeBytes(c *C) {
|
|
N := int(1e6)
|
|
|
|
src := bytes.Repeat([]byte{'1'}, N)
|
|
c.Assert(t.enc.Encode(src), IsNil)
|
|
var dst []byte
|
|
c.Assert(t.dec.Decode(&dst), IsNil)
|
|
c.Assert(dst, DeepEquals, src)
|
|
}
|
|
|
|
func (t *MsgpackTest) TestLargeString(c *C) {
|
|
N := int(1e6)
|
|
|
|
src := string(bytes.Repeat([]byte{'1'}, N))
|
|
c.Assert(t.enc.Encode(src), IsNil)
|
|
var dst string
|
|
c.Assert(t.dec.Decode(&dst), IsNil)
|
|
c.Assert(dst, Equals, src)
|
|
}
|
|
|
|
func (t *MsgpackTest) TestSliceOfStructs(c *C) {
|
|
in := []*nameStruct{&nameStruct{"hello"}}
|
|
var out []*nameStruct
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out, DeepEquals, in)
|
|
}
|
|
|
|
func (t *MsgpackTest) TestMap(c *C) {
|
|
for _, i := range []struct {
|
|
m map[string]string
|
|
b []byte
|
|
}{
|
|
{map[string]string{}, []byte{0x80}},
|
|
{map[string]string{"hello": "world"}, []byte{0x81, 0xa5, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xa5, 0x77, 0x6f, 0x72, 0x6c, 0x64}},
|
|
} {
|
|
c.Assert(t.enc.Encode(i.m), IsNil)
|
|
c.Assert(t.buf.Bytes(), DeepEquals, i.b, Commentf("err encoding %v", i.m))
|
|
var m map[string]string
|
|
c.Assert(t.dec.Decode(&m), IsNil)
|
|
c.Assert(m, DeepEquals, i.m)
|
|
}
|
|
}
|
|
|
|
func (t *MsgpackTest) TestStructNil(c *C) {
|
|
var dst *nameStruct
|
|
|
|
c.Assert(t.enc.Encode(nameStruct{Name: "foo"}), IsNil)
|
|
c.Assert(t.dec.Decode(&dst), IsNil)
|
|
c.Assert(dst, Not(IsNil))
|
|
c.Assert(dst.Name, Equals, "foo")
|
|
}
|
|
|
|
func (t *MsgpackTest) TestStructUnknownField(c *C) {
|
|
in := struct {
|
|
Field1 string
|
|
Field2 string
|
|
Field3 string
|
|
}{
|
|
Field1: "value1",
|
|
Field2: "value2",
|
|
Field3: "value3",
|
|
}
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
|
|
out := struct {
|
|
Field2 string
|
|
}{}
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Field2, Equals, "value2")
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
type coderStruct struct {
|
|
name string
|
|
}
|
|
|
|
type wrapperStruct struct {
|
|
coderStruct
|
|
}
|
|
|
|
var (
|
|
_ msgpack.CustomEncoder = (*coderStruct)(nil)
|
|
_ msgpack.CustomDecoder = (*coderStruct)(nil)
|
|
)
|
|
|
|
func (s *coderStruct) Name() string {
|
|
return s.name
|
|
}
|
|
|
|
func (s *coderStruct) EncodeMsgpack(enc *msgpack.Encoder) error {
|
|
return enc.Encode(s.name)
|
|
}
|
|
|
|
func (s *coderStruct) DecodeMsgpack(dec *msgpack.Decoder) error {
|
|
return dec.Decode(&s.name)
|
|
}
|
|
|
|
func (t *MsgpackTest) TestCoder(c *C) {
|
|
in := &coderStruct{name: "hello"}
|
|
var out coderStruct
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Name(), Equals, "hello")
|
|
}
|
|
|
|
func (t *MsgpackTest) TestNilCoder(c *C) {
|
|
in := &coderStruct{name: "hello"}
|
|
var out *coderStruct
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Name(), Equals, "hello")
|
|
}
|
|
|
|
func (t *MsgpackTest) TestNilCoderValue(c *C) {
|
|
in := &coderStruct{name: "hello"}
|
|
var out *coderStruct
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.DecodeValue(reflect.ValueOf(&out)), IsNil)
|
|
c.Assert(out.Name(), Equals, "hello")
|
|
}
|
|
|
|
func (t *MsgpackTest) TestPtrToCoder(c *C) {
|
|
in := &coderStruct{name: "hello"}
|
|
var out coderStruct
|
|
out2 := &out
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out2), IsNil)
|
|
c.Assert(out.Name(), Equals, "hello")
|
|
}
|
|
|
|
func (t *MsgpackTest) TestWrappedCoder(c *C) {
|
|
in := &wrapperStruct{coderStruct: coderStruct{name: "hello"}}
|
|
var out wrapperStruct
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Name(), Equals, "hello")
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
type struct2 struct {
|
|
Name string
|
|
}
|
|
|
|
type struct1 struct {
|
|
Name string
|
|
Struct2 struct2
|
|
}
|
|
|
|
func (t *MsgpackTest) TestNestedStructs(c *C) {
|
|
in := &struct1{Name: "hello", Struct2: struct2{Name: "world"}}
|
|
var out struct1
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out.Name, Equals, in.Name)
|
|
c.Assert(out.Struct2.Name, Equals, in.Struct2.Name)
|
|
}
|
|
|
|
type Struct4 struct {
|
|
Name2 string
|
|
}
|
|
|
|
type Struct3 struct {
|
|
Struct4
|
|
Name1 string
|
|
}
|
|
|
|
func TestEmbedding(t *testing.T) {
|
|
in := &Struct3{
|
|
Name1: "hello",
|
|
Struct4: Struct4{
|
|
Name2: "world",
|
|
},
|
|
}
|
|
var out Struct3
|
|
|
|
b, err := msgpack.Marshal(in)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = msgpack.Unmarshal(b, &out)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if out.Name1 != in.Name1 {
|
|
t.Fatalf("")
|
|
}
|
|
if out.Name2 != in.Name2 {
|
|
t.Fatalf("")
|
|
}
|
|
}
|
|
|
|
func (t *MsgpackTest) TestSliceNil(c *C) {
|
|
in := [][]*int{nil}
|
|
var out [][]*int
|
|
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
c.Assert(out, DeepEquals, in)
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
func (t *MsgpackTest) TestMapStringInterface(c *C) {
|
|
in := map[string]interface{}{
|
|
"foo": "bar",
|
|
"hello": map[string]interface{}{
|
|
"foo": "bar",
|
|
},
|
|
}
|
|
var out map[string]interface{}
|
|
|
|
c.Assert(t.enc.Encode(in), IsNil)
|
|
c.Assert(t.dec.Decode(&out), IsNil)
|
|
|
|
c.Assert(out["foo"], Equals, "bar")
|
|
mm := out["hello"].(map[string]interface{})
|
|
c.Assert(mm["foo"], Equals, "bar")
|
|
}
|