github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/tests/map_test.go (about) 1 package tests 2 3 import ( 4 "strings" 5 "testing" 6 ) 7 8 // These tests exercise the api of maps and built-in functions that operate on maps 9 func Test_MapLiteral(t *testing.T) { 10 myMap := map[string]int{"test": 0, "key": 1, "charm": 2} 11 12 assertMapApi(t, myMap) 13 } 14 15 func Test_MapLiteralAssign(t *testing.T) { 16 myMap := map[string]int{} 17 myMap["test"] = 0 18 myMap["key"] = 1 19 myMap["charm"] = 2 20 21 assertMapApi(t, myMap) 22 } 23 24 func Test_MapMake(t *testing.T) { 25 myMap := make(map[string]int) 26 myMap["test"] = 0 27 myMap["key"] = 1 28 myMap["charm"] = 2 29 30 assertMapApi(t, myMap) 31 } 32 33 func Test_MapMakeSizeHint(t *testing.T) { 34 myMap := make(map[string]int, 3) 35 myMap["test"] = 0 36 myMap["key"] = 1 37 myMap["charm"] = 2 38 39 assertMapApi(t, myMap) 40 } 41 42 func Test_MapNew(t *testing.T) { 43 myMap := new(map[string]int) 44 if *myMap != nil { 45 t.Errorf("Got: %v, Want: nil when made with new()", *myMap) 46 } 47 } 48 49 func Test_MapType(t *testing.T) { 50 defer func() { 51 if err := recover(); err == nil { 52 t.Error("assignment on nil map should panic") 53 } else { 54 str := err.(error).Error() 55 if !strings.Contains(str, "assignment to entry in nil map") { 56 t.Errorf("nil map assignment Got: %s, Want: assigning to a nil map", str) 57 } 58 } 59 }() 60 61 var myMap map[string]int 62 if myMap != nil { 63 t.Errorf("map declared with var, Got: %v, Want: nil", myMap) 64 } 65 66 myMap["key"] = 666 67 } 68 69 func Test_MapLenPrecedence(t *testing.T) { 70 // This test verifies that the expression len(m) compiles to is evaluated 71 // correctly in the context of the enclosing expression. 72 m := make(map[string]string) 73 74 if len(m) != 0 { 75 t.Errorf("inline len Got: %d, Want: 0", len(m)) 76 } 77 78 i := len(m) 79 if i != 0 { 80 t.Errorf("assigned len Got: %d, Want: 0", i) 81 } 82 } 83 84 func Test_MapRangeMutation(t *testing.T) { 85 // This test verifies that all of a map is iterated, even if the map is modified during iteration. 86 87 myMap := map[string]int{"one": 1, "two": 2, "three": 3} 88 89 var seenKeys []string 90 91 for k := range myMap { 92 seenKeys = append(seenKeys, k) 93 if k == "two" { 94 delete(myMap, k) 95 } 96 } 97 98 if len(seenKeys) != 3 { 99 t.Errorf("iteration seenKeys len Got: %d, Want: 3", len(seenKeys)) 100 } 101 } 102 103 func Test_MapRangeNil(t *testing.T) { 104 // Tests that loops on nil maps do not error. 105 i := 0 106 var m map[string]int 107 for k, v := range m { 108 _, _ = k, v 109 i++ 110 } 111 112 if i > 0 { 113 t.Error("Got: Loops happened on a nil map, Want: no looping") 114 } 115 } 116 117 func Test_MapDelete(t *testing.T) { 118 var nilMap map[string]string 119 m := map[string]string{"key": "value"} 120 121 delete(nilMap, "key") // noop 122 delete(m, "key") 123 if m["key"] == "value" { 124 t.Error("Got: entry still set, Want: should have been deleted") 125 } 126 delete(m, "key") // noop 127 } 128 129 func assertMapApi(t *testing.T, myMap map[string]int) { 130 if len(myMap) != 3 { 131 t.Errorf("initial len of map Got: %d, Want: 3", len(myMap)) 132 } 133 134 var keys []string 135 var values []int 136 137 for k, v := range myMap { 138 keys = append(keys, k) 139 values = append(values, v) 140 } 141 142 if len(keys) != 3 || !containsString(keys, "test") || !containsString(keys, "key") || !containsString(keys, "charm") { 143 t.Error("range did not contain the correct keys") 144 } 145 146 if len(values) != 3 || !containsInt(values, 0) || !containsInt(values, 1) || !containsInt(values, 2) { 147 t.Error("range did not contain the correct values") 148 } 149 150 if myMap["test"] != 0 { 151 t.Errorf("test value Got: %d, Want: 0", myMap["test"]) 152 } 153 if myMap["key"] != 1 { 154 t.Errorf("key value Got: %d, Want: 1", myMap["key"]) 155 } 156 if myMap["missing"] != 0 { 157 t.Errorf("missing value Got: %d, Want: 0", myMap["missing"]) 158 } 159 160 charm, found := myMap["charm"] 161 if charm != 2 { 162 t.Errorf("charm value Got: %d, Want: 2", charm) 163 } 164 if !found { 165 t.Error("charm should be found") 166 } 167 168 missing2, found := myMap["missing"] 169 if missing2 != 0 { 170 t.Errorf("missing value Got: %d, Want: 0", missing2) 171 } 172 if found { 173 t.Error("absent key should not be found") 174 } 175 176 delete(myMap, "missing") 177 if len(myMap) != 3 { 178 t.Errorf("len after noop delete Got: %d , Want: 3", len(myMap)) 179 } 180 181 delete(myMap, "charm") 182 if len(myMap) != 2 { 183 t.Errorf("len after delete Got: %d, Want: 2", len(myMap)) 184 } 185 186 myMap["add"] = 3 187 if len(myMap) != 3 { 188 t.Errorf("len after assign by key Got: %d, Want: 3", len(myMap)) 189 } 190 if myMap["add"] != 3 { 191 t.Errorf("add value Got: %d, Want: 3", myMap["add"]) 192 } 193 194 myMap["add"] = 10 195 if len(myMap) != 3 { 196 t.Errorf("len after update by key Got: %d, Want: 3", len(myMap)) 197 } 198 if myMap["add"] != 10 { 199 t.Errorf("add value Got: %d, Want: 10", myMap["add"]) 200 } 201 202 myMap2 := myMap 203 if len(myMap2) != len(myMap) { 204 t.Errorf("copy len Got: %d, Want: %d", len(myMap2), len(myMap)) 205 } 206 } 207 208 func containsInt(s []int, e int) bool { 209 for _, a := range s { 210 if a == e { 211 return true 212 } 213 } 214 return false 215 } 216 217 func containsString(s []string, e string) bool { 218 for _, a := range s { 219 if a == e { 220 return true 221 } 222 } 223 return false 224 } 225 226 // These benchmarks test various Map operations, and include a slice benchmark for reference. 227 const size = 10000 228 229 func makeMap(size int) map[int]string { 230 myMap := make(map[int]string, size) 231 for i := 0; i < size; i++ { 232 myMap[i] = "data" 233 } 234 235 return myMap 236 } 237 238 func makeSlice(size int) []int { 239 slice := make([]int, size) 240 for i := 0; i < size; i++ { 241 slice[i] = i 242 } 243 244 return slice 245 } 246 247 func BenchmarkSliceLen(b *testing.B) { 248 slice := makeSlice(size) 249 250 for i := 0; i < b.N; i++ { 251 if len(slice) > 0 { 252 } 253 } 254 } 255 256 func BenchmarkMapLen(b *testing.B) { 257 myMap := makeMap(size) 258 259 for i := 0; i < b.N; i++ { 260 if len(myMap) > 0 { 261 } 262 } 263 } 264 265 func BenchmarkMapNilCheck(b *testing.B) { 266 myMap := makeMap(size) 267 268 for i := 0; i < b.N; i++ { 269 if myMap != nil { 270 } 271 } 272 } 273 274 func BenchmarkMapNilElementCheck(b *testing.B) { 275 myMap := makeMap(size) 276 277 for i := 0; i < b.N; i++ { 278 if myMap[0] != "" { 279 } 280 } 281 } 282 283 func BenchmarkSliceRange(b *testing.B) { 284 slice := makeSlice(size) 285 286 for i := 0; i < b.N; i++ { 287 for range slice { 288 } 289 } 290 } 291 292 func BenchmarkMapRange(b *testing.B) { 293 myMap := makeMap(size) 294 295 for i := 0; i < b.N; i++ { 296 for range myMap { 297 } 298 } 299 }