more tests, additional methods for fields
This commit is contained in:
parent
d5c544c4f6
commit
84a0f611c7
14
field.go
14
field.go
@ -30,3 +30,17 @@ func (f *Field) IsEmbedded() bool {
|
|||||||
func (f *Field) IsExported() bool {
|
func (f *Field) IsExported() bool {
|
||||||
return f.field.PkgPath == ""
|
return f.field.PkgPath == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsZero returns true if the given field is not initalized (has a zero value).
|
||||||
|
// It panics if the field is not exported.
|
||||||
|
func (f *Field) IsZero() bool {
|
||||||
|
zero := reflect.Zero(f.value.Type()).Interface()
|
||||||
|
current := f.Value()
|
||||||
|
|
||||||
|
return reflect.DeepEqual(current, zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the given field
|
||||||
|
func (f *Field) Name() string {
|
||||||
|
return f.field.Name
|
||||||
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ type Foo struct {
|
|||||||
B int `structure:"y"`
|
B int `structure:"y"`
|
||||||
C bool `json:"c"`
|
C bool `json:"c"`
|
||||||
d string // not exported
|
d string // not exported
|
||||||
|
x string `xml:"x"` // not exported, with tag
|
||||||
*Bar // embedded
|
*Bar // embedded
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,9 +25,9 @@ func newStruct() *Struct {
|
|||||||
g: []string{"zeynep", "fatih"},
|
g: []string{"zeynep", "fatih"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// B and x is not initialized for testing
|
||||||
f := &Foo{
|
f := &Foo{
|
||||||
A: "gopher",
|
A: "gopher",
|
||||||
B: 1,
|
|
||||||
C: true,
|
C: true,
|
||||||
d: "small",
|
d: "small",
|
||||||
}
|
}
|
||||||
@ -47,3 +48,56 @@ func TestField(t *testing.T) {
|
|||||||
|
|
||||||
_ = s.Field("no-field")
|
_ = s.Field("no-field")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestField_Tag(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
v := s.Field("B").Tag("json")
|
||||||
|
if v != "" {
|
||||||
|
t.Errorf("Field's tag value of a non existing tag should return empty, got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("C").Tag("json")
|
||||||
|
if v != "c" {
|
||||||
|
t.Errorf("Field's tag value of the existing field C should return 'c', got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("d").Tag("json")
|
||||||
|
if v != "" {
|
||||||
|
t.Errorf("Field's tag value of a non exported field should return empty, got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("x").Tag("xml")
|
||||||
|
if v != "x" {
|
||||||
|
t.Errorf("Field's tag value of a non exported field with a tag should return 'x', got: %s", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
v = s.Field("A").Tag("json")
|
||||||
|
if v != "" {
|
||||||
|
t.Errorf("Field's tag value of a existing field without a tag should return empty, got: %s", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestField_Value(t *testing.T) {
|
||||||
|
s := newStruct()
|
||||||
|
|
||||||
|
v := s.Field("A").Value()
|
||||||
|
val, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("Field's value of a A should be string")
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != "gopher" {
|
||||||
|
t.Errorf("Field's value of a existing tag should return 'gopher', got: %s", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := recover()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Value of a non exported field from the field should panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// should panic
|
||||||
|
_ = s.Field("d").Value()
|
||||||
|
}
|
||||||
|
|||||||
11
structs.go
11
structs.go
@ -32,8 +32,7 @@ func (s *Struct) Fields() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Field returns a new Field struct that provides several high level functions
|
// Field returns a new Field struct that provides several high level functions
|
||||||
// around a single struct field entitiy. It panics if the field is not found or
|
// around a single struct field entitiy. It panics if the field is not found.
|
||||||
// is unexported.
|
|
||||||
func (s *Struct) Field(name string) *Field {
|
func (s *Struct) Field(name string) *Field {
|
||||||
f, ok := s.FieldOk(name)
|
f, ok := s.FieldOk(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -44,8 +43,8 @@ func (s *Struct) Field(name string) *Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Field returns a new Field struct that provides several high level functions
|
// Field returns a new Field struct that provides several high level functions
|
||||||
// around a single struct field entitiy and a boolean indicating if the field
|
// around a single struct field entitiy. The boolean returns true if the field
|
||||||
// was found. It panics if the or is unexported.
|
// was found.
|
||||||
func (s *Struct) FieldOk(name string) (*Field, bool) {
|
func (s *Struct) FieldOk(name string) (*Field, bool) {
|
||||||
v := strctVal(s.raw)
|
v := strctVal(s.raw)
|
||||||
t := v.Type()
|
t := v.Type()
|
||||||
@ -55,10 +54,6 @@ func (s *Struct) FieldOk(name string) (*Field, bool) {
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if field.PkgPath != "" {
|
|
||||||
panic("unexported field access is not allowed")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Field{
|
return &Field{
|
||||||
field: field,
|
field: field,
|
||||||
value: v.FieldByName(name),
|
value: v.FieldByName(name),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user