github.com/viant/toolbox@v0.34.5/data/map_test.go (about)

     1  package data
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/viant/toolbox"
     9  )
    10  
    11  func TestMap_GetValue(t *testing.T) {
    12  
    13  	aMap := NewMap()
    14  
    15  	{
    16  		subCollection := NewCollection()
    17  		subCollection.Push("item1")
    18  		subCollection.Push("item2")
    19  		aMap.Put("cc", subCollection)
    20  		subMap := NewMap()
    21  		subMap.Put("k1", 1)
    22  		subMap.Put("k2", 1)
    23  		aMap.Put("cc", subCollection)
    24  		aMap.Put("keys", subMap)
    25  
    26  		{
    27  			value, has := aMap.GetValue("cc[0]")
    28  			assert.True(t, has)
    29  			assert.Equal(t, "item1", value)
    30  		}
    31  		{
    32  			value, has := aMap.GetValue("keys[k1]")
    33  			assert.True(t, has)
    34  			assert.Equal(t, 1, value)
    35  		}
    36  		{
    37  			_, has := aMap.GetValue("keys[k10]")
    38  			assert.False(t, has)
    39  		}
    40  	}
    41  
    42  	{
    43  		metaMap := make(map[string]int)
    44  		metaMap["USER"] = 7
    45  		aMap.Put("meta", metaMap)
    46  
    47  		value, ok := aMap.GetValue("meta.USER")
    48  		assert.True(t, ok)
    49  		if !assert.Equal(t, 7, value) {
    50  			return
    51  		}
    52  		aMap.SetValue("meta.USER", toolbox.AsInt(value)+1)
    53  		value, ok = aMap.GetValue("meta.USER")
    54  		assert.True(t, ok)
    55  		if !assert.Equal(t, 8, value) {
    56  			return
    57  		}
    58  
    59  	}
    60  
    61  	{
    62  		var collection = NewCollection()
    63  		collection.Push("1")
    64  		collection.Push("20")
    65  		collection.Push("30")
    66  		aMap.Put("collection", collection)
    67  
    68  		var subMap = NewMap()
    69  		subMap.Put("i", 10)
    70  		subMap.Put("col", collection)
    71  		aMap.Put("a", subMap)
    72  		aMap.Put("b", "123")
    73  		aMap.Put("c", "b")
    74  	}
    75  
    76  	{ //test simple get operation
    77  		value, has := aMap.GetValue("c")
    78  		assert.True(t, has)
    79  		assert.Equal(t, "b", value)
    80  
    81  	}
    82  
    83  	{ //test  get operation
    84  		value, has := aMap.GetValue("a.col")
    85  		assert.True(t, has)
    86  		assert.Equal(t, []interface{}{"1", "20", "30"}, toolbox.AsSlice(value))
    87  
    88  	}
    89  	{ //test reference get operation
    90  		value, has := aMap.GetValue("$c")
    91  		assert.True(t, has)
    92  		assert.Equal(t, "123", value)
    93  
    94  	}
    95  
    96  	{ //test post increment operations
    97  		value, has := aMap.GetValue("a.i++")
    98  		assert.True(t, has)
    99  		assert.Equal(t, 10, value)
   100  		value, has = aMap.GetValue("a.i++")
   101  		assert.True(t, has)
   102  		assert.Equal(t, 11, value)
   103  	}
   104  
   105  	{ //test pre increment operations
   106  		value, has := aMap.GetValue("++a.i")
   107  		assert.True(t, has)
   108  		assert.Equal(t, 13, value)
   109  		value, has = aMap.GetValue("++a.i")
   110  		assert.True(t, has)
   111  		assert.Equal(t, 14, value)
   112  	}
   113  
   114  	{ //	test shift
   115  		value, has := aMap.GetValue("<-collection")
   116  		assert.True(t, has)
   117  		assert.Equal(t, "1", value)
   118  		value, has = aMap.GetValue("<-collection")
   119  		assert.True(t, has)
   120  		assert.Equal(t, "20", value)
   121  
   122  	}
   123  	{ //	test array index
   124  
   125  		var aCollection = NewCollection()
   126  		aCollection.Push(map[string]interface{}{
   127  			"k1": 1,
   128  			"K2": 2,
   129  		})
   130  		aCollection.Push(map[string]interface{}{
   131  			"k2": 3,
   132  			"K3": 4,
   133  		})
   134  		aMap.Put("c", aCollection)
   135  		value, has := aMap.GetValue("c[0].k1")
   136  		assert.True(t, has)
   137  		assert.Equal(t, 1, value)
   138  
   139  		value, has = aMap.GetValue("c[1].k2")
   140  		assert.True(t, has)
   141  		assert.Equal(t, 3, value)
   142  
   143  	}
   144  
   145  	{
   146  		subMap := NewMap()
   147  		subCollection := NewCollection()
   148  		subCollection.Push("item1")
   149  		subCollection.Push("item2")
   150  		subMap.Put("c", subCollection)
   151  		aMap.Put("s", subMap)
   152  
   153  		value, has := aMap.GetValue("s.c[0]")
   154  		assert.True(t, has)
   155  		assert.Equal(t, "item1", value)
   156  	}
   157  
   158  }
   159  
   160  func TestMap_SetValue(t *testing.T) {
   161  
   162  	aMap := NewMap()
   163  
   164  	{ // test simple Set
   165  
   166  		_, has := aMap.GetValue("z.a")
   167  		assert.False(t, has)
   168  		aMap.SetValue("z.a", "123")
   169  		value, has := aMap.GetValue("z.a")
   170  		assert.True(t, has)
   171  		assert.Equal(t, "123", value)
   172  	}
   173  
   174  	{ // test reference set
   175  
   176  		aMap.SetValue("z.b", "111")
   177  		value, has := aMap.GetValue("z.b")
   178  		assert.True(t, has)
   179  		assert.Equal(t, "111", value)
   180  
   181  		aMap.SetValue("zzz", "z.b")
   182  		aMap.SetValue("$zzz", "222")
   183  		value, has = aMap.GetValue("z.b")
   184  		assert.True(t, has)
   185  		assert.Equal(t, "222", value)
   186  	}
   187  
   188  	{
   189  		//test push
   190  		aMap.SetValue("->a.v", 1)
   191  		aMap.SetValue("->a.v", 2)
   192  
   193  		aCollection, has := aMap.GetValue("a.v")
   194  		assert.True(t, has)
   195  		assert.Equal(t, []interface{}{1, 2}, toolbox.AsSlice(aCollection))
   196  	}
   197  
   198  	{
   199  		//test mutated nested array
   200  		collection := NewCollection()
   201  		item := map[string]interface{}{
   202  			"key":  1,
   203  			"attr": 2,
   204  		}
   205  		collection.Push(item)
   206  		aMap.Put("col", collection)
   207  		aMap.SetValue("col[0].x", 20)
   208  		aMap.SetValue("col[0].attr", 30)
   209  		assert.EqualValues(t, map[string]interface{}{
   210  			"key":  1,
   211  			"attr": 30,
   212  			"x":    20,
   213  		}, item)
   214  	}
   215  
   216  }
   217  
   218  func Test_Expand(t *testing.T) {
   219  
   220  	state := NewMap()
   221  	state.Put("name", "etly")
   222  	build := NewMap()
   223  	state.Put("build", build)
   224  	build.Put("Target", "app")
   225  	build.Put("Args", "-Dmvn.test.skip")
   226  
   227  	var text = state.ExpandAsText("a $vv-ee /usr/local/app_${name}v1 $build.Target $abc $build.Args")
   228  	assert.Equal(t, "a $vv-ee /usr/local/app_etlyv1 app $abc -Dmvn.test.skip", text)
   229  	state.Put("nestedappleone", "juice")
   230  	state.Put("tag", "apple")
   231  	var txt2 = state.ExpandAsText("${nested${tag}one}")
   232  	assert.Equal(t, "juice", txt2)
   233  
   234  	text = "docker build -t $registryUsername/site_profile_backup:0.1.4 /site_profile_backup:0.1.4   /tmp/site_profile_backup/release/"
   235  	state = NewMap()
   236  	state.Put("registryUsername", "$registryUsername")
   237  	expanded := state.Expand(text)
   238  	assert.Equal(t, text, expanded)
   239  }
   240  
   241  func Test_ExpandCycleIssue(t *testing.T) {
   242  	state := NewMap()
   243  	originMap := NewMap()
   244  	originMap.Put("URL", "$origin")
   245  	state.Put("origin", originMap)
   246  	var text = state.Expand("abc ${origin}\n ")
   247  	assert.Equal(t, "abc {\"URL\":\"$origin\"}\n\n ", text)
   248  }
   249  
   250  func Test_ExpandFun(t *testing.T) {
   251  
   252  	state := NewMap()
   253  	state.Put("name", "etly")
   254  	build := NewMap()
   255  	state.Put("build", build)
   256  	build.Put("Target", "app")
   257  	build.Put("Args", "-Dmvn.test.skip")
   258  
   259  	var text = state.ExpandAsText("a $vv-ee /usr/local/app_${name}v1 $build.Target $abc $build.Args")
   260  	assert.Equal(t, "a $vv-ee /usr/local/app_etlyv1 app $abc -Dmvn.test.skip", text)
   261  
   262  }
   263  
   264  func Test_Udf(t *testing.T) {
   265  
   266  	var test = func(s interface{}, m Map) (interface{}, error) {
   267  		return fmt.Sprintf("%v", s), nil
   268  	}
   269  
   270  	var dateOfBirth = func(source interface{}, m Map) (interface{}, error) {
   271  		if !toolbox.IsSlice(source) {
   272  			return nil, fmt.Errorf("expected slice but had: %T %v", source, source)
   273  		}
   274  		return toolbox.NewDateOfBirthrovider().Get(toolbox.NewContext(), toolbox.AsSlice(source)...)
   275  	}
   276  
   277  	state := NewMap()
   278  	state.Put("test", test)
   279  	state.Put("name", "endly")
   280  	state.Put("a", "1")
   281  	state.Put("b", "2")
   282  	state.Put("Dob", dateOfBirth)
   283  
   284  
   285  
   286  	{
   287  		var text = "$xyz($name)"
   288  		expanded := state.Expand(text)
   289  		assert.EqualValues(t, "$xyz(endly)", expanded)
   290  
   291  	}
   292  
   293  	{
   294  		var text = "$xyz(hello $name $abc)"
   295  		expanded := state.Expand(text)
   296  		assert.EqualValues(t, "$xyz(hello endly $abc)", expanded)
   297  
   298  	}
   299  
   300  	{
   301  		var text = "$test(hello $abc)"
   302  		expanded := state.Expand(text)
   303  		assert.EqualValues(t, "$test(hello $abc)", expanded)
   304  	}
   305  
   306  	{
   307  		var text = "$test(hello $name $abc)"
   308  		expanded := state.Expand(text)
   309  		assert.EqualValues(t, "$test(hello endly $abc)", expanded)
   310  	}
   311  
   312  	{
   313  		var text = "$test(hello $name)"
   314  		expanded := state.Expand(text)
   315  		assert.EqualValues(t, "hello endly", expanded)
   316  	}
   317  
   318  	{
   319  		var text = "zz $a ${b}a"
   320  		expanded := state.Expand(text)
   321  		assert.EqualValues(t, "zz 1 2a", expanded)
   322  	}
   323  
   324  
   325  }
   326  
   327  func Test_Delete(t *testing.T) {
   328  	var state = NewMap()
   329  	state.SetValue("k1.v1", 1)
   330  	state.SetValue("k1.v2", 1)
   331  	state.Put("k2", 1)
   332  	state.Delete("k1.v1", "k2")
   333  	assert.EqualValues(t, 1, len(state))
   334  	assert.EqualValues(t, 1, len(state.GetMap("k1")))
   335  
   336  }
   337  
   338  func Test_Replace(t *testing.T) {
   339  	var state = NewMap()
   340  	state.SetValue("k1.v1", 1)
   341  	state.SetValue("k1.v2", 1)
   342  	state.Put("k2", 1)
   343  	state.Replace("k1.v1", "v100")
   344  	state.Replace("k2", "v200")
   345  	assert.EqualValues(t, "v100", state.Expand("$k1.v1"))
   346  	assert.EqualValues(t, "v200", state.Get("k2"))
   347  
   348  }
   349  
   350  func Test_ExpandAsText(t *testing.T) {
   351  	aMap := Map(map[string]interface{}{
   352  		"key1": 1,
   353  		"key2": map[string]interface{}{
   354  			"subKey1": 10,
   355  			"subKey2": 20,
   356  		},
   357  		"key3": "subKey2",
   358  		"array": []interface{}{
   359  			111, 222, 333,
   360  		},
   361  		"slice": []interface{}{
   362  			map[string]interface{}{
   363  				"attr1": 111,
   364  				"attr2": 222,
   365  			},
   366  		},
   367  	})
   368  	expandedText := aMap.ExpandAsText(`1: $key1, 
   369  2: ${array[2]}  
   370  3: $key2.subKey1 
   371  4: $key2[$key3] ${slice[0].attr1}  
   372  5: ${(key1 + 1) * 3} `)
   373  	assert.Equal(t, `1: 1, 
   374  2: 333  
   375  3: 10 
   376  4: 20 111  
   377  5: 6 `, expandedText)
   378  
   379  }
   380  
   381  func Test_SubState(t *testing.T) {
   382  
   383  	state := NewMap()
   384  	state.Put("meta", map[string]int{
   385  		"TABLE": 1,
   386  	})
   387  
   388  	value, ok := state.GetValue("meta.TABLE")
   389  	if !assert.True(t, ok) {
   390  		return
   391  	}
   392  	state.SetValue("meta.TABLE", toolbox.AsInt(value)+1)
   393  	value, ok = state.GetValue("meta.TABLE")
   394  	if !assert.True(t, ok) {
   395  		return
   396  	}
   397  	assert.EqualValues(t, 2, value)
   398  
   399  	payload := []uint8{34,
   400  		72,
   401  		101,
   402  		108,
   403  		108,
   404  		111,
   405  		32,
   406  		87,
   407  		111,
   408  		114,
   409  		108,
   410  		100,
   411  		34}
   412  
   413  	aMap := Map(map[string]interface{}{
   414  		"Payload": &payload,
   415  		"AsString": func(source interface{}, state Map) (interface{}, error) {
   416  			return toolbox.AsString(source), nil
   417  		}})
   418  
   419  	expanded := aMap.Expand("$AsString($Payload)")
   420  	assert.EqualValues(t, `"Hello World"`, expanded)
   421  
   422  }