github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/maps/hashbidimap/hashbidimap_test.go (about) 1 package hashbidimap 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "github.com/stretchr/testify/assert" 7 "reflect" 8 "strings" 9 "testing" 10 ) 11 12 func TestMapPut(t *testing.T) { 13 m := New[int, string]() 14 m.Put(5, "e") 15 m.Put(6, "f") 16 m.Put(7, "g") 17 m.Put(3, "c") 18 m.Put(4, "d") 19 m.Put(1, "x") 20 m.Put(2, "b") 21 m.Put(1, "a") //overwrite 22 23 if actualValue := m.Size(); actualValue != 7 { 24 t.Errorf("Got %v expected %v", actualValue, 7) 25 } 26 if actualValue, expectedValue := m.Keys(), []int{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) { 27 t.Errorf("Got %v expected %v", actualValue, expectedValue) 28 } 29 if actualValue, expectedValue := m.Values(), []string{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) { 30 t.Errorf("Got %v expected %v", actualValue, expectedValue) 31 } 32 33 // key,expectedValue,expectedFound 34 tests1 := [][]interface{}{ 35 {1, "a", true}, 36 {2, "b", true}, 37 {3, "c", true}, 38 {4, "d", true}, 39 {5, "e", true}, 40 {6, "f", true}, 41 {7, "g", true}, 42 {8, "", false}, 43 } 44 45 for _, test := range tests1 { 46 // retrievals 47 actualValue, actualFound := m.Get(test[0].(int)) 48 if actualValue != test[1] || actualFound != test[2] { 49 t.Errorf("Got %v expected %v", actualValue, test[1]) 50 } 51 } 52 } 53 54 func TestMapRemove(t *testing.T) { 55 m := New[int, string]() 56 m.Put(5, "e") 57 m.Put(6, "f") 58 m.Put(7, "g") 59 m.Put(3, "c") 60 m.Put(4, "d") 61 m.Put(1, "x") 62 m.Put(2, "b") 63 m.Put(1, "a") //overwrite 64 65 m.Remove(5) 66 m.Remove(6) 67 m.Remove(7) 68 m.Remove(8) 69 m.Remove(5) 70 71 if actualValue, expectedValue := m.Keys(), []int{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) { 72 t.Errorf("Got %v expected %v", actualValue, expectedValue) 73 } 74 75 if actualValue, expectedValue := m.Values(), []string{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) { 76 t.Errorf("Got %v expected %v", actualValue, expectedValue) 77 } 78 if actualValue := m.Size(); actualValue != 4 { 79 t.Errorf("Got %v expected %v", actualValue, 4) 80 } 81 82 tests2 := [][]interface{}{ 83 {1, "a", true}, 84 {2, "b", true}, 85 {3, "c", true}, 86 {4, "d", true}, 87 {5, "", false}, 88 {6, "", false}, 89 {7, "", false}, 90 {8, "", false}, 91 } 92 93 for _, test := range tests2 { 94 actualValue, actualFound := m.Get(test[0].(int)) 95 if actualValue != test[1] || actualFound != test[2] { 96 t.Errorf("Got %v expected %v", actualValue, test[1]) 97 } 98 } 99 100 m.Remove(1) 101 m.Remove(4) 102 m.Remove(2) 103 m.Remove(3) 104 m.Remove(2) 105 m.Remove(2) 106 107 if actualValue, expectedValue := m.Keys(), []int{}; !assert.Equal(t, actualValue, expectedValue) { 108 t.Errorf("Got %v expected %v", actualValue, expectedValue) 109 } 110 if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { 111 t.Errorf("Got %v expected %v", actualValue, expectedValue) 112 } 113 if actualValue := m.Size(); actualValue != 0 { 114 t.Errorf("Got %v expected %v", actualValue, 0) 115 } 116 if actualValue := m.Empty(); actualValue != true { 117 t.Errorf("Got %v expected %v", actualValue, true) 118 } 119 } 120 121 func TestMapGetKey(t *testing.T) { 122 m := New[int, string]() 123 m.Put(5, "e") 124 m.Put(6, "f") 125 m.Put(7, "g") 126 m.Put(3, "c") 127 m.Put(4, "d") 128 m.Put(1, "x") 129 m.Put(2, "b") 130 m.Put(1, "a") //overwrite 131 132 // key,expectedValue,expectedFound 133 tests1 := [][]interface{}{ 134 {1, "a", true}, 135 {2, "b", true}, 136 {3, "c", true}, 137 {4, "d", true}, 138 {5, "e", true}, 139 {6, "f", true}, 140 {7, "g", true}, 141 {0, "x", false}, 142 } 143 144 for _, test := range tests1 { 145 // retrievals 146 actualValue, actualFound := m.GetKey(test[1].(string)) 147 if actualValue != test[0] || actualFound != test[2] { 148 t.Errorf("Got %v expected %v", actualValue, test[0]) 149 } 150 } 151 } 152 153 func TestMapSerialization(t *testing.T) { 154 m := New[string, float64]() 155 m.Put("a", 1.0) 156 m.Put("b", 2.0) 157 m.Put("c", 3.0) 158 159 var err error 160 assert := func() { 161 if actualValue, expectedValue := m.Keys(), []string{"a", "b", "c"}; !sameElements(actualValue, expectedValue) { 162 t.Errorf("Got %v expected %v", actualValue, expectedValue) 163 } 164 if actualValue, expectedValue := m.Values(), []float64{1.0, 2.0, 3.0}; !sameElements(actualValue, expectedValue) { 165 t.Errorf("Got %v expected %v", actualValue, expectedValue) 166 } 167 if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue { 168 t.Errorf("Got %v expected %v", actualValue, expectedValue) 169 } 170 if err != nil { 171 t.Errorf("Got error %v", err) 172 } 173 } 174 175 assert() 176 177 bytes, err := m.MarshalJSON() 178 assert() 179 180 err = m.UnmarshalJSON(bytes) 181 assert() 182 183 bytes, err = json.Marshal([]interface{}{"a", "b", "c", m}) 184 if err != nil { 185 t.Errorf("Got error %v", err) 186 } 187 188 err = json.Unmarshal([]byte(`{"a":1,"b":2}`), &m) 189 if err != nil { 190 t.Errorf("Got error %v", err) 191 } 192 } 193 194 func TestMapString(t *testing.T) { 195 c := New[string, int]() 196 c.Put("a", 1) 197 if !strings.HasPrefix(c.String(), "HashBidiMap") { 198 t.Errorf("String should start with container name") 199 } 200 } 201 202 func sameElements[E any](a []E, b []E) bool { 203 if len(a) != len(b) { 204 return false 205 } 206 for _, av := range a { 207 found := false 208 for _, bv := range b { 209 if reflect.DeepEqual(av, bv) { 210 found = true 211 break 212 } 213 } 214 if !found { 215 return false 216 } 217 } 218 return true 219 } 220 221 func benchmarkGet[K, V int](b *testing.B, m *Map[K, V], size int) { 222 for i := 0; i < b.N; i++ { 223 for n := 0; n < size; n++ { 224 m.Get(K(n)) 225 } 226 } 227 } 228 229 func benchmarkPut[K, V int](b *testing.B, m *Map[K, V], size int) { 230 for i := 0; i < b.N; i++ { 231 for n := 0; n < size; n++ { 232 m.Put(K(n), V(n)) 233 } 234 } 235 } 236 237 func benchmarkRemove[K, V int](b *testing.B, m *Map[K, V], size int) { 238 for i := 0; i < b.N; i++ { 239 for n := 0; n < size; n++ { 240 m.Remove(K(n)) 241 } 242 } 243 } 244 245 func BenchmarkHashBidiMapGet100(b *testing.B) { 246 b.StopTimer() 247 size := 100 248 m := New[int, int]() 249 for n := 0; n < size; n++ { 250 m.Put(n, n) 251 } 252 b.StartTimer() 253 benchmarkGet(b, m, size) 254 } 255 256 func BenchmarkHashBidiMapGet1000(b *testing.B) { 257 b.StopTimer() 258 size := 1000 259 m := New[int, int]() 260 for n := 0; n < size; n++ { 261 m.Put(n, n) 262 } 263 b.StartTimer() 264 benchmarkGet(b, m, size) 265 } 266 267 func BenchmarkHashBidiMapGet10000(b *testing.B) { 268 b.StopTimer() 269 size := 10000 270 m := New[int, int]() 271 for n := 0; n < size; n++ { 272 m.Put(n, n) 273 } 274 b.StartTimer() 275 benchmarkGet(b, m, size) 276 } 277 278 func BenchmarkHashBidiMapGet100000(b *testing.B) { 279 b.StopTimer() 280 size := 100000 281 m := New[int, int]() 282 for n := 0; n < size; n++ { 283 m.Put(n, n) 284 } 285 b.StartTimer() 286 benchmarkGet(b, m, size) 287 } 288 289 func BenchmarkHashBidiMapPut100(b *testing.B) { 290 b.StopTimer() 291 size := 100 292 m := New[int, int]() 293 b.StartTimer() 294 benchmarkPut(b, m, size) 295 } 296 297 func BenchmarkHashBidiMapPut1000(b *testing.B) { 298 b.StopTimer() 299 size := 1000 300 m := New[int, int]() 301 for n := 0; n < size; n++ { 302 m.Put(n, n) 303 } 304 b.StartTimer() 305 benchmarkPut(b, m, size) 306 } 307 308 func BenchmarkHashBidiMapPut10000(b *testing.B) { 309 b.StopTimer() 310 size := 10000 311 m := New[int, int]() 312 for n := 0; n < size; n++ { 313 m.Put(n, n) 314 } 315 b.StartTimer() 316 benchmarkPut(b, m, size) 317 } 318 319 func BenchmarkHashBidiMapPut100000(b *testing.B) { 320 b.StopTimer() 321 size := 100000 322 m := New[int, int]() 323 for n := 0; n < size; n++ { 324 m.Put(n, n) 325 } 326 b.StartTimer() 327 benchmarkPut(b, m, size) 328 } 329 330 func BenchmarkHashBidiMapRemove100(b *testing.B) { 331 b.StopTimer() 332 size := 100 333 m := New[int, int]() 334 for n := 0; n < size; n++ { 335 m.Put(n, n) 336 } 337 b.StartTimer() 338 benchmarkRemove(b, m, size) 339 } 340 341 func BenchmarkHashBidiMapRemove1000(b *testing.B) { 342 b.StopTimer() 343 size := 1000 344 m := New[int, int]() 345 for n := 0; n < size; n++ { 346 m.Put(n, n) 347 } 348 b.StartTimer() 349 benchmarkRemove(b, m, size) 350 } 351 352 func BenchmarkHashBidiMapRemove10000(b *testing.B) { 353 b.StopTimer() 354 size := 10000 355 m := New[int, int]() 356 for n := 0; n < size; n++ { 357 m.Put(n, n) 358 } 359 b.StartTimer() 360 benchmarkRemove(b, m, size) 361 } 362 363 func BenchmarkHashBidiMapRemove100000(b *testing.B) { 364 b.StopTimer() 365 size := 100000 366 m := New[int, int]() 367 for n := 0; n < size; n++ { 368 m.Put(n, n) 369 } 370 b.StartTimer() 371 benchmarkRemove(b, m, size) 372 }