github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/maps/maps_test.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package maps 6 7 import ( 8 "math" 9 "slices" 10 "sort" 11 "strconv" 12 "testing" 13 ) 14 15 var m1 = map[int]int{1: 2, 2: 4, 4: 8, 8: 16} 16 var m2 = map[int]string{1: "2", 2: "4", 4: "8", 8: "16"} 17 18 func TestKeys(t *testing.T) { 19 want := []int{1, 2, 4, 8} 20 21 got1 := Keys(m1) 22 sort.Ints(got1) 23 if !slices.Equal(got1, want) { 24 t.Errorf("Keys(%v) = %v, want %v", m1, got1, want) 25 } 26 27 got2 := Keys(m2) 28 sort.Ints(got2) 29 if !slices.Equal(got2, want) { 30 t.Errorf("Keys(%v) = %v, want %v", m2, got2, want) 31 } 32 } 33 34 func TestValues(t *testing.T) { 35 got1 := Values(m1) 36 want1 := []int{2, 4, 8, 16} 37 sort.Ints(got1) 38 if !slices.Equal(got1, want1) { 39 t.Errorf("Values(%v) = %v, want %v", m1, got1, want1) 40 } 41 42 got2 := Values(m2) 43 want2 := []string{"16", "2", "4", "8"} 44 sort.Strings(got2) 45 if !slices.Equal(got2, want2) { 46 t.Errorf("Values(%v) = %v, want %v", m2, got2, want2) 47 } 48 } 49 50 func TestEqual(t *testing.T) { 51 if !Equal(m1, m1) { 52 t.Errorf("Equal(%v, %v) = false, want true", m1, m1) 53 } 54 if Equal(m1, (map[int]int)(nil)) { 55 t.Errorf("Equal(%v, nil) = true, want false", m1) 56 } 57 if Equal((map[int]int)(nil), m1) { 58 t.Errorf("Equal(nil, %v) = true, want false", m1) 59 } 60 if !Equal[map[int]int, map[int]int](nil, nil) { 61 t.Error("Equal(nil, nil) = false, want true") 62 } 63 if ms := map[int]int{1: 2}; Equal(m1, ms) { 64 t.Errorf("Equal(%v, %v) = true, want false", m1, ms) 65 } 66 67 // Comparing NaN for equality is expected to fail. 68 mf := map[int]float64{1: 0, 2: math.NaN()} 69 if Equal(mf, mf) { 70 t.Errorf("Equal(%v, %v) = true, want false", mf, mf) 71 } 72 } 73 74 // equal is simply ==. 75 func equal[T comparable](v1, v2 T) bool { 76 return v1 == v2 77 } 78 79 // equalNaN is like == except that all NaNs are equal. 80 func equalNaN[T comparable](v1, v2 T) bool { 81 isNaN := func(f T) bool { return f != f } 82 return v1 == v2 || (isNaN(v1) && isNaN(v2)) 83 } 84 85 // equalStr compares ints and strings. 86 func equalIntStr(v1 int, v2 string) bool { 87 return strconv.Itoa(v1) == v2 88 } 89 90 func TestEqualFunc(t *testing.T) { 91 if !EqualFunc(m1, m1, equal[int]) { 92 t.Errorf("EqualFunc(%v, %v, equal) = false, want true", m1, m1) 93 } 94 if EqualFunc(m1, (map[int]int)(nil), equal[int]) { 95 t.Errorf("EqualFunc(%v, nil, equal) = true, want false", m1) 96 } 97 if EqualFunc((map[int]int)(nil), m1, equal[int]) { 98 t.Errorf("EqualFunc(nil, %v, equal) = true, want false", m1) 99 } 100 if !EqualFunc[map[int]int, map[int]int](nil, nil, equal[int]) { 101 t.Error("EqualFunc(nil, nil, equal) = false, want true") 102 } 103 if ms := map[int]int{1: 2}; EqualFunc(m1, ms, equal[int]) { 104 t.Errorf("EqualFunc(%v, %v, equal) = true, want false", m1, ms) 105 } 106 107 // Comparing NaN for equality is expected to fail. 108 mf := map[int]float64{1: 0, 2: math.NaN()} 109 if EqualFunc(mf, mf, equal[float64]) { 110 t.Errorf("EqualFunc(%v, %v, equal) = true, want false", mf, mf) 111 } 112 // But it should succeed using equalNaN. 113 if !EqualFunc(mf, mf, equalNaN[float64]) { 114 t.Errorf("EqualFunc(%v, %v, equalNaN) = false, want true", mf, mf) 115 } 116 117 if !EqualFunc(m1, m2, equalIntStr) { 118 t.Errorf("EqualFunc(%v, %v, equalIntStr) = false, want true", m1, m2) 119 } 120 } 121 122 func TestClone(t *testing.T) { 123 mc := Clone(m1) 124 if !Equal(mc, m1) { 125 t.Errorf("Clone(%v) = %v, want %v", m1, mc, m1) 126 } 127 mc[16] = 32 128 if Equal(mc, m1) { 129 t.Errorf("Equal(%v, %v) = true, want false", mc, m1) 130 } 131 } 132 133 func TestCloneNil(t *testing.T) { 134 var m1 map[string]int 135 mc := Clone(m1) 136 if mc != nil { 137 t.Errorf("Clone(%v) = %v, want %v", m1, mc, m1) 138 } 139 } 140 141 func TestCopy(t *testing.T) { 142 mc := Clone(m1) 143 Copy(mc, mc) 144 if !Equal(mc, m1) { 145 t.Errorf("Copy(%v, %v) = %v, want %v", m1, m1, mc, m1) 146 } 147 Copy(mc, map[int]int{16: 32}) 148 want := map[int]int{1: 2, 2: 4, 4: 8, 8: 16, 16: 32} 149 if !Equal(mc, want) { 150 t.Errorf("Copy result = %v, want %v", mc, want) 151 } 152 153 type M1 map[int]bool 154 type M2 map[int]bool 155 Copy(make(M1), make(M2)) 156 } 157 158 func TestDeleteFunc(t *testing.T) { 159 mc := Clone(m1) 160 DeleteFunc(mc, func(int, int) bool { return false }) 161 if !Equal(mc, m1) { 162 t.Errorf("DeleteFunc(%v, true) = %v, want %v", m1, mc, m1) 163 } 164 DeleteFunc(mc, func(k, v int) bool { return k > 3 }) 165 want := map[int]int{1: 2, 2: 4} 166 if !Equal(mc, want) { 167 t.Errorf("DeleteFunc result = %v, want %v", mc, want) 168 } 169 } 170 171 var n map[int]int 172 173 func BenchmarkMapClone(b *testing.B) { 174 var m = make(map[int]int) 175 for i := 0; i < 1000000; i++ { 176 m[i] = i 177 } 178 b.ResetTimer() 179 for i := 0; i < b.N; i++ { 180 n = Clone(m) 181 } 182 } 183 184 func TestCloneWithDelete(t *testing.T) { 185 var m = make(map[int]int) 186 for i := 0; i < 32; i++ { 187 m[i] = i 188 } 189 for i := 8; i < 32; i++ { 190 delete(m, i) 191 } 192 m2 := Clone(m) 193 if len(m2) != 8 { 194 t.Errorf("len2(m2) = %d, want %d", len(m2), 8) 195 } 196 for i := 0; i < 8; i++ { 197 if m2[i] != m[i] { 198 t.Errorf("m2[%d] = %d, want %d", i, m2[i], m[i]) 199 } 200 } 201 } 202 203 func TestCloneWithMapAssign(t *testing.T) { 204 var m = make(map[int]int) 205 const N = 25 206 for i := 0; i < N; i++ { 207 m[i] = i 208 } 209 m2 := Clone(m) 210 if len(m2) != N { 211 t.Errorf("len2(m2) = %d, want %d", len(m2), N) 212 } 213 for i := 0; i < N; i++ { 214 if m2[i] != m[i] { 215 t.Errorf("m2[%d] = %d, want %d", i, m2[i], m[i]) 216 } 217 } 218 }