more tests, additional methods for fields

This commit is contained in:
Fatih Arslan 2014-08-10 16:42:04 +03:00
parent d5c544c4f6
commit 84a0f611c7
3 changed files with 72 additions and 9 deletions

View File

@ -30,3 +30,17 @@ func (f *Field) IsEmbedded() bool {
func (f *Field) IsExported() bool {
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
}

View File

@ -8,6 +8,7 @@ type Foo struct {
B int `structure:"y"`
C bool `json:"c"`
d string // not exported
x string `xml:"x"` // not exported, with tag
*Bar // embedded
}
@ -24,9 +25,9 @@ func newStruct() *Struct {
g: []string{"zeynep", "fatih"},
}
// B and x is not initialized for testing
f := &Foo{
A: "gopher",
B: 1,
C: true,
d: "small",
}
@ -47,3 +48,56 @@ func TestField(t *testing.T) {
_ = 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()
}

View File

@ -32,8 +32,7 @@ func (s *Struct) Fields() []string {
}
// 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
// is unexported.
// around a single struct field entitiy. It panics if the field is not found.
func (s *Struct) Field(name string) *Field {
f, ok := s.FieldOk(name)
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
// around a single struct field entitiy and a boolean indicating if the field
// was found. It panics if the or is unexported.
// around a single struct field entitiy. The boolean returns true if the field
// was found.
func (s *Struct) FieldOk(name string) (*Field, bool) {
v := strctVal(s.raw)
t := v.Type()
@ -55,10 +54,6 @@ func (s *Struct) FieldOk(name string) (*Field, bool) {
return nil, false
}
if field.PkgPath != "" {
panic("unexported field access is not allowed")
}
return &Field{
field: field,
value: v.FieldByName(name),