1
2
3
4
5 package protocmp
6
7 import (
8 "testing"
9
10 "github.com/google/go-cmp/cmp"
11
12 "google.golang.org/protobuf/internal/detrand"
13 "google.golang.org/protobuf/proto"
14 "google.golang.org/protobuf/reflect/protoreflect"
15 "google.golang.org/protobuf/testing/protopack"
16
17 testpb "google.golang.org/protobuf/internal/testprotos/test"
18 )
19
20 func init() {
21 detrand.Disable()
22 }
23
24 func TestTransform(t *testing.T) {
25 tests := []struct {
26 in proto.Message
27 want Message
28 }{{
29 in: &testpb.TestAllTypes{
30 OptionalBool: proto.Bool(false),
31 OptionalInt32: proto.Int32(-32),
32 OptionalInt64: proto.Int64(-64),
33 OptionalUint32: proto.Uint32(32),
34 OptionalUint64: proto.Uint64(64),
35 OptionalFloat: proto.Float32(32.32),
36 OptionalDouble: proto.Float64(64.64),
37 OptionalString: proto.String("string"),
38 OptionalBytes: []byte("bytes"),
39 OptionalNestedEnum: testpb.TestAllTypes_NEG.Enum(),
40 OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{A: proto.Int32(5)},
41 },
42 want: Message{
43 messageTypeKey: messageMetaOf(&testpb.TestAllTypes{}),
44 "optional_bool": bool(false),
45 "optional_int32": int32(-32),
46 "optional_int64": int64(-64),
47 "optional_uint32": uint32(32),
48 "optional_uint64": uint64(64),
49 "optional_float": float32(32.32),
50 "optional_double": float64(64.64),
51 "optional_string": string("string"),
52 "optional_bytes": []byte("bytes"),
53 "optional_nested_enum": enumOf(testpb.TestAllTypes_NEG),
54 "optional_nested_message": Message{messageTypeKey: messageMetaOf(&testpb.TestAllTypes_NestedMessage{}), "a": int32(5)},
55 },
56 }, {
57 in: &testpb.TestAllTypes{
58 RepeatedBool: []bool{false, true},
59 RepeatedInt32: []int32{32, -32},
60 RepeatedInt64: []int64{64, -64},
61 RepeatedUint32: []uint32{0, 32},
62 RepeatedUint64: []uint64{0, 64},
63 RepeatedFloat: []float32{0, 32.32},
64 RepeatedDouble: []float64{0, 64.64},
65 RepeatedString: []string{"s1", "s2"},
66 RepeatedBytes: [][]byte{{1}, {2}},
67 RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{
68 testpb.TestAllTypes_FOO,
69 testpb.TestAllTypes_BAR,
70 },
71 RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{
72 {A: proto.Int32(5)},
73 {A: proto.Int32(-5)},
74 },
75 },
76 want: Message{
77 messageTypeKey: messageMetaOf(&testpb.TestAllTypes{}),
78 "repeated_bool": []bool{false, true},
79 "repeated_int32": []int32{32, -32},
80 "repeated_int64": []int64{64, -64},
81 "repeated_uint32": []uint32{0, 32},
82 "repeated_uint64": []uint64{0, 64},
83 "repeated_float": []float32{0, 32.32},
84 "repeated_double": []float64{0, 64.64},
85 "repeated_string": []string{"s1", "s2"},
86 "repeated_bytes": [][]byte{{1}, {2}},
87 "repeated_nested_enum": []Enum{
88 enumOf(testpb.TestAllTypes_FOO),
89 enumOf(testpb.TestAllTypes_BAR),
90 },
91 "repeated_nested_message": []Message{
92 {messageTypeKey: messageMetaOf(&testpb.TestAllTypes_NestedMessage{}), "a": int32(5)},
93 {messageTypeKey: messageMetaOf(&testpb.TestAllTypes_NestedMessage{}), "a": int32(-5)},
94 },
95 },
96 }, {
97 in: &testpb.TestAllTypes{
98 MapBoolBool: map[bool]bool{true: false},
99 MapInt32Int32: map[int32]int32{-32: 32},
100 MapInt64Int64: map[int64]int64{-64: 64},
101 MapUint32Uint32: map[uint32]uint32{0: 32},
102 MapUint64Uint64: map[uint64]uint64{0: 64},
103 MapInt32Float: map[int32]float32{32: 32.32},
104 MapInt32Double: map[int32]float64{64: 64.64},
105 MapStringString: map[string]string{"k": "v", "empty": ""},
106 MapStringBytes: map[string][]byte{"k": []byte("v"), "empty": nil},
107 MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{
108 "k": testpb.TestAllTypes_FOO,
109 },
110 MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{
111 "k": {A: proto.Int32(5)},
112 },
113 },
114 want: Message{
115 messageTypeKey: messageMetaOf(&testpb.TestAllTypes{}),
116 "map_bool_bool": map[bool]bool{true: false},
117 "map_int32_int32": map[int32]int32{-32: 32},
118 "map_int64_int64": map[int64]int64{-64: 64},
119 "map_uint32_uint32": map[uint32]uint32{0: 32},
120 "map_uint64_uint64": map[uint64]uint64{0: 64},
121 "map_int32_float": map[int32]float32{32: 32.32},
122 "map_int32_double": map[int32]float64{64: 64.64},
123 "map_string_string": map[string]string{"k": "v", "empty": ""},
124 "map_string_bytes": map[string][]byte{"k": []byte("v"), "empty": []byte{}},
125 "map_string_nested_enum": map[string]Enum{
126 "k": enumOf(testpb.TestAllTypes_FOO),
127 },
128 "map_string_nested_message": map[string]Message{
129 "k": {messageTypeKey: messageMetaOf(&testpb.TestAllTypes_NestedMessage{}), "a": int32(5)},
130 },
131 },
132 }, {
133 in: func() proto.Message {
134 m := &testpb.TestAllExtensions{}
135 proto.SetExtension(m, testpb.E_OptionalBool, bool(false))
136 proto.SetExtension(m, testpb.E_OptionalInt32, int32(-32))
137 proto.SetExtension(m, testpb.E_OptionalInt64, int64(-64))
138 proto.SetExtension(m, testpb.E_OptionalUint32, uint32(32))
139 proto.SetExtension(m, testpb.E_OptionalUint64, uint64(64))
140 proto.SetExtension(m, testpb.E_OptionalFloat, float32(32.32))
141 proto.SetExtension(m, testpb.E_OptionalDouble, float64(64.64))
142 proto.SetExtension(m, testpb.E_OptionalString, string("string"))
143 proto.SetExtension(m, testpb.E_OptionalBytes, []byte("bytes"))
144 proto.SetExtension(m, testpb.E_OptionalNestedEnum, testpb.TestAllTypes_NEG)
145 proto.SetExtension(m, testpb.E_OptionalNestedMessage, &testpb.TestAllExtensions_NestedMessage{A: proto.Int32(5)})
146 return m
147 }(),
148 want: Message{
149 messageTypeKey: messageMetaOf(&testpb.TestAllExtensions{}),
150 "[goproto.proto.test.optional_bool]": bool(false),
151 "[goproto.proto.test.optional_int32]": int32(-32),
152 "[goproto.proto.test.optional_int64]": int64(-64),
153 "[goproto.proto.test.optional_uint32]": uint32(32),
154 "[goproto.proto.test.optional_uint64]": uint64(64),
155 "[goproto.proto.test.optional_float]": float32(32.32),
156 "[goproto.proto.test.optional_double]": float64(64.64),
157 "[goproto.proto.test.optional_string]": string("string"),
158 "[goproto.proto.test.optional_bytes]": []byte("bytes"),
159 "[goproto.proto.test.optional_nested_enum]": enumOf(testpb.TestAllTypes_NEG),
160 "[goproto.proto.test.optional_nested_message]": Message{messageTypeKey: messageMetaOf(&testpb.TestAllExtensions_NestedMessage{}), "a": int32(5)},
161 },
162 }, {
163 in: func() proto.Message {
164 m := &testpb.TestAllExtensions{}
165 proto.SetExtension(m, testpb.E_RepeatedBool, []bool{false, true})
166 proto.SetExtension(m, testpb.E_RepeatedInt32, []int32{32, -32})
167 proto.SetExtension(m, testpb.E_RepeatedInt64, []int64{64, -64})
168 proto.SetExtension(m, testpb.E_RepeatedUint32, []uint32{0, 32})
169 proto.SetExtension(m, testpb.E_RepeatedUint64, []uint64{0, 64})
170 proto.SetExtension(m, testpb.E_RepeatedFloat, []float32{0, 32.32})
171 proto.SetExtension(m, testpb.E_RepeatedDouble, []float64{0, 64.64})
172 proto.SetExtension(m, testpb.E_RepeatedString, []string{"s1", "s2"})
173 proto.SetExtension(m, testpb.E_RepeatedBytes, [][]byte{{1}, {2}})
174 proto.SetExtension(m, testpb.E_RepeatedNestedEnum, []testpb.TestAllTypes_NestedEnum{
175 testpb.TestAllTypes_FOO,
176 testpb.TestAllTypes_BAR,
177 })
178 proto.SetExtension(m, testpb.E_RepeatedNestedMessage, []*testpb.TestAllExtensions_NestedMessage{
179 {A: proto.Int32(5)},
180 {A: proto.Int32(-5)},
181 })
182 return m
183 }(),
184 want: Message{
185 messageTypeKey: messageMetaOf(&testpb.TestAllExtensions{}),
186 "[goproto.proto.test.repeated_bool]": []bool{false, true},
187 "[goproto.proto.test.repeated_int32]": []int32{32, -32},
188 "[goproto.proto.test.repeated_int64]": []int64{64, -64},
189 "[goproto.proto.test.repeated_uint32]": []uint32{0, 32},
190 "[goproto.proto.test.repeated_uint64]": []uint64{0, 64},
191 "[goproto.proto.test.repeated_float]": []float32{0, 32.32},
192 "[goproto.proto.test.repeated_double]": []float64{0, 64.64},
193 "[goproto.proto.test.repeated_string]": []string{"s1", "s2"},
194 "[goproto.proto.test.repeated_bytes]": [][]byte{{1}, {2}},
195 "[goproto.proto.test.repeated_nested_enum]": []Enum{
196 enumOf(testpb.TestAllTypes_FOO),
197 enumOf(testpb.TestAllTypes_BAR),
198 },
199 "[goproto.proto.test.repeated_nested_message]": []Message{
200 {messageTypeKey: messageMetaOf(&testpb.TestAllExtensions_NestedMessage{}), "a": int32(5)},
201 {messageTypeKey: messageMetaOf(&testpb.TestAllExtensions_NestedMessage{}), "a": int32(-5)},
202 },
203 },
204 }, {
205 in: func() proto.Message {
206 m := &testpb.TestAllTypes{}
207 m.ProtoReflect().SetUnknown(protopack.Message{
208 protopack.Tag{Number: 50000, Type: protopack.VarintType}, protopack.Uvarint(100),
209 protopack.Tag{Number: 50001, Type: protopack.Fixed32Type}, protopack.Uint32(200),
210 protopack.Tag{Number: 50002, Type: protopack.Fixed64Type}, protopack.Uint64(300),
211 protopack.Tag{Number: 50003, Type: protopack.BytesType}, protopack.String("hello"),
212 protopack.Message{
213 protopack.Tag{Number: 50004, Type: protopack.StartGroupType},
214 protopack.Tag{Number: 1, Type: protopack.VarintType}, protopack.Uvarint(100),
215 protopack.Tag{Number: 1, Type: protopack.Fixed32Type}, protopack.Uint32(200),
216 protopack.Tag{Number: 1, Type: protopack.Fixed64Type}, protopack.Uint64(300),
217 protopack.Tag{Number: 1, Type: protopack.BytesType}, protopack.String("hello"),
218 protopack.Message{
219 protopack.Tag{Number: 1, Type: protopack.StartGroupType},
220 protopack.Tag{Number: 1, Type: protopack.VarintType}, protopack.Uvarint(100),
221 protopack.Tag{Number: 1, Type: protopack.Fixed32Type}, protopack.Uint32(200),
222 protopack.Tag{Number: 1, Type: protopack.Fixed64Type}, protopack.Uint64(300),
223 protopack.Tag{Number: 1, Type: protopack.BytesType}, protopack.String("hello"),
224 protopack.Tag{Number: 1, Type: protopack.EndGroupType},
225 },
226 protopack.Tag{Number: 50004, Type: protopack.EndGroupType},
227 },
228 }.Marshal())
229 return m
230 }(),
231 want: Message{
232 messageTypeKey: messageMetaOf(&testpb.TestAllTypes{}),
233 "50000": protoreflect.RawFields(protopack.Message{protopack.Tag{Number: 50000, Type: protopack.VarintType}, protopack.Uvarint(100)}.Marshal()),
234 "50001": protoreflect.RawFields(protopack.Message{protopack.Tag{Number: 50001, Type: protopack.Fixed32Type}, protopack.Uint32(200)}.Marshal()),
235 "50002": protoreflect.RawFields(protopack.Message{protopack.Tag{Number: 50002, Type: protopack.Fixed64Type}, protopack.Uint64(300)}.Marshal()),
236 "50003": protoreflect.RawFields(protopack.Message{protopack.Tag{Number: 50003, Type: protopack.BytesType}, protopack.String("hello")}.Marshal()),
237 "50004": protoreflect.RawFields(protopack.Message{
238 protopack.Tag{Number: 50004, Type: protopack.StartGroupType},
239 protopack.Tag{Number: 1, Type: protopack.VarintType}, protopack.Uvarint(100),
240 protopack.Tag{Number: 1, Type: protopack.Fixed32Type}, protopack.Uint32(200),
241 protopack.Tag{Number: 1, Type: protopack.Fixed64Type}, protopack.Uint64(300),
242 protopack.Tag{Number: 1, Type: protopack.BytesType}, protopack.String("hello"),
243 protopack.Message{
244 protopack.Tag{Number: 1, Type: protopack.StartGroupType},
245 protopack.Tag{Number: 1, Type: protopack.VarintType}, protopack.Uvarint(100),
246 protopack.Tag{Number: 1, Type: protopack.Fixed32Type}, protopack.Uint32(200),
247 protopack.Tag{Number: 1, Type: protopack.Fixed64Type}, protopack.Uint64(300),
248 protopack.Tag{Number: 1, Type: protopack.BytesType}, protopack.String("hello"),
249 protopack.Tag{Number: 1, Type: protopack.EndGroupType},
250 },
251 protopack.Tag{Number: 50004, Type: protopack.EndGroupType},
252 }.Marshal()),
253 },
254 }}
255 for _, tt := range tests {
256 t.Run("", func(t *testing.T) {
257 got := transformMessage(tt.in.ProtoReflect())
258 if diff := cmp.Diff(tt.want, got); diff != "" {
259 t.Errorf("Transform() mismatch (-want +got):\n%v", diff)
260 }
261 if got.Unwrap() != tt.in {
262 t.Errorf("got.Unwrap() = %p, want %p", got.Unwrap(), tt.in)
263 }
264 })
265 }
266 }
267
268 func enumOf(e protoreflect.Enum) Enum {
269 return Enum{e.Number(), e.Descriptor()}
270 }
271
272 func messageMetaOf(m protoreflect.ProtoMessage) messageMeta {
273 return messageMeta{m: m, md: m.ProtoReflect().Descriptor()}
274 }
275
View as plain text