github.com/MetalBlockchain/metalgo@v1.11.9/utils/setmap/setmap_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 setmap
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/MetalBlockchain/metalgo/utils/set"
    12  )
    13  
    14  func TestSetMapPut(t *testing.T) {
    15  	tests := []struct {
    16  		name            string
    17  		state           *SetMap[int, int]
    18  		key             int
    19  		value           set.Set[int]
    20  		expectedRemoved []Entry[int, int]
    21  		expectedState   *SetMap[int, int]
    22  	}{
    23  		{
    24  			name:            "none removed",
    25  			state:           New[int, int](),
    26  			key:             1,
    27  			value:           set.Of(2),
    28  			expectedRemoved: nil,
    29  			expectedState: &SetMap[int, int]{
    30  				keyToSet: map[int]set.Set[int]{
    31  					1: set.Of(2),
    32  				},
    33  				valueToKey: map[int]int{
    34  					2: 1,
    35  				},
    36  			},
    37  		},
    38  		{
    39  			name: "key removed",
    40  			state: &SetMap[int, int]{
    41  				keyToSet: map[int]set.Set[int]{
    42  					1: set.Of(2),
    43  				},
    44  				valueToKey: map[int]int{
    45  					2: 1,
    46  				},
    47  			},
    48  			key:   1,
    49  			value: set.Of(3),
    50  			expectedRemoved: []Entry[int, int]{
    51  				{
    52  					Key: 1,
    53  					Set: set.Of(2),
    54  				},
    55  			},
    56  			expectedState: &SetMap[int, int]{
    57  				keyToSet: map[int]set.Set[int]{
    58  					1: set.Of(3),
    59  				},
    60  				valueToKey: map[int]int{
    61  					3: 1,
    62  				},
    63  			},
    64  		},
    65  		{
    66  			name: "value removed",
    67  			state: &SetMap[int, int]{
    68  				keyToSet: map[int]set.Set[int]{
    69  					1: set.Of(2),
    70  				},
    71  				valueToKey: map[int]int{
    72  					2: 1,
    73  				},
    74  			},
    75  			key:   3,
    76  			value: set.Of(2),
    77  			expectedRemoved: []Entry[int, int]{
    78  				{
    79  					Key: 1,
    80  					Set: set.Of(2),
    81  				},
    82  			},
    83  			expectedState: &SetMap[int, int]{
    84  				keyToSet: map[int]set.Set[int]{
    85  					3: set.Of(2),
    86  				},
    87  				valueToKey: map[int]int{
    88  					2: 3,
    89  				},
    90  			},
    91  		},
    92  		{
    93  			name: "key and value removed",
    94  			state: &SetMap[int, int]{
    95  				keyToSet: map[int]set.Set[int]{
    96  					1: set.Of(2),
    97  					3: set.Of(4),
    98  				},
    99  				valueToKey: map[int]int{
   100  					2: 1,
   101  					4: 3,
   102  				},
   103  			},
   104  			key:   1,
   105  			value: set.Of(4),
   106  			expectedRemoved: []Entry[int, int]{
   107  				{
   108  					Key: 1,
   109  					Set: set.Of(2),
   110  				},
   111  				{
   112  					Key: 3,
   113  					Set: set.Of(4),
   114  				},
   115  			},
   116  			expectedState: &SetMap[int, int]{
   117  				keyToSet: map[int]set.Set[int]{
   118  					1: set.Of(4),
   119  				},
   120  				valueToKey: map[int]int{
   121  					4: 1,
   122  				},
   123  			},
   124  		},
   125  	}
   126  	for _, test := range tests {
   127  		t.Run(test.name, func(t *testing.T) {
   128  			require := require.New(t)
   129  
   130  			removed := test.state.Put(test.key, test.value)
   131  			require.ElementsMatch(test.expectedRemoved, removed)
   132  			require.Equal(test.expectedState, test.state)
   133  		})
   134  	}
   135  }
   136  
   137  func TestSetMapHasValueAndGetKeyAndSetOverlaps(t *testing.T) {
   138  	m := New[int, int]()
   139  	require.Empty(t, m.Put(1, set.Of(2)))
   140  
   141  	tests := []struct {
   142  		name           string
   143  		value          int
   144  		expectedKey    int
   145  		expectedExists bool
   146  	}{
   147  		{
   148  			name:           "fetch unknown",
   149  			value:          3,
   150  			expectedKey:    0,
   151  			expectedExists: false,
   152  		},
   153  		{
   154  			name:           "fetch known value",
   155  			value:          2,
   156  			expectedKey:    1,
   157  			expectedExists: true,
   158  		},
   159  		{
   160  			name:           "fetch known key",
   161  			value:          1,
   162  			expectedKey:    0,
   163  			expectedExists: false,
   164  		},
   165  	}
   166  	for _, test := range tests {
   167  		t.Run(test.name, func(t *testing.T) {
   168  			require := require.New(t)
   169  
   170  			exists := m.HasValue(test.value)
   171  			require.Equal(test.expectedExists, exists)
   172  
   173  			key, exists := m.GetKey(test.value)
   174  			require.Equal(test.expectedKey, key)
   175  			require.Equal(test.expectedExists, exists)
   176  		})
   177  	}
   178  }
   179  
   180  func TestSetMapHasOverlap(t *testing.T) {
   181  	m := New[int, int]()
   182  	require.Empty(t, m.Put(1, set.Of(2)))
   183  	require.Empty(t, m.Put(2, set.Of(3, 4)))
   184  
   185  	tests := []struct {
   186  		name             string
   187  		set              set.Set[int]
   188  		expectedOverlaps bool
   189  	}{
   190  		{
   191  			name:             "small fetch unknown",
   192  			set:              set.Of(5),
   193  			expectedOverlaps: false,
   194  		},
   195  		{
   196  			name:             "large fetch unknown",
   197  			set:              set.Of(5, 6, 7, 8),
   198  			expectedOverlaps: false,
   199  		},
   200  		{
   201  			name:             "small fetch known",
   202  			set:              set.Of(3),
   203  			expectedOverlaps: true,
   204  		},
   205  		{
   206  			name:             "large fetch known",
   207  			set:              set.Of(3, 5, 6, 7, 8),
   208  			expectedOverlaps: true,
   209  		},
   210  	}
   211  	for _, test := range tests {
   212  		t.Run(test.name, func(t *testing.T) {
   213  			overlaps := m.HasOverlap(test.set)
   214  			require.Equal(t, test.expectedOverlaps, overlaps)
   215  		})
   216  	}
   217  }
   218  
   219  func TestSetMapHasKeyAndGetSet(t *testing.T) {
   220  	m := New[int, int]()
   221  	require.Empty(t, m.Put(1, set.Of(2)))
   222  
   223  	tests := []struct {
   224  		name           string
   225  		key            int
   226  		expectedValue  set.Set[int]
   227  		expectedExists bool
   228  	}{
   229  		{
   230  			name:           "fetch unknown",
   231  			key:            3,
   232  			expectedValue:  nil,
   233  			expectedExists: false,
   234  		},
   235  		{
   236  			name:           "fetch known key",
   237  			key:            1,
   238  			expectedValue:  set.Of(2),
   239  			expectedExists: true,
   240  		},
   241  		{
   242  			name:           "fetch known value",
   243  			key:            2,
   244  			expectedValue:  nil,
   245  			expectedExists: false,
   246  		},
   247  	}
   248  	for _, test := range tests {
   249  		t.Run(test.name, func(t *testing.T) {
   250  			require := require.New(t)
   251  
   252  			exists := m.HasKey(test.key)
   253  			require.Equal(test.expectedExists, exists)
   254  
   255  			value, exists := m.GetSet(test.key)
   256  			require.Equal(test.expectedValue, value)
   257  			require.Equal(test.expectedExists, exists)
   258  		})
   259  	}
   260  }
   261  
   262  func TestSetMapDeleteKey(t *testing.T) {
   263  	tests := []struct {
   264  		name            string
   265  		state           *SetMap[int, int]
   266  		key             int
   267  		expectedValue   set.Set[int]
   268  		expectedRemoved bool
   269  		expectedState   *SetMap[int, int]
   270  	}{
   271  		{
   272  			name:            "none removed",
   273  			state:           New[int, int](),
   274  			key:             1,
   275  			expectedValue:   nil,
   276  			expectedRemoved: false,
   277  			expectedState:   New[int, int](),
   278  		},
   279  		{
   280  			name: "key removed",
   281  			state: &SetMap[int, int]{
   282  				keyToSet: map[int]set.Set[int]{
   283  					1: set.Of(2),
   284  				},
   285  				valueToKey: map[int]int{
   286  					2: 1,
   287  				},
   288  			},
   289  			key:             1,
   290  			expectedValue:   set.Of(2),
   291  			expectedRemoved: true,
   292  			expectedState:   New[int, int](),
   293  		},
   294  	}
   295  	for _, test := range tests {
   296  		t.Run(test.name, func(t *testing.T) {
   297  			require := require.New(t)
   298  
   299  			value, removed := test.state.DeleteKey(test.key)
   300  			require.Equal(test.expectedValue, value)
   301  			require.Equal(test.expectedRemoved, removed)
   302  			require.Equal(test.expectedState, test.state)
   303  		})
   304  	}
   305  }
   306  
   307  func TestSetMapDeleteValue(t *testing.T) {
   308  	tests := []struct {
   309  		name            string
   310  		state           *SetMap[int, int]
   311  		value           int
   312  		expectedKey     int
   313  		expectedSet     set.Set[int]
   314  		expectedRemoved bool
   315  		expectedState   *SetMap[int, int]
   316  	}{
   317  		{
   318  			name:            "none removed",
   319  			state:           New[int, int](),
   320  			value:           1,
   321  			expectedKey:     0,
   322  			expectedSet:     nil,
   323  			expectedRemoved: false,
   324  			expectedState:   New[int, int](),
   325  		},
   326  		{
   327  			name: "key removed",
   328  			state: &SetMap[int, int]{
   329  				keyToSet: map[int]set.Set[int]{
   330  					1: set.Of(2),
   331  				},
   332  				valueToKey: map[int]int{
   333  					2: 1,
   334  				},
   335  			},
   336  			value:           2,
   337  			expectedKey:     1,
   338  			expectedSet:     set.Of(2),
   339  			expectedRemoved: true,
   340  			expectedState:   New[int, int](),
   341  		},
   342  	}
   343  	for _, test := range tests {
   344  		t.Run(test.name, func(t *testing.T) {
   345  			require := require.New(t)
   346  
   347  			key, set, removed := test.state.DeleteValue(test.value)
   348  			require.Equal(test.expectedKey, key)
   349  			require.Equal(test.expectedSet, set)
   350  			require.Equal(test.expectedRemoved, removed)
   351  			require.Equal(test.expectedState, test.state)
   352  		})
   353  	}
   354  }
   355  
   356  func TestSetMapDeleteOverlapping(t *testing.T) {
   357  	tests := []struct {
   358  		name            string
   359  		state           *SetMap[int, int]
   360  		set             set.Set[int]
   361  		expectedRemoved []Entry[int, int]
   362  		expectedState   *SetMap[int, int]
   363  	}{
   364  		{
   365  			name:            "none removed",
   366  			state:           New[int, int](),
   367  			set:             set.Of(1),
   368  			expectedRemoved: nil,
   369  			expectedState:   New[int, int](),
   370  		},
   371  		{
   372  			name: "key removed",
   373  			state: &SetMap[int, int]{
   374  				keyToSet: map[int]set.Set[int]{
   375  					1: set.Of(2),
   376  				},
   377  				valueToKey: map[int]int{
   378  					2: 1,
   379  				},
   380  			},
   381  			set: set.Of(2),
   382  			expectedRemoved: []Entry[int, int]{
   383  				{
   384  					Key: 1,
   385  					Set: set.Of(2),
   386  				},
   387  			},
   388  			expectedState: New[int, int](),
   389  		},
   390  		{
   391  			name: "multiple keys removed",
   392  			state: &SetMap[int, int]{
   393  				keyToSet: map[int]set.Set[int]{
   394  					1: set.Of(2, 3),
   395  					2: set.Of(4),
   396  				},
   397  				valueToKey: map[int]int{
   398  					2: 1,
   399  					3: 1,
   400  					4: 2,
   401  				},
   402  			},
   403  			set: set.Of(2, 4),
   404  			expectedRemoved: []Entry[int, int]{
   405  				{
   406  					Key: 1,
   407  					Set: set.Of(2, 3),
   408  				},
   409  				{
   410  					Key: 2,
   411  					Set: set.Of(4),
   412  				},
   413  			},
   414  			expectedState: New[int, int](),
   415  		},
   416  	}
   417  	for _, test := range tests {
   418  		t.Run(test.name, func(t *testing.T) {
   419  			require := require.New(t)
   420  
   421  			removed := test.state.DeleteOverlapping(test.set)
   422  			require.ElementsMatch(test.expectedRemoved, removed)
   423  			require.Equal(test.expectedState, test.state)
   424  		})
   425  	}
   426  }
   427  
   428  func TestSetMapLen(t *testing.T) {
   429  	require := require.New(t)
   430  
   431  	m := New[int, int]()
   432  	require.Zero(m.Len())
   433  	require.Zero(m.LenValues())
   434  
   435  	m.Put(1, set.Of(2))
   436  	require.Equal(1, m.Len())
   437  	require.Equal(1, m.LenValues())
   438  
   439  	m.Put(2, set.Of(3, 4))
   440  	require.Equal(2, m.Len())
   441  	require.Equal(3, m.LenValues())
   442  
   443  	m.Put(1, set.Of(4, 5))
   444  	require.Equal(1, m.Len())
   445  	require.Equal(2, m.LenValues())
   446  
   447  	m.DeleteKey(1)
   448  	require.Zero(m.Len())
   449  	require.Zero(m.LenValues())
   450  }