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  }