github.com/wangyougui/gf/v2@v2.6.5/container/gset/gset_z_unit_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 this file,
     5  // You can obtain one at https://github.com/wangyougui/gf.
     6  
     7  // go test *.go
     8  
     9  package gset_test
    10  
    11  import (
    12  	"strings"
    13  	"sync"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/wangyougui/gf/v2/container/garray"
    18  	"github.com/wangyougui/gf/v2/container/gset"
    19  	"github.com/wangyougui/gf/v2/frame/g"
    20  	"github.com/wangyougui/gf/v2/internal/json"
    21  	"github.com/wangyougui/gf/v2/test/gtest"
    22  	"github.com/wangyougui/gf/v2/util/gconv"
    23  )
    24  
    25  func TestStrSet_Var(t *testing.T) {
    26  	gtest.C(t, func(t *gtest.T) {
    27  		var s gset.StrSet
    28  		s.Add("1", "1", "2")
    29  		s.Add([]string{"3", "4"}...)
    30  		t.Assert(s.Size(), 4)
    31  		t.AssertIN("1", s.Slice())
    32  		t.AssertIN("2", s.Slice())
    33  		t.AssertIN("3", s.Slice())
    34  		t.AssertIN("4", s.Slice())
    35  		t.AssertNI("0", s.Slice())
    36  		t.Assert(s.Contains("4"), true)
    37  		t.Assert(s.Contains("5"), false)
    38  		s.Remove("1")
    39  		t.Assert(s.Size(), 3)
    40  		s.Clear()
    41  		t.Assert(s.Size(), 0)
    42  	})
    43  }
    44  
    45  func TestStrSet_Basic(t *testing.T) {
    46  	gtest.C(t, func(t *gtest.T) {
    47  		s := gset.NewStrSet()
    48  		s.Add("1", "1", "2")
    49  		s.Add([]string{"3", "4"}...)
    50  		t.Assert(s.Size(), 4)
    51  		t.AssertIN("1", s.Slice())
    52  		t.AssertIN("2", s.Slice())
    53  		t.AssertIN("3", s.Slice())
    54  		t.AssertIN("4", s.Slice())
    55  		t.AssertNI("0", s.Slice())
    56  		t.Assert(s.Contains("4"), true)
    57  		t.Assert(s.Contains("5"), false)
    58  		s.Remove("1")
    59  		t.Assert(s.Size(), 3)
    60  		s.Clear()
    61  		t.Assert(s.Size(), 0)
    62  	})
    63  }
    64  
    65  func TestStrSet_ContainsI(t *testing.T) {
    66  	gtest.C(t, func(t *gtest.T) {
    67  		s := gset.NewStrSet()
    68  		s.Add("a", "b", "C")
    69  		t.Assert(s.Contains("A"), false)
    70  		t.Assert(s.Contains("a"), true)
    71  		t.Assert(s.ContainsI("A"), true)
    72  		t.Assert(s.ContainsI("d"), false)
    73  	})
    74  }
    75  
    76  func TestStrSet_Iterator(t *testing.T) {
    77  	gtest.C(t, func(t *gtest.T) {
    78  		s := gset.NewStrSet()
    79  		s.Add("1", "2", "3")
    80  		t.Assert(s.Size(), 3)
    81  
    82  		a1 := garray.New(true)
    83  		a2 := garray.New(true)
    84  		s.Iterator(func(v string) bool {
    85  			a1.Append("1")
    86  			return false
    87  		})
    88  		s.Iterator(func(v string) bool {
    89  			a2.Append("1")
    90  			return true
    91  		})
    92  		t.Assert(a1.Len(), 1)
    93  		t.Assert(a2.Len(), 3)
    94  	})
    95  }
    96  
    97  func TestStrSet_LockFunc(t *testing.T) {
    98  	gtest.C(t, func(t *gtest.T) {
    99  		s := gset.NewStrSet()
   100  		s.Add("1", "2", "3")
   101  		t.Assert(s.Size(), 3)
   102  		s.LockFunc(func(m map[string]struct{}) {
   103  			delete(m, "1")
   104  		})
   105  		t.Assert(s.Size(), 2)
   106  		s.RLockFunc(func(m map[string]struct{}) {
   107  			t.Assert(m, map[string]struct{}{
   108  				"3": {},
   109  				"2": {},
   110  			})
   111  		})
   112  	})
   113  }
   114  
   115  func TestStrSet_Equal(t *testing.T) {
   116  	gtest.C(t, func(t *gtest.T) {
   117  		s1 := gset.NewStrSet()
   118  		s2 := gset.NewStrSet()
   119  		s3 := gset.NewStrSet()
   120  		s4 := gset.NewStrSet()
   121  		s1.Add("1", "2", "3")
   122  		s2.Add("1", "2", "3")
   123  		s3.Add("1", "2", "3", "4")
   124  		s4.Add("4", "5", "6")
   125  		t.Assert(s1.Equal(s2), true)
   126  		t.Assert(s1.Equal(s3), false)
   127  		t.Assert(s1.Equal(s4), false)
   128  		s5 := s1
   129  		t.Assert(s1.Equal(s5), true)
   130  	})
   131  }
   132  
   133  func TestStrSet_IsSubsetOf(t *testing.T) {
   134  	gtest.C(t, func(t *gtest.T) {
   135  		s1 := gset.NewStrSet()
   136  		s2 := gset.NewStrSet()
   137  		s3 := gset.NewStrSet()
   138  		s1.Add("1", "2")
   139  		s2.Add("1", "2", "3")
   140  		s3.Add("1", "2", "3", "4")
   141  		t.Assert(s1.IsSubsetOf(s2), true)
   142  		t.Assert(s2.IsSubsetOf(s3), true)
   143  		t.Assert(s1.IsSubsetOf(s3), true)
   144  		t.Assert(s2.IsSubsetOf(s1), false)
   145  		t.Assert(s3.IsSubsetOf(s2), false)
   146  
   147  		s4 := s1
   148  		t.Assert(s1.IsSubsetOf(s4), true)
   149  	})
   150  }
   151  
   152  func TestStrSet_Union(t *testing.T) {
   153  	gtest.C(t, func(t *gtest.T) {
   154  		s1 := gset.NewStrSet()
   155  		s2 := gset.NewStrSet()
   156  		s1.Add("1", "2")
   157  		s2.Add("3", "4")
   158  		s3 := s1.Union(s2)
   159  		t.Assert(s3.Contains("1"), true)
   160  		t.Assert(s3.Contains("2"), true)
   161  		t.Assert(s3.Contains("3"), true)
   162  		t.Assert(s3.Contains("4"), true)
   163  	})
   164  }
   165  
   166  func TestStrSet_Diff(t *testing.T) {
   167  	gtest.C(t, func(t *gtest.T) {
   168  		s1 := gset.NewStrSet()
   169  		s2 := gset.NewStrSet()
   170  		s1.Add("1", "2", "3")
   171  		s2.Add("3", "4", "5")
   172  		s3 := s1.Diff(s2)
   173  		t.Assert(s3.Contains("1"), true)
   174  		t.Assert(s3.Contains("2"), true)
   175  		t.Assert(s3.Contains("3"), false)
   176  		t.Assert(s3.Contains("4"), false)
   177  
   178  		s4 := s1
   179  		s5 := s1.Diff(s2, s4)
   180  		t.Assert(s5.Contains("1"), true)
   181  		t.Assert(s5.Contains("2"), true)
   182  		t.Assert(s5.Contains("3"), false)
   183  		t.Assert(s5.Contains("4"), false)
   184  	})
   185  }
   186  
   187  func TestStrSet_Intersect(t *testing.T) {
   188  	gtest.C(t, func(t *gtest.T) {
   189  		s1 := gset.NewStrSet()
   190  		s2 := gset.NewStrSet()
   191  		s1.Add("1", "2", "3")
   192  		s2.Add("3", "4", "5")
   193  		s3 := s1.Intersect(s2)
   194  		t.Assert(s3.Contains("1"), false)
   195  		t.Assert(s3.Contains("2"), false)
   196  		t.Assert(s3.Contains("3"), true)
   197  		t.Assert(s3.Contains("4"), false)
   198  	})
   199  }
   200  
   201  func TestStrSet_Complement(t *testing.T) {
   202  	gtest.C(t, func(t *gtest.T) {
   203  		s1 := gset.NewStrSet()
   204  		s2 := gset.NewStrSet()
   205  		s1.Add("1", "2", "3")
   206  		s2.Add("3", "4", "5")
   207  		s3 := s1.Complement(s2)
   208  		t.Assert(s3.Contains("1"), false)
   209  		t.Assert(s3.Contains("2"), false)
   210  		t.Assert(s3.Contains("4"), true)
   211  		t.Assert(s3.Contains("5"), true)
   212  	})
   213  }
   214  
   215  func TestNewIntSetFrom(t *testing.T) {
   216  	gtest.C(t, func(t *gtest.T) {
   217  		s1 := gset.NewIntSetFrom([]int{1, 2, 3, 4})
   218  		s2 := gset.NewIntSetFrom([]int{5, 6, 7, 8})
   219  		t.Assert(s1.Contains(3), true)
   220  		t.Assert(s1.Contains(5), false)
   221  		t.Assert(s2.Contains(3), false)
   222  		t.Assert(s2.Contains(5), true)
   223  	})
   224  }
   225  
   226  func TestStrSet_Merge(t *testing.T) {
   227  	gtest.C(t, func(t *gtest.T) {
   228  		s1 := gset.NewStrSet()
   229  		s2 := gset.NewStrSet()
   230  		s1.Add("1", "2", "3")
   231  		s2.Add("3", "4", "5")
   232  		s3 := s1.Merge(s2)
   233  		t.Assert(s3.Contains("1"), true)
   234  		t.Assert(s3.Contains("6"), false)
   235  		t.Assert(s3.Contains("4"), true)
   236  		t.Assert(s3.Contains("5"), true)
   237  	})
   238  }
   239  
   240  func TestNewStrSetFrom(t *testing.T) {
   241  	gtest.C(t, func(t *gtest.T) {
   242  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   243  		t.Assert(s1.Contains("b"), true)
   244  		t.Assert(s1.Contains("d"), false)
   245  	})
   246  }
   247  
   248  func TestStrSet_Join(t *testing.T) {
   249  	gtest.C(t, func(t *gtest.T) {
   250  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   251  		str1 := s1.Join(",")
   252  		t.Assert(strings.Contains(str1, "b"), true)
   253  		t.Assert(strings.Contains(str1, "d"), false)
   254  	})
   255  
   256  	gtest.C(t, func(t *gtest.T) {
   257  		s1 := gset.NewStrSet()
   258  		t.Assert(s1.Join(","), "")
   259  		s1.Add("a", `"b"`, `\c`)
   260  		str1 := s1.Join(",")
   261  		t.Assert(strings.Contains(str1, `"b"`), true)
   262  		t.Assert(strings.Contains(str1, `\c`), true)
   263  		t.Assert(strings.Contains(str1, `a`), true)
   264  	})
   265  }
   266  
   267  func TestStrSet_String(t *testing.T) {
   268  	gtest.C(t, func(t *gtest.T) {
   269  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   270  		str1 := s1.String()
   271  		t.Assert(strings.Contains(str1, "b"), true)
   272  		t.Assert(strings.Contains(str1, "d"), false)
   273  		s1 = nil
   274  		t.Assert(s1.String(), "")
   275  	})
   276  
   277  	gtest.C(t, func(t *gtest.T) {
   278  		s1 := gset.New(true)
   279  		s1.Add("a", "a2", "b", "c")
   280  		str1 := s1.String()
   281  		t.Assert(strings.Contains(str1, "["), true)
   282  		t.Assert(strings.Contains(str1, "]"), true)
   283  		t.Assert(strings.Contains(str1, "a2"), true)
   284  	})
   285  }
   286  
   287  func TestStrSet_Sum(t *testing.T) {
   288  	gtest.C(t, func(t *gtest.T) {
   289  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   290  		s2 := gset.NewIntSetFrom([]int{2, 3, 4}, true)
   291  		t.Assert(s1.Sum(), 0)
   292  		t.Assert(s2.Sum(), 9)
   293  	})
   294  }
   295  
   296  func TestStrSet_Size(t *testing.T) {
   297  	gtest.C(t, func(t *gtest.T) {
   298  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   299  		t.Assert(s1.Size(), 3)
   300  
   301  	})
   302  }
   303  
   304  func TestStrSet_Remove(t *testing.T) {
   305  	gtest.C(t, func(t *gtest.T) {
   306  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   307  		s1.Remove("b")
   308  		t.Assert(s1.Contains("b"), false)
   309  		t.Assert(s1.Contains("c"), true)
   310  	})
   311  }
   312  
   313  func TestStrSet_Pop(t *testing.T) {
   314  	gtest.C(t, func(t *gtest.T) {
   315  		a := []string{"a", "b", "c", "d"}
   316  		s := gset.NewStrSetFrom(a, true)
   317  		t.Assert(s.Size(), 4)
   318  		t.AssertIN(s.Pop(), a)
   319  		t.Assert(s.Size(), 3)
   320  		t.AssertIN(s.Pop(), a)
   321  		t.Assert(s.Size(), 2)
   322  
   323  		s1 := gset.StrSet{}
   324  		t.Assert(s1.Pop(), "")
   325  	})
   326  }
   327  
   328  func TestStrSet_Pops(t *testing.T) {
   329  	gtest.C(t, func(t *gtest.T) {
   330  		a := []string{"a", "b", "c", "d"}
   331  		s := gset.NewStrSetFrom(a, true)
   332  		array := s.Pops(2)
   333  		t.Assert(len(array), 2)
   334  		t.Assert(s.Size(), 2)
   335  		t.AssertIN(array, a)
   336  		t.Assert(s.Pops(0), nil)
   337  		t.AssertIN(s.Pops(2), a)
   338  		t.Assert(s.Size(), 0)
   339  	})
   340  
   341  	gtest.C(t, func(t *gtest.T) {
   342  		s := gset.NewStrSet(true)
   343  		a := []string{"1", "2", "3", "4"}
   344  		s.Add(a...)
   345  		t.Assert(s.Size(), 4)
   346  		t.Assert(s.Pops(-2), nil)
   347  		t.AssertIN(s.Pops(-1), a)
   348  	})
   349  }
   350  
   351  func TestStrSet_AddIfNotExist(t *testing.T) {
   352  	gtest.C(t, func(t *gtest.T) {
   353  		s := gset.NewStrSet(true)
   354  		s.Add("1")
   355  		t.Assert(s.Contains("1"), true)
   356  		t.Assert(s.AddIfNotExist("1"), false)
   357  		t.Assert(s.AddIfNotExist("2"), true)
   358  		t.Assert(s.Contains("2"), true)
   359  		t.Assert(s.AddIfNotExist("2"), false)
   360  		t.Assert(s.Contains("2"), true)
   361  	})
   362  	gtest.C(t, func(t *gtest.T) {
   363  		s := gset.StrSet{}
   364  		t.Assert(s.AddIfNotExist("1"), true)
   365  	})
   366  }
   367  
   368  func TestStrSet_AddIfNotExistFunc(t *testing.T) {
   369  	gtest.C(t, func(t *gtest.T) {
   370  		s := gset.NewStrSet(true)
   371  		s.Add("1")
   372  		t.Assert(s.Contains("1"), true)
   373  		t.Assert(s.Contains("2"), false)
   374  		t.Assert(s.AddIfNotExistFunc("2", func() bool { return false }), false)
   375  		t.Assert(s.Contains("2"), false)
   376  		t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), true)
   377  		t.Assert(s.Contains("2"), true)
   378  		t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), false)
   379  		t.Assert(s.Contains("2"), true)
   380  	})
   381  	gtest.C(t, func(t *gtest.T) {
   382  		s := gset.NewStrSet(true)
   383  		wg := sync.WaitGroup{}
   384  		wg.Add(1)
   385  		go func() {
   386  			defer wg.Done()
   387  			r := s.AddIfNotExistFunc("1", func() bool {
   388  				time.Sleep(100 * time.Millisecond)
   389  				return true
   390  			})
   391  			t.Assert(r, false)
   392  		}()
   393  		s.Add("1")
   394  		wg.Wait()
   395  	})
   396  	gtest.C(t, func(t *gtest.T) {
   397  		s := gset.StrSet{}
   398  		t.Assert(s.AddIfNotExistFunc("1", func() bool { return true }), true)
   399  	})
   400  }
   401  
   402  func TestStrSet_AddIfNotExistFuncLock(t *testing.T) {
   403  	gtest.C(t, func(t *gtest.T) {
   404  		s := gset.NewStrSet(true)
   405  		wg := sync.WaitGroup{}
   406  		wg.Add(2)
   407  		go func() {
   408  			defer wg.Done()
   409  			r := s.AddIfNotExistFuncLock("1", func() bool {
   410  				time.Sleep(500 * time.Millisecond)
   411  				return true
   412  			})
   413  			t.Assert(r, true)
   414  		}()
   415  		time.Sleep(100 * time.Millisecond)
   416  		go func() {
   417  			defer wg.Done()
   418  			r := s.AddIfNotExistFuncLock("1", func() bool {
   419  				return true
   420  			})
   421  			t.Assert(r, false)
   422  		}()
   423  		wg.Wait()
   424  	})
   425  	gtest.C(t, func(t *gtest.T) {
   426  		s := gset.StrSet{}
   427  		t.Assert(s.AddIfNotExistFuncLock("1", func() bool { return true }), true)
   428  	})
   429  }
   430  
   431  func TestStrSet_Json(t *testing.T) {
   432  	gtest.C(t, func(t *gtest.T) {
   433  		s1 := []string{"a", "b", "d", "c"}
   434  		a1 := gset.NewStrSetFrom(s1)
   435  		b1, err1 := json.Marshal(a1)
   436  		b2, err2 := json.Marshal(s1)
   437  		t.Assert(len(b1), len(b2))
   438  		t.Assert(err1, err2)
   439  
   440  		a2 := gset.NewStrSet()
   441  		err2 = json.UnmarshalUseNumber(b2, &a2)
   442  		t.Assert(err2, nil)
   443  		t.Assert(a2.Contains("a"), true)
   444  		t.Assert(a2.Contains("b"), true)
   445  		t.Assert(a2.Contains("c"), true)
   446  		t.Assert(a2.Contains("d"), true)
   447  		t.Assert(a2.Contains("e"), false)
   448  
   449  		var a3 gset.StrSet
   450  		err := json.UnmarshalUseNumber(b2, &a3)
   451  		t.AssertNil(err)
   452  		t.Assert(a3.Contains("a"), true)
   453  		t.Assert(a3.Contains("b"), true)
   454  		t.Assert(a3.Contains("c"), true)
   455  		t.Assert(a3.Contains("d"), true)
   456  		t.Assert(a3.Contains("e"), false)
   457  	})
   458  }
   459  
   460  func TestStrSet_Walk(t *testing.T) {
   461  	gtest.C(t, func(t *gtest.T) {
   462  		var (
   463  			set    gset.StrSet
   464  			names  = g.SliceStr{"user", "user_detail"}
   465  			prefix = "gf_"
   466  		)
   467  		set.Add(names...)
   468  		// Add prefix for given table names.
   469  		set.Walk(func(item string) string {
   470  			return prefix + item
   471  		})
   472  		t.Assert(set.Size(), 2)
   473  		t.Assert(set.Contains("gf_user"), true)
   474  		t.Assert(set.Contains("gf_user_detail"), true)
   475  	})
   476  }
   477  
   478  func TestStrSet_UnmarshalValue(t *testing.T) {
   479  	type V struct {
   480  		Name string
   481  		Set  *gset.StrSet
   482  	}
   483  	// JSON
   484  	gtest.C(t, func(t *gtest.T) {
   485  		var v *V
   486  		err := gconv.Struct(g.Map{
   487  			"name": "john",
   488  			"set":  []byte(`["1","2","3"]`),
   489  		}, &v)
   490  		t.AssertNil(err)
   491  		t.Assert(v.Name, "john")
   492  		t.Assert(v.Set.Size(), 3)
   493  		t.Assert(v.Set.Contains("1"), true)
   494  		t.Assert(v.Set.Contains("2"), true)
   495  		t.Assert(v.Set.Contains("3"), true)
   496  		t.Assert(v.Set.Contains("4"), false)
   497  	})
   498  	// Map
   499  	gtest.C(t, func(t *gtest.T) {
   500  		var v *V
   501  		err := gconv.Struct(g.Map{
   502  			"name": "john",
   503  			"set":  g.SliceStr{"1", "2", "3"},
   504  		}, &v)
   505  		t.AssertNil(err)
   506  		t.Assert(v.Name, "john")
   507  		t.Assert(v.Set.Size(), 3)
   508  		t.Assert(v.Set.Contains("1"), true)
   509  		t.Assert(v.Set.Contains("2"), true)
   510  		t.Assert(v.Set.Contains("3"), true)
   511  		t.Assert(v.Set.Contains("4"), false)
   512  	})
   513  }
   514  
   515  func TestStrSet_DeepCopy(t *testing.T) {
   516  	gtest.C(t, func(t *gtest.T) {
   517  		set := gset.NewStrSet()
   518  		set.Add("1", "2", "3")
   519  
   520  		copySet := set.DeepCopy().(*gset.StrSet)
   521  		copySet.Add("4")
   522  		t.AssertNE(set.Size(), copySet.Size())
   523  		t.AssertNE(set.String(), copySet.String())
   524  
   525  		set = nil
   526  		t.AssertNil(set.DeepCopy())
   527  	})
   528  }