github.com/MetalBlockchain/metalgo@v1.11.9/utils/set/set_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 set
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestSet(t *testing.T) {
    15  	require := require.New(t)
    16  	id1 := 1
    17  
    18  	s := Set[int]{id1: struct{}{}}
    19  
    20  	s.Add(id1)
    21  	require.True(s.Contains(id1))
    22  
    23  	s.Remove(id1)
    24  	require.False(s.Contains(id1))
    25  
    26  	s.Add(id1)
    27  	require.True(s.Contains(id1))
    28  	require.Len(s.List(), 1)
    29  	require.Equal(id1, s.List()[0])
    30  
    31  	s.Clear()
    32  	require.False(s.Contains(id1))
    33  
    34  	s.Add(id1)
    35  
    36  	s2 := Set[int]{}
    37  
    38  	require.False(s.Overlaps(s2))
    39  
    40  	s2.Union(s)
    41  	require.True(s2.Contains(id1))
    42  	require.True(s.Overlaps(s2))
    43  
    44  	s2.Difference(s)
    45  	require.False(s2.Contains(id1))
    46  	require.False(s.Overlaps(s2))
    47  }
    48  
    49  func TestOf(t *testing.T) {
    50  	tests := []struct {
    51  		name     string
    52  		elements []int
    53  		expected []int
    54  	}{
    55  		{
    56  			name:     "nil",
    57  			elements: nil,
    58  			expected: []int{},
    59  		},
    60  		{
    61  			name:     "empty",
    62  			elements: []int{},
    63  			expected: []int{},
    64  		},
    65  		{
    66  			name:     "unique elements",
    67  			elements: []int{1, 2, 3},
    68  			expected: []int{1, 2, 3},
    69  		},
    70  		{
    71  			name:     "duplicate elements",
    72  			elements: []int{1, 2, 3, 1, 2, 3},
    73  			expected: []int{1, 2, 3},
    74  		},
    75  	}
    76  	for _, tt := range tests {
    77  		t.Run(tt.name, func(t *testing.T) {
    78  			require := require.New(t)
    79  
    80  			s := Of(tt.elements...)
    81  
    82  			require.Len(s, len(tt.expected))
    83  			for _, expected := range tt.expected {
    84  				require.True(s.Contains(expected))
    85  			}
    86  		})
    87  	}
    88  }
    89  
    90  func TestSetClear(t *testing.T) {
    91  	require := require.New(t)
    92  
    93  	set := Set[int]{}
    94  	for i := 0; i < 25; i++ {
    95  		set.Add(i)
    96  	}
    97  	set.Clear()
    98  	require.Empty(set)
    99  	set.Add(1337)
   100  	require.Len(set, 1)
   101  }
   102  
   103  func TestSetPop(t *testing.T) {
   104  	require := require.New(t)
   105  
   106  	var s Set[int]
   107  	_, ok := s.Pop()
   108  	require.False(ok)
   109  
   110  	s = make(Set[int])
   111  	_, ok = s.Pop()
   112  	require.False(ok)
   113  
   114  	id1, id2 := 0, 1
   115  	s.Add(id1, id2)
   116  
   117  	got, ok := s.Pop()
   118  	require.True(ok)
   119  	require.True(got == id1 || got == id2)
   120  	require.Equal(1, s.Len())
   121  
   122  	got, ok = s.Pop()
   123  	require.True(ok)
   124  	require.True(got == id1 || got == id2)
   125  	require.Zero(s.Len())
   126  
   127  	_, ok = s.Pop()
   128  	require.False(ok)
   129  }
   130  
   131  func TestSetMarshalJSON(t *testing.T) {
   132  	require := require.New(t)
   133  	set := Set[int]{}
   134  	{
   135  		asJSON, err := set.MarshalJSON()
   136  		require.NoError(err)
   137  		require.Equal("[]", string(asJSON))
   138  	}
   139  	id1, id2 := 1, 2
   140  	id1JSON, err := json.Marshal(id1)
   141  	require.NoError(err)
   142  	id2JSON, err := json.Marshal(id2)
   143  	require.NoError(err)
   144  	set.Add(id1)
   145  	{
   146  		asJSON, err := set.MarshalJSON()
   147  		require.NoError(err)
   148  		require.Equal(fmt.Sprintf("[%s]", string(id1JSON)), string(asJSON))
   149  	}
   150  	set.Add(id2)
   151  	{
   152  		asJSON, err := set.MarshalJSON()
   153  		require.NoError(err)
   154  		require.Equal(fmt.Sprintf("[%s,%s]", string(id1JSON), string(id2JSON)), string(asJSON))
   155  	}
   156  }
   157  
   158  func TestSetUnmarshalJSON(t *testing.T) {
   159  	require := require.New(t)
   160  	set := Set[int]{}
   161  	{
   162  		require.NoError(set.UnmarshalJSON([]byte("[]")))
   163  		require.Empty(set)
   164  	}
   165  	id1, id2 := 1, 2
   166  	id1JSON, err := json.Marshal(id1)
   167  	require.NoError(err)
   168  	id2JSON, err := json.Marshal(id2)
   169  	require.NoError(err)
   170  	{
   171  		require.NoError(set.UnmarshalJSON([]byte(fmt.Sprintf("[%s]", string(id1JSON)))))
   172  		require.Len(set, 1)
   173  		require.Contains(set, id1)
   174  	}
   175  	{
   176  		require.NoError(set.UnmarshalJSON([]byte(fmt.Sprintf("[%s,%s]", string(id1JSON), string(id2JSON)))))
   177  		require.Len(set, 2)
   178  		require.Contains(set, id1)
   179  		require.Contains(set, id2)
   180  	}
   181  	{
   182  		require.NoError(set.UnmarshalJSON([]byte(fmt.Sprintf("[%d,%d,%d]", 3, 4, 5))))
   183  		require.Len(set, 3)
   184  		require.Contains(set, 3)
   185  		require.Contains(set, 4)
   186  		require.Contains(set, 5)
   187  	}
   188  	{
   189  		require.NoError(set.UnmarshalJSON([]byte(fmt.Sprintf("[%d,%d,%d, %d]", 3, 4, 5, 3))))
   190  		require.Len(set, 3)
   191  		require.Contains(set, 3)
   192  		require.Contains(set, 4)
   193  		require.Contains(set, 5)
   194  	}
   195  	{
   196  		set1 := Set[int]{}
   197  		set2 := Set[int]{}
   198  		require.NoError(set1.UnmarshalJSON([]byte(fmt.Sprintf("[%s,%s]", string(id1JSON), string(id2JSON)))))
   199  		require.NoError(set2.UnmarshalJSON([]byte(fmt.Sprintf("[%s,%s]", string(id2JSON), string(id1JSON)))))
   200  		require.Equal(set1, set2)
   201  	}
   202  }
   203  
   204  func TestSetReflectJSONMarshal(t *testing.T) {
   205  	require := require.New(t)
   206  	set := Set[int]{}
   207  	{
   208  		asJSON, err := json.Marshal(set)
   209  		require.NoError(err)
   210  		require.Equal("[]", string(asJSON))
   211  	}
   212  	id1JSON, err := json.Marshal(1)
   213  	require.NoError(err)
   214  	id2JSON, err := json.Marshal(2)
   215  	require.NoError(err)
   216  	set.Add(1)
   217  	{
   218  		asJSON, err := json.Marshal(set)
   219  		require.NoError(err)
   220  		require.Equal(fmt.Sprintf("[%s]", string(id1JSON)), string(asJSON))
   221  	}
   222  	set.Add(2)
   223  	{
   224  		asJSON, err := json.Marshal(set)
   225  		require.NoError(err)
   226  		require.Equal(fmt.Sprintf("[%s,%s]", string(id1JSON), string(id2JSON)), string(asJSON))
   227  	}
   228  }