blob: b9e04b95dfb7a10540495b9d493e6aeafa4e9142 [file] [log] [blame]
Damien Neil99f24c32019-03-13 17:06:42 -07001package proto_test
2
3import (
4 "bytes"
5 "fmt"
6 "reflect"
7 "testing"
8
9 protoV1 "github.com/golang/protobuf/proto"
Damien Neil99f24c32019-03-13 17:06:42 -070010 "github.com/golang/protobuf/v2/proto"
11 "github.com/google/go-cmp/cmp"
12)
13
14func TestEncode(t *testing.T) {
15 for _, test := range testProtos {
16 for _, want := range test.decodeTo {
17 t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
Damien Neil96c229a2019-04-03 12:17:24 -070018 opts := proto.MarshalOptions{
19 AllowPartial: test.partial,
20 }
21 wire, err := opts.Marshal(want)
Damien Neil99f24c32019-03-13 17:06:42 -070022 if err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070023 t.Fatalf("Marshal error: %v\nMessage:\n%v", err, marshalText(want))
24 }
25
26 size := proto.Size(want)
27 if size != len(wire) {
28 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 -070029 }
30
31 got := reflect.New(reflect.TypeOf(want).Elem()).Interface().(proto.Message)
Damien Neil96c229a2019-04-03 12:17:24 -070032 uopts := proto.UnmarshalOptions{
33 AllowPartial: test.partial,
34 }
35 if err := uopts.Unmarshal(wire, got); err != nil {
Damien Neil99f24c32019-03-13 17:06:42 -070036 t.Errorf("Unmarshal error: %v\nMessage:\n%v", err, protoV1.MarshalTextString(want.(protoV1.Message)))
37 return
38 }
39
Damien Neil96c229a2019-04-03 12:17:24 -070040 if test.invalidExtensions {
41 // Equal doesn't work on messages containing invalid extension data.
42 return
43 }
Damien Neil99f24c32019-03-13 17:06:42 -070044 if !protoV1.Equal(got.(protoV1.Message), want.(protoV1.Message)) {
45 t.Errorf("Unmarshal returned unexpected result; got:\n%v\nwant:\n%v", protoV1.MarshalTextString(got.(protoV1.Message)), protoV1.MarshalTextString(want.(protoV1.Message)))
46 }
47 })
48 }
49 }
50}
51
52func TestEncodeDeterministic(t *testing.T) {
53 for _, test := range testProtos {
54 for _, want := range test.decodeTo {
55 t.Run(fmt.Sprintf("%s (%T)", test.desc, want), func(t *testing.T) {
Damien Neil96c229a2019-04-03 12:17:24 -070056 opts := proto.MarshalOptions{
57 Deterministic: true,
58 AllowPartial: test.partial,
59 }
60 wire, err := opts.Marshal(want)
Damien Neil99f24c32019-03-13 17:06:42 -070061 if err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070062 t.Fatalf("Marshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070063 }
Damien Neil96c229a2019-04-03 12:17:24 -070064 wire2, err := opts.Marshal(want)
Damien Neil99f24c32019-03-13 17:06:42 -070065 if err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070066 t.Fatalf("Marshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070067 }
Damien Neil99f24c32019-03-13 17:06:42 -070068 if !bytes.Equal(wire, wire2) {
69 t.Fatalf("deterministic marshal returned varying results:\n%v", cmp.Diff(wire, wire2))
70 }
71
72 got := reflect.New(reflect.TypeOf(want).Elem()).Interface().(proto.Message)
Damien Neil96c229a2019-04-03 12:17:24 -070073 uopts := proto.UnmarshalOptions{
74 AllowPartial: test.partial,
75 }
76 if err := uopts.Unmarshal(wire, got); err != nil {
Damien Neil61e93c72019-03-27 09:23:20 -070077 t.Errorf("Unmarshal error: %v\nMessage:\n%v", err, marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070078 return
79 }
80
Damien Neil96c229a2019-04-03 12:17:24 -070081 if test.invalidExtensions {
82 // Equal doesn't work on messages containing invalid extension data.
83 return
84 }
Damien Neil99f24c32019-03-13 17:06:42 -070085 if !protoV1.Equal(got.(protoV1.Message), want.(protoV1.Message)) {
Damien Neil61e93c72019-03-27 09:23:20 -070086 t.Errorf("Unmarshal returned unexpected result; got:\n%v\nwant:\n%v", marshalText(got), marshalText(want))
Damien Neil99f24c32019-03-13 17:06:42 -070087 }
88 })
89 }
90 }
91}
Damien Neil96c229a2019-04-03 12:17:24 -070092
93func TestEncodeRequiredFieldChecks(t *testing.T) {
94 for _, test := range testProtos {
95 if !test.partial {
96 continue
97 }
98 for _, m := range test.decodeTo {
99 t.Run(fmt.Sprintf("%s (%T)", test.desc, m), func(t *testing.T) {
100 _, err := proto.Marshal(m)
101 if err == nil {
102 t.Fatalf("Marshal succeeded (want error)\nMessage:\n%v", marshalText(m))
103 }
104 })
105 }
106 }
107}