blob: f90020a48ff581b3df309882f6833797756644fe [file] [log] [blame]
Damien Neilc37adef2019-04-01 13:49:56 -07001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil99f24c32019-03-13 17:06:42 -07005package proto_test
6
7import (
8 "bytes"
9 "fmt"
Damien Neil99f24c32019-03-13 17:06:42 -070010 "testing"
11
Damien Neil99f24c32019-03-13 17:06:42 -070012 "github.com/google/go-cmp/cmp"
Damien Neile89e6242019-05-13 23:55:40 -070013 "google.golang.org/protobuf/proto"
Damien Neil3016b732019-04-07 12:43:10 -070014
Damien Neile89e6242019-05-13 23:55:40 -070015 test3pb "google.golang.org/protobuf/internal/testprotos/test3"
Damien Neil99f24c32019-03-13 17:06:42 -070016)
17
18func TestEncode(t *testing.T) {
19 for _, test := range testProtos {
20 for _, want := range test.decodeTo {
21 t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
Damien Neil96c229a2019-04-03 12:17:24 -070022 opts := proto.MarshalOptions{
23 AllowPartial: test.partial,
24 }
25 wire, err := opts.Marshal(want)
Damien Neil99f24c32019-03-13 17:06:42 -070026 if err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070027 t.Fatalf("Marshal error: %v\nMessage:\n%v", err, marshalText(want))
28 }
29
30 size := proto.Size(want)
31 if size != len(wire) {
32 t.Errorf("Size and marshal disagree: Size(m)=%v; len(Marshal(m))=%v\nMessage:\n%v", size, len(wire), marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070033 }
34
Joe Tsai378c1322019-04-25 23:48:08 -070035 got := want.ProtoReflect().New().Interface()
Damien Neil96c229a2019-04-03 12:17:24 -070036 uopts := proto.UnmarshalOptions{
37 AllowPartial: test.partial,
38 }
39 if err := uopts.Unmarshal(wire, got); err != nil {
Joe Tsai8d30bbe2019-05-16 15:53:25 -070040 t.Errorf("Unmarshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070041 return
42 }
Damien Neile6f060f2019-04-23 17:11:02 -070043 if !proto.Equal(got, want) {
Joe Tsai8d30bbe2019-05-16 15:53:25 -070044 t.Errorf("Unmarshal returned unexpected result; got:\n%v\nwant:\n%v", marshalText(got), marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070045 }
46 })
47 }
48 }
49}
50
51func TestEncodeDeterministic(t *testing.T) {
52 for _, test := range testProtos {
53 for _, want := range test.decodeTo {
54 t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
Damien Neil96c229a2019-04-03 12:17:24 -070055 opts := proto.MarshalOptions{
56 Deterministic: true,
57 AllowPartial: test.partial,
58 }
59 wire, err := opts.Marshal(want)
Damien Neil99f24c32019-03-13 17:06:42 -070060 if err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070061 t.Fatalf("Marshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070062 }
Damien Neil96c229a2019-04-03 12:17:24 -070063 wire2, err := opts.Marshal(want)
Damien Neil99f24c32019-03-13 17:06:42 -070064 if err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070065 t.Fatalf("Marshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070066 }
Damien Neil99f24c32019-03-13 17:06:42 -070067 if !bytes.Equal(wire, wire2) {
68 t.Fatalf("deterministic marshal returned varying results:\n%v", cmp.Diff(wire, wire2))
69 }
70
Joe Tsai378c1322019-04-25 23:48:08 -070071 got := want.ProtoReflect().New().Interface()
Damien Neil96c229a2019-04-03 12:17:24 -070072 uopts := proto.UnmarshalOptions{
73 AllowPartial: test.partial,
74 }
75 if err := uopts.Unmarshal(wire, got); err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070076 t.Errorf("Unmarshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070077 return
78 }
Damien Neile6f060f2019-04-23 17:11:02 -070079 if !proto.Equal(got, want) {
Damien Neil61e93c72019-03-27 09:23:20 -070080 t.Errorf("Unmarshal returned unexpected result; got:\n%v\nwant:\n%v", marshalText(got), marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070081 }
82 })
83 }
84 }
85}
Damien Neil96c229a2019-04-03 12:17:24 -070086
Damien Neilbc310b52019-04-11 11:46:55 -070087func TestEncodeInvalidUTF8(t *testing.T) {
88 for _, test := range invalidUTF8TestProtos {
89 for _, want := range test.decodeTo {
90 t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
Damien Neil8c86fc52019-06-19 09:28:29 -070091 _, err := proto.Marshal(want)
92 if err == nil {
Damien Neilbc310b52019-04-11 11:46:55 -070093 t.Errorf("Marshal did not return expected error for invalid UTF8: %v\nMessage:\n%v", err, marshalText(want))
94 }
Damien Neilbc310b52019-04-11 11:46:55 -070095 })
96 }
97 }
98}
99
Damien Neil96c229a2019-04-03 12:17:24 -0700100func TestEncodeRequiredFieldChecks(t *testing.T) {
101 for _, test := range testProtos {
102 if !test.partial {
103 continue
104 }
105 for _, m := range test.decodeTo {
106 t.Run(fmt.Sprintf("%s (%T)", test.desc, m), func(t *testing.T) {
107 _, err := proto.Marshal(m)
108 if err == nil {
109 t.Fatalf("Marshal succeeded (want error)\nMessage:\n%v", marshalText(m))
110 }
111 })
112 }
113 }
114}
Damien Neil3016b732019-04-07 12:43:10 -0700115
116func TestMarshalAppend(t *testing.T) {
117 want := []byte("prefix")
118 got := append([]byte(nil), want...)
119 got, err := proto.MarshalOptions{}.MarshalAppend(got, &test3pb.TestAllTypes{
120 OptionalString: "value",
121 })
122 if err != nil {
123 t.Fatal(err)
124 }
125 if !bytes.HasPrefix(got, want) {
126 t.Fatalf("MarshalAppend modified prefix: got %v, want prefix %v", got, want)
127 }
128}