github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/generic/path_test.go (about)

     1  /**
     2   * Copyright 2023 CloudWeGo Authors.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package generic
    18  
    19  import (
    20  	"encoding/hex"
    21  	"reflect"
    22  	"strconv"
    23  	"testing"
    24  
    25  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/base"
    26  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/example2"
    27  	"github.com/cloudwego/dynamicgo/testdata/sample"
    28  	"github.com/cloudwego/dynamicgo/thrift"
    29  	"github.com/davecgh/go-spew/spew"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestChildren(t *testing.T) {
    34  	desc := getExampleDesc()
    35  	data := getExampleData()
    36  	v := NewValue(desc, data)
    37  
    38  	// t.Run("skip", func(t *testing.T) {
    39  	// 	opts := Options{}
    40  	// 	children := make([]PathNode, 0)
    41  	// 	err := v.Children(&children, false, &opts)
    42  	// 	require.Nil(t, err)
    43  	// 	checkHelper2(t, getExampleValue(v), children, true)
    44  	// })
    45  
    46  	t.Run("recurse", func(t *testing.T) {
    47  		children := make([]PathNode, 0)
    48  		opts := Options{}
    49  		err := v.Children(&children, true, &opts)
    50  		require.NoError(t, err)
    51  		require.Equal(t, 4, len(children))
    52  		exp := toInterface2(sample.Example2Obj, false, b2s)
    53  		act := PathNodeToInterface(PathNode{
    54  			Node: v.Node,
    55  			Next: children,
    56  		}, &opts, false)
    57  		// require.Equal(t, exp, act)
    58  		require.True(t, DeepEqual(exp, act))
    59  		require.True(t, DeepEqual(act, exp))
    60  	})
    61  
    62  	t.Run("NotScanParentNode", func(t *testing.T) {
    63  		children := make([]PathNode, 0)
    64  		opts := Options{}
    65  		opts.NotScanParentNode = true
    66  		err := v.Children(&children, true, &opts)
    67  		require.NoError(t, err)
    68  		require.Equal(t, 4, len(children))
    69  		exp := toInterface2(sample.Example2Obj, false, b2s)
    70  		act := PathNodeToInterface(PathNode{
    71  			Node: v.Node,
    72  			Next: children,
    73  		}, &opts, false)
    74  		require.True(t, DeepEqual(exp, act))
    75  		require.True(t, DeepEqual(act, exp))
    76  	})
    77  
    78  	t.Run("StoreChildrenById", func(t *testing.T) {
    79  		children := make([]PathNode, 0)
    80  		opts := Options{}
    81  		opts.StoreChildrenById = true
    82  		err := v.Children(&children, true, &opts)
    83  		require.NoError(t, err)
    84  		require.Equal(t, 257, len(children))
    85  		// get
    86  		require.Equal(t, thrift.STRING, children[desc.Struct().Fields()[0].ID()].Node.Type())
    87  		base := children[desc.Struct().Fields()[2].ID()]
    88  		require.Equal(t, thrift.STRUCT, base.Node.Type())
    89  		require.Equal(t, thrift.STRUCT, base.Field(thrift.FieldID(255), &opts).Node.Type())
    90  		// set
    91  		var testByte byte = 123
    92  		exist, err := base.SetField(2, NewNodeByte(testByte), &opts)
    93  		require.NoError(t, err)
    94  		require.True(t, exist)
    95  		exist, err = base.SetField(299, NewNodeByte(testByte), &opts)
    96  		require.NoError(t, err)
    97  		require.False(t, exist)
    98  		// get again
    99  		require.Equal(t, thrift.STRUCT, base.Field(thrift.FieldID(255), &opts).Node.Type())
   100  
   101  		// marshal
   102  		out, err := base.Marshal(&opts)
   103  		require.NoError(t, err)
   104  		act := example2.NewInnerBase()
   105  		_, err = act.FastRead(out)
   106  		require.NoError(t, err)
   107  		require.Equal(t, testByte, byte(act.Byte))
   108  	})
   109  
   110  	t.Run("StoreChildrenByHash", func(t *testing.T) {
   111  		opts := Options{}
   112  		exp := example2.NewExampleReq()
   113  		exp.Base = base.NewBase()
   114  		exp.Base.Extra = map[string]string{}
   115  		for i := 0; i < 100; i++ {
   116  			exp.Base.Extra[strconv.Itoa(i)] = strconv.Itoa(i)
   117  		}
   118  		exp.InnerBase = example2.NewInnerBase()
   119  		exp.InnerBase.MapInt32String = map[int32]string{}
   120  		for i := 0; i < 100; i++ {
   121  			exp.InnerBase.MapInt32String[int32(i)] = strconv.Itoa(i)
   122  		}
   123  		in := make([]byte, exp.BLength())
   124  		exp.FastWriteNocopy(in, nil)
   125  		x := NewValue(getExampleDesc(), in)
   126  
   127  		// load
   128  		children := make([]PathNode, 0)
   129  		opts.StoreChildrenByHash = true
   130  		opts.StoreChildrenById = true
   131  		err := x.Children(&children, true, &opts)
   132  		require.NoError(t, err)
   133  
   134  		// get str key
   135  		con := &children[255].Next[6]
   136  		require.Nil(t, con.GetByStr("c", &opts))
   137  		pv := con.GetByStr("0", &opts)
   138  		require.NotNil(t, pv)
   139  		v, err := pv.Interface(&opts)
   140  		require.NoError(t, err)
   141  		require.Equal(t, "0", v)
   142  
   143  		// set str key
   144  		exist, err := con.SetByStr("0", NewNodeString("123"), &opts)
   145  		require.NoError(t, err)
   146  		require.True(t, exist)
   147  		exist, err = con.SetByStr("299", NewNodeString("123"), &opts)
   148  		require.NoError(t, err)
   149  		require.False(t, exist)
   150  
   151  		// get str key again
   152  		pv = con.GetByStr("0", &opts)
   153  		require.NotNil(t, pv)
   154  		v, err = pv.Interface(&opts)
   155  		require.NoError(t, err)
   156  		require.Equal(t, "123", v)
   157  
   158  		// get int key
   159  		con2 := &children[3].Next[12]
   160  		require.Nil(t, con2.GetByInt(299, &opts))
   161  		pv = con2.GetByInt(0, &opts)
   162  		require.NotNil(t, pv)
   163  		v, err = pv.Interface(&opts)
   164  		require.NoError(t, err)
   165  		require.Equal(t, "0", v)
   166  
   167  		// set int key
   168  		exist, err = con2.SetByInt(0, NewNodeString("123"), &opts)
   169  		require.NoError(t, err)
   170  		require.True(t, exist)
   171  		exist, err = con2.SetByInt(299, NewNodeString("123"), &opts)
   172  		require.NoError(t, err)
   173  		require.False(t, exist)
   174  
   175  		// get int key again
   176  		pv = con2.GetByInt(0, &opts)
   177  		require.NotNil(t, pv)
   178  		v, err = pv.Interface(&opts)
   179  		require.NoError(t, err)
   180  		require.Equal(t, "123", v)
   181  
   182  		// marshal
   183  		r := PathNode{
   184  			Node: x.Node,
   185  			Next: children,
   186  		}
   187  		out, err := r.Marshal(&opts)
   188  		require.NoError(t, err)
   189  		act := example2.NewExampleReq()
   190  		_, err = act.FastRead(out)
   191  		require.NoError(t, err)
   192  		require.Equal(t, "123", act.Base.Extra["0"])
   193  		require.Equal(t, "123", act.Base.Extra["299"])
   194  		require.Equal(t, "123", act.InnerBase.MapInt32String[0])
   195  		require.Equal(t, "123", act.InnerBase.MapInt32String[299])
   196  	})
   197  }
   198  
   199  var (
   200  	BasePathNode = PathNode{
   201  		Path: NewPathFieldId(255),
   202  		Next: []PathNode{
   203  			{
   204  				Path: NewPathFieldId(1),
   205  			},
   206  			{
   207  				Path: NewPathFieldId(2),
   208  			},
   209  			{
   210  				Path: NewPathFieldId(3),
   211  			},
   212  			{
   213  				Path: NewPathFieldId(4),
   214  			},
   215  			{
   216  				Path: NewPathFieldId(5),
   217  				Next: []PathNode{
   218  					{
   219  						Path: NewPathFieldId(1),
   220  					},
   221  					{
   222  						Path: NewPathFieldId(2),
   223  					},
   224  				},
   225  			},
   226  			{
   227  				Path: NewPathFieldId(6),
   228  			},
   229  		},
   230  	}
   231  	InnerBasePathNode = PathNode{
   232  		Path: NewPathFieldId(3),
   233  		Next: []PathNode{
   234  			{
   235  				Path: NewPathFieldId(1),
   236  			},
   237  			{
   238  				Path: NewPathFieldId(2),
   239  			},
   240  			{
   241  				Path: NewPathFieldId(3),
   242  			},
   243  			{
   244  				Path: NewPathFieldId(4),
   245  			},
   246  			{
   247  				Path: NewPathFieldId(5),
   248  			},
   249  			{
   250  				Path: NewPathFieldId(6),
   251  			},
   252  			{
   253  				Path: NewPathFieldId(7),
   254  			},
   255  			{
   256  				Path: NewPathFieldId(8),
   257  			},
   258  			{
   259  				Path: NewPathFieldId(9),
   260  			},
   261  			{
   262  				Path: NewPathFieldId(10),
   263  			},
   264  			{
   265  				Path: NewPathFieldId(11),
   266  			},
   267  			{
   268  				Path: NewPathFieldId(12),
   269  			},
   270  			{
   271  				Path: NewPathFieldId(13),
   272  			},
   273  			{
   274  				Path: NewPathFieldId(14),
   275  			},
   276  			{
   277  				Path: NewPathFieldId(15),
   278  			},
   279  			{
   280  				Path: NewPathFieldId(16),
   281  			},
   282  			BasePathNode,
   283  		},
   284  	}
   285  	ExamplePathNode = PathNode{
   286  		Path: NewPathFieldName("root"),
   287  		Next: []PathNode{
   288  			{
   289  				Path: NewPathFieldId(1),
   290  			},
   291  			{
   292  				Path: NewPathFieldId(2),
   293  			},
   294  			InnerBasePathNode,
   295  			BasePathNode,
   296  			{
   297  				Path: NewPathFieldId(32767),
   298  			},
   299  		},
   300  	}
   301  )
   302  
   303  func TestPathCast(t *testing.T) {
   304  	t.Run("field id", func(t *testing.T) {
   305  		exp := thrift.FieldID(1)
   306  		path := NewPathFieldId(exp)
   307  		require.Equal(t, exp, path.Id())
   308  		require.Equal(t, exp, path.Value())
   309  	})
   310  	t.Run("field name", func(t *testing.T) {
   311  		exp := "name"
   312  		path := NewPathFieldName(exp)
   313  		require.Equal(t, exp, path.Str())
   314  		require.Equal(t, exp, path.Value())
   315  	})
   316  	t.Run("index", func(t *testing.T) {
   317  		exp := 1
   318  		path := NewPathIndex(exp)
   319  		require.Equal(t, exp, path.Int())
   320  		require.Equal(t, exp, path.Value())
   321  	})
   322  	t.Run("key", func(t *testing.T) {
   323  		exp := "key"
   324  		path := NewPathStrKey(exp)
   325  		require.Equal(t, exp, path.Str())
   326  		require.Equal(t, exp, path.Value())
   327  	})
   328  	// t.Run("obj key", func(t *testing.T) {
   329  	// 	exp := struct{ A int }{1}
   330  	// 	path := NewPathObjKey(exp)
   331  	// 	require.Equal(t, exp, path.Value())
   332  	// })
   333  }
   334  
   335  // func TestDescriptorToPN(t *testing.T) {
   336  // 	desc := getExampleDesc()
   337  
   338  // 	t.Run("field id", func(t *testing.T) {
   339  // 		var opts = &Options{
   340  // 			// OnlyScanStruct: true,
   341  // 		}
   342  // 		var exp = ExamplePathNode
   343  
   344  // 		act := PathNode{
   345  // 			Path: NewPathFieldName("root"),
   346  // 		}
   347  // 		require.Nil(t, DescriptorToPathNode(desc, &act, opts))
   348  // 		require.Equal(t, exp, act)
   349  // 	})
   350  // }
   351  
   352  func TestPathReuse(t *testing.T) {
   353  	desc := getExampleDesc()
   354  	data := getExampleData()
   355  	root := NewValue(desc, data)
   356  
   357  	obj := ExamplePathNode.Fork()
   358  	require.Equal(t, ExamplePathNode, obj)
   359  
   360  	obj.Node = root.Node
   361  	opts := &Options{}
   362  	require.Nil(t, obj.Assgin(true, opts))
   363  	out1, err := obj.Marshal(opts)
   364  	require.Nil(t, err)
   365  
   366  	obj.ResetValue()
   367  	require.Equal(t, ExamplePathNode, obj)
   368  
   369  	obj.Node = root.Node
   370  	require.Nil(t, obj.Assgin(true, opts))
   371  	out2, err := obj.Marshal(opts)
   372  	require.Nil(t, err)
   373  
   374  	require.Equal(t, out1, out2)
   375  }
   376  
   377  func TestPathEmpty(t *testing.T) {
   378  	desc := getExampleDesc()
   379  	data := getExampleData()
   380  	root := NewValue(desc, data)
   381  	opts := &Options{}
   382  
   383  	ori := PathNode{
   384  		Path: NewPathFieldName("root"),
   385  		Node: root.Node,
   386  	}
   387  	root.Children(&ori.Next, true, opts)
   388  
   389  	obj := ori.Fork()
   390  	obj.Next = append(obj.Next, PathNode{Path: NewPathFieldName("empty")})
   391  	obj.Next[2].Next = append(obj.Next[2].Next, PathNode{Path: NewPathFieldName("empty")})
   392  	obj.Next[2].Next[7].Next = append(obj.Next[2].Next[7].Next, PathNode{Path: NewPathIndex(1024)})
   393  	obj.Next[2].Next[8].Next = append(obj.Next[2].Next[8].Next, PathNode{Path: NewPathStrKey("empty")})
   394  	obj.Node = root.Node
   395  
   396  	require.Nil(t, obj.Assgin(true, opts))
   397  	out1, err := obj.Marshal(opts)
   398  	require.Nil(t, err)
   399  
   400  	obj = ori.Fork()
   401  	obj.Node = root.Node
   402  	require.Nil(t, obj.Assgin(true, opts))
   403  	out2, err := obj.Marshal(opts)
   404  	require.Nil(t, err)
   405  
   406  	require.Equal(t, out1, out2)
   407  }
   408  
   409  func TestTreeGet(t *testing.T) {
   410  	desc := getExampleDesc()
   411  	data := getExampleData()
   412  
   413  	exp := example2.NewExampleReq()
   414  	v := NewValue(desc, data)
   415  	tree := PathNode{
   416  		Node: v.Node,
   417  		Next: []PathNode{
   418  			{
   419  				Path: NewPathFieldId(1),
   420  			},
   421  			{
   422  				Path: NewPathFieldId(3),
   423  				Next: []PathNode{
   424  					{
   425  						Path: NewPathFieldId(1),
   426  					},
   427  					{
   428  						Path: NewPathFieldId(8),
   429  						Next: []PathNode{
   430  							{
   431  								Path: NewPathIndex(1),
   432  							},
   433  						},
   434  					},
   435  					{
   436  						Path: NewPathFieldId(9),
   437  						Next: []PathNode{
   438  							{
   439  								Path: NewPathStrKey("b"),
   440  							},
   441  						},
   442  					},
   443  					{
   444  						Path: NewPathFieldId(12),
   445  						Next: []PathNode{
   446  							{
   447  								Path: NewPathIntKey(2),
   448  							},
   449  						},
   450  					},
   451  				},
   452  			},
   453  			{
   454  				Path: NewPathFieldId(255),
   455  				Next: []PathNode{
   456  					{
   457  						Path: NewPathFieldId(2),
   458  					},
   459  				},
   460  			},
   461  		},
   462  	}
   463  	opts := Options{}
   464  	err := tree.Assgin(true, &opts)
   465  	require.NoError(t, err)
   466  
   467  	_, err = exp.FastRead(data)
   468  	require.Nil(t, err)
   469  
   470  	expM2 := map[int]interface{}{}
   471  	for k, v := range exp.InnerBase.MapInt32String {
   472  		expM2[int(k)] = v
   473  	}
   474  	checkHelper(t, *exp.Msg, tree.Next[0].Node, "String")
   475  	checkHelper(t, exp.InnerBase.Bool, tree.Next[1].Next[0].Node, "Bool")
   476  	checkHelper(t, exp.InnerBase.ListInt32, tree.Next[1].Next[1].Node, "List")
   477  	checkHelper(t, exp.InnerBase.MapStringString, tree.Next[1].Next[2].Node, "StrMap")
   478  	checkHelper(t, expM2, tree.Next[1].Next[3].Node, "IntMap")
   479  	checkHelper(t, exp.Base.Client, tree.Next[2].Next[0].Node, "String")
   480  
   481  	out, err := tree.Marshal(&opts)
   482  	require.Nil(t, err)
   483  	println(hex.Dump(out))
   484  }
   485  
   486  func TestTreeMarshal(t *testing.T) {
   487  	desc := getExampleDesc()
   488  	data := getExampleData()
   489  
   490  	v := NewValue(desc, data)
   491  	tree := PathNode{
   492  		Node: v.Node,
   493  		Next: []PathNode{
   494  			{
   495  				Path: NewPathFieldId(1),
   496  			},
   497  			{
   498  				Path: NewPathFieldId(3),
   499  				Next: []PathNode{
   500  					{
   501  						Path: NewPathFieldId(1),
   502  					},
   503  					{
   504  						Path: NewPathFieldId(8),
   505  						Next: []PathNode{
   506  							{
   507  								Path: NewPathIndex(1),
   508  							},
   509  						},
   510  					},
   511  					{
   512  						Path: NewPathFieldId(9),
   513  						Next: []PathNode{
   514  							{
   515  								Path: NewPathStrKey("b"),
   516  							},
   517  						},
   518  					},
   519  					{
   520  						Path: NewPathFieldId(12),
   521  						Next: []PathNode{
   522  							{
   523  								Path: NewPathIntKey(2),
   524  							},
   525  						},
   526  					},
   527  				},
   528  			},
   529  			{
   530  				Path: NewPathFieldId(255),
   531  				Next: []PathNode{
   532  					{
   533  						Path: NewPathFieldId(2),
   534  					},
   535  				},
   536  			},
   537  		},
   538  	}
   539  	opts := Options{}
   540  	err := tree.Assgin(true, &opts)
   541  	require.NoError(t, err)
   542  
   543  	out, err := tree.Marshal(&opts)
   544  	require.Nil(t, err)
   545  	// spew.Dump(out)
   546  	exp := example2.NewExampleReq()
   547  	_, err = exp.FastRead(out)
   548  	require.Nil(t, err)
   549  
   550  	x := v.GetByPath(PathExampleByte...)
   551  	tt := PathNode{
   552  		Path: NewPathFieldName("Msg"),
   553  		Node: x.Node,
   554  		Next: []PathNode{
   555  			tree,
   556  		},
   557  	}
   558  	out, err = tt.Marshal(&opts)
   559  	require.Nil(t, err)
   560  	require.Equal(t, x.Raw(), out)
   561  }
   562  
   563  func getExampleValue(v Value) []PathNode {
   564  	return []PathNode{
   565  		{
   566  			Path: NewPathFieldId(1),
   567  			Node: v.GetByPath(NewPathFieldName("Msg")).Node,
   568  		},
   569  		{
   570  			Path: NewPathFieldId(3),
   571  			Node: v.GetByPath(NewPathFieldName("InnerBase")).Node,
   572  		},
   573  		{
   574  			Path: NewPathFieldId(255),
   575  			Node: v.GetByPath(NewPathFieldName("Base")).Node,
   576  		},
   577  		{
   578  			Path: NewPathFieldId(32767),
   579  			Node: v.GetByPath(NewPathFieldName("Subfix")).Node,
   580  		},
   581  	}
   582  }
   583  
   584  func getInnerBase(v Value) []PathNode {
   585  	return []PathNode{
   586  		{
   587  			Path: NewPathFieldId(1),
   588  			Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("LogID")).Node,
   589  		},
   590  		{
   591  			Path: NewPathFieldId(2),
   592  			Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Caller")).Node,
   593  		},
   594  		{
   595  			Path: NewPathFieldId(3),
   596  			Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Addr")).Node,
   597  		},
   598  		{
   599  			Path: NewPathFieldId(4),
   600  			Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Client")).Node,
   601  		},
   602  		{
   603  			Path: NewPathFieldId(5),
   604  			Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("TrafficEnv")).Node,
   605  			Next: []PathNode{
   606  				{
   607  					Path: NewPathFieldId(1),
   608  					Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("TrafficEnv"), NewPathFieldName("Open")).Node,
   609  				},
   610  				{
   611  					Path: NewPathFieldId(2),
   612  					Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("TrafficEnv"), NewPathFieldName("Env")).Node,
   613  				},
   614  			},
   615  		},
   616  		{
   617  			Path: NewPathFieldId(6),
   618  			Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra")).Node,
   619  			Next: []PathNode{
   620  				{
   621  					Path: NewPathStrKey("a"),
   622  					Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("a")).Node,
   623  				},
   624  				{
   625  					Path: NewPathStrKey("b"),
   626  					Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")).Node,
   627  				},
   628  				{
   629  					Path: NewPathStrKey("c"),
   630  					Node: v.GetByPath(NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("c")).Node,
   631  				},
   632  			},
   633  		},
   634  	}
   635  }
   636  
   637  func checkHelper2(t *testing.T, exp []PathNode, act []PathNode, checkNode bool) {
   638  	require.Equal(t, len(exp), len(act))
   639  	for i := range exp {
   640  		t.Logf("Path: %s\n", exp[i].Path)
   641  		found := false
   642  		for j := range act {
   643  			if exp[i].Path.String() == act[j].Path.String() {
   644  				if checkNode {
   645  					require.Equal(t, exp[i].Node, act[j].Node)
   646  				}
   647  				checkHelper2(t, exp[i].Next, act[j].Next, checkNode)
   648  				found = true
   649  				break
   650  			}
   651  		}
   652  		require.True(t, found)
   653  	}
   654  }
   655  
   656  // func toPathNode(v interface{}, ret *PathNode) {
   657  // 	vt := reflect.ValueOf(v)
   658  // 	if vt.Kind() == reflect.Ptr {
   659  // 		if vt.IsNil() {
   660  // 			return
   661  // 		}
   662  // 		vt = vt.Elem()
   663  // 	}
   664  
   665  // 	if k := vt.Kind(); k == reflect.Slice || k == reflect.Array {
   666  // 		if vt.Type() == bytesType || vt.Len() == 0 {
   667  // 			return
   668  // 		}
   669  // 		if len(ret.Next) < vt.Len() {
   670  // 			ret.Next = make([]PathNode, vt.Len())
   671  // 		}
   672  // 		var r *PathNode
   673  // 		for i := 0; i < vt.Len(); i++ {
   674  // 			r = &r.Next[i]
   675  // 			r.Path = NewPathIndex(i)
   676  // 			toPathNode(vt.Index(i).Interface(), r)
   677  // 		}
   678  // 		return
   679  // 	} else if k == reflect.Map {
   680  // 		if vt.Len() == 0 {
   681  // 			return
   682  // 		}
   683  // 		if len(ret.Next) < vt.Len() {
   684  // 			ret.Next = make([]PathNode, vt.Len())
   685  // 		}
   686  // 		if kt := vt.Type().Key().Kind(); kt == reflect.String {
   687  // 			var r *PathNode
   688  // 			for i, k := range vt.MapKeys() {
   689  // 				r = &r.Next[i]
   690  // 				r.Path = NewPathStrKey(k.String())
   691  // 				toPathNode(vt.MapIndex(k).Interface(), r)
   692  // 			}
   693  // 			return
   694  // 		} else if kt == reflect.Int || kt == reflect.Int8 || kt == reflect.Int16 || kt == reflect.Int32 || kt == reflect.Int64 {
   695  // 			var r *PathNode
   696  // 			for i, k := range vt.MapKeys() {
   697  // 				r = &r.Next[i]
   698  // 				r.Path = NewPathIntKey(int(k.Int()))
   699  // 				toPathNode(vt.MapIndex(k).Interface(), r)
   700  // 			}
   701  // 			return
   702  // 		}
   703  // 	} else if k == reflect.Struct {
   704  // 		var r *PathNode
   705  // 		if vt.NumField() == 0 {
   706  // 			return
   707  // 		}
   708  // 		if len(ret.Next) < vt.NumField() {
   709  // 			ret.Next = make([]PathNode, vt.NumField())
   710  // 		}
   711  // 		for i := 0; i < vt.NumField(); i++ {
   712  // 			r = &r.Next[i]
   713  // 			field := vt.Type().Field(i)
   714  // 			tag := field.Tag.Get("thrift")
   715  // 			ts := strings.Split(tag, ",")
   716  // 			id := i
   717  // 			if len(ts) > 1 {
   718  // 				id, _ = strconv.Atoi(ts[1])
   719  // 			}
   720  // 			r.Path = NewPathFieldId(thrift.FieldID(id))
   721  // 			toPathNode(vt.Field(i).Interface(), r)
   722  // 		}
   723  // 		return
   724  // 	} else {
   725  // 		ret.Node = NewNodeAny(vt.Interface())
   726  // 		return
   727  // 	}
   728  // }
   729  
   730  func DeepEqual(exp interface{}, act interface{}) bool {
   731  	switch ev := exp.(type) {
   732  	case map[int]interface{}:
   733  		av, ok := act.(map[int]interface{})
   734  		if !ok {
   735  			return false
   736  		}
   737  		for k, v := range ev {
   738  			vv, ok := av[k]
   739  			if !ok {
   740  				return false
   741  			}
   742  			if !DeepEqual(v, vv) {
   743  				return false
   744  			}
   745  		}
   746  		return true
   747  	case map[string]interface{}:
   748  		av, ok := act.(map[string]interface{})
   749  		if !ok {
   750  			return false
   751  		}
   752  		for k, v := range ev {
   753  			vv, ok := av[k]
   754  			if !ok {
   755  				return false
   756  			}
   757  			if !DeepEqual(v, vv) {
   758  				return false
   759  			}
   760  		}
   761  		return true
   762  	case map[interface{}]interface{}:
   763  		av, ok := act.(map[interface{}]interface{})
   764  		if !ok {
   765  			return false
   766  		}
   767  		if len(ev) == 0 {
   768  			return true
   769  		}
   770  		erv := reflect.ValueOf(ev)
   771  		arv := reflect.ValueOf(av)
   772  		eks := erv.MapKeys()
   773  		aks := arv.MapKeys()
   774  		isPointer := eks[0].Elem().Kind() == reflect.Ptr
   775  		if !isPointer {
   776  			for k, v := range ev {
   777  				vv, ok := av[k]
   778  				if !ok {
   779  					return false
   780  				}
   781  				if !DeepEqual(v, vv) {
   782  					return false
   783  				}
   784  			}
   785  		} else {
   786  			for _, ek := range eks {
   787  				found := false
   788  				for _, ak := range aks {
   789  					if DeepEqual(ek.Elem().Elem().Interface(), ak.Elem().Elem().Interface()) {
   790  						found = true
   791  						evv := erv.MapIndex(ek)
   792  						avv := arv.MapIndex(ak)
   793  						if !DeepEqual(evv.Interface(), avv.Interface()) {
   794  							return false
   795  						}
   796  					}
   797  					if !found {
   798  						return false
   799  					}
   800  				}
   801  			}
   802  		}
   803  		return true
   804  	case []interface{}:
   805  		av, ok := act.([]interface{})
   806  		if !ok {
   807  			return false
   808  		}
   809  		for i, v := range ev {
   810  			vv := av[i]
   811  			if !DeepEqual(v, vv) {
   812  				return false
   813  			}
   814  		}
   815  		return true
   816  	default:
   817  		return reflect.DeepEqual(exp, act)
   818  	}
   819  }
   820  
   821  func TestDeepEqual(t *testing.T) {
   822  	a := map[interface{}]interface{}{
   823  		float64(0.1): "A",
   824  		float64(0.2): "B",
   825  		float64(0.3): "C",
   826  		float64(0.4): "D",
   827  		float64(0.5): "E",
   828  		float64(0.6): "F",
   829  		float64(0.7): "G",
   830  		float64(0.8): "H",
   831  		float64(0.9): "I",
   832  	}
   833  	b := map[interface{}]interface{}{
   834  		float64(0.4): "D",
   835  		float64(0.8): "H",
   836  		float64(0.7): "G",
   837  		float64(0.5): "E",
   838  		float64(0.6): "F",
   839  		float64(0.9): "I",
   840  		float64(0.2): "B",
   841  		float64(0.1): "A",
   842  		float64(0.3): "C",
   843  	}
   844  	for i := 0; i < 10; i++ {
   845  		require.Equal(t, a, b)
   846  	}
   847  	require.True(t, DeepEqual(a, b))
   848  }
   849  
   850  func TestUnknownFields(t *testing.T) {
   851  	desc := getExampleDesc()
   852  	data := getExampleSuperData()
   853  	v := NewValue(desc, data)
   854  
   855  	t.Run("Children()", func(t *testing.T) {
   856  		// t.Run("allow", func(t *testing.T) {
   857  		children := make([]PathNode, 0)
   858  		opts := Options{}
   859  		err := v.Children(&children, true, &opts)
   860  		require.Nil(t, err)
   861  		act := PathNodeToInterface(PathNode{Node: v.Node, Next: children}, &opts, false)
   862  		exp := toInterface2(sample.Example2Super, false, b2s)
   863  		if !DeepEqual(exp, act) {
   864  			t.Fatal()
   865  		}
   866  		if !DeepEqual(act, exp) {
   867  			t.Fatal()
   868  		}
   869  		// require.Equal(t, exp, act)
   870  		// })
   871  
   872  		// t.Run("disallow", func(t *testing.T) {
   873  		// children := make([]PathNode, 0)
   874  		// opts := Options{
   875  		// 	DisallowUnknow: true,
   876  		// }
   877  		// err := v.Children(&children, false, &opts)
   878  		// require.NotNil(t, err)
   879  		// require.Equal(t, meta.ErrUnknownField, err.(meta.Error).Code.Behavior())
   880  		// })
   881  	})
   882  
   883  	t.Run("Assgin(true, )", func(t *testing.T) {
   884  		// t.Run("allow", func(t *testing.T) {
   885  		opts := Options{
   886  			DescriptorToPathNodeWriteDefualt:  true,
   887  			DescriptorToPathNodeWriteOptional: true,
   888  		}
   889  		path := PathNode{
   890  			Node: v.Node,
   891  		}
   892  		err := DescriptorToPathNode(desc, &path, &opts)
   893  		if err != nil {
   894  			t.Fatal(err)
   895  		}
   896  		err = path.Assgin(true, &opts)
   897  		require.NoError(t, err)
   898  		act := PathNodeToInterface(path, &opts, true)
   899  		exp := toInterface2(sample.Example2Obj, false, b2s)
   900  		// require.Equal(t, exp, act)
   901  		if !DeepEqual(exp, act) {
   902  			spew.Dump(exp, act)
   903  			t.Fatal()
   904  		}
   905  
   906  		// })
   907  		// t.Run("disallow", func(t *testing.T) {
   908  		// 	opts := Options{
   909  		// 		DisallowUnknow: true,
   910  		// 	}
   911  		// 	path := PathNode{
   912  		// 		Node: v.Node,
   913  		// 	}
   914  		// 	err := DescriptorToPathNode(desc, &path, &opts)
   915  		// 	if err != nil {
   916  		// 		t.Fatal(err)
   917  		// 	}
   918  		// 	err = path.Assgin(true, &opts)
   919  		// 	require.Error(t, err)
   920  		// 	require.Equal(t, meta.ErrUnknownField, err.(Value).ErrCode())
   921  		// })
   922  	})
   923  
   924  	// t.Run("Interface()/ByName", func(t *testing.T) {
   925  	// 	// t.Run("allow", func(t *testing.T) {
   926  	// 	opts := Options{
   927  	// 		DisallowUnknow: false,
   928  	// 		StructByName:   true,
   929  	// 	}
   930  	// 	ret, err := v.Interface(&opts)
   931  	// 	require.NoError(t, err)
   932  	// 	rv := toInterface2(sample.Example2Obj, false, true)
   933  	// 	require.Equal(t, rv, ret)
   934  	// })
   935  	// t.Run("disallow", func(t *testing.T) {
   936  	// 	opts := Options{
   937  	// 		DisallowUnknow: true,
   938  	// 		StructByName:   true,
   939  	// 	}
   940  	// 	_, err := v.Interface(&opts)
   941  	// 	require.Error(t, err)
   942  	// 	require.Equal(t, meta.ErrUnknownField, err.(Value).ErrCode())
   943  	// })
   944  	// })
   945  
   946  	t.Run("Interface()", func(t *testing.T) {
   947  		// t.Run("allow", func(t *testing.T) {
   948  		opts := Options{
   949  			// DisallowUnknow: false,
   950  			// StructByName:   false,
   951  		}
   952  		ret, err := v.Interface(&opts)
   953  		require.NoError(t, err)
   954  		rv := toInterface2(sample.Example2Super, false, b2s)
   955  		if !DeepEqual(rv, ret) {
   956  			t.Fatal()
   957  		}
   958  		if !DeepEqual(ret, rv) {
   959  			t.Fatal()
   960  		}
   961  		// })
   962  		// t.Run("disallow", func(t *testing.T) {
   963  		// 	opts := Options{
   964  		// 		DisallowUnknow: true,
   965  		// 		StructByName:   false,
   966  		// 	}
   967  		// 	_, err := v.Interface(&opts)
   968  		// 	require.Error(t, err)
   969  		// 	require.Equal(t, meta.ErrUnknownField, err.(Value).ErrCode())
   970  		// })
   971  	})
   972  
   973  	t.Run("Marshal()", func(t *testing.T) {
   974  		children := make([]PathNode, 0)
   975  		opts := Options{}
   976  		err := v.Children(&children, true, &opts)
   977  		require.Nil(t, err)
   978  		tree := PathNode{
   979  			Node: v.Node,
   980  			Next: children,
   981  		}
   982  		out, err := tree.Marshal(&opts)
   983  		require.NoError(t, err)
   984  
   985  		act := example2.NewExampleSuper()
   986  		_, err = act.FastRead(out)
   987  		require.NoError(t, err)
   988  
   989  		// require.Equal(t, sample.Example2Super, act)
   990  	})
   991  }
   992  
   993  func TestDescriptorToPathNode(t *testing.T) {
   994  	type args struct {
   995  		desc *thrift.TypeDescriptor
   996  		root *PathNode
   997  		opts *Options
   998  	}
   999  	tests := []struct {
  1000  		name    string
  1001  		args    args
  1002  		wantErr bool
  1003  	}{
  1004  		{name: "defualt", args: args{
  1005  			desc: getExampleDesc(),
  1006  			root: new(PathNode),
  1007  			opts: &Options{},
  1008  		}, wantErr: false},
  1009  		{name: "array size 1", args: args{
  1010  			desc: getExampleDesc(),
  1011  			root: new(PathNode),
  1012  			opts: &Options{
  1013  				DescriptorToPathNodeArraySize: 1,
  1014  				DescriptorToPathNodeMaxDepth:  256,
  1015  			},
  1016  		}, wantErr: false},
  1017  		{name: "map size 1", args: args{
  1018  			desc: getExampleDesc(),
  1019  			root: new(PathNode),
  1020  			opts: &Options{
  1021  				DescriptorToPathNodeMapSize:  1,
  1022  				DescriptorToPathNodeMaxDepth: 256,
  1023  			},
  1024  		}, wantErr: false},
  1025  	}
  1026  	for _, tt := range tests {
  1027  		t.Run(tt.name, func(t *testing.T) {
  1028  			if err := DescriptorToPathNode(tt.args.desc, tt.args.root, tt.args.opts); (err != nil) != tt.wantErr {
  1029  				t.Errorf("DescriptorToPathNode() error = %v, wantErr %v", err, tt.wantErr)
  1030  			}
  1031  			println(tt.name)
  1032  			spew.Dump(PathNodeToInterface(*tt.args.root, tt.args.opts, false))
  1033  		})
  1034  
  1035  	}
  1036  }