github.com/goki/ki@v1.1.11/kit/embeds_test.go (about)

     1  // Copyright (c) 2018, The GoKi 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.
     4  
     5  package kit
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"testing"
    11  )
    12  
    13  type A struct {
    14  	Mbr1 string
    15  	Mbr2 int
    16  }
    17  
    18  type AIf interface {
    19  	AFun() bool
    20  }
    21  
    22  func (a *A) AFun() bool {
    23  	return true
    24  }
    25  
    26  var _ AIf = &A{}
    27  
    28  type B struct {
    29  	A
    30  	Mbr3 string
    31  	Mbr4 int
    32  }
    33  
    34  type C struct {
    35  	B
    36  	Mbr5 string
    37  	Mbr6 int
    38  }
    39  
    40  type D struct {
    41  	Mbr5 string
    42  	Mbr6 int
    43  	NmdA A
    44  }
    45  
    46  var a = A{}
    47  var b = B{}
    48  var c = C{}
    49  var d = D{}
    50  
    51  func InitC() {
    52  	c.Mbr1 = "mbr1 string"
    53  	c.Mbr2 = 2
    54  	c.Mbr3 = "mbr3 string"
    55  	c.Mbr4 = 4
    56  	c.Mbr5 = "mbr5 string"
    57  	c.Mbr6 = 6
    58  }
    59  
    60  func InitD() {
    61  	d.Mbr5 = "mbr5 string"
    62  	d.Mbr6 = 6
    63  	d.NmdA.Mbr1 = "a in d"
    64  	d.NmdA.Mbr2 = 2
    65  }
    66  
    67  func TestTypeEmbeds(t *testing.T) {
    68  	InitC()
    69  
    70  	a_in_a := TypeEmbeds(reflect.TypeOf(a), reflect.TypeOf(a))
    71  	// fmt.Printf("A embeds A: %v\n", a_in_a)
    72  
    73  	b_in_a := TypeEmbeds(reflect.TypeOf(a), reflect.TypeOf(b))
    74  	// fmt.Printf("A embeds B: %v\n", b_in_a)
    75  
    76  	a_in_b := TypeEmbeds(reflect.TypeOf(b), reflect.TypeOf(a))
    77  	// fmt.Printf("B embeds A: %v\n", a_in_b)
    78  
    79  	a_in_c := TypeEmbeds(reflect.TypeOf(c), reflect.TypeOf(a))
    80  	// fmt.Printf("C embeds A: %v\n", a_in_c)
    81  
    82  	aiftype := reflect.TypeOf((*AIf)(nil)).Elem()
    83  
    84  	// note: MUST use pointer for checking implements for pointer receivers!
    85  	// fmt.Printf("a implements Aif %v\n", reflect.TypeOf(&a).Implements(aiftype))
    86  
    87  	aif_in_c := EmbedImplements(reflect.TypeOf(c), aiftype)
    88  	// fmt.Printf("C implements AIf: %v\n", aif_in_c)
    89  
    90  	aif_in_d := EmbedImplements(reflect.TypeOf(d), aiftype)
    91  	// fmt.Printf("D implements AIf: %v\n", aif_in_d)
    92  
    93  	if a_in_a != true || b_in_a != false || a_in_b != true || a_in_c != true || aif_in_c != true || aif_in_d != false {
    94  		t.Errorf("something wrong in TypeEmbeds: should have: true, false, true, true, true, false is: %v %v %v %v %v %v\n", a_in_a, b_in_a, a_in_b, a_in_c, aif_in_c, aif_in_d)
    95  	}
    96  }
    97  
    98  func TestEmbed(t *testing.T) {
    99  	InitC()
   100  
   101  	aa := Embed(&a, reflect.TypeOf(a))
   102  	aas := fmt.Sprintf("%+v", aa)
   103  	aat := "&{Mbr1: Mbr2:0}"
   104  	if aas != aat {
   105  		t.Errorf("Didn't get proper embedded members of A from A: %v != %v\n", aas, aat)
   106  	}
   107  
   108  	ca := Embed(&c, reflect.TypeOf(a))
   109  	cas := fmt.Sprintf("%+v", ca)
   110  	cat := "&{Mbr1:mbr1 string Mbr2:2}"
   111  	if cas != cat {
   112  		t.Errorf("Didn't get proper embedded members of C from A: %v != %v\n", cas, cat)
   113  	}
   114  }
   115  
   116  func TestFlatFields(t *testing.T) {
   117  	InitC()
   118  
   119  	// FlatFieldsTypeFunc(reflect.TypeOf(c), func(typ reflect.Type, field reflect.StructField) {
   120  	// 	fmt.Printf("typ: %v, field: %v\n", typ, field)
   121  	// })
   122  
   123  	// FlatFieldsValueFunc(c, func(stru interface{}, typ reflect.Type, field reflect.StructField, fieldVal reflect.Value) {
   124  	// 	fmt.Printf("typ: %v, field: %v val: %v\n", typ, field, fieldVal)
   125  	// })
   126  
   127  	// note: these test the above TypeFun and ValueFun
   128  
   129  	ff := FlatFields(reflect.TypeOf(c))
   130  	ffs := fmt.Sprintf("%v", ff)
   131  	fft := `[{Mbr1  string  0 [0] false} {Mbr2  int  16 [1] false} {Mbr3  string  24 [1] false} {Mbr4  int  40 [2] false} {Mbr5  string  48 [1] false} {Mbr6  int  64 [2] false}]`
   132  	if ffs != fft {
   133  		t.Errorf("Didn't get proper flat field list of C: %v != %v\n", ffs, fft)
   134  	}
   135  
   136  	ffv := FlatFieldVals(&c)
   137  	ffvs := fmt.Sprintf("%v", ffv)
   138  	ffvt := `[mbr1 string <int Value> mbr3 string <int Value> mbr5 string <int Value>]`
   139  	if ffvs != ffvt {
   140  		t.Errorf("Didn't get proper flat field value list of C: %v != %v\n", ffvs, ffvt)
   141  	}
   142  
   143  	ffi := FlatFieldInterfaces(&c)
   144  	ffis := ""
   145  	for _, fi := range ffi {
   146  		ffis += fmt.Sprintf("%v,", NonPtrInterface(fi))
   147  	}
   148  	ffit := `mbr1 string,2,mbr3 string,4,mbr5 string,6,`
   149  	if ffis != ffit {
   150  		t.Errorf("Didn't get proper flat field interface list of C: %v != %v\n", ffis, ffit)
   151  	}
   152  }
   153  
   154  func TestFlatFieldsByName(t *testing.T) {
   155  	InitC()
   156  
   157  	fif, _ := FlatFieldByName(reflect.TypeOf(c), "Mbr3")
   158  	fifs := fmt.Sprintf("%v", fif)
   159  	fift := `{Mbr3  string  24 [0 1] false}`
   160  	if fifs != fift {
   161  		t.Errorf("Didn't get proper find flat field by name: %v != %v\n", fifs, fift)
   162  	}
   163  
   164  	fifn, _ := FlatFieldByName(reflect.TypeOf(c), "Mbr31")
   165  	fifns := fmt.Sprintf("%v", fifn)
   166  	fifnt := `{  <nil>  0 [] false}`
   167  	if fifns != fifnt {
   168  		t.Errorf("Didn't get proper nil find flat field by name: %v != %v\n", fifns, fifnt)
   169  	}
   170  
   171  	fifv := FlatFieldValueByName(&c, "Mbr4")
   172  	fifvs := fmt.Sprintf("%v", fifv)
   173  	fifvt := `4`
   174  	if fifvs != fifvt {
   175  		t.Errorf("Didn't get proper find flat field value by name: %v != %v\n", fifvs, fifvt)
   176  	}
   177  
   178  	fifi := FlatFieldInterfaceByName(&c, "Mbr2")
   179  	fifis := fmt.Sprintf("%v", NonPtrInterface(fifi))
   180  	fifit := `2`
   181  	if fifis != fifit {
   182  		t.Errorf("Didn't get proper find flat field value by name: %v != %v\n", fifis, fifit)
   183  	}
   184  
   185  }
   186  
   187  func TestFieldPaths(t *testing.T) {
   188  	InitD()
   189  
   190  	fld, ok := FieldByPath(reflect.TypeOf(d), "NmdA.Mbr1")
   191  	if !ok {
   192  		t.Errorf("FieldByPath failed per err msg, fld %v\n", fld.Name)
   193  	}
   194  
   195  	fi, ok := FieldValueByPath(d, "NmdA.Mbr1")
   196  	if !ok {
   197  		t.Errorf("FieldValueByPath failed per err msg, fi %v\n", fi)
   198  	}
   199  	// fmt.Printf("fi: %v\n", fi)
   200  }