@@ -144,6 +144,7 @@ func TestTimeToUnstructured(t *testing.T) {
144
144
145
145
func TestTypeReflectEntryOf (t * testing.T ) {
146
146
testString := ""
147
+ testCustomType := customOmitZeroType {}
147
148
tests := map [string ]struct {
148
149
arg interface {}
149
150
want * TypeReflectCacheEntry
@@ -196,6 +197,62 @@ func TestTypeReflectEntryOf(t *testing.T) {
196
197
},
197
198
},
198
199
},
200
+ "StructWith*StringFieldOmitzero" : {
201
+ arg : struct {
202
+ F1 * string `json:"f1,omitzero"`
203
+ }{},
204
+ want : & TypeReflectCacheEntry {
205
+ structFields : map [string ]* FieldCacheEntry {
206
+ "f1" : {
207
+ JsonName : "f1" ,
208
+ omitzero : func (v reflect.Value ) bool { return v .IsZero () },
209
+ fieldPath : [][]int {{0 }},
210
+ fieldType : reflect .TypeOf (& testString ),
211
+ TypeEntry : & TypeReflectCacheEntry {},
212
+ },
213
+ },
214
+ orderedStructFields : []* FieldCacheEntry {
215
+ {
216
+ JsonName : "f1" ,
217
+ omitzero : func (v reflect.Value ) bool { return v .IsZero () },
218
+ fieldPath : [][]int {{0 }},
219
+ fieldType : reflect .TypeOf (& testString ),
220
+ TypeEntry : & TypeReflectCacheEntry {},
221
+ },
222
+ },
223
+ },
224
+ },
225
+ "StructWith*CustomFieldOmitzero" : {
226
+ arg : struct {
227
+ F1 customOmitZeroType `json:"f1,omitzero"`
228
+ }{},
229
+ want : & TypeReflectCacheEntry {
230
+ structFields : map [string ]* FieldCacheEntry {
231
+ "f1" : {
232
+ JsonName : "f1" ,
233
+ omitzero : func (v reflect.Value ) bool { return false },
234
+ fieldPath : [][]int {{0 }},
235
+ fieldType : reflect .TypeOf (testCustomType ),
236
+ TypeEntry : & TypeReflectCacheEntry {
237
+ structFields : map [string ]* FieldCacheEntry {},
238
+ orderedStructFields : []* FieldCacheEntry {},
239
+ },
240
+ },
241
+ },
242
+ orderedStructFields : []* FieldCacheEntry {
243
+ {
244
+ JsonName : "f1" ,
245
+ omitzero : func (v reflect.Value ) bool { return false },
246
+ fieldPath : [][]int {{0 }},
247
+ fieldType : reflect .TypeOf (testCustomType ),
248
+ TypeEntry : & TypeReflectCacheEntry {
249
+ structFields : map [string ]* FieldCacheEntry {},
250
+ orderedStructFields : []* FieldCacheEntry {},
251
+ },
252
+ },
253
+ },
254
+ },
255
+ },
199
256
"StructWithInlinedField" : {
200
257
arg : struct {
201
258
F1 string `json:",inline"`
@@ -208,13 +265,55 @@ func TestTypeReflectEntryOf(t *testing.T) {
208
265
}
209
266
for name , tt := range tests {
210
267
t .Run (name , func (t * testing.T ) {
211
- if got := TypeReflectEntryOf (reflect .TypeOf (tt .arg )); ! reflect .DeepEqual (got , tt .want ) {
212
- t .Errorf ("TypeReflectEntryOf() = %v, want %v" , got , tt .want )
268
+ got := TypeReflectEntryOf (reflect .TypeOf (tt .arg ))
269
+
270
+ // evaluate non-comparable omitzero functions
271
+ for k , v := range got .structFields {
272
+ compareOmitZero (t , v .fieldType , v .omitzero , tt .want .structFields [k ].omitzero )
273
+ }
274
+ for i , v := range got .orderedStructFields {
275
+ compareOmitZero (t , v .fieldType , v .omitzero , tt .want .orderedStructFields [i ].omitzero )
276
+ }
277
+
278
+ // clear non-comparable omitzero functions
279
+ for k , v := range got .structFields {
280
+ v .omitzero = nil
281
+ tt .want .structFields [k ].omitzero = nil
282
+ }
283
+ for i , v := range got .orderedStructFields {
284
+ v .omitzero = nil
285
+ tt .want .orderedStructFields [i ].omitzero = nil
286
+ }
287
+
288
+ // compare remaining fields
289
+ if ! reflect .DeepEqual (got , tt .want ) {
290
+ t .Errorf ("TypeReflectEntryOf() got\n %#v\n want\n %#v" , got , tt .want )
213
291
}
214
292
})
215
293
}
216
294
}
217
295
296
+ type customOmitZeroType struct {
297
+ }
298
+
299
+ func (c * customOmitZeroType ) IsZero () bool {
300
+ return false
301
+ }
302
+
303
+ func compareOmitZero (t * testing.T , fieldType reflect.Type , got , want func (reflect.Value ) bool ) {
304
+ t .Helper ()
305
+ if (want == nil ) != (got == nil ) {
306
+ t .Fatalf ("wanted omitzero=%v, got omitzero=%v" , (want == nil ), (got == nil ))
307
+ }
308
+ if want == nil {
309
+ return
310
+ }
311
+ v := reflect .New (fieldType ).Elem ()
312
+ if e , a := want (v ), got (v ); e != a {
313
+ t .Fatalf ("wanted omitzero()=%v, got omitzero()=%v" , e , a )
314
+ }
315
+ }
316
+
218
317
func TestUnmarshal (t * testing.T ) {
219
318
for _ , tc := range []struct {
220
319
JSON string
0 commit comments