1 // Copyright 2021 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.
13 type structField
struct {
18 var fieldsTests
= []struct {
23 testName
: "SimpleStruct",
29 expect
: []structField
{{
40 testName
: "NonEmbeddedStructMember",
46 expect
: []structField
{{
51 testName
: "EmbeddedExportedStruct",
55 expect
: []structField
{{
66 testName
: "EmbeddedUnexportedStruct",
70 expect
: []structField
{{
81 testName
: "TwoEmbeddedStructsWithCancellingMembers",
86 expect
: []structField
{{
97 testName
: "EmbeddedStructsWithSameFieldsAtDifferentDepths",
105 expect
: []structField
{{
113 index
: []int{0, 0, 0},
116 index
: []int{0, 0, 0, 0},
119 index
: []int{0, 0, 0, 0, 2},
128 index
: []int{1, 0, 0},
137 index
: []int{2, 0, 0},
146 index
: []int{3, 0, 0},
152 testName
: "EmbeddedPointerStruct",
156 expect
: []structField
{{
164 testName
: "EmbeddedNotAPointer",
168 expect
: []structField
{{
173 testName
: "RecursiveEmbedding",
175 expect
: []structField
{{
186 testName
: "RecursiveEmbedding2",
188 expect
: []structField
{{
199 testName
: "RecursiveEmbedding3",
201 expect
: []structField
{{
282 type M
map[string]any
293 func TestFields(t
*testing
.T
) {
294 for _
, test
:= range fieldsTests
{
296 t
.Run(test
.testName
, func(t
*testing
.T
) {
297 typ
:= TypeOf(test
.val
)
298 fields
:= VisibleFields(typ
)
299 if got
, want
:= len(fields
), len(test
.expect
); got
!= want
{
300 t
.Fatalf("unexpected field count; got %d want %d", got
, want
)
303 for j
, field
:= range fields
{
304 expect
:= test
.expect
[j
]
305 t
.Logf("field %d: %s", j
, expect
.name
)
306 gotField
:= typ
.FieldByIndex(field
.Index
)
307 // Unfortunately, FieldByIndex does not return
308 // a field with the same index that we passed in,
309 // so we set it to the expected value so that
310 // it can be compared later with the result of FieldByName.
311 gotField
.Index
= field
.Index
312 expectField
:= typ
.FieldByIndex(expect
.index
)
314 expectField
.Index
= expect
.index
315 if !DeepEqual(gotField
, expectField
) {
316 t
.Fatalf("unexpected field result\ngot %#v\nwant %#v", gotField
, expectField
)
319 // Sanity check that we can actually access the field by the
321 gotField1
, ok
:= typ
.FieldByName(expect
.name
)
323 t
.Fatalf("field %q not accessible by name", expect
.name
)
325 if !DeepEqual(gotField1
, expectField
) {
326 t
.Fatalf("unexpected FieldByName result; got %#v want %#v", gotField1
, expectField
)
333 // Must not panic with nil embedded pointer.
334 func TestFieldByIndexErr(t
*testing
.T
) {
342 _
, err
:= v
.FieldByIndexErr([]int{0, 0})
344 t
.Fatal("expected error")
346 if !strings
.Contains(err
.Error(), "embedded struct field A") {