github.com/gogf/gf/v2@v2.7.4/container/gmap/gmap_z_unit_hash_str_str_test.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with gm file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gmap_test
     8  
     9  import (
    10  	"strconv"
    11  	"testing"
    12  
    13  	"github.com/gogf/gf/v2/container/garray"
    14  	"github.com/gogf/gf/v2/container/gmap"
    15  	"github.com/gogf/gf/v2/frame/g"
    16  	"github.com/gogf/gf/v2/internal/json"
    17  	"github.com/gogf/gf/v2/test/gtest"
    18  	"github.com/gogf/gf/v2/util/gconv"
    19  )
    20  
    21  func Test_StrStrMap_Var(t *testing.T) {
    22  	gtest.C(t, func(t *gtest.T) {
    23  		var m gmap.StrStrMap
    24  		m.Set("a", "a")
    25  
    26  		t.Assert(m.Get("a"), "a")
    27  		t.Assert(m.Size(), 1)
    28  		t.Assert(m.IsEmpty(), false)
    29  
    30  		t.Assert(m.GetOrSet("b", "b"), "b")
    31  		t.Assert(m.SetIfNotExist("b", "b"), false)
    32  
    33  		t.Assert(m.SetIfNotExist("c", "c"), true)
    34  
    35  		t.Assert(m.Remove("b"), "b")
    36  		t.Assert(m.Contains("b"), false)
    37  
    38  		t.AssertIN("c", m.Keys())
    39  		t.AssertIN("a", m.Keys())
    40  		t.AssertIN("a", m.Values())
    41  		t.AssertIN("c", m.Values())
    42  
    43  		m.Flip()
    44  
    45  		t.Assert(m.Map(), map[string]string{"a": "a", "c": "c"})
    46  
    47  		m.Clear()
    48  		t.Assert(m.Size(), 0)
    49  		t.Assert(m.IsEmpty(), true)
    50  	})
    51  }
    52  
    53  func Test_StrStrMap_Basic(t *testing.T) {
    54  	gtest.C(t, func(t *gtest.T) {
    55  		m := gmap.NewStrStrMap()
    56  		m.Set("a", "a")
    57  
    58  		t.Assert(m.Get("a"), "a")
    59  		t.Assert(m.Size(), 1)
    60  		t.Assert(m.IsEmpty(), false)
    61  
    62  		t.Assert(m.GetOrSet("b", "b"), "b")
    63  		t.Assert(m.SetIfNotExist("b", "b"), false)
    64  
    65  		t.Assert(m.SetIfNotExist("c", "c"), true)
    66  
    67  		t.Assert(m.Remove("b"), "b")
    68  		t.Assert(m.Contains("b"), false)
    69  
    70  		t.AssertIN("c", m.Keys())
    71  		t.AssertIN("a", m.Keys())
    72  		t.AssertIN("a", m.Values())
    73  		t.AssertIN("c", m.Values())
    74  
    75  		m.Flip()
    76  
    77  		t.Assert(m.Map(), map[string]string{"a": "a", "c": "c"})
    78  
    79  		m.Clear()
    80  		t.Assert(m.Size(), 0)
    81  		t.Assert(m.IsEmpty(), true)
    82  
    83  		m2 := gmap.NewStrStrMapFrom(map[string]string{"a": "a", "b": "b"})
    84  		t.Assert(m2.Map(), map[string]string{"a": "a", "b": "b"})
    85  	})
    86  }
    87  
    88  func Test_StrStrMap_Set_Fun(t *testing.T) {
    89  	gtest.C(t, func(t *gtest.T) {
    90  		m := gmap.NewStrStrMap()
    91  
    92  		m.GetOrSetFunc("a", getStr)
    93  		m.GetOrSetFuncLock("b", getStr)
    94  		t.Assert(m.Get("a"), "z")
    95  		t.Assert(m.Get("b"), "z")
    96  		t.Assert(m.SetIfNotExistFunc("a", getStr), false)
    97  		t.Assert(m.SetIfNotExistFunc("c", getStr), true)
    98  
    99  		t.Assert(m.SetIfNotExistFuncLock("b", getStr), false)
   100  		t.Assert(m.SetIfNotExistFuncLock("d", getStr), true)
   101  	})
   102  
   103  	gtest.C(t, func(t *gtest.T) {
   104  		m := gmap.NewStrStrMapFrom(nil)
   105  
   106  		t.Assert(m.GetOrSetFuncLock("b", getStr), "z")
   107  	})
   108  }
   109  
   110  func Test_StrStrMap_Batch(t *testing.T) {
   111  	gtest.C(t, func(t *gtest.T) {
   112  		m := gmap.NewStrStrMap()
   113  
   114  		m.Sets(map[string]string{"a": "a", "b": "b", "c": "c"})
   115  		t.Assert(m.Map(), map[string]string{"a": "a", "b": "b", "c": "c"})
   116  		m.Removes([]string{"a", "b"})
   117  		t.Assert(m.Map(), map[string]string{"c": "c"})
   118  	})
   119  }
   120  
   121  func Test_StrStrMap_Iterator_Deadlock(t *testing.T) {
   122  	gtest.C(t, func(t *gtest.T) {
   123  		m := gmap.NewStrStrMapFrom(map[string]string{"1": "1", "2": "2", "3": "3", "4": "4"}, true)
   124  		m.Iterator(func(k string, _ string) bool {
   125  			kInt, _ := strconv.Atoi(k)
   126  			if kInt%2 == 0 {
   127  				m.Remove(k)
   128  			}
   129  			return true
   130  		})
   131  		t.Assert(m.Size(), 2)
   132  	})
   133  }
   134  
   135  func Test_StrStrMap_Iterator(t *testing.T) {
   136  	gtest.C(t, func(t *gtest.T) {
   137  		expect := map[string]string{"a": "a", "b": "b"}
   138  		m := gmap.NewStrStrMapFrom(expect)
   139  		m.Iterator(func(k string, v string) bool {
   140  			t.Assert(expect[k], v)
   141  			return true
   142  		})
   143  		// 断言返回值对遍历控制
   144  		i := 0
   145  		j := 0
   146  		m.Iterator(func(k string, v string) bool {
   147  			i++
   148  			return true
   149  		})
   150  		m.Iterator(func(k string, v string) bool {
   151  			j++
   152  			return false
   153  		})
   154  		t.Assert(i, 2)
   155  		t.Assert(j, 1)
   156  	})
   157  }
   158  
   159  func Test_StrStrMap_Lock(t *testing.T) {
   160  	gtest.C(t, func(t *gtest.T) {
   161  		expect := map[string]string{"a": "a", "b": "b"}
   162  
   163  		m := gmap.NewStrStrMapFrom(expect)
   164  		m.LockFunc(func(m map[string]string) {
   165  			t.Assert(m, expect)
   166  		})
   167  		m.RLockFunc(func(m map[string]string) {
   168  			t.Assert(m, expect)
   169  		})
   170  	})
   171  }
   172  
   173  func Test_StrStrMap_Clone(t *testing.T) {
   174  	gtest.C(t, func(t *gtest.T) {
   175  		// clone 方法是深克隆
   176  		m := gmap.NewStrStrMapFrom(map[string]string{"a": "a", "b": "b", "c": "c"})
   177  
   178  		m_clone := m.Clone()
   179  		m.Remove("a")
   180  		// 修改原 map,clone 后的 map 不影响
   181  		t.AssertIN("a", m_clone.Keys())
   182  
   183  		m_clone.Remove("b")
   184  		// 修改clone map,原 map 不影响
   185  		t.AssertIN("b", m.Keys())
   186  	})
   187  }
   188  
   189  func Test_StrStrMap_Merge(t *testing.T) {
   190  	gtest.C(t, func(t *gtest.T) {
   191  		m1 := gmap.NewStrStrMap()
   192  		m2 := gmap.NewStrStrMap()
   193  		m1.Set("a", "a")
   194  		m2.Set("b", "b")
   195  		m1.Merge(m2)
   196  		t.Assert(m1.Map(), map[string]string{"a": "a", "b": "b"})
   197  		m3 := gmap.NewStrStrMapFrom(nil)
   198  		m3.Merge(m2)
   199  		t.Assert(m3.Map(), m2.Map())
   200  	})
   201  }
   202  
   203  func Test_StrStrMap_Map(t *testing.T) {
   204  	gtest.C(t, func(t *gtest.T) {
   205  		m := gmap.NewStrStrMap()
   206  		m.Set("1", "1")
   207  		m.Set("2", "2")
   208  		t.Assert(m.Get("1"), "1")
   209  		t.Assert(m.Get("2"), "2")
   210  		data := m.Map()
   211  		t.Assert(data["1"], "1")
   212  		t.Assert(data["2"], "2")
   213  		data["3"] = "3"
   214  		t.Assert(m.Get("3"), "3")
   215  		m.Set("4", "4")
   216  		t.Assert(data["4"], "4")
   217  	})
   218  }
   219  
   220  func Test_StrStrMap_MapCopy(t *testing.T) {
   221  	gtest.C(t, func(t *gtest.T) {
   222  		m := gmap.NewStrStrMap()
   223  		m.Set("1", "1")
   224  		m.Set("2", "2")
   225  		t.Assert(m.Get("1"), "1")
   226  		t.Assert(m.Get("2"), "2")
   227  		data := m.MapCopy()
   228  		t.Assert(data["1"], "1")
   229  		t.Assert(data["2"], "2")
   230  		data["3"] = "3"
   231  		t.Assert(m.Get("3"), "")
   232  		m.Set("4", "4")
   233  		t.Assert(data["4"], "")
   234  	})
   235  }
   236  
   237  func Test_StrStrMap_FilterEmpty(t *testing.T) {
   238  	gtest.C(t, func(t *gtest.T) {
   239  		m := gmap.NewStrStrMap()
   240  		m.Set("1", "")
   241  		m.Set("2", "2")
   242  		t.Assert(m.Size(), 2)
   243  		t.Assert(m.Get("1"), "")
   244  		t.Assert(m.Get("2"), "2")
   245  		m.FilterEmpty()
   246  		t.Assert(m.Size(), 1)
   247  		t.Assert(m.Get("2"), "2")
   248  	})
   249  }
   250  
   251  func Test_StrStrMap_Json(t *testing.T) {
   252  	// Marshal
   253  	gtest.C(t, func(t *gtest.T) {
   254  		data := g.MapStrStr{
   255  			"k1": "v1",
   256  			"k2": "v2",
   257  		}
   258  		m1 := gmap.NewStrStrMapFrom(data)
   259  		b1, err1 := json.Marshal(m1)
   260  		b2, err2 := json.Marshal(data)
   261  		t.Assert(err1, err2)
   262  		t.Assert(b1, b2)
   263  	})
   264  	// Unmarshal
   265  	gtest.C(t, func(t *gtest.T) {
   266  		data := g.MapStrStr{
   267  			"k1": "v1",
   268  			"k2": "v2",
   269  		}
   270  		b, err := json.Marshal(data)
   271  		t.AssertNil(err)
   272  
   273  		m := gmap.NewStrStrMap()
   274  		err = json.UnmarshalUseNumber(b, m)
   275  		t.AssertNil(err)
   276  		t.Assert(m.Get("k1"), data["k1"])
   277  		t.Assert(m.Get("k2"), data["k2"])
   278  	})
   279  	gtest.C(t, func(t *gtest.T) {
   280  		data := g.MapStrStr{
   281  			"k1": "v1",
   282  			"k2": "v2",
   283  		}
   284  		b, err := json.Marshal(data)
   285  		t.AssertNil(err)
   286  
   287  		var m gmap.StrStrMap
   288  		err = json.UnmarshalUseNumber(b, &m)
   289  		t.AssertNil(err)
   290  		t.Assert(m.Get("k1"), data["k1"])
   291  		t.Assert(m.Get("k2"), data["k2"])
   292  	})
   293  }
   294  
   295  func Test_StrStrMap_Pop(t *testing.T) {
   296  	gtest.C(t, func(t *gtest.T) {
   297  		m := gmap.NewStrStrMapFrom(g.MapStrStr{
   298  			"k1": "v1",
   299  			"k2": "v2",
   300  		})
   301  		t.Assert(m.Size(), 2)
   302  
   303  		k1, v1 := m.Pop()
   304  		t.AssertIN(k1, g.Slice{"k1", "k2"})
   305  		t.AssertIN(v1, g.Slice{"v1", "v2"})
   306  		t.Assert(m.Size(), 1)
   307  		k2, v2 := m.Pop()
   308  		t.AssertIN(k2, g.Slice{"k1", "k2"})
   309  		t.AssertIN(v2, g.Slice{"v1", "v2"})
   310  		t.Assert(m.Size(), 0)
   311  
   312  		t.AssertNE(k1, k2)
   313  		t.AssertNE(v1, v2)
   314  
   315  		k3, v3 := m.Pop()
   316  		t.Assert(k3, "")
   317  		t.Assert(v3, "")
   318  	})
   319  }
   320  
   321  func Test_StrStrMap_Pops(t *testing.T) {
   322  	gtest.C(t, func(t *gtest.T) {
   323  		m := gmap.NewStrStrMapFrom(g.MapStrStr{
   324  			"k1": "v1",
   325  			"k2": "v2",
   326  			"k3": "v3",
   327  		})
   328  		t.Assert(m.Size(), 3)
   329  
   330  		kArray := garray.New()
   331  		vArray := garray.New()
   332  		for k, v := range m.Pops(1) {
   333  			t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
   334  			t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
   335  			kArray.Append(k)
   336  			vArray.Append(v)
   337  		}
   338  		t.Assert(m.Size(), 2)
   339  		for k, v := range m.Pops(2) {
   340  			t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
   341  			t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
   342  			kArray.Append(k)
   343  			vArray.Append(v)
   344  		}
   345  		t.Assert(m.Size(), 0)
   346  
   347  		t.Assert(kArray.Unique().Len(), 3)
   348  		t.Assert(vArray.Unique().Len(), 3)
   349  
   350  		v := m.Pops(1)
   351  		t.AssertNil(v)
   352  		v = m.Pops(-1)
   353  		t.AssertNil(v)
   354  	})
   355  }
   356  
   357  func TestStrStrMap_UnmarshalValue(t *testing.T) {
   358  	type V struct {
   359  		Name string
   360  		Map  *gmap.StrStrMap
   361  	}
   362  	// JSON
   363  	gtest.C(t, func(t *gtest.T) {
   364  		var v *V
   365  		err := gconv.Struct(map[string]interface{}{
   366  			"name": "john",
   367  			"map":  []byte(`{"k1":"v1","k2":"v2"}`),
   368  		}, &v)
   369  		t.AssertNil(err)
   370  		t.Assert(v.Name, "john")
   371  		t.Assert(v.Map.Size(), 2)
   372  		t.Assert(v.Map.Get("k1"), "v1")
   373  		t.Assert(v.Map.Get("k2"), "v2")
   374  	})
   375  	// Map
   376  	gtest.C(t, func(t *gtest.T) {
   377  		var v *V
   378  		err := gconv.Struct(map[string]interface{}{
   379  			"name": "john",
   380  			"map": g.Map{
   381  				"k1": "v1",
   382  				"k2": "v2",
   383  			},
   384  		}, &v)
   385  		t.AssertNil(err)
   386  		t.Assert(v.Name, "john")
   387  		t.Assert(v.Map.Size(), 2)
   388  		t.Assert(v.Map.Get("k1"), "v1")
   389  		t.Assert(v.Map.Get("k2"), "v2")
   390  	})
   391  }
   392  
   393  func Test_StrStrMap_DeepCopy(t *testing.T) {
   394  	gtest.C(t, func(t *gtest.T) {
   395  		m := gmap.NewStrStrMapFrom(g.MapStrStr{
   396  			"key1": "val1",
   397  			"key2": "val2",
   398  		})
   399  		t.Assert(m.Size(), 2)
   400  
   401  		n := m.DeepCopy().(*gmap.StrStrMap)
   402  		n.Set("key1", "v1")
   403  		t.AssertNE(m.Get("key1"), n.Get("key1"))
   404  	})
   405  }
   406  
   407  func Test_StrStrMap_IsSubOf(t *testing.T) {
   408  	gtest.C(t, func(t *gtest.T) {
   409  		m1 := gmap.NewStrStrMapFrom(g.MapStrStr{
   410  			"k1": "v1",
   411  			"k2": "v2",
   412  		})
   413  		m2 := gmap.NewStrStrMapFrom(g.MapStrStr{
   414  			"k2": "v2",
   415  		})
   416  		t.Assert(m1.IsSubOf(m2), false)
   417  		t.Assert(m2.IsSubOf(m1), true)
   418  		t.Assert(m2.IsSubOf(m2), true)
   419  	})
   420  }
   421  
   422  func Test_StrStrMap_Diff(t *testing.T) {
   423  	gtest.C(t, func(t *gtest.T) {
   424  		m1 := gmap.NewStrStrMapFrom(g.MapStrStr{
   425  			"0": "0",
   426  			"1": "1",
   427  			"2": "2",
   428  			"3": "3",
   429  		})
   430  		m2 := gmap.NewStrStrMapFrom(g.MapStrStr{
   431  			"0": "0",
   432  			"2": "2",
   433  			"3": "31",
   434  			"4": "4",
   435  		})
   436  		addedKeys, removedKeys, updatedKeys := m1.Diff(m2)
   437  		t.Assert(addedKeys, []string{"4"})
   438  		t.Assert(removedKeys, []string{"1"})
   439  		t.Assert(updatedKeys, []string{"3"})
   440  	})
   441  }