1
2
3
4
5
6
7
8
9 package proto_test
10
11 import (
12 "bytes"
13 "errors"
14 "fmt"
15 "testing"
16
17 "google.golang.org/protobuf/internal/impl"
18 "google.golang.org/protobuf/proto"
19 "google.golang.org/protobuf/runtime/protoiface"
20
21 legacypb "google.golang.org/protobuf/internal/testprotos/legacy"
22 )
23
24 type selfMarshaler struct {
25 bytes []byte
26 err error
27 }
28
29 func (m selfMarshaler) Reset() {}
30 func (m selfMarshaler) ProtoMessage() {}
31
32 func (m selfMarshaler) String() string {
33 return fmt.Sprintf("selfMarshaler{bytes:%v, err:%v}", m.bytes, m.err)
34 }
35
36 func (m selfMarshaler) Marshal() ([]byte, error) {
37 return m.bytes, m.err
38 }
39
40 func (m *selfMarshaler) Unmarshal(b []byte) error {
41 m.bytes = b
42 return m.err
43 }
44
45 func TestLegacyMarshalMethod(t *testing.T) {
46 for _, test := range []selfMarshaler{
47 {bytes: []byte("marshal")},
48 {bytes: []byte("marshal"), err: errors.New("some error")},
49 } {
50 m := impl.Export{}.MessageOf(test).Interface()
51 b, err := proto.Marshal(m)
52 if err != test.err || !bytes.Equal(b, test.bytes) {
53 t.Errorf("proto.Marshal(%v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
54 }
55 if gotSize, wantSize := proto.Size(m), len(test.bytes); gotSize != wantSize {
56 t.Fatalf("proto.Size(%v) = %v, want %v", test, gotSize, wantSize)
57 }
58
59 prefix := []byte("prefix")
60 want := append(prefix, test.bytes...)
61 b, err = proto.MarshalOptions{}.MarshalAppend(prefix, m)
62 if err != test.err || !bytes.Equal(b, want) {
63 t.Errorf("MarshalAppend(%v, %v) = %v, %v; want %v, %v", prefix, test, b, err, test.bytes, test.err)
64 }
65
66 b, err = proto.MarshalOptions{
67 Deterministic: true,
68 }.MarshalAppend(nil, m)
69 if err != test.err || !bytes.Equal(b, test.bytes) {
70 t.Errorf("MarshalOptions{Deterministic:true}.MarshalAppend(nil, %v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
71 }
72 }
73 }
74
75 func TestLegacyUnmarshalMethod(t *testing.T) {
76 sm := &selfMarshaler{}
77 m := impl.Export{}.MessageOf(sm).Interface()
78 want := []byte("unmarshal")
79 if err := proto.Unmarshal(want, m); err != nil {
80 t.Fatalf("proto.Unmarshal(selfMarshaler{}) = %v, want nil", err)
81 }
82 if !bytes.Equal(sm.bytes, want) {
83 t.Fatalf("proto.Unmarshal(selfMarshaler{}): Marshal method not called")
84 }
85 }
86
87 type descPanicSelfMarshaler struct{}
88
89 const descPanicSelfMarshalerBytes = "bytes"
90
91 func (m *descPanicSelfMarshaler) Reset() {}
92 func (m *descPanicSelfMarshaler) ProtoMessage() {}
93 func (m *descPanicSelfMarshaler) Descriptor() ([]byte, []int) { panic("Descriptor method panics") }
94 func (m *descPanicSelfMarshaler) String() string { return "descPanicSelfMarshaler{}" }
95 func (m *descPanicSelfMarshaler) Marshal() ([]byte, error) {
96 return []byte(descPanicSelfMarshalerBytes), nil
97 }
98
99 func TestSelfMarshalerDescriptorPanics(t *testing.T) {
100 m := &descPanicSelfMarshaler{}
101 got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
102 want := []byte(descPanicSelfMarshalerBytes)
103 if err != nil || !bytes.Equal(got, want) {
104 t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
105 }
106 }
107
108 type descSelfMarshaler struct {
109 someField int
110 }
111
112 const descSelfMarshalerBytes = "bytes"
113
114 func (m *descSelfMarshaler) Reset() {}
115 func (m *descSelfMarshaler) ProtoMessage() {}
116 func (m *descSelfMarshaler) Descriptor() ([]byte, []int) {
117 return ((*legacypb.Legacy)(nil)).GetF1().Descriptor()
118 }
119 func (m *descSelfMarshaler) String() string {
120 return "descSelfMarshaler{}"
121 }
122 func (m *descSelfMarshaler) Marshal() ([]byte, error) {
123 return []byte(descSelfMarshalerBytes), nil
124 }
125
126 func TestSelfMarshalerWithDescriptor(t *testing.T) {
127 m := &descSelfMarshaler{}
128 got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
129 want := []byte(descSelfMarshalerBytes)
130 if err != nil || !bytes.Equal(got, want) {
131 t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
132 }
133 }
134
135 func TestDecodeFastCheckInitialized(t *testing.T) {
136 for _, test := range testValidMessages {
137 if !test.checkFastInit {
138 continue
139 }
140 for _, message := range test.decodeTo {
141 t.Run(fmt.Sprintf("%s (%T)", test.desc, message), func(t *testing.T) {
142 m := message.ProtoReflect().New()
143 opts := proto.UnmarshalOptions{
144 AllowPartial: true,
145 }
146 out, err := opts.UnmarshalState(protoiface.UnmarshalInput{
147 Buf: test.wire,
148 Message: m,
149 })
150 if err != nil {
151 t.Fatalf("Unmarshal error: %v", err)
152 }
153 if got, want := (out.Flags&protoiface.UnmarshalInitialized != 0), !test.partial; got != want {
154 t.Errorf("out.Initialized = %v, want %v", got, want)
155 }
156 })
157 }
158 }
159 }
160
161 type selfMerger struct {
162 src protoiface.MessageV1
163 }
164
165 func (*selfMerger) Reset() {}
166 func (*selfMerger) ProtoMessage() {}
167 func (*selfMerger) String() string { return "selfMerger{}" }
168 func (m *selfMerger) Merge(src protoiface.MessageV1) {
169 m.src = src
170 }
171
172 func TestLegacyMergeMethod(t *testing.T) {
173 src := &selfMerger{}
174 dst := &selfMerger{}
175 proto.Merge(
176 impl.Export{}.MessageOf(dst).Interface(),
177 impl.Export{}.MessageOf(src).Interface(),
178 )
179 if got, want := dst.src, src; got != want {
180 t.Errorf("Merge(dst, src): want dst.src = src, got %v", got)
181 }
182 if got := src.src; got != nil {
183 t.Errorf("Merge(dst, src): want src.src = nil, got %v", got)
184 }
185 }
186
View as plain text