blob: ad72d9e4c57130ca0c86b55dfd363915fd8e3a1b [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
32// We need to compile the .pb.gos, which import this package, so
33// to run the test we must make install here and then make in the
34// testdata directory.
35// gotest: make install && cd testdata && make nuke && make
36
37package proto_test
38
39import (
40 "bytes"
41 "fmt"
David Symonds03c9d412010-08-26 14:23:18 +100042 "os"
David Symonds5b7775e2010-12-01 10:09:04 +110043 "reflect"
44 "strings"
Rob Pikeaaa3a622010-03-20 22:32:34 -070045 "testing"
46
47 . "goprotobuf.googlecode.com/hg/proto"
48 . "./testdata/_obj/test_proto"
49)
50
51var globalO *Buffer
52
53func old() *Buffer {
54 if globalO == nil {
55 globalO = NewBuffer(nil)
56 }
57 globalO.Reset()
58 return globalO
59}
60
61func equalbytes(b1, b2 []byte, t *testing.T) {
62 if len(b1) != len(b2) {
63 t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2))
64 return
65 }
66 for i := 0; i < len(b1); i++ {
67 if b1[i] != b2[i] {
68 t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2)
69 }
70 }
71}
72
73func initGoTestField() *GoTestField {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070074 f := new(GoTestField)
Rob Pikeaaa3a622010-03-20 22:32:34 -070075 f.Label = String("label")
76 f.Type = String("type")
77 return f
78}
79
80// These are all structurally equivalent but the tag numbers differ.
81// (It's remarkable that required, optional, and repeated all have
82// 8 letters.)
83func initGoTest_RequiredGroup() *GoTest_RequiredGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070084 return &GoTest_RequiredGroup{
85 RequiredField: String("required"),
86 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070087}
88
89func initGoTest_OptionalGroup() *GoTest_OptionalGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070090 return &GoTest_OptionalGroup{
91 RequiredField: String("optional"),
92 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070093}
94
95func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup {
Rob Pikec6d8e4a2010-07-28 15:34:32 -070096 return &GoTest_RepeatedGroup{
97 RequiredField: String("repeated"),
98 }
Rob Pikeaaa3a622010-03-20 22:32:34 -070099}
100
101func initGoTest(setdefaults bool) *GoTest {
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700102 pb := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700103 if setdefaults {
104 pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted)
105 pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted)
106 pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted)
107 pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted)
108 pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted)
109 pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted)
110 pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted)
111 pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted)
112 pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted)
113 pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted)
114 pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted
115 pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted)
116 pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
117 }
118
119 pb.Kind = Int32(GoTest_TIME)
120 pb.RequiredField = initGoTestField()
121 pb.F_BoolRequired = Bool(true)
122 pb.F_Int32Required = Int32(3)
123 pb.F_Int64Required = Int64(6)
124 pb.F_Fixed32Required = Uint32(32)
125 pb.F_Fixed64Required = Uint64(64)
126 pb.F_Uint32Required = Uint32(3232)
127 pb.F_Uint64Required = Uint64(6464)
128 pb.F_FloatRequired = Float32(3232)
129 pb.F_DoubleRequired = Float64(6464)
130 pb.F_StringRequired = String("string")
131 pb.F_BytesRequired = []byte("bytes")
132 pb.F_Sint32Required = Int32(-32)
133 pb.F_Sint64Required = Int64(-64)
134 pb.Requiredgroup = initGoTest_RequiredGroup()
135
136 return pb
137}
138
139func fail(msg string, b *bytes.Buffer, s string, t *testing.T) {
140 data := b.Bytes()
141 ld := len(data)
142 ls := len(s) / 2
143
144 fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls)
145
146 // find the interesting spot - n
147 n := ls
148 if ld < ls {
149 n = ld
150 }
151 j := 0
152 for i := 0; i < n; i++ {
153 bs := hex(s[j])*16 + hex(s[j+1])
154 j += 2
155 if data[i] == bs {
156 continue
157 }
158 n = i
159 break
160 }
161 l := n - 10
162 if l < 0 {
163 l = 0
164 }
165 h := n + 10
166
167 // find the interesting spot - n
168 fmt.Printf("is[%d]:", l)
169 for i := l; i < h; i++ {
170 if i >= ld {
171 fmt.Printf(" --")
172 continue
173 }
174 fmt.Printf(" %.2x", data[i])
175 }
176 fmt.Printf("\n")
177
178 fmt.Printf("sb[%d]:", l)
179 for i := l; i < h; i++ {
180 if i >= ls {
181 fmt.Printf(" --")
182 continue
183 }
184 bs := hex(s[j])*16 + hex(s[j+1])
185 j += 2
186 fmt.Printf(" %.2x", bs)
187 }
188 fmt.Printf("\n")
189
190 t.Fail()
191
Rob Pikeaaa3a622010-03-20 22:32:34 -0700192 // t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
193 // Print the output in a partially-decoded format; can
194 // be helpful when updating the test. It produces the output
195 // that is pasted, with minor edits, into the argument to verify().
196 // data := b.Bytes()
197 // nesting := 0
198 // for b.Len() > 0 {
199 // start := len(data) - b.Len()
200 // var u uint64
201 // u, err := DecodeVarint(b)
202 // if err != nil {
203 // fmt.Printf("decode error on varint:", err)
204 // return
205 // }
206 // wire := u & 0x7
207 // tag := u >> 3
208 // switch wire {
209 // case WireVarint:
210 // v, err := DecodeVarint(b)
211 // if err != nil {
212 // fmt.Printf("decode error on varint:", err)
213 // return
214 // }
215 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
216 // data[start:len(data)-b.Len()], tag, wire, v)
217 // case WireFixed32:
218 // v, err := DecodeFixed32(b)
219 // if err != nil {
220 // fmt.Printf("decode error on fixed32:", err)
221 // return
222 // }
223 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
224 // data[start:len(data)-b.Len()], tag, wire, v)
225 // case WireFixed64:
226 // v, err := DecodeFixed64(b)
227 // if err != nil {
228 // fmt.Printf("decode error on fixed64:", err)
229 // return
230 // }
231 // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n",
232 // data[start:len(data)-b.Len()], tag, wire, v)
233 // case WireBytes:
234 // nb, err := DecodeVarint(b)
235 // if err != nil {
236 // fmt.Printf("decode error on bytes:", err)
237 // return
238 // }
239 // after_tag := len(data) - b.Len()
240 // str := make([]byte, nb)
241 // _, err = b.Read(str)
242 // if err != nil {
243 // fmt.Printf("decode error on bytes:", err)
244 // return
245 // }
246 // fmt.Printf("\t\t\"%x\" \"%x\" // field %d, encoding %d (FIELD)\n",
247 // data[start:after_tag], str, tag, wire)
248 // case WireStartGroup:
249 // nesting++
250 // fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
251 // data[start:len(data)-b.Len()], tag, nesting)
252 // case WireEndGroup:
253 // fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
254 // data[start:len(data)-b.Len()], tag, nesting)
255 // nesting--
256 // default:
257 // fmt.Printf("unrecognized wire type %d\n", wire)
258 // return
259 // }
260 // }
261}
262
263func hex(c uint8) uint8 {
264 if '0' <= c && c <= '9' {
265 return c - '0'
266 }
267 if 'a' <= c && c <= 'f' {
268 return 10 + c - 'a'
269 }
270 if 'A' <= c && c <= 'F' {
271 return 10 + c - 'A'
272 }
273 return 0
274}
275
276func equal(b []byte, s string, t *testing.T) bool {
277 if 2*len(b) != len(s) {
278 // fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t)
279 fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s))
280 return false
281 }
282 for i, j := 0, 0; i < len(b); i, j = i+1, j+2 {
283 x := hex(s[j])*16 + hex(s[j+1])
284 if b[i] != x {
285 // fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t)
286 fmt.Printf("bad byte[%d]:%x %x", i, b[i], x)
287 return false
288 }
289 }
290 return true
291}
292
293func overify(t *testing.T, pb *GoTest, expected string) {
294 o := old()
295 err := o.Marshal(pb)
296 if err != nil {
297 fmt.Printf("overify marshal-1 err = %v", err)
298 o.DebugPrint("", o.Bytes())
299 t.Fatalf("expected = %s", expected)
300 }
301 if !equal(o.Bytes(), expected, t) {
302 o.DebugPrint("overify neq 1", o.Bytes())
303 t.Fatalf("expected = %s", expected)
304 }
305
306 // Now test Unmarshal by recreating the original buffer.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700307 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700308 err = o.Unmarshal(pbd)
309 if err != nil {
310 t.Fatalf("overify unmarshal err = %v", err)
311 o.DebugPrint("", o.Bytes())
312 t.Fatalf("string = %s", expected)
313 }
314 o.Reset()
315 err = o.Marshal(pbd)
316 if err != nil {
317 t.Errorf("overify marshal-2 err = %v", err)
318 o.DebugPrint("", o.Bytes())
319 t.Fatalf("string = %s", expected)
320 }
321 if !equal(o.Bytes(), expected, t) {
322 o.DebugPrint("overify neq 2", o.Bytes())
323 t.Fatalf("string = %s", expected)
324 }
325}
326
327// Simple tests for numeric encode/decode primitives (varint, etc.)
328func TestNumericPrimitives(t *testing.T) {
329 for i := uint64(0); i < 1e6; i += 111 {
330 o := old()
331 if o.EncodeVarint(i) != nil {
332 t.Error("EncodeVarint")
333 break
334 }
335 x, e := o.DecodeVarint()
336 if e != nil {
337 t.Fatal("DecodeVarint")
338 }
339 if x != i {
340 t.Fatal("varint decode fail:", i, x)
341 }
342
343 o = old()
344 if o.EncodeFixed32(i) != nil {
345 t.Fatal("encFixed32")
346 }
347 x, e = o.DecodeFixed32()
348 if e != nil {
349 t.Fatal("decFixed32")
350 }
351 if x != i {
352 t.Fatal("fixed32 decode fail:", i, x)
353 }
354
355 o = old()
356 if o.EncodeFixed64(i*1234567) != nil {
357 t.Error("encFixed64")
358 break
359 }
360 x, e = o.DecodeFixed64()
361 if e != nil {
362 t.Error("decFixed64")
363 break
364 }
365 if x != i*1234567 {
366 t.Error("fixed64 decode fail:", i*1234567, x)
367 break
368 }
369
370 o = old()
371 i32 := int32(i - 12345)
372 if o.EncodeZigzag32(uint64(i32)) != nil {
373 t.Fatal("EncodeZigzag32")
374 }
375 x, e = o.DecodeZigzag32()
376 if e != nil {
377 t.Fatal("DecodeZigzag32")
378 }
379 if x != uint64(uint32(i32)) {
380 t.Fatal("zigzag32 decode fail:", i32, x)
381 }
382
383 o = old()
384 i64 := int64(i - 12345)
385 if o.EncodeZigzag64(uint64(i64)) != nil {
386 t.Fatal("EncodeZigzag64")
387 }
388 x, e = o.DecodeZigzag64()
389 if e != nil {
390 t.Fatal("DecodeZigzag64")
391 }
392 if x != uint64(i64) {
393 t.Fatal("zigzag64 decode fail:", i64, x)
394 }
395 }
396}
397
398// Simple tests for bytes
399func TestBytesPrimitives(t *testing.T) {
400 o := old()
401 bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'}
402 if o.EncodeRawBytes(bytes) != nil {
403 t.Error("EncodeRawBytes")
404 }
405 decb, e := o.DecodeRawBytes(false)
406 if e != nil {
407 t.Error("DecodeRawBytes")
408 }
409 equalbytes(bytes, decb, t)
410}
411
412// Simple tests for strings
413func TestStringPrimitives(t *testing.T) {
414 o := old()
415 s := "now is the time"
416 if o.EncodeStringBytes(s) != nil {
417 t.Error("enc_string")
418 }
419 decs, e := o.DecodeStringBytes()
420 if e != nil {
421 t.Error("dec_string")
422 }
423 if s != decs {
424 t.Error("string encode/decode fail:", s, decs)
425 }
426}
427
428// Do we catch the "required bit not set" case?
429func TestRequiredBit(t *testing.T) {
430 o := old()
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700431 pb := new(GoTest)
David Symonds5b7775e2010-12-01 10:09:04 +1100432 err := o.Marshal(pb)
433 if err == nil {
434 t.Error("did not catch missing required fields")
435 } else if strings.Index(err.String(), "GoTest") < 0 {
436 t.Error("wrong error type:", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700437 }
438}
439
440// Check that all fields are nil.
441// Clearly silly, and a residue from a more interesting test with an earlier,
442// different initialization property, but it once caught a compiler bug so
443// it lives.
444func checkInitialized(pb *GoTest, t *testing.T) {
445 if pb.F_BoolDefaulted != nil {
446 t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted)
447 }
448 if pb.F_Int32Defaulted != nil {
449 t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted)
450 }
451 if pb.F_Int64Defaulted != nil {
452 t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted)
453 }
454 if pb.F_Fixed32Defaulted != nil {
455 t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted)
456 }
457 if pb.F_Fixed64Defaulted != nil {
458 t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted)
459 }
460 if pb.F_Uint32Defaulted != nil {
461 t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted)
462 }
463 if pb.F_Uint64Defaulted != nil {
464 t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted)
465 }
466 if pb.F_FloatDefaulted != nil {
467 t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted)
468 }
469 if pb.F_DoubleDefaulted != nil {
470 t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted)
471 }
472 if pb.F_StringDefaulted != nil {
473 t.Error("New or Reset did not set string:", *pb.F_StringDefaulted)
474 }
475 if pb.F_BytesDefaulted != nil {
476 t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted))
477 }
478 if pb.F_Sint32Defaulted != nil {
479 t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted)
480 }
481 if pb.F_Sint64Defaulted != nil {
482 t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted)
483 }
484}
485
486// Does Reset() reset?
487func TestReset(t *testing.T) {
488 pb := initGoTest(true)
489 // muck with some values
490 pb.F_BoolDefaulted = Bool(false)
491 pb.F_Int32Defaulted = Int32(237)
492 pb.F_Int64Defaulted = Int64(12346)
493 pb.F_Fixed32Defaulted = Uint32(32000)
494 pb.F_Fixed64Defaulted = Uint64(666)
495 pb.F_Uint32Defaulted = Uint32(323232)
496 pb.F_Uint64Defaulted = nil
497 pb.F_FloatDefaulted = nil
498 pb.F_DoubleDefaulted = Float64(0)
499 pb.F_StringDefaulted = String("gotcha")
500 pb.F_BytesDefaulted = []byte("asdfasdf")
501 pb.F_Sint32Defaulted = Int32(123)
502 pb.F_Sint64Defaulted = Int64(789)
503 pb.Reset()
504 checkInitialized(pb, t)
505}
506
507// All required fields set, no defaults provided.
508func TestEncodeDecode1(t *testing.T) {
509 pb := initGoTest(false)
510 overify(t, pb,
511 "0807"+ // field 1, encoding 0, value 7
512 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
513 "5001"+ // field 10, encoding 0, value 1
514 "5803"+ // field 11, encoding 0, value 3
515 "6006"+ // field 12, encoding 0, value 6
516 "6d20000000"+ // field 13, encoding 5, value 0x20
517 "714000000000000000"+ // field 14, encoding 1, value 0x40
518 "78a019"+ // field 15, encoding 0, value 0xca0 = 3232
519 "8001c032"+ // field 16, encoding 0, value 0x1940 = 6464
520 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
521 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
522 "9a0106"+"737472696e67"+ // field 19, encoding 2, string "string"
523 "aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes"
524 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
525 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
526 "b304"+ // field 70, encoding 3, start group
527 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
528 "b404") // field 70, encoding 4, end group
529}
530
531// All required fields set, defaults provided.
532func TestEncodeDecode2(t *testing.T) {
533 pb := initGoTest(true)
534 overify(t, pb,
535 "0807"+ // field 1, encoding 0, value 7
536 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
537 "5001"+ // field 10, encoding 0, value 1
538 "5803"+ // field 11, encoding 0, value 3
539 "6006"+ // field 12, encoding 0, value 6
540 "6d20000000"+ // field 13, encoding 5, value 32
541 "714000000000000000"+ // field 14, encoding 1, value 64
542 "78a019"+ // field 15, encoding 0, value 3232
543 "8001c032"+ // field 16, encoding 0, value 6464
544 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
545 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
546 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
547 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
548 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
549 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
550 "c00201"+ // field 40, encoding 0, value 1
551 "c80220"+ // field 41, encoding 0, value 32
552 "d00240"+ // field 42, encoding 0, value 64
553 "dd0240010000"+ // field 43, encoding 5, value 320
554 "e1028002000000000000"+ // field 44, encoding 1, value 640
555 "e8028019"+ // field 45, encoding 0, value 3200
556 "f0028032"+ // field 46, encoding 0, value 6400
557 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
558 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
559 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
David Symonds5f7b9e02010-11-30 10:42:39 +1100560 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700561 "90193f"+ // field 402, encoding 0, value 63
562 "98197f"+ // field 403, encoding 0, value 127
563 "b304"+ // start group field 70 level 1
564 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
565 "b404") // end group field 70 level 1
566
567}
568
569// All default fields set to their default value by hand
570func TestEncodeDecode3(t *testing.T) {
571 pb := initGoTest(false)
572 pb.F_BoolDefaulted = Bool(true)
573 pb.F_Int32Defaulted = Int32(32)
574 pb.F_Int64Defaulted = Int64(64)
575 pb.F_Fixed32Defaulted = Uint32(320)
576 pb.F_Fixed64Defaulted = Uint64(640)
577 pb.F_Uint32Defaulted = Uint32(3200)
578 pb.F_Uint64Defaulted = Uint64(6400)
579 pb.F_FloatDefaulted = Float32(314159)
580 pb.F_DoubleDefaulted = Float64(271828)
581 pb.F_StringDefaulted = String("hello, \"world!\"\n")
582 pb.F_BytesDefaulted = []byte("Bignose")
583 pb.F_Sint32Defaulted = Int32(-32)
584 pb.F_Sint64Defaulted = Int64(-64)
585
586 overify(t, pb,
587 "0807"+ // field 1, encoding 0, value 7
588 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
589 "5001"+ // field 10, encoding 0, value 1
590 "5803"+ // field 11, encoding 0, value 3
591 "6006"+ // field 12, encoding 0, value 6
592 "6d20000000"+ // field 13, encoding 5, value 32
593 "714000000000000000"+ // field 14, encoding 1, value 64
594 "78a019"+ // field 15, encoding 0, value 3232
595 "8001c032"+ // field 16, encoding 0, value 6464
596 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
597 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
598 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
599 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
600 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
601 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
602 "c00201"+ // field 40, encoding 0, value 1
603 "c80220"+ // field 41, encoding 0, value 32
604 "d00240"+ // field 42, encoding 0, value 64
605 "dd0240010000"+ // field 43, encoding 5, value 320
606 "e1028002000000000000"+ // field 44, encoding 1, value 640
607 "e8028019"+ // field 45, encoding 0, value 3200
608 "f0028032"+ // field 46, encoding 0, value 6400
609 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
610 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
611 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
David Symonds5f7b9e02010-11-30 10:42:39 +1100612 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700613 "90193f"+ // field 402, encoding 0, value 63
614 "98197f"+ // field 403, encoding 0, value 127
615 "b304"+ // start group field 70 level 1
616 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
617 "b404") // end group field 70 level 1
618
619}
620
621// All required fields set, defaults provided, all non-defaulted optional fields have values.
622func TestEncodeDecode4(t *testing.T) {
623 pb := initGoTest(true)
624 pb.Table = String("hello")
625 pb.Param = Int32(7)
626 pb.OptionalField = initGoTestField()
627 pb.F_BoolOptional = Bool(true)
628 pb.F_Int32Optional = Int32(32)
629 pb.F_Int64Optional = Int64(64)
630 pb.F_Fixed32Optional = Uint32(3232)
631 pb.F_Fixed64Optional = Uint64(6464)
632 pb.F_Uint32Optional = Uint32(323232)
633 pb.F_Uint64Optional = Uint64(646464)
634 pb.F_FloatOptional = Float32(32.)
635 pb.F_DoubleOptional = Float64(64.)
636 pb.F_StringOptional = String("hello")
637 pb.F_BytesOptional = []byte("Bignose")
638 pb.F_Sint32Optional = Int32(-32)
639 pb.F_Sint64Optional = Int64(-64)
640 pb.Optionalgroup = initGoTest_OptionalGroup()
641
642 overify(t, pb,
643 "0807"+ // field 1, encoding 0, value 7
644 "1205"+"68656c6c6f"+ // field 2, encoding 2, string "hello"
645 "1807"+ // field 3, encoding 0, value 7
646 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
647 "320d"+"0a056c6162656c120474797065"+ // field 6, encoding 2 (GoTestField)
648 "5001"+ // field 10, encoding 0, value 1
649 "5803"+ // field 11, encoding 0, value 3
650 "6006"+ // field 12, encoding 0, value 6
651 "6d20000000"+ // field 13, encoding 5, value 32
652 "714000000000000000"+ // field 14, encoding 1, value 64
653 "78a019"+ // field 15, encoding 0, value 3232
654 "8001c032"+ // field 16, encoding 0, value 6464
655 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
656 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
657 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
658 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
659 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
660 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
661 "f00101"+ // field 30, encoding 0, value 1
662 "f80120"+ // field 31, encoding 0, value 32
663 "800240"+ // field 32, encoding 0, value 64
664 "8d02a00c0000"+ // field 33, encoding 5, value 3232
665 "91024019000000000000"+ // field 34, encoding 1, value 6464
666 "9802a0dd13"+ // field 35, encoding 0, value 323232
667 "a002c0ba27"+ // field 36, encoding 0, value 646464
668 "ad0200000042"+ // field 37, encoding 5, value 32.0
669 "b1020000000000005040"+ // field 38, encoding 1, value 64.0
670 "ba0205"+"68656c6c6f"+ // field 39, encoding 2, string "hello"
671 "ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose"
672 "f0123f"+ // field 302, encoding 0, value 63
673 "f8127f"+ // field 303, encoding 0, value 127
674 "c00201"+ // field 40, encoding 0, value 1
675 "c80220"+ // field 41, encoding 0, value 32
676 "d00240"+ // field 42, encoding 0, value 64
677 "dd0240010000"+ // field 43, encoding 5, value 320
678 "e1028002000000000000"+ // field 44, encoding 1, value 640
679 "e8028019"+ // field 45, encoding 0, value 3200
680 "f0028032"+ // field 46, encoding 0, value 6400
681 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
682 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
683 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
David Symonds5f7b9e02010-11-30 10:42:39 +1100684 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700685 "90193f"+ // field 402, encoding 0, value 63
686 "98197f"+ // field 403, encoding 0, value 127
687 "b304"+ // start group field 70 level 1
688 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
689 "b404"+ // end group field 70 level 1
690 "d305"+ // start group field 90 level 1
691 "da0508"+"6f7074696f6e616c"+ // field 91, encoding 2, string "optional"
692 "d405") // end group field 90 level 1
693
694}
695
696// All required fields set, defaults provided, all repeated fields given two values.
697func TestEncodeDecode5(t *testing.T) {
698 pb := initGoTest(true)
699 pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()}
700 pb.F_BoolRepeated = []bool{false, true}
701 pb.F_Int32Repeated = []int32{32, 33}
702 pb.F_Int64Repeated = []int64{64, 65}
703 pb.F_Fixed32Repeated = []uint32{3232, 3333}
704 pb.F_Fixed64Repeated = []uint64{6464, 6565}
705 pb.F_Uint32Repeated = []uint32{323232, 333333}
706 pb.F_Uint64Repeated = []uint64{646464, 656565}
707 pb.F_FloatRepeated = []float32{32., 33.}
708 pb.F_DoubleRepeated = []float64{64., 65.}
709 pb.F_StringRepeated = []string{"hello", "sailor"}
710 pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")}
711 pb.F_Sint32Repeated = []int32{32, -32}
712 pb.F_Sint64Repeated = []int64{64, -64}
713 pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()}
714
715 overify(t, pb,
716 "0807"+ // field 1, encoding 0, value 7
717 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
718 "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
719 "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
720 "5001"+ // field 10, encoding 0, value 1
721 "5803"+ // field 11, encoding 0, value 3
722 "6006"+ // field 12, encoding 0, value 6
723 "6d20000000"+ // field 13, encoding 5, value 32
724 "714000000000000000"+ // field 14, encoding 1, value 64
725 "78a019"+ // field 15, encoding 0, value 3232
726 "8001c032"+ // field 16, encoding 0, value 6464
727 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
728 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
729 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
730 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
731 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
732 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
733 "a00100"+ // field 20, encoding 0, value 0
734 "a00101"+ // field 20, encoding 0, value 1
735 "a80120"+ // field 21, encoding 0, value 32
736 "a80121"+ // field 21, encoding 0, value 33
737 "b00140"+ // field 22, encoding 0, value 64
738 "b00141"+ // field 22, encoding 0, value 65
739 "bd01a00c0000"+ // field 23, encoding 5, value 3232
740 "bd01050d0000"+ // field 23, encoding 5, value 3333
741 "c1014019000000000000"+ // field 24, encoding 1, value 6464
742 "c101a519000000000000"+ // field 24, encoding 1, value 6565
743 "c801a0dd13"+ // field 25, encoding 0, value 323232
744 "c80195ac14"+ // field 25, encoding 0, value 333333
745 "d001c0ba27"+ // field 26, encoding 0, value 646464
746 "d001b58928"+ // field 26, encoding 0, value 656565
747 "dd0100000042"+ // field 27, encoding 5, value 32.0
748 "dd0100000442"+ // field 27, encoding 5, value 33.0
749 "e1010000000000005040"+ // field 28, encoding 1, value 64.0
750 "e1010000000000405040"+ // field 28, encoding 1, value 65.0
751 "ea0105"+"68656c6c6f"+ // field 29, encoding 2, string "hello"
752 "ea0106"+"7361696c6f72"+ // field 29, encoding 2, string "sailor"
753 "ca0c03"+"626967"+ // field 201, encoding 2, string "big"
754 "ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose"
David Symonds5b7775e2010-12-01 10:09:04 +1100755 "d00c40"+ // field 202, encoding 0, value 32
756 "d00c3f"+ // field 202, encoding 0, value -32
757 "d80c8001"+ // field 203, encoding 0, value 64
758 "d80c7f"+ // field 203, encoding 0, value -64
Rob Pikeaaa3a622010-03-20 22:32:34 -0700759 "c00201"+ // field 40, encoding 0, value 1
760 "c80220"+ // field 41, encoding 0, value 32
761 "d00240"+ // field 42, encoding 0, value 64
762 "dd0240010000"+ // field 43, encoding 5, value 320
763 "e1028002000000000000"+ // field 44, encoding 1, value 640
764 "e8028019"+ // field 45, encoding 0, value 3200
765 "f0028032"+ // field 46, encoding 0, value 6400
766 "fd02e0659948"+ // field 47, encoding 5, value 314159.0
767 "81030000000050971041"+ // field 48, encoding 1, value 271828.0
768 "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
David Symonds5f7b9e02010-11-30 10:42:39 +1100769 "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700770 "90193f"+ // field 402, encoding 0, value 63
771 "98197f"+ // field 403, encoding 0, value 127
772 "b304"+ // start group field 70 level 1
773 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
774 "b404"+ // end group field 70 level 1
775 "8305"+ // start group field 80 level 1
776 "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
777 "8405"+ // end group field 80 level 1
778 "8305"+ // start group field 80 level 1
779 "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
780 "8405") // end group field 80 level 1
781
782}
783
David Symonds5b7775e2010-12-01 10:09:04 +1100784// All required fields set, all packed repeated fields given two values.
785func TestEncodeDecode6(t *testing.T) {
786 pb := initGoTest(false)
787 pb.F_BoolRepeatedPacked = []bool{false, true}
788 pb.F_Int32RepeatedPacked = []int32{32, 33}
789 pb.F_Int64RepeatedPacked = []int64{64, 65}
790 pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333}
791 pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565}
792 pb.F_Uint32RepeatedPacked = []uint32{323232, 333333}
793 pb.F_Uint64RepeatedPacked = []uint64{646464, 656565}
794 pb.F_FloatRepeatedPacked = []float32{32., 33.}
795 pb.F_DoubleRepeatedPacked = []float64{64., 65.}
796 pb.F_Sint32RepeatedPacked = []int32{32, -32}
797 pb.F_Sint64RepeatedPacked = []int64{64, -64}
798
799 overify(t, pb,
800 "0807"+ // field 1, encoding 0, value 7
801 "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
802 "5001"+ // field 10, encoding 0, value 1
803 "5803"+ // field 11, encoding 0, value 3
804 "6006"+ // field 12, encoding 0, value 6
805 "6d20000000"+ // field 13, encoding 5, value 32
806 "714000000000000000"+ // field 14, encoding 1, value 64
807 "78a019"+ // field 15, encoding 0, value 3232
808 "8001c032"+ // field 16, encoding 0, value 6464
809 "8d0100004a45"+ // field 17, encoding 5, value 3232.0
810 "9101000000000040b940"+ // field 18, encoding 1, value 6464.0
811 "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
812 "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
813 "b0063f"+ // field 102, encoding 0, 0x3f zigzag32
814 "b8067f"+ // field 103, encoding 0, 0x7f zigzag64
815 "9203020001"+ // field 50, encoding 2, 2 bytes, value 0, value 1
816 "9a03022021"+ // field 51, encoding 2, 2 bytes, value 32, value 33
817 "a203024041"+ // field 52, encoding 2, 2 bytes, value 64, value 65
818 "aa0308"+ // field 53, encoding 2, 8 bytes
819 "a00c0000050d0000"+ // value 3232, value 3333
820 "b20310"+ // field 54, encoding 2, 16 bytes
821 "4019000000000000a519000000000000"+ // value 6464, value 6565
822 "ba0306"+ // field 55, encoding 2, 6 bytes
823 "a0dd1395ac14"+ // value 323232, value 333333
824 "c20306"+ // field 56, encoding 2, 6 bytes
825 "c0ba27b58928"+ // value 646464, value 656565
826 "ca0308"+ // field 57, encoding 2, 8 bytes
827 "0000004200000442"+ // value 32.0, value 33.0
828 "d20310"+ // field 58, encoding 2, 16 bytes
829 "00000000000050400000000000405040"+ // value 64.0, value 65.0
830 "b21f02"+ // field 502, encoding 2, 2 bytes
831 "403f"+ // value 32, value -32
832 "ba1f03"+ // field 503, encoding 2, 3 bytes
833 "80017f"+ // value 64, value -64
834 "b304"+ // start group field 70 level 1
835 "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
836 "b404") // end group field 70 level 1
837}
838
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800839// Test that we can encode empty bytes fields.
840func TestEncodeDecodeBytes1(t *testing.T) {
841 pb := initGoTest(false)
842
843 // Create our bytes
844 pb.F_BytesRequired = []byte{}
David Symonds5b7775e2010-12-01 10:09:04 +1100845 pb.F_BytesRepeated = [][]byte{[]byte{}}
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800846 pb.F_BytesOptional = []byte{}
847
848 d, err := Marshal(pb)
849 if err != nil {
850 t.Errorf(err.String())
851 }
852
853 pbd := new(GoTest)
854 if err := Unmarshal(d, pbd); err != nil {
855 t.Errorf(err.String())
856 }
857
858 if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 {
859 t.Errorf("required empty bytes field is incorrect")
860 }
861 if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil {
862 t.Errorf("repeated empty bytes field is incorrect")
863 }
864 if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 {
865 t.Errorf("optional empty bytes field is incorrect")
866 }
867}
868
869// Test that we encode nil-valued fields of a repeated bytes field correctly.
870// Since entries in a repeated field cannot be nil, nil must mean empty value.
871func TestEncodeDecodeBytes2(t *testing.T) {
872 pb := initGoTest(false)
873
874 // Create our bytes
David Symonds5b7775e2010-12-01 10:09:04 +1100875 pb.F_BytesRepeated = [][]byte{nil}
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800876
877 d, err := Marshal(pb)
David Symonds5b7775e2010-12-01 10:09:04 +1100878 if err != nil {
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800879 t.Errorf(err.String())
880 }
881
882 pbd := new(GoTest)
883 if err := Unmarshal(d, pbd); err != nil {
884 t.Errorf(err.String())
885 }
886
887 if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil {
888 t.Errorf("Unexpected value for repeated bytes field")
889 }
890}
891
Rob Pikeaaa3a622010-03-20 22:32:34 -0700892// All required fields set, defaults provided, all repeated fields given two values.
893func TestSkippingUnrecognizedFields(t *testing.T) {
894 o := old()
895 pb := initGoTestField()
896
897 // Marshal it normally.
898 o.Marshal(pb)
899
900 // Now new a GoSkipTest record.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700901 skip := &GoSkipTest{
902 SkipInt32: Int32(32),
903 SkipFixed32: Uint32(3232),
904 SkipFixed64: Uint64(6464),
905 SkipString: String("skipper"),
906 Skipgroup: &GoSkipTest_SkipGroup{
907 GroupInt32: Int32(75),
908 GroupString: String("wxyz"),
909 },
910 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700911
912 // Marshal it into same buffer.
913 o.Marshal(skip)
914
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700915 pbd := new(GoTestField)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700916 o.Unmarshal(pbd)
917
918 // The __unrecognized field should be a marshaling of GoSkipTest
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700919 skipd := new(GoSkipTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700920
921 o.SetBuf(pbd.XXX_unrecognized)
922 o.Unmarshal(skipd)
923
924 if *skipd.SkipInt32 != *skip.SkipInt32 {
925 t.Error("skip int32", skipd.SkipInt32)
926 }
927 if *skipd.SkipFixed32 != *skip.SkipFixed32 {
928 t.Error("skip fixed32", skipd.SkipFixed32)
929 }
930 if *skipd.SkipFixed64 != *skip.SkipFixed64 {
931 t.Error("skip fixed64", skipd.SkipFixed64)
932 }
933 if *skipd.SkipString != *skip.SkipString {
934 t.Error("skip string", *skipd.SkipString)
935 }
936 if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 {
937 t.Error("skip group int32", skipd.Skipgroup.GroupInt32)
938 }
939 if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString {
940 t.Error("skip group string", *skipd.Skipgroup.GroupString)
941 }
942}
943
944// Check that we can grow an array (repeated field) to have many elements.
945// This test doesn't depend only on our encoding; for variety, it makes sure
946// we create, encode, and decode the correct contents explicitly. It's therefore
947// a bit messier.
948// This test also uses (and hence tests) the Marshal/Unmarshal functions
949// instead of the methods.
950func TestBigRepeated(t *testing.T) {
951 pb := initGoTest(true)
952
953 // Create the arrays
954 const N = 50 // Internally the library starts much smaller.
955 pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N)
956 pb.F_Sint64Repeated = make([]int64, N)
957 pb.F_Sint32Repeated = make([]int32, N)
958 pb.F_BytesRepeated = make([][]byte, N)
959 pb.F_StringRepeated = make([]string, N)
960 pb.F_DoubleRepeated = make([]float64, N)
961 pb.F_FloatRepeated = make([]float32, N)
962 pb.F_Uint64Repeated = make([]uint64, N)
963 pb.F_Uint32Repeated = make([]uint32, N)
964 pb.F_Fixed64Repeated = make([]uint64, N)
965 pb.F_Fixed32Repeated = make([]uint32, N)
966 pb.F_Int64Repeated = make([]int64, N)
967 pb.F_Int32Repeated = make([]int32, N)
968 pb.F_BoolRepeated = make([]bool, N)
969 pb.RepeatedField = make([]*GoTestField, N)
970
971 // Fill in the arrays with checkable values.
972 igtf := initGoTestField()
973 igtrg := initGoTest_RepeatedGroup()
974 for i := 0; i < N; i++ {
975 pb.Repeatedgroup[i] = igtrg
976 pb.F_Sint64Repeated[i] = int64(i)
977 pb.F_Sint32Repeated[i] = int32(i)
978 s := fmt.Sprint(i)
979 pb.F_BytesRepeated[i] = []byte(s)
980 pb.F_StringRepeated[i] = s
981 pb.F_DoubleRepeated[i] = float64(i)
982 pb.F_FloatRepeated[i] = float32(i)
983 pb.F_Uint64Repeated[i] = uint64(i)
984 pb.F_Uint32Repeated[i] = uint32(i)
985 pb.F_Fixed64Repeated[i] = uint64(i)
986 pb.F_Fixed32Repeated[i] = uint32(i)
987 pb.F_Int64Repeated[i] = int64(i)
988 pb.F_Int32Repeated[i] = int32(i)
989 pb.F_BoolRepeated[i] = i%2 == 0
990 pb.RepeatedField[i] = igtf
991 }
992
993 // Marshal.
994 buf, _ := Marshal(pb)
995
996 // Now test Unmarshal by recreating the original buffer.
Rob Pikec6d8e4a2010-07-28 15:34:32 -0700997 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700998 Unmarshal(buf, pbd)
999
1000 // Check the checkable values
1001 for i := uint64(0); i < N; i++ {
1002 if pbd.Repeatedgroup[i] == nil { // TODO: more checking?
1003 t.Error("pbd.Repeatedgroup bad")
1004 }
1005 var x uint64
1006 x = uint64(pbd.F_Sint64Repeated[i])
1007 if x != i {
1008 t.Error("pbd.F_Sint64Repeated bad", x, i)
1009 }
1010 x = uint64(pbd.F_Sint32Repeated[i])
1011 if x != i {
1012 t.Error("pbd.F_Sint32Repeated bad", x, i)
1013 }
1014 s := fmt.Sprint(i)
1015 equalbytes(pbd.F_BytesRepeated[i], []byte(s), t)
1016 if pbd.F_StringRepeated[i] != s {
1017 t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i)
1018 }
1019 x = uint64(pbd.F_DoubleRepeated[i])
1020 if x != i {
1021 t.Error("pbd.F_DoubleRepeated bad", x, i)
1022 }
1023 x = uint64(pbd.F_FloatRepeated[i])
1024 if x != i {
1025 t.Error("pbd.F_FloatRepeated bad", x, i)
1026 }
1027 x = pbd.F_Uint64Repeated[i]
1028 if x != i {
1029 t.Error("pbd.F_Uint64Repeated bad", x, i)
1030 }
1031 x = uint64(pbd.F_Uint32Repeated[i])
1032 if x != i {
1033 t.Error("pbd.F_Uint32Repeated bad", x, i)
1034 }
1035 x = pbd.F_Fixed64Repeated[i]
1036 if x != i {
1037 t.Error("pbd.F_Fixed64Repeated bad", x, i)
1038 }
1039 x = uint64(pbd.F_Fixed32Repeated[i])
1040 if x != i {
1041 t.Error("pbd.F_Fixed32Repeated bad", x, i)
1042 }
1043 x = uint64(pbd.F_Int64Repeated[i])
1044 if x != i {
1045 t.Error("pbd.F_Int64Repeated bad", x, i)
1046 }
1047 x = uint64(pbd.F_Int32Repeated[i])
1048 if x != i {
1049 t.Error("pbd.F_Int32Repeated bad", x, i)
1050 }
1051 if pbd.F_BoolRepeated[i] != (i%2 == 0) {
1052 t.Error("pbd.F_BoolRepeated bad", x, i)
1053 }
1054 if pbd.RepeatedField[i] == nil { // TODO: more checking?
1055 t.Error("pbd.RepeatedField bad")
1056 }
1057 }
1058}
1059
1060// Verify we give a useful message when decoding to the wrong structure type.
1061func TestTypeMismatch(t *testing.T) {
1062 pb1 := initGoTest(true)
1063
1064 // Marshal
1065 o := old()
1066 o.Marshal(pb1)
1067
1068 // Now Unmarshal it to the wrong type.
1069 pb2 := initGoTestField()
1070 err := o.Unmarshal(pb2)
1071 switch err {
1072 case ErrWrongType:
1073 // fine
1074 case nil:
1075 t.Error("expected wrong type error, got no error")
1076 default:
1077 t.Error("expected wrong type error, got", err)
1078 }
1079}
1080
David Symonds5b7775e2010-12-01 10:09:04 +11001081func encodeDecode(t *testing.T, in, out interface{}, msg string) {
1082 buf, err := Marshal(in)
1083 if err != nil {
1084 t.Fatalf("failed marshaling %v: %v", msg, err)
1085 }
1086 if err := Unmarshal(buf, out); err != nil {
1087 t.Fatalf("failed unmarshaling %v: %v", msg, err)
1088 }
1089}
1090
1091func TestPackedNonPackedDecoderSwitching(t *testing.T) {
1092 np, p := new(NonPackedTest), new(PackedTest)
1093
1094 // non-packed -> packed
1095 np.A = []int32{0, 1, 1, 2, 3, 5}
1096 encodeDecode(t, np, p, "non-packed -> packed")
1097 if !reflect.DeepEqual(np.A, p.B) {
1098 t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B)
1099 }
1100
1101 // packed -> non-packed
1102 np.Reset()
1103 p.B = []int32{3, 1, 4, 1, 5, 9}
1104 encodeDecode(t, p, np, "packed -> non-packed")
1105 if !reflect.DeepEqual(p.B, np.A) {
1106 t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A)
1107 }
1108}
1109
Rob Pikeaaa3a622010-03-20 22:32:34 -07001110func TestProto1RepeatedGroup(t *testing.T) {
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001111 pb := &MessageList{
1112 Message: []*MessageList_Message{
1113 &MessageList_Message{
1114 Name: String("blah"),
1115 Count: Int32(7),
1116 },
1117 // NOTE: pb.Message[1] is a nil
1118 nil,
1119 },
1120 }
Rob Pikeaaa3a622010-03-20 22:32:34 -07001121
1122 o := old()
1123 if err := o.Marshal(pb); err != ErrRepeatedHasNil {
1124 t.Fatalf("unexpected or no error when marshaling: %v", err)
1125 }
1126}
1127
Rob Pike9caa5b92010-05-11 16:04:57 -07001128
Rob Pikeaaa3a622010-03-20 22:32:34 -07001129// Test that enums work. Checks for a bug introduced by making enums
1130// named types instead of int32: newInt32FromUint64 would crash with
1131// a type mismatch in reflect.PointTo.
1132func TestEnum(t *testing.T) {
1133 pb := new(GoEnum)
1134 pb.Foo = NewFOO(FOO_FOO1)
1135 o := old()
1136 if err := o.Marshal(pb); err != nil {
Rob Pike853f9112010-12-17 13:56:46 -08001137 t.Fatal("error encoding enum:", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001138 }
1139 pb1 := new(GoEnum)
1140 if err := o.Unmarshal(pb1); err != nil {
Rob Pike853f9112010-12-17 13:56:46 -08001141 t.Fatal("error decoding enum:", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001142 }
1143 if *pb1.Foo != FOO_FOO1 {
Rob Pike853f9112010-12-17 13:56:46 -08001144 t.Error("expected 7 but got ", *pb1.Foo)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001145 }
1146}
1147
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001148// Verify that absent required fields cause Marshal/Unmarshal to return errors.
1149func TestRequiredFieldEnforcement(t *testing.T) {
1150 pb := new(GoTestField)
1151 _, err := Marshal(pb)
David Symonds5b7775e2010-12-01 10:09:04 +11001152 if err == nil {
1153 t.Error("marshal: expected error, got nil")
1154 } else if strings.Index(err.String(), "GoTestField") < 0 {
1155 t.Errorf("marshal: bad error type: %v", err)
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001156 }
1157
1158 // A slightly sneaky, yet valid, proto. It encodes the same required field twice,
1159 // so simply counting the required fields is insufficient.
1160 // field 1, encoding 2, value "hi"
1161 buf := []byte("\x0A\x02hi\x0A\x02hi")
1162 err = Unmarshal(buf, pb)
David Symonds5b7775e2010-12-01 10:09:04 +11001163 if err == nil {
1164 t.Error("unmarshal: expected error, got nil")
1165 } else if strings.Index(err.String(), "GoTestField") < 0 {
1166 t.Errorf("unmarshal: bad error type: %v", err)
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001167 }
1168}
1169
David Symonds03c9d412010-08-26 14:23:18 +10001170// A type that implements the Marshaler interface, but is not nillable.
1171type nonNillableInt uint64
1172
1173func (nni nonNillableInt) Marshal() ([]byte, os.Error) {
1174 return EncodeVarint(uint64(nni)), nil
1175}
1176
1177type NNIMessage struct {
1178 nni nonNillableInt
1179}
1180
1181// A type that implements the Marshaler interface and is nillable.
1182type nillableMessage struct {
1183 x uint64
1184}
1185
1186func (nm *nillableMessage) Marshal() ([]byte, os.Error) {
1187 return EncodeVarint(nm.x), nil
1188}
1189
1190type NMMessage struct {
1191 nm *nillableMessage
1192}
1193
1194// Verify a type that uses the Marshaler interface, but has a nil pointer.
1195func TestNilMarshaler(t *testing.T) {
1196 // Try a struct with a Marshaler field that is nil.
1197 // It should be directly marshable.
1198 nmm := new(NMMessage)
1199 if _, err := Marshal(nmm); err != nil {
1200 t.Error("unexpected error marshaling nmm: ", err)
1201 }
1202
1203 // Try a struct with a Marshaler field that is not nillable.
1204 nnim := new(NNIMessage)
1205 nnim.nni = 7
1206 var _ Marshaler = nnim.nni // verify it is truly a Marshaler
1207 if _, err := Marshal(nnim); err != nil {
1208 t.Error("unexpected error marshaling nnim: ", err)
1209 }
1210}
1211
Rob Pikeaaa3a622010-03-20 22:32:34 -07001212func BenchmarkMarshal(b *testing.B) {
1213 b.StopTimer()
1214
1215 pb := initGoTest(true)
1216
1217 // Create an array
1218 const N = 1000 // Internally the library starts much smaller.
1219 pb.F_Int32Repeated = make([]int32, N)
1220
1221 // Fill in the array with some values.
1222 for i := 0; i < N; i++ {
1223 pb.F_Int32Repeated[i] = int32(i)
1224 }
1225 p := NewBuffer(nil)
1226
1227 b.StartTimer()
1228 for i := 0; i < b.N; i++ {
1229 p.Reset()
1230 p.Marshal(pb)
1231 }
1232}
1233
1234func BenchmarkUnmarshal(b *testing.B) {
1235 b.StopTimer()
1236
1237 pb := initGoTest(true)
1238
1239 // Create an array
1240 const N = 1000 // Internally the library starts much smaller.
1241 pb.F_Int32Repeated = make([]int32, N)
1242
1243 // Fill in the array with some values.
1244 for i := 0; i < N; i++ {
1245 pb.F_Int32Repeated[i] = int32(i)
1246 }
Rob Pikec6d8e4a2010-07-28 15:34:32 -07001247 pbd := new(GoTest)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001248 p := NewBuffer(nil)
1249 p.Marshal(pb)
1250 p2 := NewBuffer(nil)
1251
1252 b.StartTimer()
1253 for i := 0; i < b.N; i++ {
1254 p2.SetBuf(p.Bytes())
1255 p2.Unmarshal(pbd)
1256 }
1257}