-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmap.go
More file actions
243 lines (208 loc) · 7.11 KB
/
Copy pathmap.go
File metadata and controls
243 lines (208 loc) · 7.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
package assert
import (
"fmt"
"reflect"
"testing"
)
// MapHasKey tests whether the map contains the specified key or not, it will fail if the map does
// not contain the key, or the type of the key cannot assign to the type of the key of the map.
//
// a := assert.New(t)
// a.MapHasKey(map[string]int{"a":1}, "a") // success
// a.MapHasKey(map[string]int{"a":1}, "b") // fail
// a.MapHasKey(map[string]int{"a":1}, 1) // fail
func (a *Assertion) MapHasKey(m, key any, message ...any) error {
a.Helper()
return tryMapHasKey(a.T, false, m, key, message...)
}
// MapHasKeyNow tests whether the map contains the specified key or not, and it will terminate the
// execution if the test fails. It will fail if the map does not contain the key, or the type of
// the key cannot assign to the type of the key of the map.
//
// a := assert.New(t)
// a.MapHasKeyNow(map[string]int{"a":1}, "a") // success
// a.MapHasKeyNow(map[string]int{"a":1}, "b") // fail and terminate
// // never run
func (a *Assertion) MapHasKeyNow(m, key any, message ...any) error {
a.Helper()
return tryMapHasKey(a.T, true, m, key, message...)
}
// NotMapHasKey tests whether the map contains the specified key or not, it will fail if the map
// contain the key. It will also set the test result to success if the type of the key cannot
// assign to the type of the key of the map.
//
// a := assert.New(t)
// a.NotMapHasKey(map[string]int{"a":1}, "b") // success
// a.NotMapHasKey(map[string]int{"a":1}, 1) // success
// a.NotMapHasKey(map[string]int{"a":1}, "a") // fail
func (a *Assertion) NotMapHasKey(m, key any, message ...any) error {
a.Helper()
return tryNotMapHasKey(a.T, false, m, key, message...)
}
// NotMapHasKeyNow tests whether the map contains the specified key or not, it will fail if the map
// contain the key, and it will terminate the execution if the test fails. It will also set the
// test result to success if the type of the key cannot assign to the type of the key of the map.
//
// a := assert.New(t)
// a.NotMapHasKeyNow(map[string]int{"a":1}, "b") // success
// a.NotMapHasKeyNow(map[string]int{"a":1}, 1) // success
// a.NotMapHasKeyNow(map[string]int{"a":1}, "a") // fail and terminate
// // never run
func (a *Assertion) NotMapHasKeyNow(m, key any, message ...any) error {
a.Helper()
return tryNotMapHasKey(a.T, true, m, key, message...)
}
// tryMapHasKey tries to test whether the map contains the specified key or not, and it'll fail if
// the map does not contains the specified key.
func tryMapHasKey(
t *testing.T,
failedNow bool,
m, key any,
message ...any,
) error {
t.Helper()
return test(
t,
func() bool { return isMapHasKey(m, key) },
failedNow,
fmt.Sprintf(defaultErrMessageMapHasKey, key),
message...,
)
}
// tryNotMapHasKey tries to test whether the map contains the specified key or not, and it'll fail
// if the map contains the specified key.
func tryNotMapHasKey(
t *testing.T,
failedNow bool,
m, key any,
message ...any,
) error {
t.Helper()
return test(
t,
func() bool { return !isMapHasKey(m, key) },
failedNow,
fmt.Sprintf(defaultErrMessageNotMapHasKey, key),
message...,
)
}
// MapHasValue tests whether the map contains the specified value or not, it will fail if the map
// does not contain the value, or the type of the value cannot assign to the type of the values of
// the map.
//
// a := assert.New(t)
// a.MapHasValue(map[string]int{"a":1}, 1) // success
// a.MapHasValue(map[string]int{"a":1}, 2) // fail
// a.MapHasValue(map[string]int{"a":1}, "a") // fail
func (a *Assertion) MapHasValue(m, value any, message ...any) error {
a.Helper()
return tryMapHasValue(a.T, false, m, value, message...)
}
// MapHasValueNow tests whether the map contains the specified value or not, and it will terminate
// the execution if the test fails. It will fail if the map does not contain the value, or the type
// of the value cannot assign to the type of the value of the map.
//
// a := assert.New(t)
// a.MapHasValueNow(map[string]int{"a":1}, 1) // success
// a.MapHasValueNow(map[string]int{"a":1}, 2) // fail and terminate
// // never run
func (a *Assertion) MapHasValueNow(m, value any, message ...any) error {
a.Helper()
return tryMapHasValue(a.T, true, m, value, message...)
}
// NotMapHasValue tests whether the map contains the specified value or not, it will fail if the
// map contain the value. It will also set the test result to success if the type of the value
// cannot assign to the type of the value of the map.
//
// a := assert.New(t)
// a.NotMapHasValue(map[string]int{"a":1}, 2) // success
// a.NotMapHasValue(map[string]int{"a":1}, "a") // success
// a.NotMapHasValue(map[string]int{"a":1}, 1) // fail
func (a *Assertion) NotMapHasValue(m, value any, message ...any) error {
a.Helper()
return tryNotMapHasValue(a.T, false, m, value, message...)
}
// NotMapHasValueNow tests whether the map contains the specified value or not, it will fail if the
// map contain the value, and it will terminate the execution if the test fails. It will also set
// the test result to success if the type of the value cannot assign to the type of the value of
// the map.
//
// a := assert.New(t)
// a.NotMapHasValueNow(map[string]int{"a":1}, 2) // success
// a.NotMapHasValueNow(map[string]int{"a":1}, "a") // success
// a.NotMapHasValueNow(map[string]int{"a":1}, 1) // fail and terminate
// // never run
func (a *Assertion) NotMapHasValueNow(m, value any, message ...any) error {
a.Helper()
return tryNotMapHasValue(a.T, true, m, value, message...)
}
// tryMapHasValue tries to test whether the map contains the specified value or not, and it'll fail
// if the map does not contains the specified value.
func tryMapHasValue(
t *testing.T,
failedNow bool,
m, value any,
message ...any,
) error {
t.Helper()
return test(
t,
func() bool { return isMapHasValue(m, value) },
failedNow,
fmt.Sprintf(defaultErrMessageMapHasValue, value),
message...,
)
}
// tryNotMapHasValue tries to test whether the map contains the specified value or not, and it'll
// fail if the map contains the specified value.
func tryNotMapHasValue(
t *testing.T,
failedNow bool,
m, value any,
message ...any,
) error {
t.Helper()
return test(
t,
func() bool { return !isMapHasValue(m, value) },
failedNow,
fmt.Sprintf(defaultErrMessageNotMapHasValue, value),
message...,
)
}
// isMapHasValue checks whether the map contains the specified key or not.
func isMapHasKey(m, k any) bool {
if m == nil || reflect.TypeOf(m).Kind() != reflect.Map {
return false
}
mv := reflect.ValueOf(m)
if mv.Len() == 0 {
return false
}
if !reflect.TypeOf(k).AssignableTo(mv.Type().Key()) {
return false
}
return mv.MapIndex(reflect.ValueOf(k)).Kind() != reflect.Invalid
}
// isMapHasValue checks whether the map contains the specified value or not.
func isMapHasValue(m, v any) bool {
if m == nil || reflect.TypeOf(m).Kind() != reflect.Map {
return false
}
mv := reflect.ValueOf(m)
if mv.Len() == 0 {
return false
}
if !reflect.TypeOf(v).AssignableTo(mv.Type().Elem()) {
return false
}
vv := reflect.ValueOf(v)
iter := mv.MapRange()
for iter.Next() {
mvv := iter.Value()
if isEqual(mvv, vv.Convert(mvv.Type())) {
return true
}
}
return false
}