@@ -144,6 +144,7 @@ func TestTimeToUnstructured(t *testing.T) {
144144
145145func TestTypeReflectEntryOf (t * testing.T ) {
146146 testString := ""
147+ testCustomType := customOmitZeroType {}
147148 tests := map [string ]struct {
148149 arg interface {}
149150 want * TypeReflectCacheEntry
@@ -196,6 +197,62 @@ func TestTypeReflectEntryOf(t *testing.T) {
196197 },
197198 },
198199 },
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+ },
199256 "StructWithInlinedField" : {
200257 arg : struct {
201258 F1 string `json:",inline"`
@@ -208,13 +265,55 @@ func TestTypeReflectEntryOf(t *testing.T) {
208265 }
209266 for name , tt := range tests {
210267 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 )
213291 }
214292 })
215293 }
216294}
217295
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+
218317func TestUnmarshal (t * testing.T ) {
219318 for _ , tc := range []struct {
220319 JSON string
0 commit comments