sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/genyaml/populate_struct_test.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package genyaml 18 19 import ( 20 "testing" 21 ) 22 23 func TestPopulateStructHandlesPointerFields(t *testing.T) { 24 s := struct { 25 Field *struct { 26 NestedField *int 27 } 28 }{} 29 30 PopulateStruct(&s) 31 if s.Field == nil { 32 t.Fatalf("Pointer field in struct didn't get set, struct: %+v", s) 33 } 34 if s.Field.NestedField == nil { 35 t.Fatalf("Nested pointer field in struct didn't get set, struct: %+v", s) 36 } 37 } 38 39 func TestPopulateStructHandlesSlicesOfLiterals(t *testing.T) { 40 s := struct { 41 Field []struct { 42 NestedField *int 43 } 44 }{} 45 46 PopulateStruct(&s) 47 if n := len(s.Field); n != 1 { 48 t.Fatalf("Slice didn't get populated, struct: %+v", s) 49 } 50 51 if s.Field[0].NestedField == nil { 52 t.Fatalf("Slice element field didn't get populated, struct: %+v", s) 53 } 54 } 55 56 func TestPopulateStructHandlesSliceOfPointers(t *testing.T) { 57 s := struct { 58 Field []*struct { 59 NestedField *int 60 } 61 }{} 62 63 PopulateStruct(&s) 64 if n := len(s.Field); n != 1 { 65 t.Fatalf("Slice didn't get populated, struct: %+v", s) 66 } 67 if s.Field[0] == nil { 68 t.Fatalf("Slice element didn't get populated, struct: %+v", s) 69 } 70 71 if s.Field[0].NestedField == nil { 72 t.Fatalf("Slice element field didn't get populated, struct: %+v", s) 73 } 74 } 75 76 func TestPopulateStructHandlesMaps(t *testing.T) { 77 s := struct { 78 Field map[string]struct { 79 NestedField *int 80 } 81 }{} 82 83 PopulateStruct(&s) 84 if n := len(s.Field); n != 1 { 85 t.Fatalf("Map didn't get populated, struct: %+v", s) 86 } 87 88 for _, v := range s.Field { 89 if v.NestedField == nil { 90 t.Fatalf("Pointer field in map element didn't get populated, struct: %+v", s) 91 } 92 } 93 } 94 95 func TestPopulateStructHandlesMapsWithPointerValues(t *testing.T) { 96 s := struct { 97 Field map[string]*struct { 98 NestedField *int 99 } 100 }{} 101 102 PopulateStruct(&s) 103 if n := len(s.Field); n != 1 { 104 t.Fatalf("Map didn't get populated, struct: %+v", s) 105 } 106 107 for _, v := range s.Field { 108 if v == nil { 109 t.Fatalf("Map value is a nilpointer, struct: %+v", s) 110 } 111 if v.NestedField == nil { 112 t.Fatalf("Pointer field in map element didn't get populated, struct: %+v", s) 113 } 114 } 115 } 116 117 func TestPopulateStructHandlesMapsWithPointerKeys(t *testing.T) { 118 s := struct { 119 Field map[*string]struct { 120 NestedField *int 121 } 122 }{} 123 124 PopulateStruct(&s) 125 if n := len(s.Field); n != 1 { 126 t.Fatalf("Map didn't get populated, struct: %+v", s) 127 } 128 129 for k, v := range s.Field { 130 if k == nil { 131 t.Fatalf("Map key is a nilpointer, struct: %+v", s) 132 } 133 if v.NestedField == nil { 134 t.Fatalf("Pointer field in map element didn't get populated, struct: %+v", s) 135 } 136 } 137 } 138 139 // this is needed because genyaml uses a custom json unmarshaler that omits empty structs 140 // even if they are not pointers. If we don't do this, structs that only have string fields 141 // end up being omitted. 142 // TODO: Is there a necessity for genyaml to have this custom unmarshaler? 143 func TestPopulateStructSetsStrings(t *testing.T) { 144 s := struct { 145 String string 146 Field struct { 147 String string 148 } 149 }{} 150 151 PopulateStruct(&s) 152 if s.String == "" { 153 t.Errorf("String field didn't get set, struct: %+v", s) 154 } 155 if s.Field.String == "" { 156 t.Errorf("Nested string field didn't get set, struct: %+v", s) 157 } 158 } 159 160 func TestPopulateStructBool(t *testing.T) { 161 s := struct { 162 Bool bool `json:"bool,omitempty"` 163 String string `json:"string,omitempty"` 164 }{} 165 166 PopulateStruct(&s) 167 if !s.Bool { 168 t.Fatalf("Bool field didn't get set, struct: %+v", s) 169 } 170 } 171 172 func TestPopulateStructHandlesUnexportedFields(_ *testing.T) { 173 s := struct { 174 unexported *struct { 175 justAsUnexported *int 176 } 177 }{} 178 179 PopulateStruct(&s) 180 // This test indicates success by not panicking, so nothing further to check 181 }