blob: 2fe53edc4bd408cf79ec8f6299ea6882865d84d4 [file] [log] [blame]
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001// Copyright 2018 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
5package impl
6
7import (
Joe Tsai91e14662018-09-13 13:24:35 -07008 "fmt"
9 "math"
10 "strings"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070011 "testing"
12
13 "github.com/google/go-cmp/cmp"
Joe Tsai91e14662018-09-13 13:24:35 -070014 "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070015
Joe Tsai2c870bb2018-10-17 11:46:52 -070016 "github.com/golang/protobuf/proto"
Joe Tsai01ab2962018-09-21 17:44:00 -070017 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
18 ptype "github.com/golang/protobuf/v2/reflect/prototype"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070019)
20
Joe Tsaic6b75612018-09-13 14:24:37 -070021func mustMakeMessageDesc(t ptype.StandaloneMessage) pref.MessageDescriptor {
22 md, err := ptype.NewMessage(&t)
23 if err != nil {
24 panic(err)
25 }
26 return md
27}
28
Joe Tsai91e14662018-09-13 13:24:35 -070029var V = pref.ValueOf
30
Joe Tsaifa02f4e2018-09-12 16:20:37 -070031type (
32 MyBool bool
33 MyInt32 int32
34 MyInt64 int64
35 MyUint32 uint32
36 MyUint64 uint64
37 MyFloat32 float32
38 MyFloat64 float64
39 MyString string
40 MyBytes []byte
Joe Tsai91e14662018-09-13 13:24:35 -070041
42 NamedStrings []MyString
43 NamedBytes []MyBytes
Joe Tsaibbfaeb72018-10-17 00:27:21 +000044
45 MapStrings map[MyString]MyString
46 MapBytes map[MyString]MyBytes
Joe Tsaifa02f4e2018-09-12 16:20:37 -070047)
48
Joe Tsai91e14662018-09-13 13:24:35 -070049// List of test operations to perform on messages, vectors, or maps.
50type (
51 messageOp interface{} // equalMessage | hasFields | getFields | setFields | clearFields | vectorFields | mapFields
52 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070053
Joe Tsai91e14662018-09-13 13:24:35 -070054 vectorOp interface{} // equalVector | lenVector | getVector | setVector | appendVector | truncVector
55 vectorOps []vectorOp
56
Joe Tsaibbfaeb72018-10-17 00:27:21 +000057 mapOp interface{} // equalMap | lenMap | hasMap | getMap | setMap | clearMap | rangeMap
58 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070059)
60
61// Test operations performed on a message.
62type (
63 equalMessage pref.Message
64 hasFields map[pref.FieldNumber]bool
65 getFields map[pref.FieldNumber]pref.Value
66 setFields map[pref.FieldNumber]pref.Value
67 clearFields map[pref.FieldNumber]bool
68 vectorFields map[pref.FieldNumber]vectorOps
69 mapFields map[pref.FieldNumber]mapOps
70 messageFields map[pref.FieldNumber]messageOps
71 // TODO: Mutable, Range, ExtensionTypes
72)
73
74// Test operations performed on a vector.
75type (
76 equalVector pref.Vector
77 lenVector int
78 getVector map[int]pref.Value
79 setVector map[int]pref.Value
80 appendVector []pref.Value
81 truncVector int
82 // TODO: Mutable, MutableAppend
83)
84
Joe Tsaibbfaeb72018-10-17 00:27:21 +000085// Test operations performed on a map.
86type (
87 equalMap pref.Map
88 lenMap int
89 hasMap map[interface{}]bool
90 getMap map[interface{}]pref.Value
91 setMap map[interface{}]pref.Value
92 clearMap map[interface{}]bool
93 rangeMap map[interface{}]pref.Value
Joe Tsai3903b212018-10-17 11:54:32 -070094 // TODO: Mutable
Joe Tsaibbfaeb72018-10-17 00:27:21 +000095)
96
Joe Tsai91e14662018-09-13 13:24:35 -070097func TestScalarProto2(t *testing.T) {
98 type ScalarProto2 struct {
99 Bool *bool `protobuf:"1"`
100 Int32 *int32 `protobuf:"2"`
101 Int64 *int64 `protobuf:"3"`
102 Uint32 *uint32 `protobuf:"4"`
103 Uint64 *uint64 `protobuf:"5"`
104 Float32 *float32 `protobuf:"6"`
105 Float64 *float64 `protobuf:"7"`
106 String *string `protobuf:"8"`
107 StringA []byte `protobuf:"9"`
108 Bytes []byte `protobuf:"10"`
109 BytesA *string `protobuf:"11"`
110
111 MyBool *MyBool `protobuf:"12"`
112 MyInt32 *MyInt32 `protobuf:"13"`
113 MyInt64 *MyInt64 `protobuf:"14"`
114 MyUint32 *MyUint32 `protobuf:"15"`
115 MyUint64 *MyUint64 `protobuf:"16"`
116 MyFloat32 *MyFloat32 `protobuf:"17"`
117 MyFloat64 *MyFloat64 `protobuf:"18"`
118 MyString *MyString `protobuf:"19"`
119 MyStringA MyBytes `protobuf:"20"`
120 MyBytes MyBytes `protobuf:"21"`
121 MyBytesA *MyString `protobuf:"22"`
122 }
123
124 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
125 Syntax: pref.Proto2,
126 FullName: "ScalarProto2",
127 Fields: []ptype.Field{
128 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
129 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2))},
130 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3))},
131 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4))},
132 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5))},
133 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6))},
134 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7))},
135 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8"))},
136 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9"))},
137 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("10"))},
138 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11"))},
139
140 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
141 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(13))},
142 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(14))},
143 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(15))},
144 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(16))},
145 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(17))},
146 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(18))},
147 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("19"))},
148 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("20"))},
149 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("21"))},
150 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("22"))},
151 },
152 })}
153
154 testMessage(t, nil, mi.MessageOf(&ScalarProto2{}), messageOps{
155 hasFields{
156 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
157 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
158 },
159 getFields{
160 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
161 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
162 },
163 setFields{
164 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
165 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
166 },
167 hasFields{
168 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
169 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
170 },
171 equalMessage(mi.MessageOf(&ScalarProto2{
172 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
173 new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
174 })),
175 clearFields{
176 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
177 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
178 },
179 equalMessage(mi.MessageOf(&ScalarProto2{})),
180 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700181}
182
Joe Tsai91e14662018-09-13 13:24:35 -0700183func TestScalarProto3(t *testing.T) {
184 type ScalarProto3 struct {
185 Bool bool `protobuf:"1"`
186 Int32 int32 `protobuf:"2"`
187 Int64 int64 `protobuf:"3"`
188 Uint32 uint32 `protobuf:"4"`
189 Uint64 uint64 `protobuf:"5"`
190 Float32 float32 `protobuf:"6"`
191 Float64 float64 `protobuf:"7"`
192 String string `protobuf:"8"`
193 StringA []byte `protobuf:"9"`
194 Bytes []byte `protobuf:"10"`
195 BytesA string `protobuf:"11"`
Joe Tsaic6b75612018-09-13 14:24:37 -0700196
Joe Tsai91e14662018-09-13 13:24:35 -0700197 MyBool MyBool `protobuf:"12"`
198 MyInt32 MyInt32 `protobuf:"13"`
199 MyInt64 MyInt64 `protobuf:"14"`
200 MyUint32 MyUint32 `protobuf:"15"`
201 MyUint64 MyUint64 `protobuf:"16"`
202 MyFloat32 MyFloat32 `protobuf:"17"`
203 MyFloat64 MyFloat64 `protobuf:"18"`
204 MyString MyString `protobuf:"19"`
205 MyStringA MyBytes `protobuf:"20"`
206 MyBytes MyBytes `protobuf:"21"`
207 MyBytesA MyString `protobuf:"22"`
208 }
Joe Tsaic6b75612018-09-13 14:24:37 -0700209
Joe Tsai91e14662018-09-13 13:24:35 -0700210 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
211 Syntax: pref.Proto3,
212 FullName: "ScalarProto3",
213 Fields: []ptype.Field{
214 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
215 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
216 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
217 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
218 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
219 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
220 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
221 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
222 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
223 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
224 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700225
Joe Tsai91e14662018-09-13 13:24:35 -0700226 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
227 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
228 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
229 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
230 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
231 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
232 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
233 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
234 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
235 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
236 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
237 },
238 })}
239
240 testMessage(t, nil, mi.MessageOf(&ScalarProto3{}), messageOps{
241 hasFields{
242 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
243 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
244 },
245 getFields{
246 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
247 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
248 },
249 setFields{
250 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
251 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
252 },
253 hasFields{
254 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
255 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
256 },
257 equalMessage(mi.MessageOf(&ScalarProto3{})),
258 setFields{
259 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
260 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
261 },
262 hasFields{
263 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
264 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
265 },
266 equalMessage(mi.MessageOf(&ScalarProto3{
267 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
268 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
269 })),
270 clearFields{
271 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
272 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
273 },
274 equalMessage(mi.MessageOf(&ScalarProto3{})),
275 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700276}
277
Joe Tsai91e14662018-09-13 13:24:35 -0700278func TestRepeatedScalars(t *testing.T) {
279 type RepeatedScalars struct {
280 Bools []bool `protobuf:"1"`
281 Int32s []int32 `protobuf:"2"`
282 Int64s []int64 `protobuf:"3"`
283 Uint32s []uint32 `protobuf:"4"`
284 Uint64s []uint64 `protobuf:"5"`
285 Float32s []float32 `protobuf:"6"`
286 Float64s []float64 `protobuf:"7"`
287 Strings []string `protobuf:"8"`
288 StringsA [][]byte `protobuf:"9"`
289 Bytes [][]byte `protobuf:"10"`
290 BytesA []string `protobuf:"11"`
Joe Tsaic6b75612018-09-13 14:24:37 -0700291
Joe Tsai91e14662018-09-13 13:24:35 -0700292 MyStrings1 []MyString `protobuf:"12"`
293 MyStrings2 []MyBytes `protobuf:"13"`
294 MyBytes1 []MyBytes `protobuf:"14"`
295 MyBytes2 []MyString `protobuf:"15"`
Joe Tsaic6b75612018-09-13 14:24:37 -0700296
Joe Tsai91e14662018-09-13 13:24:35 -0700297 MyStrings3 NamedStrings `protobuf:"16"`
298 MyStrings4 NamedBytes `protobuf:"17"`
299 MyBytes3 NamedBytes `protobuf:"18"`
300 MyBytes4 NamedStrings `protobuf:"19"`
301 }
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700302
Joe Tsai91e14662018-09-13 13:24:35 -0700303 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
304 Syntax: pref.Proto2,
305 FullName: "RepeatedScalars",
306 Fields: []ptype.Field{
307 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
308 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
309 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
310 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
311 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
312 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
313 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
314 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
315 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
316 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
317 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700318
Joe Tsai91e14662018-09-13 13:24:35 -0700319 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
320 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
321 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
322 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
323
324 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
325 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
326 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
327 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700328 },
Joe Tsai91e14662018-09-13 13:24:35 -0700329 })}
330
331 empty := mi.MessageOf(&RepeatedScalars{})
332 emptyFS := empty.KnownFields()
333
334 want := mi.MessageOf(&RepeatedScalars{
335 Bools: []bool{true, false, true},
336 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
337 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
338 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
339 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
340 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
341 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
342 Strings: []string{"8", "", "eight"},
343 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
344 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
345 BytesA: []string{"11", "", "eleven"},
346
347 MyStrings1: []MyString{"12", "", "twelve"},
348 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
349 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
350 MyBytes2: []MyString{"15", "", "fifteen"},
351
352 MyStrings3: NamedStrings{"16", "", "sixteen"},
353 MyStrings4: NamedBytes{[]byte("17"), nil, []byte("seventeen")},
354 MyBytes3: NamedBytes{[]byte("18"), nil, []byte("eighteen")},
355 MyBytes4: NamedStrings{"19", "", "nineteen"},
356 })
357 wantFS := want.KnownFields()
358
359 testMessage(t, nil, mi.MessageOf(&RepeatedScalars{}), messageOps{
360 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false},
361 getFields{1: emptyFS.Get(1), 3: emptyFS.Get(3), 5: emptyFS.Get(5), 7: emptyFS.Get(7), 9: emptyFS.Get(9), 11: emptyFS.Get(11), 13: emptyFS.Get(13), 15: emptyFS.Get(15), 17: emptyFS.Get(17), 19: emptyFS.Get(19)},
362 setFields{1: wantFS.Get(1), 3: wantFS.Get(3), 5: wantFS.Get(5), 7: wantFS.Get(7), 9: wantFS.Get(9), 11: wantFS.Get(11), 13: wantFS.Get(13), 15: wantFS.Get(15), 17: wantFS.Get(17), 19: wantFS.Get(19)},
363 vectorFields{
364 2: {
365 lenVector(0),
366 appendVector{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
367 getVector{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
368 equalVector(wantFS.Get(2).Vector()),
369 },
370 4: {
371 appendVector{V(uint32(0)), V(uint32(0)), V(uint32(0))},
372 setVector{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
373 lenVector(3),
374 },
375 6: {
376 appendVector{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
377 equalVector(wantFS.Get(6).Vector()),
378 },
379 8: {
380 appendVector{V(""), V(""), V(""), V(""), V(""), V("")},
381 lenVector(6),
382 setVector{0: V("8"), 2: V("eight")},
383 truncVector(3),
384 equalVector(wantFS.Get(8).Vector()),
385 },
386 10: {
387 appendVector{V([]byte(nil)), V([]byte(nil))},
388 setVector{0: V([]byte("10"))},
389 appendVector{V([]byte("wrong"))},
390 setVector{2: V([]byte("ten"))},
391 equalVector(wantFS.Get(10).Vector()),
392 },
393 12: {
394 appendVector{V("12"), V("wrong"), V("twelve")},
395 setVector{1: V("")},
396 equalVector(wantFS.Get(12).Vector()),
397 },
398 14: {
399 appendVector{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
400 equalVector(wantFS.Get(14).Vector()),
401 },
402 16: {
403 appendVector{V("16"), V(""), V("sixteen"), V("extra")},
404 truncVector(3),
405 equalVector(wantFS.Get(16).Vector()),
406 },
407 18: {
408 appendVector{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
409 equalVector(wantFS.Get(18).Vector()),
410 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700411 },
Joe Tsai91e14662018-09-13 13:24:35 -0700412 hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true},
413 equalMessage(want),
414 clearFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000415 equalMessage(empty),
416 })
417}
418
419func TestMapScalars(t *testing.T) {
420 type MapScalars struct {
421 KeyBools map[bool]string `protobuf:"1"`
422 KeyInt32s map[int32]string `protobuf:"2"`
423 KeyInt64s map[int64]string `protobuf:"3"`
424 KeyUint32s map[uint32]string `protobuf:"4"`
425 KeyUint64s map[uint64]string `protobuf:"5"`
426 KeyStrings map[string]string `protobuf:"6"`
427
428 ValBools map[string]bool `protobuf:"7"`
429 ValInt32s map[string]int32 `protobuf:"8"`
430 ValInt64s map[string]int64 `protobuf:"9"`
431 ValUint32s map[string]uint32 `protobuf:"10"`
432 ValUint64s map[string]uint64 `protobuf:"11"`
433 ValFloat32s map[string]float32 `protobuf:"12"`
434 ValFloat64s map[string]float64 `protobuf:"13"`
435 ValStrings map[string]string `protobuf:"14"`
436 ValStringsA map[string][]byte `protobuf:"15"`
437 ValBytes map[string][]byte `protobuf:"16"`
438 ValBytesA map[string]string `protobuf:"17"`
439
440 MyStrings1 map[MyString]MyString `protobuf:"18"`
441 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
442 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
443 MyBytes2 map[MyString]MyString `protobuf:"21"`
444
445 MyStrings3 MapStrings `protobuf:"22"`
446 MyStrings4 MapBytes `protobuf:"23"`
447 MyBytes3 MapBytes `protobuf:"24"`
448 MyBytes4 MapStrings `protobuf:"25"`
449 }
450
451 mustMakeMapEntry := func(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
452 return ptype.Field{
453 Name: pref.Name(fmt.Sprintf("f%d", n)),
454 Number: n,
455 Cardinality: pref.Repeated,
456 Kind: pref.MessageKind,
457 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
458 Syntax: pref.Proto2,
459 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
460 Fields: []ptype.Field{
461 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
462 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
463 },
464 IsMapEntry: true,
465 }),
466 }
467 }
468 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
469 Syntax: pref.Proto2,
470 FullName: "MapScalars",
471 Fields: []ptype.Field{
472 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
473 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
474 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
475 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
476 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
477 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
478
479 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
480 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
481 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
482 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
483 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
484 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
485 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
486 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
487 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
488 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
489 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
490
491 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
492 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
493 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
494 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
495
496 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
497 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
498 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
499 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
500 },
501 })}
502
503 empty := mi.MessageOf(&MapScalars{})
504 emptyFS := empty.KnownFields()
505
506 want := mi.MessageOf(&MapScalars{
507 KeyBools: map[bool]string{true: "true", false: "false"},
508 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
509 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
510 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
511 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
512 KeyStrings: map[string]string{"": "", "foo": "bar"},
513
514 ValBools: map[string]bool{"true": true, "false": false},
515 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
516 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
517 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
518 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
519 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
520 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
521 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
522 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
523 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
524 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
525
526 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
527 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
528 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
529 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
530
531 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
532 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
533 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
534 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
535 })
536 wantFS := want.KnownFields()
537
538 testMessage(t, nil, mi.MessageOf(&MapScalars{}), messageOps{
539 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false, 23: false, 24: false, 25: false},
540 getFields{1: emptyFS.Get(1), 3: emptyFS.Get(3), 5: emptyFS.Get(5), 7: emptyFS.Get(7), 9: emptyFS.Get(9), 11: emptyFS.Get(11), 13: emptyFS.Get(13), 15: emptyFS.Get(15), 17: emptyFS.Get(17), 19: emptyFS.Get(19), 21: emptyFS.Get(21), 23: emptyFS.Get(23), 25: emptyFS.Get(25)},
541 setFields{1: wantFS.Get(1), 3: wantFS.Get(3), 5: wantFS.Get(5), 7: wantFS.Get(7), 9: wantFS.Get(9), 11: wantFS.Get(11), 13: wantFS.Get(13), 15: wantFS.Get(15), 17: wantFS.Get(17), 19: wantFS.Get(19), 21: wantFS.Get(21), 23: wantFS.Get(23), 25: wantFS.Get(25)},
542 mapFields{
543 2: {
544 lenMap(0),
545 hasMap{int32(0): false, int32(-1): false, int32(2): false},
546 setMap{int32(0): V("zero")},
547 lenMap(1),
548 hasMap{int32(0): true, int32(-1): false, int32(2): false},
549 setMap{int32(-1): V("one")},
550 lenMap(2),
551 hasMap{int32(0): true, int32(-1): true, int32(2): false},
552 setMap{int32(2): V("two")},
553 lenMap(3),
554 hasMap{int32(0): true, int32(-1): true, int32(2): true},
555 },
556 4: {
557 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
558 equalMap(wantFS.Get(4).Map()),
559 },
560 6: {
561 clearMap{"noexist": true},
562 setMap{"foo": V("bar")},
563 setMap{"": V("empty")},
564 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
565 setMap{"": V(""), "extra": V("extra")},
566 clearMap{"extra": true, "noexist": true},
567 },
568 8: {
569 equalMap(emptyFS.Get(8).Map()),
570 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
571 },
572 10: {
573 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
574 lenMap(3),
575 equalMap(wantFS.Get(10).Map()),
576 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
577 },
578 12: {
579 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
580 clearMap{"e": true, "phi": true},
581 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
582 },
583 14: {
584 equalMap(emptyFS.Get(14).Map()),
585 setMap{"s1": V("s1"), "s2": V("s2")},
586 },
587 16: {
588 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
589 equalMap(wantFS.Get(16).Map()),
590 },
591 18: {
592 hasMap{"s1": false, "s2": false, "s3": false},
593 setMap{"s1": V("s1"), "s2": V("s2")},
594 hasMap{"s1": true, "s2": true, "s3": false},
595 },
596 20: {
597 equalMap(emptyFS.Get(20).Map()),
598 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
599 },
600 22: {
601 rangeMap{},
602 setMap{"s1": V("s1"), "s2": V("s2")},
603 rangeMap{"s1": V("s1"), "s2": V("s2")},
604 lenMap(2),
605 },
606 24: {
607 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
608 equalMap(wantFS.Get(24).Map()),
609 },
610 },
611 hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true, 23: true, 24: true, 25: true},
612 equalMessage(want),
613 clearFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true, 23: true, 24: true, 25: true},
614 equalMessage(empty),
Joe Tsai91e14662018-09-13 13:24:35 -0700615 })
616}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700617
Joe Tsai2c870bb2018-10-17 11:46:52 -0700618type (
619 OneofScalars struct {
620 Union isOneofScalars_Union `protobuf_oneof:"union"`
621 }
622 isOneofScalars_Union interface {
623 isOneofScalars_Union()
624 }
625
626 OneofScalars_Bool struct {
627 Bool bool `protobuf:"1"`
628 }
629 OneofScalars_Int32 struct {
630 Int32 MyInt32 `protobuf:"2"`
631 }
632 OneofScalars_Int64 struct {
633 Int64 int64 `protobuf:"3"`
634 }
635 OneofScalars_Uint32 struct {
636 Uint32 MyUint32 `protobuf:"4"`
637 }
638 OneofScalars_Uint64 struct {
639 Uint64 uint64 `protobuf:"5"`
640 }
641 OneofScalars_Float32 struct {
642 Float32 MyFloat32 `protobuf:"6"`
643 }
644 OneofScalars_Float64 struct {
645 Float64 float64 `protobuf:"7"`
646 }
647 OneofScalars_String struct {
648 String string `protobuf:"8"`
649 }
650 OneofScalars_StringA struct {
651 StringA []byte `protobuf:"9"`
652 }
653 OneofScalars_StringB struct {
654 StringB MyString `protobuf:"10"`
655 }
656 OneofScalars_Bytes struct {
657 Bytes []byte `protobuf:"11"`
658 }
659 OneofScalars_BytesA struct {
660 BytesA string `protobuf:"12"`
661 }
662 OneofScalars_BytesB struct {
663 BytesB MyBytes `protobuf:"13"`
664 }
665)
666
667func (*OneofScalars) XXX_OneofFuncs() (func(proto.Message, *proto.Buffer) error, func(proto.Message, int, int, *proto.Buffer) (bool, error), func(proto.Message) int, []interface{}) {
668 return nil, nil, nil, []interface{}{
669 (*OneofScalars_Bool)(nil),
670 (*OneofScalars_Int32)(nil),
671 (*OneofScalars_Int64)(nil),
672 (*OneofScalars_Uint32)(nil),
673 (*OneofScalars_Uint64)(nil),
674 (*OneofScalars_Float32)(nil),
675 (*OneofScalars_Float64)(nil),
676 (*OneofScalars_String)(nil),
677 (*OneofScalars_StringA)(nil),
678 (*OneofScalars_StringB)(nil),
679 (*OneofScalars_Bytes)(nil),
680 (*OneofScalars_BytesA)(nil),
681 (*OneofScalars_BytesB)(nil),
682 }
683}
684
685func (*OneofScalars_Bool) isOneofScalars_Union() {}
686func (*OneofScalars_Int32) isOneofScalars_Union() {}
687func (*OneofScalars_Int64) isOneofScalars_Union() {}
688func (*OneofScalars_Uint32) isOneofScalars_Union() {}
689func (*OneofScalars_Uint64) isOneofScalars_Union() {}
690func (*OneofScalars_Float32) isOneofScalars_Union() {}
691func (*OneofScalars_Float64) isOneofScalars_Union() {}
692func (*OneofScalars_String) isOneofScalars_Union() {}
693func (*OneofScalars_StringA) isOneofScalars_Union() {}
694func (*OneofScalars_StringB) isOneofScalars_Union() {}
695func (*OneofScalars_Bytes) isOneofScalars_Union() {}
696func (*OneofScalars_BytesA) isOneofScalars_Union() {}
697func (*OneofScalars_BytesB) isOneofScalars_Union() {}
698
699func TestOneofs(t *testing.T) {
700 mi := MessageType{Desc: mustMakeMessageDesc(ptype.StandaloneMessage{
701 Syntax: pref.Proto2,
702 FullName: "ScalarProto2",
703 Fields: []ptype.Field{
704 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
705 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
706 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
707 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
708 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
709 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
710 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
711 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
712 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
713 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
714 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
715 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
716 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
717 },
718 Oneofs: []ptype.Oneof{{Name: "union"}},
719 })}
720
721 empty := mi.MessageOf(&OneofScalars{})
722 want1 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Bool{true}})
723 want2 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Int32{20}})
724 want3 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Int64{30}})
725 want4 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Uint32{40}})
726 want5 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Uint64{50}})
727 want6 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Float32{60}})
728 want7 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Float64{70}})
729 want8 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_String{string("80")}})
730 want9 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}})
731 want10 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_StringB{MyString("100")}})
732 want11 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}})
733 want12 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_BytesA{string("120")}})
734 want13 := mi.MessageOf(&OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}})
735
736 testMessage(t, nil, mi.MessageOf(&OneofScalars{}), messageOps{
737 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
738 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
739
740 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage(want1),
741 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage(want2),
742 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage(want3),
743 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage(want4),
744 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage(want5),
745 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage(want6),
746 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage(want7),
747 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage(want8),
748 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage(want9),
749 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage(want10),
750 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage(want11),
751 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage(want12),
752 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage(want13),
753
754 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: true},
755 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("130"))},
756 clearFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true},
757 equalMessage(want13),
758 clearFields{13: true},
759 equalMessage(empty),
760 })
761}
762
Joe Tsai91e14662018-09-13 13:24:35 -0700763// TODO: Need to test singular and repeated messages
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700764
Joe Tsai91e14662018-09-13 13:24:35 -0700765var cmpOpts = cmp.Options{
766 cmp.Transformer("UnwrapValue", func(v pref.Value) interface{} {
767 return v.Interface()
768 }),
769 cmp.Transformer("UnwrapMessage", func(m pref.Message) interface{} {
770 v := m.Interface()
771 if v, ok := v.(interface{ Unwrap() interface{} }); ok {
772 return v.Unwrap()
773 }
774 return v
775 }),
776 cmp.Transformer("UnwrapVector", func(v pref.Vector) interface{} {
777 return v.(interface{ Unwrap() interface{} }).Unwrap()
778 }),
779 cmp.Transformer("UnwrapMap", func(m pref.Map) interface{} {
780 return m.(interface{ Unwrap() interface{} }).Unwrap()
781 }),
782 cmpopts.EquateNaNs(),
783}
784
785func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
786 fs := m.KnownFields()
787 for i, op := range tt {
788 p.Push(i)
789 switch op := op.(type) {
790 case equalMessage:
791 if diff := cmp.Diff(op, m, cmpOpts); diff != "" {
792 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
793 }
794 case hasFields:
795 got := map[pref.FieldNumber]bool{}
796 want := map[pref.FieldNumber]bool(op)
797 for n := range want {
798 got[n] = fs.Has(n)
799 }
800 if diff := cmp.Diff(want, got); diff != "" {
801 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
802 }
803 case getFields:
804 got := map[pref.FieldNumber]pref.Value{}
805 want := map[pref.FieldNumber]pref.Value(op)
806 for n := range want {
807 got[n] = fs.Get(n)
808 }
809 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
810 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
811 }
812 case setFields:
813 for n, v := range op {
814 fs.Set(n, v)
815 }
816 case clearFields:
817 for n, ok := range op {
818 if ok {
819 fs.Clear(n)
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700820 }
821 }
Joe Tsai91e14662018-09-13 13:24:35 -0700822 case vectorFields:
823 for n, tt := range op {
824 p.Push(int(n))
825 testVectors(t, p, fs.Mutable(n).(pref.Vector), tt)
826 p.Pop()
827 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000828 case mapFields:
829 for n, tt := range op {
830 p.Push(int(n))
831 testMaps(t, p, fs.Mutable(n).(pref.Map), tt)
832 p.Pop()
833 }
Joe Tsai91e14662018-09-13 13:24:35 -0700834 default:
835 t.Fatalf("operation %v, invalid operation: %T", p, op)
836 }
837 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700838 }
839}
Joe Tsai91e14662018-09-13 13:24:35 -0700840
841func testVectors(t *testing.T, p path, v pref.Vector, tt vectorOps) {
842 for i, op := range tt {
843 p.Push(i)
844 switch op := op.(type) {
845 case equalVector:
846 if diff := cmp.Diff(op, v, cmpOpts); diff != "" {
847 t.Errorf("operation %v, vector mismatch (-want, +got):\n%s", p, diff)
848 }
849 case lenVector:
850 if got, want := v.Len(), int(op); got != want {
851 t.Errorf("operation %v, Vector.Len = %d, want %d", p, got, want)
852 }
853 case getVector:
854 got := map[int]pref.Value{}
855 want := map[int]pref.Value(op)
856 for n := range want {
857 got[n] = v.Get(n)
858 }
859 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
860 t.Errorf("operation %v, Vector.Get mismatch (-want, +got):\n%s", p, diff)
861 }
862 case setVector:
863 for n, e := range op {
864 v.Set(n, e)
865 }
866 case appendVector:
867 for _, e := range op {
868 v.Append(e)
869 }
870 case truncVector:
871 v.Truncate(int(op))
872 default:
873 t.Fatalf("operation %v, invalid operation: %T", p, op)
874 }
875 p.Pop()
876 }
877}
878
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000879func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
880 for i, op := range tt {
881 p.Push(i)
882 switch op := op.(type) {
883 case equalMap:
884 if diff := cmp.Diff(op, m, cmpOpts); diff != "" {
885 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
886 }
887 case lenMap:
888 if got, want := m.Len(), int(op); got != want {
889 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
890 }
891 case hasMap:
892 got := map[interface{}]bool{}
893 want := map[interface{}]bool(op)
894 for k := range want {
895 got[k] = m.Has(V(k).MapKey())
896 }
897 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
898 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
899 }
900 case getMap:
901 got := map[interface{}]pref.Value{}
902 want := map[interface{}]pref.Value(op)
903 for k := range want {
904 got[k] = m.Get(V(k).MapKey())
905 }
906 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
907 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
908 }
909 case setMap:
910 for k, v := range op {
911 m.Set(V(k).MapKey(), v)
912 }
913 case clearMap:
914 for v, ok := range op {
915 if ok {
916 m.Clear(V(v).MapKey())
917 }
918 }
919 case rangeMap:
920 got := map[interface{}]pref.Value{}
921 want := map[interface{}]pref.Value(op)
922 m.Range(func(k pref.MapKey, v pref.Value) bool {
923 got[k.Interface()] = v
924 return true
925 })
926 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
927 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
928 }
929 default:
930 t.Fatalf("operation %v, invalid operation: %T", p, op)
931 }
932 p.Pop()
933 }
934}
935
Joe Tsai91e14662018-09-13 13:24:35 -0700936type path []int
937
938func (p *path) Push(i int) { *p = append(*p, i) }
939func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
940func (p path) String() string {
941 var ss []string
942 for _, i := range p {
943 ss = append(ss, fmt.Sprint(i))
944 }
945 return strings.Join(ss, ".")
946}