github.com/MetalBlockchain/metalgo@v1.11.9/utils/bag/bag_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package bag
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestBagOf(t *testing.T) {
    13  	tests := []struct {
    14  		name           string
    15  		elements       []int
    16  		expectedCounts map[int]int
    17  	}{
    18  		{
    19  			name:           "nil",
    20  			elements:       nil,
    21  			expectedCounts: map[int]int{},
    22  		},
    23  		{
    24  			name:           "empty",
    25  			elements:       []int{},
    26  			expectedCounts: map[int]int{},
    27  		},
    28  		{
    29  			name:     "unique elements",
    30  			elements: []int{1, 2, 3},
    31  			expectedCounts: map[int]int{
    32  				1: 1,
    33  				2: 1,
    34  				3: 1,
    35  			},
    36  		},
    37  		{
    38  			name:     "duplicate elements",
    39  			elements: []int{1, 2, 3, 1, 2, 3},
    40  			expectedCounts: map[int]int{
    41  				1: 2,
    42  				2: 2,
    43  				3: 2,
    44  			},
    45  		},
    46  	}
    47  	for _, tt := range tests {
    48  		t.Run(tt.name, func(t *testing.T) {
    49  			require := require.New(t)
    50  
    51  			b := Of(tt.elements...)
    52  
    53  			require.Equal(len(tt.elements), b.Len())
    54  			for entry, count := range tt.expectedCounts {
    55  				require.Equal(count, b.Count(entry))
    56  			}
    57  		})
    58  	}
    59  }
    60  
    61  func TestBagAdd(t *testing.T) {
    62  	require := require.New(t)
    63  
    64  	elt0 := 0
    65  	elt1 := 1
    66  
    67  	bag := Bag[int]{}
    68  
    69  	require.Zero(bag.Count(elt0))
    70  	require.Zero(bag.Count(elt1))
    71  	require.Zero(bag.Len())
    72  	require.Empty(bag.List())
    73  	mode, freq := bag.Mode()
    74  	require.Equal(elt0, mode)
    75  	require.Zero(freq)
    76  	require.Empty(bag.Threshold())
    77  
    78  	bag.Add(elt0)
    79  
    80  	require.Equal(1, bag.Count(elt0))
    81  	require.Zero(bag.Count(elt1))
    82  	require.Equal(1, bag.Len())
    83  	require.Len(bag.List(), 1)
    84  	mode, freq = bag.Mode()
    85  	require.Equal(elt0, mode)
    86  	require.Equal(1, freq)
    87  	require.Len(bag.Threshold(), 1)
    88  
    89  	bag.Add(elt0)
    90  
    91  	require.Equal(2, bag.Count(elt0))
    92  	require.Zero(bag.Count(elt1))
    93  	require.Equal(2, bag.Len())
    94  	require.Len(bag.List(), 1)
    95  	mode, freq = bag.Mode()
    96  	require.Equal(elt0, mode)
    97  	require.Equal(2, freq)
    98  	require.Len(bag.Threshold(), 1)
    99  
   100  	bag.AddCount(elt1, 3)
   101  
   102  	require.Equal(2, bag.Count(elt0))
   103  	require.Equal(3, bag.Count(elt1))
   104  	require.Equal(5, bag.Len())
   105  	require.Len(bag.List(), 2)
   106  	mode, freq = bag.Mode()
   107  	require.Equal(elt1, mode)
   108  	require.Equal(3, freq)
   109  	require.Len(bag.Threshold(), 2)
   110  }
   111  
   112  func TestBagSetThreshold(t *testing.T) {
   113  	require := require.New(t)
   114  
   115  	elt0 := 0
   116  	elt1 := 1
   117  
   118  	bag := Bag[int]{}
   119  
   120  	bag.AddCount(elt0, 2)
   121  	bag.AddCount(elt1, 3)
   122  
   123  	bag.SetThreshold(0)
   124  
   125  	require.Equal(2, bag.Count(elt0))
   126  	require.Equal(3, bag.Count(elt1))
   127  	require.Equal(5, bag.Len())
   128  	require.Len(bag.List(), 2)
   129  	mode, freq := bag.Mode()
   130  	require.Equal(elt1, mode)
   131  	require.Equal(3, freq)
   132  	require.Len(bag.Threshold(), 2)
   133  
   134  	bag.SetThreshold(3)
   135  
   136  	require.Equal(2, bag.Count(elt0))
   137  	require.Equal(3, bag.Count(elt1))
   138  	require.Equal(5, bag.Len())
   139  	require.Len(bag.List(), 2)
   140  	mode, freq = bag.Mode()
   141  	require.Equal(elt1, mode)
   142  	require.Equal(3, freq)
   143  	require.Len(bag.Threshold(), 1)
   144  }
   145  
   146  func TestBagFilter(t *testing.T) {
   147  	require := require.New(t)
   148  
   149  	elt0 := 0
   150  	elt1 := 1
   151  	elt2 := 2
   152  
   153  	bag := Bag[int]{}
   154  
   155  	bag.AddCount(elt0, 1)
   156  	bag.AddCount(elt1, 3)
   157  	bag.AddCount(elt2, 5)
   158  
   159  	filterFunc := func(elt int) bool {
   160  		return elt%2 == 0
   161  	}
   162  	even := bag.Filter(filterFunc)
   163  
   164  	require.Equal(1, even.Count(elt0))
   165  	require.Zero(even.Count(elt1))
   166  	require.Equal(5, even.Count(elt2))
   167  }
   168  
   169  func TestBagSplit(t *testing.T) {
   170  	require := require.New(t)
   171  
   172  	elt0 := 0
   173  	elt1 := 1
   174  	elt2 := 2
   175  
   176  	bag := Bag[int]{}
   177  
   178  	bag.AddCount(elt0, 1)
   179  	bag.AddCount(elt1, 3)
   180  	bag.AddCount(elt2, 5)
   181  
   182  	bags := bag.Split(func(i int) bool {
   183  		return i%2 != 0
   184  	})
   185  
   186  	evens := bags[0]
   187  	odds := bags[1]
   188  
   189  	require.Equal(1, evens.Count(elt0))
   190  	require.Zero(evens.Count(elt1))
   191  	require.Equal(5, evens.Count(elt2))
   192  	require.Zero(odds.Count(elt0))
   193  	require.Equal(3, odds.Count(elt1))
   194  	require.Zero(odds.Count(elt2))
   195  }
   196  
   197  func TestBagString(t *testing.T) {
   198  	elt0 := 123
   199  
   200  	bag := Bag[int]{}
   201  
   202  	bag.AddCount(elt0, 1337)
   203  
   204  	expected := `Bag[int]: (Size = 1337)
   205      123: 1337`
   206  
   207  	require.Equal(t, expected, bag.String())
   208  }
   209  
   210  func TestBagRemove(t *testing.T) {
   211  	require := require.New(t)
   212  
   213  	elt0 := 0
   214  	elt1 := 1
   215  	elt2 := 2
   216  
   217  	bag := Bag[int]{}
   218  
   219  	bag.Remove(elt0)
   220  	require.Zero(bag.Len())
   221  
   222  	bag.AddCount(elt0, 3)
   223  	bag.AddCount(elt1, 2)
   224  	bag.Add(elt2)
   225  	require.Equal(6, bag.Len())
   226  	require.Len(bag.counts, 3)
   227  	mode, freq := bag.Mode()
   228  	require.Equal(elt0, mode)
   229  	require.Equal(3, freq)
   230  
   231  	bag.Remove(elt0)
   232  
   233  	require.Zero(bag.Count(elt0))
   234  	require.Equal(2, bag.Count(elt1))
   235  	require.Equal(1, bag.Count(elt2))
   236  	require.Equal(3, bag.Len())
   237  	require.Len(bag.counts, 2)
   238  	mode, freq = bag.Mode()
   239  	require.Equal(elt1, mode)
   240  	require.Equal(2, freq)
   241  
   242  	bag.Remove(elt1)
   243  	require.Zero(bag.Count(elt0))
   244  	require.Zero(bag.Count(elt1))
   245  	require.Equal(1, bag.Count(elt2))
   246  	require.Equal(1, bag.Len())
   247  	require.Len(bag.counts, 1)
   248  	mode, freq = bag.Mode()
   249  	require.Equal(elt2, mode)
   250  	require.Equal(1, freq)
   251  }
   252  
   253  func TestBagEquals(t *testing.T) {
   254  	require := require.New(t)
   255  
   256  	bag1 := Bag[int]{}
   257  	bag2 := Bag[int]{}
   258  
   259  	// Case: both empty
   260  	require.True(bag1.Equals(bag2))
   261  	require.True(bag2.Equals(bag1))
   262  
   263  	// Case: one empty, one not
   264  	bag1.Add(0)
   265  	require.False(bag1.Equals(bag2))
   266  	require.False(bag2.Equals(bag1))
   267  
   268  	bag2.Add(0)
   269  	require.True(bag1.Equals(bag2))
   270  	require.True(bag2.Equals(bag1))
   271  
   272  	// Case: both non-empty, different elements
   273  	bag1.Add(1)
   274  	require.False(bag1.Equals(bag2))
   275  	require.False(bag2.Equals(bag1))
   276  
   277  	bag2.Add(1)
   278  	require.True(bag1.Equals(bag2))
   279  	require.True(bag2.Equals(bag1))
   280  
   281  	// Case: both non-empty, different counts
   282  	bag1.Add(0)
   283  	require.False(bag1.Equals(bag2))
   284  	require.False(bag2.Equals(bag1))
   285  
   286  	bag2.Add(0)
   287  	require.True(bag1.Equals(bag2))
   288  	require.True(bag2.Equals(bag1))
   289  }