github.com/MetalBlockchain/metalgo@v1.11.9/utils/bimap/bimap_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 bimap 5 6 import ( 7 "encoding/json" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestBiMapPut(t *testing.T) { 14 tests := []struct { 15 name string 16 state *BiMap[int, int] 17 key int 18 value int 19 expectedRemoved []Entry[int, int] 20 expectedState *BiMap[int, int] 21 }{ 22 { 23 name: "none removed", 24 state: New[int, int](), 25 key: 1, 26 value: 2, 27 expectedRemoved: nil, 28 expectedState: &BiMap[int, int]{ 29 keyToValue: map[int]int{ 30 1: 2, 31 }, 32 valueToKey: map[int]int{ 33 2: 1, 34 }, 35 }, 36 }, 37 { 38 name: "key removed", 39 state: &BiMap[int, int]{ 40 keyToValue: map[int]int{ 41 1: 2, 42 }, 43 valueToKey: map[int]int{ 44 2: 1, 45 }, 46 }, 47 key: 1, 48 value: 3, 49 expectedRemoved: []Entry[int, int]{ 50 { 51 Key: 1, 52 Value: 2, 53 }, 54 }, 55 expectedState: &BiMap[int, int]{ 56 keyToValue: map[int]int{ 57 1: 3, 58 }, 59 valueToKey: map[int]int{ 60 3: 1, 61 }, 62 }, 63 }, 64 { 65 name: "value removed", 66 state: &BiMap[int, int]{ 67 keyToValue: map[int]int{ 68 1: 2, 69 }, 70 valueToKey: map[int]int{ 71 2: 1, 72 }, 73 }, 74 key: 3, 75 value: 2, 76 expectedRemoved: []Entry[int, int]{ 77 { 78 Key: 1, 79 Value: 2, 80 }, 81 }, 82 expectedState: &BiMap[int, int]{ 83 keyToValue: map[int]int{ 84 3: 2, 85 }, 86 valueToKey: map[int]int{ 87 2: 3, 88 }, 89 }, 90 }, 91 { 92 name: "key and value removed", 93 state: &BiMap[int, int]{ 94 keyToValue: map[int]int{ 95 1: 2, 96 3: 4, 97 }, 98 valueToKey: map[int]int{ 99 2: 1, 100 4: 3, 101 }, 102 }, 103 key: 1, 104 value: 4, 105 expectedRemoved: []Entry[int, int]{ 106 { 107 Key: 1, 108 Value: 2, 109 }, 110 { 111 Key: 3, 112 Value: 4, 113 }, 114 }, 115 expectedState: &BiMap[int, int]{ 116 keyToValue: map[int]int{ 117 1: 4, 118 }, 119 valueToKey: map[int]int{ 120 4: 1, 121 }, 122 }, 123 }, 124 } 125 for _, test := range tests { 126 t.Run(test.name, func(t *testing.T) { 127 require := require.New(t) 128 129 removed := test.state.Put(test.key, test.value) 130 require.Equal(test.expectedRemoved, removed) 131 require.Equal(test.expectedState, test.state) 132 }) 133 } 134 } 135 136 func TestBiMapHasValueAndGetKey(t *testing.T) { 137 m := New[int, int]() 138 require.Empty(t, m.Put(1, 2)) 139 140 tests := []struct { 141 name string 142 value int 143 expectedKey int 144 expectedExists bool 145 }{ 146 { 147 name: "fetch unknown", 148 value: 3, 149 expectedKey: 0, 150 expectedExists: false, 151 }, 152 { 153 name: "fetch known value", 154 value: 2, 155 expectedKey: 1, 156 expectedExists: true, 157 }, 158 { 159 name: "fetch known key", 160 value: 1, 161 expectedKey: 0, 162 expectedExists: false, 163 }, 164 } 165 for _, test := range tests { 166 t.Run(test.name, func(t *testing.T) { 167 require := require.New(t) 168 169 exists := m.HasValue(test.value) 170 require.Equal(test.expectedExists, exists) 171 172 key, exists := m.GetKey(test.value) 173 require.Equal(test.expectedKey, key) 174 require.Equal(test.expectedExists, exists) 175 }) 176 } 177 } 178 179 func TestBiMapHasKeyAndGetValue(t *testing.T) { 180 m := New[int, int]() 181 require.Empty(t, m.Put(1, 2)) 182 183 tests := []struct { 184 name string 185 key int 186 expectedValue int 187 expectedExists bool 188 }{ 189 { 190 name: "fetch unknown", 191 key: 3, 192 expectedValue: 0, 193 expectedExists: false, 194 }, 195 { 196 name: "fetch known key", 197 key: 1, 198 expectedValue: 2, 199 expectedExists: true, 200 }, 201 { 202 name: "fetch known value", 203 key: 2, 204 expectedValue: 0, 205 expectedExists: false, 206 }, 207 } 208 for _, test := range tests { 209 t.Run(test.name, func(t *testing.T) { 210 require := require.New(t) 211 212 exists := m.HasKey(test.key) 213 require.Equal(test.expectedExists, exists) 214 215 value, exists := m.GetValue(test.key) 216 require.Equal(test.expectedValue, value) 217 require.Equal(test.expectedExists, exists) 218 }) 219 } 220 } 221 222 func TestBiMapDeleteKey(t *testing.T) { 223 tests := []struct { 224 name string 225 state *BiMap[int, int] 226 key int 227 expectedValue int 228 expectedRemoved bool 229 expectedState *BiMap[int, int] 230 }{ 231 { 232 name: "none removed", 233 state: New[int, int](), 234 key: 1, 235 expectedValue: 0, 236 expectedRemoved: false, 237 expectedState: New[int, int](), 238 }, 239 { 240 name: "key removed", 241 state: &BiMap[int, int]{ 242 keyToValue: map[int]int{ 243 1: 2, 244 }, 245 valueToKey: map[int]int{ 246 2: 1, 247 }, 248 }, 249 key: 1, 250 expectedValue: 2, 251 expectedRemoved: true, 252 expectedState: New[int, int](), 253 }, 254 } 255 for _, test := range tests { 256 t.Run(test.name, func(t *testing.T) { 257 require := require.New(t) 258 259 value, removed := test.state.DeleteKey(test.key) 260 require.Equal(test.expectedValue, value) 261 require.Equal(test.expectedRemoved, removed) 262 require.Equal(test.expectedState, test.state) 263 }) 264 } 265 } 266 267 func TestBiMapDeleteValue(t *testing.T) { 268 tests := []struct { 269 name string 270 state *BiMap[int, int] 271 value int 272 expectedKey int 273 expectedRemoved bool 274 expectedState *BiMap[int, int] 275 }{ 276 { 277 name: "none removed", 278 state: New[int, int](), 279 value: 1, 280 expectedKey: 0, 281 expectedRemoved: false, 282 expectedState: New[int, int](), 283 }, 284 { 285 name: "key removed", 286 state: &BiMap[int, int]{ 287 keyToValue: map[int]int{ 288 1: 2, 289 }, 290 valueToKey: map[int]int{ 291 2: 1, 292 }, 293 }, 294 value: 2, 295 expectedKey: 1, 296 expectedRemoved: true, 297 expectedState: New[int, int](), 298 }, 299 } 300 for _, test := range tests { 301 t.Run(test.name, func(t *testing.T) { 302 require := require.New(t) 303 304 key, removed := test.state.DeleteValue(test.value) 305 require.Equal(test.expectedKey, key) 306 require.Equal(test.expectedRemoved, removed) 307 require.Equal(test.expectedState, test.state) 308 }) 309 } 310 } 311 312 func TestBiMapLenAndLists(t *testing.T) { 313 require := require.New(t) 314 315 m := New[int, int]() 316 require.Zero(m.Len()) 317 require.Empty(m.Keys()) 318 require.Empty(m.Values()) 319 320 m.Put(1, 2) 321 require.Equal(1, m.Len()) 322 require.ElementsMatch([]int{1}, m.Keys()) 323 require.ElementsMatch([]int{2}, m.Values()) 324 325 m.Put(2, 3) 326 require.Equal(2, m.Len()) 327 require.ElementsMatch([]int{1, 2}, m.Keys()) 328 require.ElementsMatch([]int{2, 3}, m.Values()) 329 330 m.Put(1, 3) 331 require.Equal(1, m.Len()) 332 require.ElementsMatch([]int{1}, m.Keys()) 333 require.ElementsMatch([]int{3}, m.Values()) 334 335 m.DeleteKey(1) 336 require.Zero(m.Len()) 337 require.Empty(m.Keys()) 338 require.Empty(m.Values()) 339 } 340 341 func TestBiMapJSON(t *testing.T) { 342 require := require.New(t) 343 344 expectedMap := New[int, int]() 345 expectedMap.Put(1, 2) 346 expectedMap.Put(2, 3) 347 348 jsonBytes, err := json.Marshal(expectedMap) 349 require.NoError(err) 350 351 expectedJSONBytes := []byte(`{"1":2,"2":3}`) 352 require.Equal(expectedJSONBytes, jsonBytes) 353 354 var unmarshalledMap BiMap[int, int] 355 require.NoError(json.Unmarshal(jsonBytes, &unmarshalledMap)) 356 require.Equal(expectedMap, &unmarshalledMap) 357 } 358 359 func TestBiMapInvalidJSON(t *testing.T) { 360 require := require.New(t) 361 362 invalidJSONBytes := []byte(`{"1":2,"2":2}`) 363 var unmarshalledMap BiMap[int, int] 364 err := json.Unmarshal(invalidJSONBytes, &unmarshalledMap) 365 require.ErrorIs(err, errNotBijective) 366 }