blob: 1c7e84f56a9faba719225cdeabca9d46d2c68e8b [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
3// Copyright 2010 Google Inc. All rights reserved.
4// http://code.google.com/p/goprotobuf/
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
Rob Pikeaaa3a622010-03-20 22:32:34 -070032package proto_test
33
34import (
35 "bytes"
Rob Pike022b1012011-11-08 16:33:51 -080036 "encoding/json"
Rob Pikeaaa3a622010-03-20 22:32:34 -070037 "fmt"
David Symondsb79d99b2011-08-29 16:38:49 +100038 "math"
David Symonds5b7775e2010-12-01 10:09:04 +110039 "reflect"
40 "strings"
Rob Pikeaaa3a622010-03-20 22:32:34 -070041 "testing"
42
Rob Pikeaaa3a622010-03-20 22:32:34 -070043 . "./testdata/_obj/test_proto"
Rob Pike3f6f2d82011-12-18 13:55:35 -080044 . "code.google.com/p/goprotobuf/proto"
Rob Pikeaaa3a622010-03-20 22:32:34 -070045)
46
47var globalO *Buffer
48
49func old() *Buffer {
50 if globalO == nil {
51 globalO = NewBuffer(nil)
52 }
53 globalO.Reset()
54 return globalO
55}
56
57func equalbytes(b1, b2 []byte, t *testing.T) {
58 if len(b1) != len(b2) {
59 t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2))
60 return
61 }
62 for i := 0; i < len(b1); i++ {
63 if b1[i] != b2[i] {
64 t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2)
65 }
66 }
67}
68
69func initGoTestField() *GoTestField {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070070 f := new(GoTestField)
Rob Pikeaaa3a622010-03-20 22:32:34 -070071 f.Label = String("label")
72 f.Type = String("type")
73 return f
74}
75
76// These are all structurally equivalent but the tag numbers differ.
77// (It's remarkable that required, optional, and repeated all have
78// 8 letters.)
79func initGoTest_RequiredGroup() *GoTest_RequiredGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070080 return &GoTest_RequiredGroup{
81 RequiredField: String("required"),
82 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070083}
84
85func initGoTest_OptionalGroup() *GoTest_OptionalGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070086 return &GoTest_OptionalGroup{
87 RequiredField: String("optional"),
88 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070089}
90
91func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070092 return &GoTest_RepeatedGroup{
93 RequiredField: String("repeated"),
94 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070095}
96
97func initGoTest(setdefaults bool) *GoTest {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070098 pb := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -070099 if setdefaults {
100 pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted)
101 pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted)
102 pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted)
103 pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted)
104 pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted)
105 pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted)
106 pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted)
107 pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted)
108 pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted)
109 pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted)
110 pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted
111 pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted)
112 pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
113 }
114
David Symondsdd9ca042011-08-29 16:07:16 +1000115 pb.Kind = NewGoTest_KIND(GoTest_TIME)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700116 pb.RequiredField = initGoTestField()
117 pb.F_BoolRequired = Bool(true)
118 pb.F_Int32Required = Int32(3)
119 pb.F_Int64Required = Int64(6)
120 pb.F_Fixed32Required = Uint32(32)
121 pb.F_Fixed64Required = Uint64(64)
122 pb.F_Uint32Required = Uint32(3232)
123 pb.F_Uint64Required = Uint64(6464)
124 pb.F_FloatRequired = Float32(3232)
125 pb.F_DoubleRequired = Float64(6464)
126 pb.F_StringRequired = String("string")
127 pb.F_BytesRequired = []byte("bytes")
128 pb.F_Sint32Required = Int32(-32)
129 pb.F_Sint64Required = Int64(-64)
130 pb.Requiredgroup = initGoTest_RequiredGroup()
131
132 return pb
133}
134
135func fail(msg string, b *bytes.Buffer, s string, t *testing.T) {
136 data := b.Bytes()
137 ld := len(data)
138 ls := len(s) / 2
139
140 fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls)
141
142 // find the interesting spot - n
143 n := ls
144 if ld < ls {
145 n = ld
146 }
147 j := 0
148 for i := 0; i < n; i++ {
149 bs := hex(s[j])*16 + hex(s[j+1])
150 j += 2
151 if data[i] == bs {
152 continue
153 }
154 n = i
155 break
156 }
157 l := n - 10
158 if l < 0 {
159 l = 0
160 }
161 h := n + 10
162
163 // find the interesting spot - n
164 fmt.Printf("is[%d]:", l)
165 for i := l; i < h; i++ {
166 if i >= ld {
167 fmt.Printf(" --")
168 continue
169 }
170 fmt.Printf(" %.2x", data[i])
171 }
172 fmt.Printf("\n")
173
174 fmt.Printf("sb[%d]:", l)
175 for i := l; i < h; i++ {
176 if i >= ls {
177 fmt.Printf(" --")
178 continue
179 }
180 bs := hex(s[j])*16 + hex(s[j+1])
181 j += 2
182 fmt.Printf(" %.2x", bs)
183 }
184 fmt.Printf("\n")
185
186 t.Fail()
187
Rob Pikeaaa3a622010-03-20 22:32:34 -0700188 // t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
189 // Print the output in a partially-decoded format; can
190 // be helpful when updating the test. It produces the output
191 // that is pasted, with minor edits, into the argument to verify().
192 // data := b.Bytes()
193 // nesting := 0
194 // for b.Len() > 0 {
195 // start := len(data) - b.Len()
196 // var u uint64
197 // u, err := DecodeVarint(b)
198 // if err != nil {
199 // fmt.Printf("decode error on varint:", err)
200 // return
201 // }
202 // wire := u & 0x7
203 // tag := u >> 3
204 // switch wire {
205 // case WireVarint:
206 // v, err := DecodeVarint(b)
207 // if err != nil {
208 // fmt.Printf("decode error on varint:", err)
209 // return
210 // }
211 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
212 // data[start:len(data)-b.Len()], tag, wire, v)
213 // case WireFixed32:
214 // v, err := DecodeFixed32(b)
215 // if err != nil {
216 // fmt.Printf("decode error on fixed32:", err)
217 // return
218 // }
219 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
220 // data[start:len(data)-b.Len()], tag, wire, v)
221 // case WireFixed64:
222 // v, err := DecodeFixed64(b)
223 // if err != nil {
224 // fmt.Printf("decode error on fixed64:", err)
225 // return
226 // }
227 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
228 // data[start:len(data)-b.Len()], tag, wire, v)
229 // case WireBytes:
230 // nb, err := DecodeVarint(b)
231 // if err != nil {
232 // fmt.Printf("decode error on bytes:", err)
233 // return
234 // }
235 // after_tag := len(data) - b.Len()
236 // str := make([]byte, nb)
237 // _, err = b.Read(str)
238 // if err != nil {
239 // fmt.Printf("decode error on bytes:", err)
240 // return
241 // }
242 // fmt.Printf("\t\t\"%x\" \"%x\" // field %d, encoding %d (FIELD)\n",
243 // data[start:after_tag], str, tag, wire)
244 // case WireStartGroup:
245 // nesting++
246 // fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
247 // data[start:len(data)-b.Len()], tag, nesting)
248 // case WireEndGroup:
249 // fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
250 // data[start:len(data)-b.Len()], tag, nesting)
251 // nesting--
252 // default:
253 // fmt.Printf("unrecognized wire type %d\n", wire)
254 // return
255 // }
256 // }
257}
258
259func hex(c uint8) uint8 {
260 if '0' <= c && c <= '9' {
261 return c - '0'
262 }
263 if 'a' <= c && c <= 'f' {
264 return 10 + c - 'a'
265 }
266 if 'A' <= c && c <= 'F' {
267 return 10 + c - 'A'
268 }
269 return 0
270}
271
272func equal(b []byte, s string, t *testing.T) bool {
273 if 2*len(b) != len(s) {
274 // fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t)
275 fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s))
276 return false
277 }
278 for i, j := 0, 0; i < len(b); i, j = i+1, j+2 {
279 x := hex(s[j])*16 + hex(s[j+1])
280 if b[i] != x {
281 // fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t)
282 fmt.Printf("bad byte[%d]:%x %x", i, b[i], x)
283 return false
284 }
285 }
286 return true
287}
288
289func overify(t *testing.T, pb *GoTest, expected string) {
290 o := old()
291 err := o.Marshal(pb)
292 if err != nil {
293 fmt.Printf("overify marshal-1 err = %v", err)
294 o.DebugPrint("", o.Bytes())
295 t.Fatalf("expected = %s", expected)
296 }
297 if !equal(o.Bytes(), expected, t) {
298 o.DebugPrint("overify neq 1", o.Bytes())
299 t.Fatalf("expected = %s", expected)
300 }
301
302 // Now test Unmarshal by recreating the original buffer.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700303 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700304 err = o.Unmarshal(pbd)
305 if err != nil {
306 t.Fatalf("overify unmarshal err = %v", err)
307 o.DebugPrint("", o.Bytes())
308 t.Fatalf("string = %s", expected)
309 }
310 o.Reset()
311 err = o.Marshal(pbd)
312 if err != nil {
313 t.Errorf("overify marshal-2 err = %v", err)
314 o.DebugPrint("", o.Bytes())
315 t.Fatalf("string = %s", expected)
316 }
317 if !equal(o.Bytes(), expected, t) {
318 o.DebugPrint("overify neq 2", o.Bytes())
319 t.Fatalf("string = %s", expected)
320 }
321}
322
323// Simple tests for numeric encode/decode primitives (varint, etc.)
324func TestNumericPrimitives(t *testing.T) {
325 for i := uint64(0); i < 1e6; i += 111 {
326 o := old()
327 if o.EncodeVarint(i) != nil {
328 t.Error("EncodeVarint")
329 break
330 }
331 x, e := o.DecodeVarint()
332 if e != nil {
333 t.Fatal("DecodeVarint")
334 }
335 if x != i {
336 t.Fatal("varint decode fail:", i, x)
337 }
338
339 o = old()
340 if o.EncodeFixed32(i) != nil {
341 t.Fatal("encFixed32")
342 }
343 x, e = o.DecodeFixed32()
344 if e != nil {
345 t.Fatal("decFixed32")
346 }
347 if x != i {
348 t.Fatal("fixed32 decode fail:", i, x)
349 }
350
351 o = old()
352 if o.EncodeFixed64(i*1234567) != nil {
353 t.Error("encFixed64")
354 break
355 }
356 x, e = o.DecodeFixed64()
357 if e != nil {
358 t.Error("decFixed64")
359 break
360 }
361 if x != i*1234567 {
362 t.Error("fixed64 decode fail:", i*1234567, x)
363 break
364 }
365
366 o = old()
367 i32 := int32(i - 12345)
368 if o.EncodeZigzag32(uint64(i32)) != nil {
369 t.Fatal("EncodeZigzag32")
370 }
371 x, e = o.DecodeZigzag32()
372 if e != nil {
373 t.Fatal("DecodeZigzag32")
374 }
375 if x != uint64(uint32(i32)) {
376 t.Fatal("zigzag32 decode fail:", i32, x)
377 }
378
379 o = old()
380 i64 := int64(i - 12345)
381 if o.EncodeZigzag64(uint64(i64)) != nil {
382 t.Fatal("EncodeZigzag64")
383 }
384 x, e = o.DecodeZigzag64()
385 if e != nil {
386 t.Fatal("DecodeZigzag64")
387 }
388 if x != uint64(i64) {
389 t.Fatal("zigzag64 decode fail:", i64, x)
390 }
391 }
392}
393
394// Simple tests for bytes
395func TestBytesPrimitives(t *testing.T) {
396 o := old()
397 bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'}
398 if o.EncodeRawBytes(bytes) != nil {
399 t.Error("EncodeRawBytes")
400 }
401 decb, e := o.DecodeRawBytes(false)
402 if e != nil {
403 t.Error("DecodeRawBytes")
404 }
405 equalbytes(bytes, decb, t)
406}
407
408// Simple tests for strings
409func TestStringPrimitives(t *testing.T) {
410 o := old()
411 s := "now is the time"
412 if o.EncodeStringBytes(s) != nil {
413 t.Error("enc_string")
414 }
415 decs, e := o.DecodeStringBytes()
416 if e != nil {
417 t.Error("dec_string")
418 }
419 if s != decs {
420 t.Error("string encode/decode fail:", s, decs)
421 }
422}
423
424// Do we catch the "required bit not set" case?
425func TestRequiredBit(t *testing.T) {
426 o := old()
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700427 pb := new(GoTest)
David Symonds5b7775e2010-12-01 10:09:04 +1100428 err := o.Marshal(pb)
429 if err == nil {
430 t.Error("did not catch missing required fields")
Rob Pikea17fdd92011-11-02 12:43:05 -0700431 } else if strings.Index(err.Error(), "GoTest") < 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100432 t.Error("wrong error type:", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700433 }
434}
435
436// Check that all fields are nil.
437// Clearly silly, and a residue from a more interesting test with an earlier,
438// different initialization property, but it once caught a compiler bug so
439// it lives.
440func checkInitialized(pb *GoTest, t *testing.T) {
441 if pb.F_BoolDefaulted != nil {
442 t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted)
443 }
444 if pb.F_Int32Defaulted != nil {
445 t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted)
446 }
447 if pb.F_Int64Defaulted != nil {
448 t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted)
449 }
450 if pb.F_Fixed32Defaulted != nil {
451 t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted)
452 }
453 if pb.F_Fixed64Defaulted != nil {
454 t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted)
455 }
456 if pb.F_Uint32Defaulted != nil {
457 t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted)
458 }
459 if pb.F_Uint64Defaulted != nil {
460 t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted)
461 }
462 if pb.F_FloatDefaulted != nil {
463 t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted)
464 }
465 if pb.F_DoubleDefaulted != nil {
466 t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted)
467 }
468 if pb.F_StringDefaulted != nil {
469 t.Error("New or Reset did not set string:", *pb.F_StringDefaulted)
470 }
471 if pb.F_BytesDefaulted != nil {
472 t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted))
473 }
474 if pb.F_Sint32Defaulted != nil {
475 t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted)
476 }
477 if pb.F_Sint64Defaulted != nil {
478 t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted)
479 }
480}
481
482// Does Reset() reset?
483func TestReset(t *testing.T) {
484 pb := initGoTest(true)
485 // muck with some values
486 pb.F_BoolDefaulted = Bool(false)
487 pb.F_Int32Defaulted = Int32(237)
488 pb.F_Int64Defaulted = Int64(12346)
489 pb.F_Fixed32Defaulted = Uint32(32000)
490 pb.F_Fixed64Defaulted = Uint64(666)
491 pb.F_Uint32Defaulted = Uint32(323232)
492 pb.F_Uint64Defaulted = nil
493 pb.F_FloatDefaulted = nil
494 pb.F_DoubleDefaulted = Float64(0)
495 pb.F_StringDefaulted = String("gotcha")
496 pb.F_BytesDefaulted = []byte("asdfasdf")
497 pb.F_Sint32Defaulted = Int32(123)
498 pb.F_Sint64Defaulted = Int64(789)
499 pb.Reset()
500 checkInitialized(pb, t)
501}
502
503// All required fields set, no defaults provided.
504func TestEncodeDecode1(t *testing.T) {
505 pb := initGoTest(false)
506 overify(t, pb,
507 "0807"+ // field 1, encoding 0, value 7
508 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
509 "5001"+ // field 10, encoding 0, value 1
510 "5803"+ // field 11, encoding 0, value 3
511 "6006"+ // field 12, encoding 0, value 6
512 "6d20000000"+ // field 13, encoding 5, value 0x20
513 "714000000000000000"+ // field 14, encoding 1, value 0x40
514 "78a019"+ // field 15, encoding 0, value 0xca0 = 3232
515 "8001c032"+ // field 16, encoding 0, value 0x1940 = 6464
516 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
517 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
518 "9a0106"+"737472696e67"+ // field 19, encoding 2, string "string"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700519 "b304"+ // field 70, encoding 3, start group
520 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
David Symondsd15e81b2011-10-03 14:31:12 -0700521 "b404"+ // field 70, encoding 4, end group
522 "aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes"
523 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
524 "b8067f") // field 103, encoding 0, 0x7f zigzag64
Rob Pikeaaa3a622010-03-20 22:32:34 -0700525}
526
527// All required fields set, defaults provided.
528func TestEncodeDecode2(t *testing.T) {
529 pb := initGoTest(true)
530 overify(t, pb,
531 "0807"+ // field 1, encoding 0, value 7
532 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
533 "5001"+ // field 10, encoding 0, value 1
534 "5803"+ // field 11, encoding 0, value 3
535 "6006"+ // field 12, encoding 0, value 6
536 "6d20000000"+ // field 13, encoding 5, value 32
537 "714000000000000000"+ // field 14, encoding 1, value 64
538 "78a019"+ // field 15, encoding 0, value 3232
539 "8001c032"+ // field 16, encoding 0, value 6464
540 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
541 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
542 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700543 "c00201"+ // field 40, encoding 0, value 1
544 "c80220"+ // field 41, encoding 0, value 32
545 "d00240"+ // field 42, encoding 0, value 64
546 "dd0240010000"+ // field 43, encoding 5, value 320
547 "e1028002000000000000"+ // field 44, encoding 1, value 640
548 "e8028019"+ // field 45, encoding 0, value 3200
549 "f0028032"+ // field 46, encoding 0, value 6400
550 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
551 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
552 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700553 "b304"+ // start group field 70 level 1
554 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
David Symondsd15e81b2011-10-03 14:31:12 -0700555 "b404"+ // end group field 70 level 1
556 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
557 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
558 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
559 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
560 "90193f"+ // field 402, encoding 0, value 63
561 "98197f") // field 403, encoding 0, value 127
Rob Pikeaaa3a622010-03-20 22:32:34 -0700562
563}
564
565// All default fields set to their default value by hand
566func TestEncodeDecode3(t *testing.T) {
567 pb := initGoTest(false)
568 pb.F_BoolDefaulted = Bool(true)
569 pb.F_Int32Defaulted = Int32(32)
570 pb.F_Int64Defaulted = Int64(64)
571 pb.F_Fixed32Defaulted = Uint32(320)
572 pb.F_Fixed64Defaulted = Uint64(640)
573 pb.F_Uint32Defaulted = Uint32(3200)
574 pb.F_Uint64Defaulted = Uint64(6400)
575 pb.F_FloatDefaulted = Float32(314159)
576 pb.F_DoubleDefaulted = Float64(271828)
577 pb.F_StringDefaulted = String("hello, \"world!\"\n")
578 pb.F_BytesDefaulted = []byte("Bignose")
579 pb.F_Sint32Defaulted = Int32(-32)
580 pb.F_Sint64Defaulted = Int64(-64)
581
582 overify(t, pb,
583 "0807"+ // field 1, encoding 0, value 7
584 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
585 "5001"+ // field 10, encoding 0, value 1
586 "5803"+ // field 11, encoding 0, value 3
587 "6006"+ // field 12, encoding 0, value 6
588 "6d20000000"+ // field 13, encoding 5, value 32
589 "714000000000000000"+ // field 14, encoding 1, value 64
590 "78a019"+ // field 15, encoding 0, value 3232
591 "8001c032"+ // field 16, encoding 0, value 6464
592 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
593 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
594 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700595 "c00201"+ // field 40, encoding 0, value 1
596 "c80220"+ // field 41, encoding 0, value 32
597 "d00240"+ // field 42, encoding 0, value 64
598 "dd0240010000"+ // field 43, encoding 5, value 320
599 "e1028002000000000000"+ // field 44, encoding 1, value 640
600 "e8028019"+ // field 45, encoding 0, value 3200
601 "f0028032"+ // field 46, encoding 0, value 6400
602 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
603 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
604 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700605 "b304"+ // start group field 70 level 1
606 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
David Symondsd15e81b2011-10-03 14:31:12 -0700607 "b404"+ // end group field 70 level 1
608 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
609 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
610 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
611 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
612 "90193f"+ // field 402, encoding 0, value 63
613 "98197f") // field 403, encoding 0, value 127
Rob Pikeaaa3a622010-03-20 22:32:34 -0700614
615}
616
617// All required fields set, defaults provided, all non-defaulted optional fields have values.
618func TestEncodeDecode4(t *testing.T) {
619 pb := initGoTest(true)
620 pb.Table = String("hello")
621 pb.Param = Int32(7)
622 pb.OptionalField = initGoTestField()
623 pb.F_BoolOptional = Bool(true)
624 pb.F_Int32Optional = Int32(32)
625 pb.F_Int64Optional = Int64(64)
626 pb.F_Fixed32Optional = Uint32(3232)
627 pb.F_Fixed64Optional = Uint64(6464)
628 pb.F_Uint32Optional = Uint32(323232)
629 pb.F_Uint64Optional = Uint64(646464)
630 pb.F_FloatOptional = Float32(32.)
631 pb.F_DoubleOptional = Float64(64.)
632 pb.F_StringOptional = String("hello")
633 pb.F_BytesOptional = []byte("Bignose")
634 pb.F_Sint32Optional = Int32(-32)
635 pb.F_Sint64Optional = Int64(-64)
636 pb.Optionalgroup = initGoTest_OptionalGroup()
637
638 overify(t, pb,
639 "0807"+ // field 1, encoding 0, value 7
640 "1205"+"68656c6c6f"+ // field 2, encoding 2, string "hello"
641 "1807"+ // field 3, encoding 0, value 7
642 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
643 "320d"+"0a056c6162656c120474797065"+ // field 6, encoding 2 (GoTestField)
644 "5001"+ // field 10, encoding 0, value 1
645 "5803"+ // field 11, encoding 0, value 3
646 "6006"+ // field 12, encoding 0, value 6
647 "6d20000000"+ // field 13, encoding 5, value 32
648 "714000000000000000"+ // field 14, encoding 1, value 64
649 "78a019"+ // field 15, encoding 0, value 3232
650 "8001c032"+ // field 16, encoding 0, value 6464
651 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
652 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
653 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700654 "f00101"+ // field 30, encoding 0, value 1
655 "f80120"+ // field 31, encoding 0, value 32
656 "800240"+ // field 32, encoding 0, value 64
657 "8d02a00c0000"+ // field 33, encoding 5, value 3232
658 "91024019000000000000"+ // field 34, encoding 1, value 6464
659 "9802a0dd13"+ // field 35, encoding 0, value 323232
660 "a002c0ba27"+ // field 36, encoding 0, value 646464
661 "ad0200000042"+ // field 37, encoding 5, value 32.0
662 "b1020000000000005040"+ // field 38, encoding 1, value 64.0
663 "ba0205"+"68656c6c6f"+ // field 39, encoding 2, string "hello"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700664 "c00201"+ // field 40, encoding 0, value 1
665 "c80220"+ // field 41, encoding 0, value 32
666 "d00240"+ // field 42, encoding 0, value 64
667 "dd0240010000"+ // field 43, encoding 5, value 320
668 "e1028002000000000000"+ // field 44, encoding 1, value 640
669 "e8028019"+ // field 45, encoding 0, value 3200
670 "f0028032"+ // field 46, encoding 0, value 6400
671 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
672 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
673 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700674 "b304"+ // start group field 70 level 1
675 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
676 "b404"+ // end group field 70 level 1
677 "d305"+ // start group field 90 level 1
678 "da0508"+"6f7074696f6e616c"+ // field 91, encoding 2, string "optional"
David Symondsd15e81b2011-10-03 14:31:12 -0700679 "d405"+ // end group field 90 level 1
680 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
681 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
682 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
683 "ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose"
684 "f0123f"+ // field 302, encoding 0, value 63
685 "f8127f"+ // field 303, encoding 0, value 127
686 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
687 "90193f"+ // field 402, encoding 0, value 63
688 "98197f") // field 403, encoding 0, value 127
Rob Pikeaaa3a622010-03-20 22:32:34 -0700689
690}
691
692// All required fields set, defaults provided, all repeated fields given two values.
693func TestEncodeDecode5(t *testing.T) {
694 pb := initGoTest(true)
695 pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()}
696 pb.F_BoolRepeated = []bool{false, true}
697 pb.F_Int32Repeated = []int32{32, 33}
698 pb.F_Int64Repeated = []int64{64, 65}
699 pb.F_Fixed32Repeated = []uint32{3232, 3333}
700 pb.F_Fixed64Repeated = []uint64{6464, 6565}
701 pb.F_Uint32Repeated = []uint32{323232, 333333}
702 pb.F_Uint64Repeated = []uint64{646464, 656565}
703 pb.F_FloatRepeated = []float32{32., 33.}
704 pb.F_DoubleRepeated = []float64{64., 65.}
705 pb.F_StringRepeated = []string{"hello", "sailor"}
706 pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")}
707 pb.F_Sint32Repeated = []int32{32, -32}
708 pb.F_Sint64Repeated = []int64{64, -64}
709 pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()}
710
711 overify(t, pb,
712 "0807"+ // field 1, encoding 0, value 7
713 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
714 "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
715 "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
716 "5001"+ // field 10, encoding 0, value 1
717 "5803"+ // field 11, encoding 0, value 3
718 "6006"+ // field 12, encoding 0, value 6
719 "6d20000000"+ // field 13, encoding 5, value 32
720 "714000000000000000"+ // field 14, encoding 1, value 64
721 "78a019"+ // field 15, encoding 0, value 3232
722 "8001c032"+ // field 16, encoding 0, value 6464
723 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
724 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
725 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700726 "a00100"+ // field 20, encoding 0, value 0
727 "a00101"+ // field 20, encoding 0, value 1
728 "a80120"+ // field 21, encoding 0, value 32
729 "a80121"+ // field 21, encoding 0, value 33
730 "b00140"+ // field 22, encoding 0, value 64
731 "b00141"+ // field 22, encoding 0, value 65
732 "bd01a00c0000"+ // field 23, encoding 5, value 3232
733 "bd01050d0000"+ // field 23, encoding 5, value 3333
734 "c1014019000000000000"+ // field 24, encoding 1, value 6464
735 "c101a519000000000000"+ // field 24, encoding 1, value 6565
736 "c801a0dd13"+ // field 25, encoding 0, value 323232
737 "c80195ac14"+ // field 25, encoding 0, value 333333
738 "d001c0ba27"+ // field 26, encoding 0, value 646464
739 "d001b58928"+ // field 26, encoding 0, value 656565
740 "dd0100000042"+ // field 27, encoding 5, value 32.0
741 "dd0100000442"+ // field 27, encoding 5, value 33.0
742 "e1010000000000005040"+ // field 28, encoding 1, value 64.0
743 "e1010000000000405040"+ // field 28, encoding 1, value 65.0
744 "ea0105"+"68656c6c6f"+ // field 29, encoding 2, string "hello"
745 "ea0106"+"7361696c6f72"+ // field 29, encoding 2, string "sailor"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700746 "c00201"+ // field 40, encoding 0, value 1
747 "c80220"+ // field 41, encoding 0, value 32
748 "d00240"+ // field 42, encoding 0, value 64
749 "dd0240010000"+ // field 43, encoding 5, value 320
750 "e1028002000000000000"+ // field 44, encoding 1, value 640
751 "e8028019"+ // field 45, encoding 0, value 3200
752 "f0028032"+ // field 46, encoding 0, value 6400
753 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
754 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
755 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700756 "b304"+ // start group field 70 level 1
757 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
758 "b404"+ // end group field 70 level 1
759 "8305"+ // start group field 80 level 1
760 "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
761 "8405"+ // end group field 80 level 1
762 "8305"+ // start group field 80 level 1
763 "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
David Symondsd15e81b2011-10-03 14:31:12 -0700764 "8405"+ // end group field 80 level 1
765 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
766 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
767 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
768 "ca0c03"+"626967"+ // field 201, encoding 2, string "big"
769 "ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose"
770 "d00c40"+ // field 202, encoding 0, value 32
771 "d00c3f"+ // field 202, encoding 0, value -32
772 "d80c8001"+ // field 203, encoding 0, value 64
773 "d80c7f"+ // field 203, encoding 0, value -64
774 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
775 "90193f"+ // field 402, encoding 0, value 63
776 "98197f") // field 403, encoding 0, value 127
Rob Pikeaaa3a622010-03-20 22:32:34 -0700777
778}
779
David Symonds5b7775e2010-12-01 10:09:04 +1100780// All required fields set, all packed repeated fields given two values.
781func TestEncodeDecode6(t *testing.T) {
782 pb := initGoTest(false)
783 pb.F_BoolRepeatedPacked = []bool{false, true}
784 pb.F_Int32RepeatedPacked = []int32{32, 33}
785 pb.F_Int64RepeatedPacked = []int64{64, 65}
786 pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333}
787 pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565}
788 pb.F_Uint32RepeatedPacked = []uint32{323232, 333333}
789 pb.F_Uint64RepeatedPacked = []uint64{646464, 656565}
790 pb.F_FloatRepeatedPacked = []float32{32., 33.}
791 pb.F_DoubleRepeatedPacked = []float64{64., 65.}
792 pb.F_Sint32RepeatedPacked = []int32{32, -32}
793 pb.F_Sint64RepeatedPacked = []int64{64, -64}
794
795 overify(t, pb,
796 "0807"+ // field 1, encoding 0, value 7
797 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
798 "5001"+ // field 10, encoding 0, value 1
799 "5803"+ // field 11, encoding 0, value 3
800 "6006"+ // field 12, encoding 0, value 6
801 "6d20000000"+ // field 13, encoding 5, value 32
802 "714000000000000000"+ // field 14, encoding 1, value 64
803 "78a019"+ // field 15, encoding 0, value 3232
804 "8001c032"+ // field 16, encoding 0, value 6464
805 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
806 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
807 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
David Symonds5b7775e2010-12-01 10:09:04 +1100808 "9203020001"+ // field 50, encoding 2, 2 bytes, value 0, value 1
809 "9a03022021"+ // field 51, encoding 2, 2 bytes, value 32, value 33
810 "a203024041"+ // field 52, encoding 2, 2 bytes, value 64, value 65
811 "aa0308"+ // field 53, encoding 2, 8 bytes
812 "a00c0000050d0000"+ // value 3232, value 3333
813 "b20310"+ // field 54, encoding 2, 16 bytes
814 "4019000000000000a519000000000000"+ // value 6464, value 6565
815 "ba0306"+ // field 55, encoding 2, 6 bytes
816 "a0dd1395ac14"+ // value 323232, value 333333
817 "c20306"+ // field 56, encoding 2, 6 bytes
818 "c0ba27b58928"+ // value 646464, value 656565
819 "ca0308"+ // field 57, encoding 2, 8 bytes
820 "0000004200000442"+ // value 32.0, value 33.0
821 "d20310"+ // field 58, encoding 2, 16 bytes
822 "00000000000050400000000000405040"+ // value 64.0, value 65.0
David Symondsd15e81b2011-10-03 14:31:12 -0700823 "b304"+ // start group field 70 level 1
824 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
825 "b404"+ // end group field 70 level 1
826 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
827 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
828 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
David Symonds5b7775e2010-12-01 10:09:04 +1100829 "b21f02"+ // field 502, encoding 2, 2 bytes
830 "403f"+ // value 32, value -32
831 "ba1f03"+ // field 503, encoding 2, 3 bytes
David Symondsd15e81b2011-10-03 14:31:12 -0700832 "80017f") // value 64, value -64
David Symonds5b7775e2010-12-01 10:09:04 +1100833}
834
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800835// Test that we can encode empty bytes fields.
836func TestEncodeDecodeBytes1(t *testing.T) {
837 pb := initGoTest(false)
838
839 // Create our bytes
840 pb.F_BytesRequired = []byte{}
David Symondsd9da6ba2011-08-30 14:41:30 +1000841 pb.F_BytesRepeated = [][]byte{{}}
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800842 pb.F_BytesOptional = []byte{}
843
844 d, err := Marshal(pb)
845 if err != nil {
Rob Pikea17fdd92011-11-02 12:43:05 -0700846 t.Error(err)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800847 }
848
849 pbd := new(GoTest)
850 if err := Unmarshal(d, pbd); err != nil {
Rob Pikea17fdd92011-11-02 12:43:05 -0700851 t.Error(err)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800852 }
853
854 if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 {
Rob Pikea17fdd92011-11-02 12:43:05 -0700855 t.Error("required empty bytes field is incorrect")
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800856 }
857 if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil {
Rob Pikea17fdd92011-11-02 12:43:05 -0700858 t.Error("repeated empty bytes field is incorrect")
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800859 }
860 if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 {
Rob Pikea17fdd92011-11-02 12:43:05 -0700861 t.Error("optional empty bytes field is incorrect")
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800862 }
863}
864
865// Test that we encode nil-valued fields of a repeated bytes field correctly.
866// Since entries in a repeated field cannot be nil, nil must mean empty value.
867func TestEncodeDecodeBytes2(t *testing.T) {
868 pb := initGoTest(false)
869
870 // Create our bytes
David Symonds5b7775e2010-12-01 10:09:04 +1100871 pb.F_BytesRepeated = [][]byte{nil}
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800872
873 d, err := Marshal(pb)
David Symonds5b7775e2010-12-01 10:09:04 +1100874 if err != nil {
Rob Pikea17fdd92011-11-02 12:43:05 -0700875 t.Error(err)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800876 }
877
878 pbd := new(GoTest)
879 if err := Unmarshal(d, pbd); err != nil {
Rob Pikea17fdd92011-11-02 12:43:05 -0700880 t.Error(err)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800881 }
882
883 if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil {
Rob Pikea17fdd92011-11-02 12:43:05 -0700884 t.Error("Unexpected value for repeated bytes field")
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800885 }
886}
887
Rob Pikeaaa3a622010-03-20 22:32:34 -0700888// All required fields set, defaults provided, all repeated fields given two values.
889func TestSkippingUnrecognizedFields(t *testing.T) {
890 o := old()
891 pb := initGoTestField()
892
893 // Marshal it normally.
894 o.Marshal(pb)
895
896 // Now new a GoSkipTest record.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700897 skip := &GoSkipTest{
898 SkipInt32: Int32(32),
899 SkipFixed32: Uint32(3232),
900 SkipFixed64: Uint64(6464),
901 SkipString: String("skipper"),
902 Skipgroup: &GoSkipTest_SkipGroup{
903 GroupInt32: Int32(75),
904 GroupString: String("wxyz"),
905 },
906 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700907
908 // Marshal it into same buffer.
909 o.Marshal(skip)
910
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700911 pbd := new(GoTestField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700912 o.Unmarshal(pbd)
913
914 // The __unrecognized field should be a marshaling of GoSkipTest
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700915 skipd := new(GoSkipTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700916
917 o.SetBuf(pbd.XXX_unrecognized)
918 o.Unmarshal(skipd)
919
920 if *skipd.SkipInt32 != *skip.SkipInt32 {
921 t.Error("skip int32", skipd.SkipInt32)
922 }
923 if *skipd.SkipFixed32 != *skip.SkipFixed32 {
924 t.Error("skip fixed32", skipd.SkipFixed32)
925 }
926 if *skipd.SkipFixed64 != *skip.SkipFixed64 {
927 t.Error("skip fixed64", skipd.SkipFixed64)
928 }
929 if *skipd.SkipString != *skip.SkipString {
930 t.Error("skip string", *skipd.SkipString)
931 }
932 if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 {
933 t.Error("skip group int32", skipd.Skipgroup.GroupInt32)
934 }
935 if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString {
936 t.Error("skip group string", *skipd.Skipgroup.GroupString)
937 }
938}
939
940// Check that we can grow an array (repeated field) to have many elements.
941// This test doesn't depend only on our encoding; for variety, it makes sure
942// we create, encode, and decode the correct contents explicitly. It's therefore
943// a bit messier.
944// This test also uses (and hence tests) the Marshal/Unmarshal functions
945// instead of the methods.
946func TestBigRepeated(t *testing.T) {
947 pb := initGoTest(true)
948
949 // Create the arrays
950 const N = 50 // Internally the library starts much smaller.
951 pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N)
952 pb.F_Sint64Repeated = make([]int64, N)
953 pb.F_Sint32Repeated = make([]int32, N)
954 pb.F_BytesRepeated = make([][]byte, N)
955 pb.F_StringRepeated = make([]string, N)
956 pb.F_DoubleRepeated = make([]float64, N)
957 pb.F_FloatRepeated = make([]float32, N)
958 pb.F_Uint64Repeated = make([]uint64, N)
959 pb.F_Uint32Repeated = make([]uint32, N)
960 pb.F_Fixed64Repeated = make([]uint64, N)
961 pb.F_Fixed32Repeated = make([]uint32, N)
962 pb.F_Int64Repeated = make([]int64, N)
963 pb.F_Int32Repeated = make([]int32, N)
964 pb.F_BoolRepeated = make([]bool, N)
965 pb.RepeatedField = make([]*GoTestField, N)
966
967 // Fill in the arrays with checkable values.
968 igtf := initGoTestField()
969 igtrg := initGoTest_RepeatedGroup()
970 for i := 0; i < N; i++ {
971 pb.Repeatedgroup[i] = igtrg
972 pb.F_Sint64Repeated[i] = int64(i)
973 pb.F_Sint32Repeated[i] = int32(i)
974 s := fmt.Sprint(i)
975 pb.F_BytesRepeated[i] = []byte(s)
976 pb.F_StringRepeated[i] = s
977 pb.F_DoubleRepeated[i] = float64(i)
978 pb.F_FloatRepeated[i] = float32(i)
979 pb.F_Uint64Repeated[i] = uint64(i)
980 pb.F_Uint32Repeated[i] = uint32(i)
981 pb.F_Fixed64Repeated[i] = uint64(i)
982 pb.F_Fixed32Repeated[i] = uint32(i)
983 pb.F_Int64Repeated[i] = int64(i)
984 pb.F_Int32Repeated[i] = int32(i)
985 pb.F_BoolRepeated[i] = i%2 == 0
986 pb.RepeatedField[i] = igtf
987 }
988
989 // Marshal.
990 buf, _ := Marshal(pb)
991
992 // Now test Unmarshal by recreating the original buffer.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700993 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700994 Unmarshal(buf, pbd)
995
996 // Check the checkable values
997 for i := uint64(0); i < N; i++ {
998 if pbd.Repeatedgroup[i] == nil { // TODO: more checking?
999 t.Error("pbd.Repeatedgroup bad")
1000 }
1001 var x uint64
1002 x = uint64(pbd.F_Sint64Repeated[i])
1003 if x != i {
1004 t.Error("pbd.F_Sint64Repeated bad", x, i)
1005 }
1006 x = uint64(pbd.F_Sint32Repeated[i])
1007 if x != i {
1008 t.Error("pbd.F_Sint32Repeated bad", x, i)
1009 }
1010 s := fmt.Sprint(i)
1011 equalbytes(pbd.F_BytesRepeated[i], []byte(s), t)
1012 if pbd.F_StringRepeated[i] != s {
1013 t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i)
1014 }
1015 x = uint64(pbd.F_DoubleRepeated[i])
1016 if x != i {
1017 t.Error("pbd.F_DoubleRepeated bad", x, i)
1018 }
1019 x = uint64(pbd.F_FloatRepeated[i])
1020 if x != i {
1021 t.Error("pbd.F_FloatRepeated bad", x, i)
1022 }
1023 x = pbd.F_Uint64Repeated[i]
1024 if x != i {
1025 t.Error("pbd.F_Uint64Repeated bad", x, i)
1026 }
1027 x = uint64(pbd.F_Uint32Repeated[i])
1028 if x != i {
1029 t.Error("pbd.F_Uint32Repeated bad", x, i)
1030 }
1031 x = pbd.F_Fixed64Repeated[i]
1032 if x != i {
1033 t.Error("pbd.F_Fixed64Repeated bad", x, i)
1034 }
1035 x = uint64(pbd.F_Fixed32Repeated[i])
1036 if x != i {
1037 t.Error("pbd.F_Fixed32Repeated bad", x, i)
1038 }
1039 x = uint64(pbd.F_Int64Repeated[i])
1040 if x != i {
1041 t.Error("pbd.F_Int64Repeated bad", x, i)
1042 }
1043 x = uint64(pbd.F_Int32Repeated[i])
1044 if x != i {
1045 t.Error("pbd.F_Int32Repeated bad", x, i)
1046 }
1047 if pbd.F_BoolRepeated[i] != (i%2 == 0) {
1048 t.Error("pbd.F_BoolRepeated bad", x, i)
1049 }
1050 if pbd.RepeatedField[i] == nil { // TODO: more checking?
1051 t.Error("pbd.RepeatedField bad")
1052 }
1053 }
1054}
1055
1056// Verify we give a useful message when decoding to the wrong structure type.
1057func TestTypeMismatch(t *testing.T) {
1058 pb1 := initGoTest(true)
1059
1060 // Marshal
1061 o := old()
1062 o.Marshal(pb1)
1063
1064 // Now Unmarshal it to the wrong type.
1065 pb2 := initGoTestField()
1066 err := o.Unmarshal(pb2)
1067 switch err {
1068 case ErrWrongType:
1069 // fine
1070 case nil:
1071 t.Error("expected wrong type error, got no error")
1072 default:
1073 t.Error("expected wrong type error, got", err)
1074 }
1075}
1076
David Symonds5b7775e2010-12-01 10:09:04 +11001077func encodeDecode(t *testing.T, in, out interface{}, msg string) {
1078 buf, err := Marshal(in)
1079 if err != nil {
1080 t.Fatalf("failed marshaling %v: %v", msg, err)
1081 }
1082 if err := Unmarshal(buf, out); err != nil {
1083 t.Fatalf("failed unmarshaling %v: %v", msg, err)
1084 }
1085}
1086
1087func TestPackedNonPackedDecoderSwitching(t *testing.T) {
1088 np, p := new(NonPackedTest), new(PackedTest)
1089
1090 // non-packed -> packed
1091 np.A = []int32{0, 1, 1, 2, 3, 5}
1092 encodeDecode(t, np, p, "non-packed -> packed")
1093 if !reflect.DeepEqual(np.A, p.B) {
1094 t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B)
1095 }
1096
1097 // packed -> non-packed
1098 np.Reset()
1099 p.B = []int32{3, 1, 4, 1, 5, 9}
1100 encodeDecode(t, p, np, "packed -> non-packed")
1101 if !reflect.DeepEqual(p.B, np.A) {
1102 t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A)
1103 }
1104}
1105
Rob Pikeaaa3a622010-03-20 22:32:34 -07001106func TestProto1RepeatedGroup(t *testing.T) {
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001107 pb := &MessageList{
1108 Message: []*MessageList_Message{
1109 &MessageList_Message{
1110 Name: String("blah"),
1111 Count: Int32(7),
1112 },
1113 // NOTE: pb.Message[1] is a nil
1114 nil,
1115 },
1116 }
Rob Pikeaaa3a622010-03-20 22:32:34 -07001117
1118 o := old()
1119 if err := o.Marshal(pb); err != ErrRepeatedHasNil {
1120 t.Fatalf("unexpected or no error when marshaling: %v", err)
1121 }
1122}
1123
Rob Pikeaaa3a622010-03-20 22:32:34 -07001124// Test that enums work. Checks for a bug introduced by making enums
1125// named types instead of int32: newInt32FromUint64 would crash with
1126// a type mismatch in reflect.PointTo.
1127func TestEnum(t *testing.T) {
1128 pb := new(GoEnum)
1129 pb.Foo = NewFOO(FOO_FOO1)
1130 o := old()
1131 if err := o.Marshal(pb); err != nil {
Rob Pike853f9112010-12-17 13:56:46 -08001132 t.Fatal("error encoding enum:", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001133 }
1134 pb1 := new(GoEnum)
1135 if err := o.Unmarshal(pb1); err != nil {
Rob Pike853f9112010-12-17 13:56:46 -08001136 t.Fatal("error decoding enum:", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001137 }
1138 if *pb1.Foo != FOO_FOO1 {
Rob Pike853f9112010-12-17 13:56:46 -08001139 t.Error("expected 7 but got ", *pb1.Foo)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001140 }
1141}
1142
David Symondse37856c2011-06-22 12:52:53 +10001143// Enum types have String methods. Check that enum fields can be printed.
1144// We don't care what the value actually is, just as long as it doesn't crash.
1145func TestPrintingNilEnumFields(t *testing.T) {
1146 pb := new(GoEnum)
1147 fmt.Sprintf("%+v", pb)
1148}
1149
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001150// Verify that absent required fields cause Marshal/Unmarshal to return errors.
1151func TestRequiredFieldEnforcement(t *testing.T) {
1152 pb := new(GoTestField)
1153 _, err := Marshal(pb)
David Symonds5b7775e2010-12-01 10:09:04 +11001154 if err == nil {
1155 t.Error("marshal: expected error, got nil")
Rob Pikea17fdd92011-11-02 12:43:05 -07001156 } else if strings.Index(err.Error(), "GoTestField") < 0 {
David Symonds5b7775e2010-12-01 10:09:04 +11001157 t.Errorf("marshal: bad error type: %v", err)
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001158 }
1159
1160 // A slightly sneaky, yet valid, proto. It encodes the same required field twice,
1161 // so simply counting the required fields is insufficient.
1162 // field 1, encoding 2, value "hi"
1163 buf := []byte("\x0A\x02hi\x0A\x02hi")
1164 err = Unmarshal(buf, pb)
David Symonds5b7775e2010-12-01 10:09:04 +11001165 if err == nil {
1166 t.Error("unmarshal: expected error, got nil")
Rob Pikea17fdd92011-11-02 12:43:05 -07001167 } else if strings.Index(err.Error(), "GoTestField") < 0 {
David Symonds5b7775e2010-12-01 10:09:04 +11001168 t.Errorf("unmarshal: bad error type: %v", err)
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001169 }
1170}
1171
David Symonds03c9d412010-08-26 14:23:18 +10001172// A type that implements the Marshaler interface, but is not nillable.
1173type nonNillableInt uint64
1174
Rob Pikea17fdd92011-11-02 12:43:05 -07001175func (nni nonNillableInt) Marshal() ([]byte, error) {
David Symonds03c9d412010-08-26 14:23:18 +10001176 return EncodeVarint(uint64(nni)), nil
1177}
1178
1179type NNIMessage struct {
1180 nni nonNillableInt
1181}
1182
1183// A type that implements the Marshaler interface and is nillable.
1184type nillableMessage struct {
1185 x uint64
1186}
1187
Rob Pikea17fdd92011-11-02 12:43:05 -07001188func (nm *nillableMessage) Marshal() ([]byte, error) {
David Symonds03c9d412010-08-26 14:23:18 +10001189 return EncodeVarint(nm.x), nil
1190}
1191
1192type NMMessage struct {
1193 nm *nillableMessage
1194}
1195
1196// Verify a type that uses the Marshaler interface, but has a nil pointer.
1197func TestNilMarshaler(t *testing.T) {
1198 // Try a struct with a Marshaler field that is nil.
1199 // It should be directly marshable.
1200 nmm := new(NMMessage)
1201 if _, err := Marshal(nmm); err != nil {
1202 t.Error("unexpected error marshaling nmm: ", err)
1203 }
1204
1205 // Try a struct with a Marshaler field that is not nillable.
1206 nnim := new(NNIMessage)
1207 nnim.nni = 7
1208 var _ Marshaler = nnim.nni // verify it is truly a Marshaler
1209 if _, err := Marshal(nnim); err != nil {
1210 t.Error("unexpected error marshaling nnim: ", err)
1211 }
1212}
1213
David Symonds7656e742011-07-22 14:54:17 +10001214// Check that passing a struct to Marshal returns a good error,
1215// rather than panicking.
1216func TestStructMarshaling(t *testing.T) {
1217 _, err := Marshal(OtherMessage{})
1218 if err != ErrNotPtr {
1219 t.Errorf("got %v, expected %v", err, ErrNotPtr)
1220 }
1221}
1222
David Symondsb79d99b2011-08-29 16:38:49 +10001223func TestAllSetDefaults(t *testing.T) {
1224 // Exercise SetDefaults with all scalar field types.
1225 m := &Defaults{
1226 // NaN != NaN, so override that here.
1227 F_Nan: Float32(1.7),
1228 }
1229 expected := &Defaults{
1230 F_Bool: Bool(true),
1231 F_Int32: Int32(32),
1232 F_Int64: Int64(64),
1233 F_Fixed32: Uint32(320),
1234 F_Fixed64: Uint64(640),
1235 F_Uint32: Uint32(3200),
1236 F_Uint64: Uint64(6400),
1237 F_Float: Float32(314159),
1238 F_Double: Float64(271828),
1239 F_String: String(`hello, "world!"` + "\n"),
1240 F_Bytes: []byte("Bignose"),
1241 F_Sint32: Int32(-32),
1242 F_Sint64: Int64(-64),
1243 F_Enum: NewDefaults_Color(Defaults_GREEN),
1244 F_Pinf: Float32(float32(math.Inf(1))),
1245 F_Ninf: Float32(float32(math.Inf(-1))),
1246 F_Nan: Float32(1.7),
1247 }
1248 SetDefaults(m)
1249 if !Equal(m, expected) {
1250 t.Errorf(" got %v\nwant %v", m, expected)
1251 }
1252}
1253
1254func TestSetDefaultsWithSetField(t *testing.T) {
1255 // Check that a set value is not overridden.
1256 m := &Defaults{
1257 F_Int32: Int32(12),
1258 }
1259 SetDefaults(m)
1260 if v := GetInt32(m.F_Int32); v != 12 {
1261 t.Errorf("m.FInt32 = %v, want 12", v)
1262 }
1263}
1264
1265func TestSetDefaultsWithSubMessage(t *testing.T) {
1266 m := &OtherMessage{
1267 Key: Int64(123),
1268 Inner: &InnerMessage{
1269 Host: String("gopher"),
1270 },
1271 }
1272 expected := &OtherMessage{
1273 Key: Int64(123),
1274 Inner: &InnerMessage{
1275 Host: String("gopher"),
1276 Port: Int32(4000),
1277 },
1278 }
1279 SetDefaults(m)
1280 if !Equal(m, expected) {
David Symonds814b9362011-12-13 09:10:47 +11001281 t.Errorf("\n got %v\nwant %v", m, expected)
David Symondsb79d99b2011-08-29 16:38:49 +10001282 }
1283}
1284
David Symondsd73d7b12011-09-28 10:56:43 -07001285func TestMaximumTagNumber(t *testing.T) {
1286 m := &MaxTag{
1287 LastField: String("natural goat essence"),
1288 }
1289 buf, err := Marshal(m)
1290 if err != nil {
1291 t.Fatalf("proto.Marshal failed: %v", err)
1292 }
1293 m2 := new(MaxTag)
1294 if err := Unmarshal(buf, m2); err != nil {
1295 t.Fatalf("proto.Unmarshal failed: %v", err)
1296 }
1297 if got, want := GetString(m2.LastField), *m.LastField; got != want {
1298 t.Errorf("got %q, want %q", got, want)
1299 }
1300}
1301
David Symonds002ec402011-09-29 17:24:20 -07001302func TestJSON(t *testing.T) {
1303 m := &MyMessage{
1304 Count: Int32(4),
1305 Pet: []string{"bunny", "kitty"},
1306 Inner: &InnerMessage{
1307 Host: String("cauchy"),
1308 },
1309 }
1310 const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"}}`
1311
1312 b, err := json.Marshal(m)
1313 if err != nil {
1314 t.Fatalf("json.Marshal failed: %v", err)
1315 }
1316 s := string(b)
1317 if s != expected {
1318 t.Errorf("got %s\nwant %s", s, expected)
1319 }
1320}
1321
Rob Pikeaaa3a622010-03-20 22:32:34 -07001322func BenchmarkMarshal(b *testing.B) {
1323 b.StopTimer()
1324
1325 pb := initGoTest(true)
1326
1327 // Create an array
1328 const N = 1000 // Internally the library starts much smaller.
1329 pb.F_Int32Repeated = make([]int32, N)
David Symondsd9da6ba2011-08-30 14:41:30 +10001330 pb.F_DoubleRepeated = make([]float64, N)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001331
1332 // Fill in the array with some values.
1333 for i := 0; i < N; i++ {
1334 pb.F_Int32Repeated[i] = int32(i)
David Symondsd9da6ba2011-08-30 14:41:30 +10001335 pb.F_DoubleRepeated[i] = float64(i)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001336 }
David Symondsd9da6ba2011-08-30 14:41:30 +10001337
Rob Pikeaaa3a622010-03-20 22:32:34 -07001338 p := NewBuffer(nil)
1339
1340 b.StartTimer()
1341 for i := 0; i < b.N; i++ {
1342 p.Reset()
1343 p.Marshal(pb)
1344 }
1345}
1346
1347func BenchmarkUnmarshal(b *testing.B) {
1348 b.StopTimer()
1349
1350 pb := initGoTest(true)
1351
1352 // Create an array
1353 const N = 1000 // Internally the library starts much smaller.
1354 pb.F_Int32Repeated = make([]int32, N)
1355
1356 // Fill in the array with some values.
1357 for i := 0; i < N; i++ {
1358 pb.F_Int32Repeated[i] = int32(i)
1359 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001360 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001361 p := NewBuffer(nil)
1362 p.Marshal(pb)
1363 p2 := NewBuffer(nil)
1364
1365 b.StartTimer()
1366 for i := 0; i < b.N; i++ {
1367 p2.SetBuf(p.Bytes())
1368 p2.Unmarshal(pbd)
1369 }
1370}