github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/g/field_test.go (about) 1 package g_test 2 3 import ( 4 "github.com/angenalZZZ/gofunc/g" 5 "reflect" 6 "testing" 7 ) 8 9 // A test struct that defines all cases 10 type Foo struct { 11 A string 12 B int `struct:"y"` 13 C bool `json:"c"` 14 d string // not exported 15 E *Baz 16 x string `xml:"x"` // not exported, with tag 17 Y []string 18 Z map[string]interface{} 19 *Bar // embedded 20 } 21 22 type Baz struct { 23 A string 24 B int 25 } 26 27 type Bar struct { 28 E string 29 F int 30 g []string 31 } 32 33 func newStruct() *g.Struct { 34 b := &Bar{ 35 E: "example", 36 F: 2, 37 g: []string{"zeynep", "fatih"}, 38 } 39 40 // B and x is not initialized for testing 41 f := &Foo{ 42 A: "gopher", 43 C: true, 44 d: "small", 45 E: nil, 46 Y: []string{"example"}, 47 Z: nil, 48 } 49 f.Bar = b 50 51 return g.NewStruct(f) 52 } 53 54 func TestField_Set(t *testing.T) { 55 s := newStruct() 56 57 f := s.Field("A") 58 err := f.Set("fatih") 59 if err != nil { 60 t.Error(err) 61 } 62 63 if f.Value().(string) != "fatih" { 64 t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih") 65 } 66 67 f = s.Field("Y") 68 err = f.Set([]string{"override", "with", "this"}) 69 if err != nil { 70 t.Error(err) 71 } 72 73 sliceLen := len(f.Value().([]string)) 74 if sliceLen != 3 { 75 t.Errorf("Setted values slice length is wrong: %d, want: %d", sliceLen, 3) 76 } 77 78 f = s.Field("C") 79 err = f.Set(false) 80 if err != nil { 81 t.Error(err) 82 } 83 84 if f.Value().(bool) { 85 t.Errorf("Setted value is wrong: %t want: %t", f.Value().(bool), false) 86 } 87 88 // let's pass a different type 89 f = s.Field("A") 90 err = f.Set(123) // Field A is of type string, but we are going to pass an integer 91 if err == nil { 92 t.Error("Setting a field's value with a different type than the field's type should return an error") 93 } 94 95 // old value should be still there :) 96 if f.Value().(string) != "fatih" { 97 t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih") 98 } 99 100 // let's access an unexported field, which should give an error 101 f = s.Field("d") 102 err = f.Set("large") 103 if err != g.ErrNotExported { 104 t.Error(err) 105 } 106 107 // let's set a pointer to struct 108 b := &Bar{ 109 E: "gopher", 110 F: 2, 111 } 112 113 f = s.Field("Bar") 114 err = f.Set(b) 115 if err != nil { 116 t.Error(err) 117 } 118 119 baz := &Baz{ 120 A: "helloWorld", 121 B: 42, 122 } 123 124 f = s.Field("E") 125 err = f.Set(baz) 126 if err != nil { 127 t.Error(err) 128 } 129 130 ba := s.Field("E").Value().(*Baz) 131 132 if ba.A != "helloWorld" { 133 t.Errorf("could not set baz. Got: %s Want: helloWorld", ba.A) 134 } 135 } 136 137 func TestField_NotSettable(t *testing.T) { 138 a := map[int]Baz{ 139 4: { 140 A: "value", 141 }, 142 } 143 144 s := g.NewStruct(a[4]) 145 146 if err := s.Field("A").Set("newValue"); err != g.ErrNotSettable { 147 t.Errorf("Trying to set non-settable field should error with %q. Got %q instead.", g.ErrNotSettable, err) 148 } 149 } 150 151 func TestField_Zero(t *testing.T) { 152 s := newStruct() 153 154 f := s.Field("A") 155 err := f.Zero() 156 if err != nil { 157 t.Error(err) 158 } 159 160 if f.Value().(string) != "" { 161 t.Errorf("Zeroed value is wrong: %s want: %s", f.Value().(string), "") 162 } 163 164 f = s.Field("Y") 165 err = f.Zero() 166 if err != nil { 167 t.Error(err) 168 } 169 170 sliceLen := len(f.Value().([]string)) 171 if sliceLen != 0 { 172 t.Errorf("Zeroed values slice length is wrong: %d, want: %d", sliceLen, 0) 173 } 174 175 f = s.Field("C") 176 err = f.Zero() 177 if err != nil { 178 t.Error(err) 179 } 180 181 if f.Value().(bool) { 182 t.Errorf("Zeroed value is wrong: %t want: %t", f.Value().(bool), false) 183 } 184 185 // let's access an unexported field, which should give an error 186 f = s.Field("d") 187 err = f.Zero() 188 if err != g.ErrNotExported { 189 t.Error(err) 190 } 191 192 f = s.Field("Bar") 193 err = f.Zero() 194 if err != nil { 195 t.Error(err) 196 } 197 198 f = s.Field("E") 199 err = f.Zero() 200 if err != nil { 201 t.Error(err) 202 } 203 204 v := s.FieldValue("E") 205 if !v.IsNil() { 206 t.Errorf("could not set baz. Got: %s Want: <nil>", v.Interface()) 207 } 208 } 209 210 func TestField(t *testing.T) { 211 s := newStruct() 212 213 defer func() { 214 err := recover() 215 if err == nil { 216 t.Error("Retrieveing a non existing field from the struct should panic") 217 } 218 }() 219 220 _ = s.Field("no-field") 221 } 222 223 func TestField_Kind(t *testing.T) { 224 s := newStruct() 225 226 f := s.Field("A") 227 if f.Kind() != reflect.String { 228 t.Errorf("Field A has wrong kind: %s want: %s", f.Kind(), reflect.String) 229 } 230 231 f = s.Field("B") 232 if f.Kind() != reflect.Int { 233 t.Errorf("Field B has wrong kind: %s want: %s", f.Kind(), reflect.Int) 234 } 235 236 // unexported 237 f = s.Field("d") 238 if f.Kind() != reflect.String { 239 t.Errorf("Field d has wrong kind: %s want: %s", f.Kind(), reflect.String) 240 } 241 } 242 243 func TestField_Tag(t *testing.T) { 244 s := newStruct() 245 246 v := s.Field("B").Tag("json") 247 if v != "" { 248 t.Errorf("Field's tag value of a non existing tag should return empty, got: %s", v) 249 } 250 251 v = s.Field("C").Tag("json") 252 if v != "c" { 253 t.Errorf("Field's tag value of the existing field C should return 'c', got: %s", v) 254 } 255 256 v = s.Field("d").Tag("json") 257 if v != "" { 258 t.Errorf("Field's tag value of a non exported field should return empty, got: %s", v) 259 } 260 261 v = s.Field("x").Tag("xml") 262 if v != "x" { 263 t.Errorf("Field's tag value of a non exported field with a tag should return 'x', got: %s", v) 264 } 265 266 v = s.Field("A").Tag("json") 267 if v != "" { 268 t.Errorf("Field's tag value of a existing field without a tag should return empty, got: %s", v) 269 } 270 } 271 272 func TestField_Value(t *testing.T) { 273 s := newStruct() 274 275 v := s.Field("A").Value() 276 val, ok := v.(string) 277 if !ok { 278 t.Errorf("Field's value of a A should be string") 279 } 280 281 if val != "gopher" { 282 t.Errorf("Field's value of a existing tag should return 'gopher', got: %s", val) 283 } 284 285 defer func() { 286 err := recover() 287 if err == nil { 288 t.Error("Value of a non exported field from the field should panic") 289 } 290 }() 291 292 // should panic 293 _ = s.Field("d").Value() 294 } 295 296 func TestField_IsEmbedded(t *testing.T) { 297 s := newStruct() 298 299 if !s.Field("Bar").IsEmbedded() { 300 t.Errorf("Fields 'Bar' field is an embedded field") 301 } 302 303 if s.Field("d").IsEmbedded() { 304 t.Errorf("Fields 'd' field is not an embedded field") 305 } 306 } 307 308 func TestField_IsExported(t *testing.T) { 309 s := newStruct() 310 311 if !s.Field("Bar").IsExported() { 312 t.Errorf("Fields 'Bar' field is an exported field") 313 } 314 315 if !s.Field("A").IsExported() { 316 t.Errorf("Fields 'A' field is an exported field") 317 } 318 319 if s.Field("d").IsExported() { 320 t.Errorf("Fields 'd' field is not an exported field") 321 } 322 } 323 324 func TestField_IsZero(t *testing.T) { 325 s := newStruct() 326 327 if s.Field("A").IsZero() { 328 t.Errorf("Fields 'A' field is an initialized field") 329 } 330 331 if !s.Field("B").IsZero() { 332 t.Errorf("Fields 'B' field is not an initialized field") 333 } 334 } 335 336 func TestField_Name(t *testing.T) { 337 s := newStruct() 338 339 if s.Field("A").Name() != "A" { 340 t.Errorf("Fields 'A' field should have the name 'A'") 341 } 342 } 343 344 func TestField_Field(t *testing.T) { 345 s := newStruct() 346 347 e := s.Field("Bar").Field("E") 348 349 val, ok := e.Value().(string) 350 if !ok { 351 t.Error("The value of the field 'e' inside 'Bar' struct should be string") 352 } 353 354 if val != "example" { 355 t.Errorf("The value of 'e' should be 'example, got: %s", val) 356 } 357 358 defer func() { 359 err := recover() 360 if err == nil { 361 t.Error("Field of a non existing nested struct should panic") 362 } 363 }() 364 365 _ = s.Field("Bar").Field("e") 366 } 367 368 func TestField_Fields(t *testing.T) { 369 s := newStruct() 370 fields := s.Field("Bar").Fields() 371 372 if len(fields) != 3 { 373 t.Errorf("We expect 3 fields in embedded struct, was: %d", len(fields)) 374 } 375 } 376 377 func TestField_FieldOk(t *testing.T) { 378 s := newStruct() 379 380 b, ok := s.FieldOk("Bar") 381 if !ok { 382 t.Error("The field 'Bar' should exists.") 383 } 384 385 e, ok := b.FieldOk("E") 386 if !ok { 387 t.Error("The field 'E' should exists.") 388 } 389 390 val, ok := e.Value().(string) 391 if !ok { 392 t.Error("The value of the field 'e' inside 'Bar' struct should be string") 393 } 394 395 if val != "example" { 396 t.Errorf("The value of 'e' should be 'example, got: %s", val) 397 } 398 }