1package msgpack_test 2 3import ( 4 "bufio" 5 "bytes" 6 "reflect" 7 "testing" 8 "time" 9 10 . "gopkg.in/check.v1" 11 12 "github.com/vmihailenco/msgpack/v4" 13) 14 15type nameStruct struct { 16 Name string 17} 18 19func TestGocheck(t *testing.T) { TestingT(t) } 20 21type MsgpackTest struct { 22 buf *bytes.Buffer 23 enc *msgpack.Encoder 24 dec *msgpack.Decoder 25} 26 27var _ = Suite(&MsgpackTest{}) 28 29func (t *MsgpackTest) SetUpTest(c *C) { 30 t.buf = &bytes.Buffer{} 31 t.enc = msgpack.NewEncoder(t.buf) 32 t.dec = msgpack.NewDecoder(bufio.NewReader(t.buf)) 33} 34 35func (t *MsgpackTest) TestDecodeNil(c *C) { 36 c.Assert(t.dec.Decode(nil), NotNil) 37} 38 39func (t *MsgpackTest) TestTime(c *C) { 40 in := time.Now() 41 var out time.Time 42 c.Assert(t.enc.Encode(in), IsNil) 43 c.Assert(t.dec.Decode(&out), IsNil) 44 c.Assert(out.Equal(in), Equals, true) 45 46 var zero time.Time 47 c.Assert(t.enc.Encode(zero), IsNil) 48 c.Assert(t.dec.Decode(&out), IsNil) 49 c.Assert(out.Equal(zero), Equals, true) 50 c.Assert(out.IsZero(), Equals, true) 51} 52 53func (t *MsgpackTest) TestLargeBytes(c *C) { 54 N := int(1e6) 55 56 src := bytes.Repeat([]byte{'1'}, N) 57 c.Assert(t.enc.Encode(src), IsNil) 58 var dst []byte 59 c.Assert(t.dec.Decode(&dst), IsNil) 60 c.Assert(dst, DeepEquals, src) 61} 62 63func (t *MsgpackTest) TestLargeString(c *C) { 64 N := int(1e6) 65 66 src := string(bytes.Repeat([]byte{'1'}, N)) 67 c.Assert(t.enc.Encode(src), IsNil) 68 var dst string 69 c.Assert(t.dec.Decode(&dst), IsNil) 70 c.Assert(dst, Equals, src) 71} 72 73func (t *MsgpackTest) TestSliceOfStructs(c *C) { 74 in := []*nameStruct{&nameStruct{"hello"}} 75 var out []*nameStruct 76 c.Assert(t.enc.Encode(in), IsNil) 77 c.Assert(t.dec.Decode(&out), IsNil) 78 c.Assert(out, DeepEquals, in) 79} 80 81func (t *MsgpackTest) TestMap(c *C) { 82 for _, i := range []struct { 83 m map[string]string 84 b []byte 85 }{ 86 {map[string]string{}, []byte{0x80}}, 87 {map[string]string{"hello": "world"}, []byte{0x81, 0xa5, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xa5, 0x77, 0x6f, 0x72, 0x6c, 0x64}}, 88 } { 89 c.Assert(t.enc.Encode(i.m), IsNil) 90 c.Assert(t.buf.Bytes(), DeepEquals, i.b, Commentf("err encoding %v", i.m)) 91 var m map[string]string 92 c.Assert(t.dec.Decode(&m), IsNil) 93 c.Assert(m, DeepEquals, i.m) 94 } 95} 96 97func (t *MsgpackTest) TestStructNil(c *C) { 98 var dst *nameStruct 99 100 c.Assert(t.enc.Encode(nameStruct{Name: "foo"}), IsNil) 101 c.Assert(t.dec.Decode(&dst), IsNil) 102 c.Assert(dst, Not(IsNil)) 103 c.Assert(dst.Name, Equals, "foo") 104} 105 106func (t *MsgpackTest) TestStructUnknownField(c *C) { 107 in := struct { 108 Field1 string 109 Field2 string 110 Field3 string 111 }{ 112 Field1: "value1", 113 Field2: "value2", 114 Field3: "value3", 115 } 116 c.Assert(t.enc.Encode(in), IsNil) 117 118 out := struct { 119 Field2 string 120 }{} 121 c.Assert(t.dec.Decode(&out), IsNil) 122 c.Assert(out.Field2, Equals, "value2") 123} 124 125//------------------------------------------------------------------------------ 126 127type coderStruct struct { 128 name string 129} 130 131type wrapperStruct struct { 132 coderStruct 133} 134 135var ( 136 _ msgpack.CustomEncoder = (*coderStruct)(nil) 137 _ msgpack.CustomDecoder = (*coderStruct)(nil) 138) 139 140func (s *coderStruct) Name() string { 141 return s.name 142} 143 144func (s *coderStruct) EncodeMsgpack(enc *msgpack.Encoder) error { 145 return enc.Encode(s.name) 146} 147 148func (s *coderStruct) DecodeMsgpack(dec *msgpack.Decoder) error { 149 return dec.Decode(&s.name) 150} 151 152func (t *MsgpackTest) TestCoder(c *C) { 153 in := &coderStruct{name: "hello"} 154 var out coderStruct 155 c.Assert(t.enc.Encode(in), IsNil) 156 c.Assert(t.dec.Decode(&out), IsNil) 157 c.Assert(out.Name(), Equals, "hello") 158} 159 160func (t *MsgpackTest) TestNilCoder(c *C) { 161 in := &coderStruct{name: "hello"} 162 var out *coderStruct 163 c.Assert(t.enc.Encode(in), IsNil) 164 c.Assert(t.dec.Decode(&out), IsNil) 165 c.Assert(out.Name(), Equals, "hello") 166} 167 168func (t *MsgpackTest) TestNilCoderValue(c *C) { 169 in := &coderStruct{name: "hello"} 170 var out *coderStruct 171 c.Assert(t.enc.Encode(in), IsNil) 172 c.Assert(t.dec.DecodeValue(reflect.ValueOf(&out)), IsNil) 173 c.Assert(out.Name(), Equals, "hello") 174} 175 176func (t *MsgpackTest) TestPtrToCoder(c *C) { 177 in := &coderStruct{name: "hello"} 178 var out coderStruct 179 out2 := &out 180 c.Assert(t.enc.Encode(in), IsNil) 181 c.Assert(t.dec.Decode(&out2), IsNil) 182 c.Assert(out.Name(), Equals, "hello") 183} 184 185func (t *MsgpackTest) TestWrappedCoder(c *C) { 186 in := &wrapperStruct{coderStruct: coderStruct{name: "hello"}} 187 var out wrapperStruct 188 c.Assert(t.enc.Encode(in), IsNil) 189 c.Assert(t.dec.Decode(&out), IsNil) 190 c.Assert(out.Name(), Equals, "hello") 191} 192 193//------------------------------------------------------------------------------ 194 195type struct2 struct { 196 Name string 197} 198 199type struct1 struct { 200 Name string 201 Struct2 struct2 202} 203 204func (t *MsgpackTest) TestNestedStructs(c *C) { 205 in := &struct1{Name: "hello", Struct2: struct2{Name: "world"}} 206 var out struct1 207 c.Assert(t.enc.Encode(in), IsNil) 208 c.Assert(t.dec.Decode(&out), IsNil) 209 c.Assert(out.Name, Equals, in.Name) 210 c.Assert(out.Struct2.Name, Equals, in.Struct2.Name) 211} 212 213type Struct4 struct { 214 Name2 string 215} 216 217type Struct3 struct { 218 Struct4 219 Name1 string 220} 221 222func TestEmbedding(t *testing.T) { 223 in := &Struct3{ 224 Name1: "hello", 225 Struct4: Struct4{ 226 Name2: "world", 227 }, 228 } 229 var out Struct3 230 231 b, err := msgpack.Marshal(in) 232 if err != nil { 233 t.Fatal(err) 234 } 235 236 err = msgpack.Unmarshal(b, &out) 237 if err != nil { 238 t.Fatal(err) 239 } 240 if out.Name1 != in.Name1 { 241 t.Fatalf("") 242 } 243 if out.Name2 != in.Name2 { 244 t.Fatalf("") 245 } 246} 247 248func (t *MsgpackTest) TestSliceNil(c *C) { 249 in := [][]*int{nil} 250 var out [][]*int 251 252 c.Assert(t.enc.Encode(in), IsNil) 253 c.Assert(t.dec.Decode(&out), IsNil) 254 c.Assert(out, DeepEquals, in) 255} 256 257//------------------------------------------------------------------------------ 258 259func (t *MsgpackTest) TestMapStringInterface(c *C) { 260 in := map[string]interface{}{ 261 "foo": "bar", 262 "hello": map[string]interface{}{ 263 "foo": "bar", 264 }, 265 } 266 var out map[string]interface{} 267 268 c.Assert(t.enc.Encode(in), IsNil) 269 c.Assert(t.dec.Decode(&out), IsNil) 270 271 c.Assert(out["foo"], Equals, "bar") 272 mm := out["hello"].(map[string]interface{}) 273 c.Assert(mm["foo"], Equals, "bar") 274} 275