...

Source file src/k8s.io/utils/set/set_test.go

Documentation: k8s.io/utils/set

     1  /*
     2  Copyright 2023 The Kubernetes 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 set
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  )
    23  
    24  func TestStringSetHasAll(t *testing.T) {
    25  	s := New[string]()
    26  	s2 := New[string]()
    27  	if len(s) != 0 {
    28  		t.Errorf("Expected len=0: %d", len(s))
    29  	}
    30  	s.Insert("a", "b")
    31  	if len(s) != 2 {
    32  		t.Errorf("Expected len=2: %d", len(s))
    33  	}
    34  	s.Insert("c")
    35  	if s.Has("d") {
    36  		t.Errorf("Unexpected contents: %#v", s)
    37  	}
    38  	if !s.Has("a") {
    39  		t.Errorf("Missing contents: %#v", s)
    40  	}
    41  	s.Delete("a")
    42  	if s.Has("a") {
    43  		t.Errorf("Unexpected contents: %#v", s)
    44  	}
    45  	s.Insert("a")
    46  	if s.HasAll("a", "b", "d") {
    47  		t.Errorf("Unexpected contents: %#v", s)
    48  	}
    49  	if !s.HasAll("a", "b") {
    50  		t.Errorf("Missing contents: %#v", s)
    51  	}
    52  	s2.Insert("a", "b", "d")
    53  	if s.IsSuperset(s2) {
    54  		t.Errorf("Unexpected contents: %#v", s)
    55  	}
    56  	s2.Delete("d")
    57  	if !s.IsSuperset(s2) {
    58  		t.Errorf("Missing contents: %#v", s)
    59  	}
    60  }
    61  
    62  func TestTypeInference(t *testing.T) {
    63  	s := New("a", "b", "c")
    64  	if len(s) != 3 {
    65  		t.Errorf("Expected len=3: %d", len(s))
    66  	}
    67  }
    68  
    69  func TestStringSetDeleteMultiples(t *testing.T) {
    70  	s := New[string]()
    71  	s.Insert("a", "b", "c")
    72  	if len(s) != 3 {
    73  		t.Errorf("Expected len=3: %d", len(s))
    74  	}
    75  
    76  	s.Delete("a", "c")
    77  	if len(s) != 1 {
    78  		t.Errorf("Expected len=1: %d", len(s))
    79  	}
    80  	if s.Has("a") {
    81  		t.Errorf("Unexpected contents: %#v", s)
    82  	}
    83  	if s.Has("c") {
    84  		t.Errorf("Unexpected contents: %#v", s)
    85  	}
    86  	if !s.Has("b") {
    87  		t.Errorf("Missing contents: %#v", s)
    88  	}
    89  }
    90  
    91  func TestNewStringSetWithMultipleStrings(t *testing.T) {
    92  	s := New[string]("a", "b", "c")
    93  	if len(s) != 3 {
    94  		t.Errorf("Expected len=3: %d", len(s))
    95  	}
    96  	if !s.Has("a") || !s.Has("b") || !s.Has("c") {
    97  		t.Errorf("Unexpected contents: %#v", s)
    98  	}
    99  }
   100  
   101  func TestStringSetSortedList(t *testing.T) {
   102  	s := New[string]("z", "y", "x", "a")
   103  	if !reflect.DeepEqual(s.SortedList(), []string{"a", "x", "y", "z"}) {
   104  		t.Errorf("SortedList gave unexpected result: %#v", s.SortedList())
   105  	}
   106  }
   107  
   108  func TestStringSetUnsortedList(t *testing.T) {
   109  	s := New[string]("z", "y", "x", "a")
   110  	ul := s.UnsortedList()
   111  	if len(ul) != 4 || !s.Has("z") || !s.Has("y") || !s.Has("x") || !s.Has("a") {
   112  		t.Errorf("UnsortedList gave unexpected result: %#v", s.UnsortedList())
   113  	}
   114  }
   115  
   116  func TestStringSetDifference(t *testing.T) {
   117  	a := New[string]("1", "2", "3")
   118  	b := New[string]("1", "2", "4", "5")
   119  	c := a.Difference(b)
   120  	d := b.Difference(a)
   121  	if len(c) != 1 {
   122  		t.Errorf("Expected len=1: %d", len(c))
   123  	}
   124  	if !c.Has("3") {
   125  		t.Errorf("Unexpected contents: %#v", c.SortedList())
   126  	}
   127  	if len(d) != 2 {
   128  		t.Errorf("Expected len=2: %d", len(d))
   129  	}
   130  	if !d.Has("4") || !d.Has("5") {
   131  		t.Errorf("Unexpected contents: %#v", d.SortedList())
   132  	}
   133  }
   134  
   135  func TestStringSetHasAny(t *testing.T) {
   136  	a := New[string]("1", "2", "3")
   137  
   138  	if !a.HasAny("1", "4") {
   139  		t.Errorf("expected true, got false")
   140  	}
   141  
   142  	if a.HasAny("0", "4") {
   143  		t.Errorf("expected false, got true")
   144  	}
   145  }
   146  
   147  func TestStringSetEquals(t *testing.T) {
   148  	// Simple case (order doesn't matter)
   149  	a := New[string]("1", "2")
   150  	b := New[string]("2", "1")
   151  	if !a.Equal(b) {
   152  		t.Errorf("Expected to be equal: %v vs %v", a, b)
   153  	}
   154  	a = New[string]("1", "2", "3")
   155  	b = New[string]("2", "1")
   156  	if a.Equal(b) {
   157  		t.Errorf("Expected to be not-equal: %v vs %v", a, b)
   158  	}
   159  	// It is a set; duplicates are ignored
   160  	a = New[string]("1", "2")
   161  	b = New[string]("2", "2", "1")
   162  	if !a.Equal(b) {
   163  		t.Errorf("Expected to be equal: %v vs %v", a, b)
   164  	}
   165  	// Edge cases around empty sets / empty strings
   166  	a = New[string]()
   167  	b = New[string]()
   168  	if !a.Equal(b) {
   169  		t.Errorf("Expected to be equal: %v vs %v", a, b)
   170  	}
   171  
   172  	b = New[string]("1", "2", "3")
   173  	if a.Equal(b) {
   174  		t.Errorf("Expected to be not-equal: %v vs %v", a, b)
   175  	}
   176  	if b.Equal(a) {
   177  		t.Errorf("Expected to be not-equal: %v vs %v", b, a)
   178  	}
   179  
   180  	b = New[string]("1", "2", "")
   181  	if a.Equal(b) {
   182  		t.Errorf("Expected to be not-equal: %v vs %v", a, b)
   183  	}
   184  	if b.Equal(a) {
   185  		t.Errorf("Expected to be not-equal: %v vs %v", b, a)
   186  	}
   187  
   188  	// Check for equality after mutation
   189  	a = New[string]()
   190  	a.Insert("1")
   191  	if a.Equal(b) {
   192  		t.Errorf("Expected to be not-equal: %v vs %v", a, b)
   193  	}
   194  
   195  	a.Insert("2")
   196  	if a.Equal(b) {
   197  		t.Errorf("Expected to be not-equal: %v vs %v", a, b)
   198  	}
   199  
   200  	a.Insert("")
   201  	if !a.Equal(b) {
   202  		t.Errorf("Expected to be equal: %v vs %v", a, b)
   203  	}
   204  
   205  	a.Delete("")
   206  	if a.Equal(b) {
   207  		t.Errorf("Expected to be not-equal: %v vs %v", a, b)
   208  	}
   209  }
   210  
   211  func TestStringUnion(t *testing.T) {
   212  	tests := []struct {
   213  		s1       Set[string]
   214  		s2       Set[string]
   215  		expected Set[string]
   216  	}{
   217  		{
   218  			New[string]("1", "2", "3", "4"),
   219  			New[string]("3", "4", "5", "6"),
   220  			New[string]("1", "2", "3", "4", "5", "6"),
   221  		},
   222  		{
   223  			New[string]("1", "2", "3", "4"),
   224  			New[string](),
   225  			New[string]("1", "2", "3", "4"),
   226  		},
   227  		{
   228  			New[string](),
   229  			New[string]("1", "2", "3", "4"),
   230  			New[string]("1", "2", "3", "4"),
   231  		},
   232  		{
   233  			New[string](),
   234  			New[string](),
   235  			New[string](),
   236  		},
   237  	}
   238  
   239  	for _, test := range tests {
   240  		union := test.s1.Union(test.s2)
   241  		if union.Len() != test.expected.Len() {
   242  			t.Errorf("Expected union.Len()=%d but got %d", test.expected.Len(), union.Len())
   243  		}
   244  
   245  		if !union.Equal(test.expected) {
   246  			t.Errorf("Expected union.Equal(expected) but not true.  union:%v expected:%v", union.SortedList(), test.expected.SortedList())
   247  		}
   248  	}
   249  }
   250  
   251  func TestStringIntersection(t *testing.T) {
   252  	tests := []struct {
   253  		s1       Set[string]
   254  		s2       Set[string]
   255  		expected Set[string]
   256  	}{
   257  		{
   258  			New[string]("1", "2", "3", "4"),
   259  			New[string]("3", "4", "5", "6"),
   260  			New[string]("3", "4"),
   261  		},
   262  		{
   263  			New[string]("1", "2", "3", "4"),
   264  			New[string]("1", "2", "3", "4"),
   265  			New[string]("1", "2", "3", "4"),
   266  		},
   267  		{
   268  			New[string]("1", "2", "3", "4"),
   269  			New[string](),
   270  			New[string](),
   271  		},
   272  		{
   273  			New[string](),
   274  			New[string]("1", "2", "3", "4"),
   275  			New[string](),
   276  		},
   277  		{
   278  			New[string](),
   279  			New[string](),
   280  			New[string](),
   281  		},
   282  	}
   283  
   284  	for _, test := range tests {
   285  		intersection := test.s1.Intersection(test.s2)
   286  		if intersection.Len() != test.expected.Len() {
   287  			t.Errorf("Expected intersection.Len()=%d but got %d", test.expected.Len(), intersection.Len())
   288  		}
   289  
   290  		if !intersection.Equal(test.expected) {
   291  			t.Errorf("Expected intersection.Equal(expected) but not true.  intersection:%v expected:%v", intersection.SortedList(), test.expected.SortedList())
   292  		}
   293  	}
   294  }
   295  
   296  func TestKeySet(t *testing.T) {
   297  	m := map[string]string{
   298  		"hallo":   "world",
   299  		"goodbye": "and goodnight",
   300  	}
   301  	expected := []string{"goodbye", "hallo"}
   302  	gotList := KeySet(m).SortedList() // List() returns a sorted list
   303  	if len(gotList) != len(m) {
   304  		t.Fatalf("got %v elements, wanted %v", len(gotList), len(m))
   305  	}
   306  	for i, entry := range KeySet(m).SortedList() {
   307  		if entry != expected[i] {
   308  			t.Errorf("got %v, expected %v", entry, expected[i])
   309  		}
   310  	}
   311  }
   312  
   313  func TestSetSymmetricDifference(t *testing.T) {
   314  	a := New("1", "2", "3")
   315  	b := New("1", "2", "4", "5")
   316  	c := a.SymmetricDifference(b)
   317  	d := b.SymmetricDifference(a)
   318  	if !c.Equal(New("3", "4", "5")) {
   319  		t.Errorf("Unexpected contents: %#v", c.SortedList())
   320  	}
   321  	if !d.Equal(New("3", "4", "5")) {
   322  		t.Errorf("Unexpected contents: %#v", d.SortedList())
   323  	}
   324  }
   325  
   326  func TestSetClear(t *testing.T) {
   327  	s := New[string]()
   328  	s.Insert("a", "b", "c")
   329  	if s.Len() != 3 {
   330  		t.Errorf("Expected len=3: %d", s.Len())
   331  	}
   332  
   333  	s.Clear()
   334  	if s.Len() != 0 {
   335  		t.Errorf("Expected len=0: %d", s.Len())
   336  	}
   337  }
   338  
   339  func TestSetClearWithSharedReference(t *testing.T) {
   340  	s := New[string]()
   341  	s.Insert("a", "b", "c")
   342  	if s.Len() != 3 {
   343  		t.Errorf("Expected len=3: %d", s.Len())
   344  	}
   345  
   346  	m := s
   347  	s.Clear()
   348  	if s.Len() != 0 {
   349  		t.Errorf("Expected len=0 on the cleared set: %d", s.Len())
   350  	}
   351  	if m.Len() != 0 {
   352  		t.Errorf("Expected len=0 on the shared reference: %d", m.Len())
   353  	}
   354  }
   355  
   356  func TestSetClearInSeparateFunction(t *testing.T) {
   357  	s := New[string]()
   358  	s.Insert("a", "b", "c")
   359  	if s.Len() != 3 {
   360  		t.Errorf("Expected len=3: %d", s.Len())
   361  	}
   362  
   363  	clearSetAndAdd(s, "d")
   364  	if s.Len() != 1 {
   365  		t.Errorf("Expected len=1: %d", s.Len())
   366  	}
   367  	if !s.Has("d") {
   368  		t.Errorf("Unexpected contents: %#v", s)
   369  	}
   370  }
   371  
   372  func clearSetAndAdd[T ordered](s Set[T], a T) {
   373  	s.Clear()
   374  	s.Insert(a)
   375  }
   376  
   377  func TestPopAny(t *testing.T) {
   378  	a := New[string]("1", "2")
   379  	_, popped := a.PopAny()
   380  	if !popped {
   381  		t.Errorf("got len(%d): wanted 1", a.Len())
   382  	}
   383  	_, popped = a.PopAny()
   384  	if !popped {
   385  		t.Errorf("got len(%d): wanted 0", a.Len())
   386  	}
   387  	zeroVal, popped := a.PopAny()
   388  	if popped {
   389  		t.Errorf("got len(%d): wanted 0", a.Len())
   390  	}
   391  	if zeroVal != "" {
   392  		t.Errorf("should have gotten zero value when popping an empty set")
   393  	}
   394  }
   395  
   396  func TestClone(t *testing.T) {
   397  	a := New[string]("1", "2")
   398  	a.Insert("3")
   399  
   400  	got := a.Clone()
   401  	if !reflect.DeepEqual(got, a) {
   402  		t.Errorf("Expected to be equal: %v vs %v", got, a)
   403  	}
   404  }
   405  

View as plain text