Skip to content

Commit 47522d3

Browse files
committed
refactor: refactor files.
1 parent c762ea8 commit 47522d3

File tree

10 files changed

+444
-442
lines changed

10 files changed

+444
-442
lines changed

equal.go renamed to compare.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package assert
22

33
import (
44
"fmt"
5+
"math"
56
"reflect"
67
"testing"
78
)
@@ -356,3 +357,114 @@ func tryNotTrue(t *testing.T, failedNow bool, val any, message ...any) error {
356357
message...,
357358
)
358359
}
360+
361+
// isEqual checks the equality of the values.
362+
func isEqual(x, y any) bool {
363+
if x == nil || y == nil {
364+
return x == y
365+
}
366+
367+
var v1, v2 reflect.Value
368+
if xv, ok := x.(reflect.Value); ok {
369+
v1 = xv
370+
} else {
371+
v1 = reflect.ValueOf(x)
372+
}
373+
if yv, ok := y.(reflect.Value); ok {
374+
v2 = yv
375+
} else {
376+
v2 = reflect.ValueOf(y)
377+
}
378+
379+
if isSame, isMixSign := isSameType(v1.Type(), v2.Type()); !isSame {
380+
if isMixSign {
381+
return isEqualForMixSignInt(v1, v2)
382+
}
383+
return false
384+
}
385+
386+
switch v1.Kind() {
387+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
388+
return v1.Int() == v2.Int()
389+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
390+
reflect.Uintptr:
391+
return v1.Uint() == v2.Uint()
392+
case reflect.Float32, reflect.Float64:
393+
return v1.Float() == v2.Float()
394+
case reflect.Complex64, reflect.Complex128:
395+
return v1.Complex() == v2.Complex()
396+
case reflect.String:
397+
return v1.String() == v2.String()
398+
case reflect.Slice:
399+
return isSliceEqual(v1, v2)
400+
default:
401+
return v1.Interface() == v2.Interface()
402+
}
403+
}
404+
405+
// isEqualForMixSignInt checks the equality of two integers one of an integer is signed, but
406+
// another one is unsigned.
407+
func isEqualForMixSignInt(v1, v2 reflect.Value) bool {
408+
intVal := v1
409+
uintVal := v2
410+
if v1.Kind() >= reflect.Uint && v1.Kind() <= reflect.Uintptr {
411+
intVal = v2
412+
uintVal = v1
413+
}
414+
415+
if intVal.Int() < 0 {
416+
return false
417+
} else if uintVal.Uint() > uint64(math.MaxInt64) {
418+
return false
419+
}
420+
421+
return intVal.Int() == int64(uintVal.Uint())
422+
}
423+
424+
// isNil checks whether a value is nil or not. It'll always return false if the value is not a
425+
// channel, a function, a map, a point, an unsafe point, an interface, or a slice.
426+
func isNil(val any) bool {
427+
if val == nil {
428+
return true
429+
}
430+
431+
v := reflect.ValueOf(val)
432+
433+
switch v.Kind() {
434+
case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.UnsafePointer,
435+
reflect.Interface, reflect.Slice:
436+
return v.IsNil()
437+
default:
438+
return false
439+
}
440+
}
441+
442+
// isTrue checks whether a value is truthy or not. It'll return true if the value is not the zero
443+
// value for its type. For a slice, a truthy value should not be the zero value and the length must
444+
// be greater than 0. For nil, it'll always return false.
445+
func isTrue(v any) bool {
446+
rv := reflect.ValueOf(v)
447+
448+
switch rv.Kind() {
449+
case reflect.Invalid:
450+
return false // always false
451+
case reflect.Slice:
452+
return v != nil && rv.Len() > 0
453+
default:
454+
return !rv.IsZero()
455+
}
456+
}
457+
458+
// isComparable gets the type of the value, and checks whether the type is comparable or not.
459+
func isComparable(v any) bool {
460+
switch v.(type) {
461+
case
462+
int, int8, int16, int32, int64, // Signed integer
463+
uint, uint8, uint16, uint32, uint64, uintptr, // Unsigned integer
464+
float32, float64, // Floating-point number
465+
string: // string
466+
return true
467+
default:
468+
return false
469+
}
470+
}

equal_test.go renamed to compare_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package assert
22

33
import (
4+
"math"
45
"testing"
56
)
67

@@ -226,3 +227,116 @@ func testTrueAndNotTrue(a, mockA *Assertion, v any, isTruthy bool) {
226227
mockA.NotTrueNow(v)
227228
}, isTruthy)
228229
}
230+
231+
func TestIsEqual(t *testing.T) {
232+
assert := New(t)
233+
234+
type testStruct1 struct {
235+
A int
236+
}
237+
type testStruct2 struct {
238+
A int
239+
}
240+
241+
var s1 *testStruct1
242+
243+
assert.Equal(isEqual(nil, nil), true)
244+
assert.Equal(isEqual(nil, s1), false) // s1 is nil
245+
assert.Equal(isEqual(true, false), false)
246+
assert.Equal(isEqual(1, 1), true)
247+
assert.Equal(isEqual(1, 2), false)
248+
assert.Equal(isEqual(1, int64(1)), true)
249+
assert.Equal(isEqual(1, int64(2)), false)
250+
assert.Equal(isEqual(uint(1), uint(1)), true)
251+
assert.Equal(isEqual(uint(1), uint(2)), false)
252+
assert.Equal(isEqual(uint(1), uint64(1)), true)
253+
assert.Equal(isEqual(uint(1), uint64(2)), false)
254+
assert.Equal(isEqual(uint(1), uintptr(1)), true)
255+
assert.Equal(isEqual(1.0, 1.0), true)
256+
assert.Equal(isEqual(1.0, 2.0), false)
257+
assert.Equal(isEqual(1.0, float32(1.0)), true)
258+
assert.Equal(isEqual(1.0, float32(2.0)), false)
259+
assert.Equal(isEqual(complex(1, 1), complex(1, 1)), true)
260+
assert.Equal(isEqual(complex(1, 1), complex(2, 2)), false)
261+
assert.Equal(isEqual(complex(1, 1), complex64(complex(1, 1))), true)
262+
assert.Equal(isEqual(complex(1, 1), complex64(complex(2, 2))), false)
263+
assert.Equal(isEqual([1]int{0}, [1]int{0}), true)
264+
assert.Equal(isEqual([1]int{0}, [1]int{1}), false)
265+
assert.Equal(isEqual([1]int{0}, [2]int{0, 0}), false)
266+
assert.Equal(isEqual([1]int{0}, [1]float64{0.0}), false)
267+
assert.Equal(isEqual("hello", "hello"), true)
268+
assert.Equal(isEqual("hello", "world"), false)
269+
270+
slice1 := []int{0}
271+
slice2 := []int{0}
272+
slice3 := []int{0, 0}
273+
slice4 := []int{1}
274+
slice5 := []float64{0.0}
275+
assert.Equal(isEqual(slice1, slice1), true)
276+
assert.Equal(isEqual(slice1, slice2), true)
277+
assert.Equal(isEqual(slice1, slice3), false)
278+
assert.Equal(isEqual(slice1, slice4), false)
279+
assert.Equal(isEqual(slice1, slice5), false)
280+
281+
assert.Equal(isEqual(testStruct1{A: 0}, testStruct1{A: 0}), true)
282+
assert.Equal(isEqual(testStruct1{A: 0}, testStruct1{A: 1}), false)
283+
assert.Equal(isEqual(s1, s1), true)
284+
assert.Equal(isEqual(&testStruct1{A: 0}, &testStruct1{A: 1}), false)
285+
assert.Equal(isEqual(testStruct1{A: 0}, testStruct2{A: 0}), false)
286+
}
287+
288+
func TestIsEqualOfMixSignInt(t *testing.T) {
289+
assert := New(t)
290+
291+
assert.True(isEqual(0, uint(0)))
292+
assert.True(isEqual(1, uint(1)))
293+
assert.True(isEqual(uint(1), 1))
294+
assert.True(isEqual(math.MaxInt64, uint64(math.MaxInt64)))
295+
assert.NotTrue(isEqual(-1, uint64(math.MaxUint64)))
296+
assert.NotTrue(isEqual(uint64(math.MaxUint64), -1))
297+
assert.NotTrue(isEqual(uint64(math.MaxUint64), 0))
298+
}
299+
300+
func TestIsNil(t *testing.T) {
301+
assert := New(t)
302+
303+
assert.NotTrue(isNil(1)) // int
304+
assert.NotTrue(isNil("")) // string
305+
assert.True(isNil(nil))
306+
var testAssert *Assertion
307+
assert.True(isNil(testAssert))
308+
assert.NotTrue(isNil(assert))
309+
}
310+
311+
func TestIsTrue(t *testing.T) {
312+
assert := New(t)
313+
314+
// reflect.Invalid
315+
assert.NotTrue(isTrue(nil))
316+
317+
// reflect.Slice
318+
assert.True(isTrue([]int{0}))
319+
assert.NotTrue(isTrue([]int{}))
320+
321+
// other kinds
322+
assert.True(isTrue(1))
323+
assert.NotTrue(isTrue(0))
324+
assert.True(isTrue(1.0))
325+
assert.NotTrue(isTrue(0.0))
326+
assert.True(isTrue("Hello"))
327+
assert.NotTrue(isTrue(""))
328+
assert.True(isTrue(func() {}))
329+
}
330+
331+
func TestIsComparable(t *testing.T) {
332+
assert := New(t)
333+
334+
assert.Equal(isComparable(1), true)
335+
assert.Equal(isComparable(int64(1)), true)
336+
assert.Equal(isComparable(uint64(1)), true)
337+
assert.Equal(isComparable(float32(1.0)), true)
338+
assert.Equal(isComparable(1.0), true)
339+
assert.Equal(isComparable("Hello"), true)
340+
assert.Equal(isComparable([]byte{'H', 'e', 'l', 'l', 'o'}), false)
341+
assert.Equal(isComparable([]int{1, 2, 3}), false)
342+
}

map.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package assert
22

33
import (
44
"fmt"
5+
"reflect"
56
"testing"
67
)
78

@@ -186,3 +187,49 @@ func tryNotMapHasValue(
186187
message...,
187188
)
188189
}
190+
191+
// isMapHasValue checks whether the map contains the specified key or not.
192+
func isMapHasKey(m, k any) bool {
193+
if m == nil || reflect.TypeOf(m).Kind() != reflect.Map {
194+
return false
195+
}
196+
197+
mv := reflect.ValueOf(m)
198+
if mv.Len() == 0 {
199+
return false
200+
}
201+
202+
if !reflect.TypeOf(k).AssignableTo(mv.Type().Key()) {
203+
return false
204+
}
205+
206+
return mv.MapIndex(reflect.ValueOf(k)).Kind() != reflect.Invalid
207+
}
208+
209+
// isMapHasValue checks whether the map contains the specified value or not.
210+
func isMapHasValue(m, v any) bool {
211+
if m == nil || reflect.TypeOf(m).Kind() != reflect.Map {
212+
return false
213+
}
214+
215+
mv := reflect.ValueOf(m)
216+
if mv.Len() == 0 {
217+
return false
218+
}
219+
220+
if !reflect.TypeOf(v).AssignableTo(mv.Type().Elem()) {
221+
return false
222+
}
223+
224+
vv := reflect.ValueOf(v)
225+
iter := mv.MapRange()
226+
227+
for iter.Next() {
228+
mvv := iter.Value()
229+
if isEqual(mvv, vv.Convert(mvv.Type())) {
230+
return true
231+
}
232+
}
233+
234+
return false
235+
}

map_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,81 @@ func tesMapHasValueAndNotMapHasValue(
105105
mockA.NotMapHasValueNow(m, key)
106106
}, isHasValue)
107107
}
108+
109+
func TestIsMapHasKey(t *testing.T) {
110+
assert := New(t)
111+
112+
assert.NotTrue(isMapHasKey(nil, nil))
113+
assert.NotTrue(isMapHasKey(map[string]int{}, "a"))
114+
assert.True(isMapHasKey(map[string]int{
115+
"a": 1,
116+
"b": 2,
117+
}, "a"))
118+
assert.NotTrue(isMapHasKey(map[string]int{
119+
"a": 1,
120+
"b": 2,
121+
}, "c"))
122+
assert.NotTrue(isMapHasKey(map[string]int{
123+
"a": 1,
124+
"b": 2,
125+
}, 1))
126+
assert.True(isMapHasKey(map[any]int{
127+
"a": 1,
128+
1: 2,
129+
}, 1))
130+
assert.True(isMapHasKey(map[any]int{
131+
"a": 1,
132+
1: 2,
133+
}, "a"))
134+
assert.NotTrue(isMapHasKey(map[any]int{
135+
"a": 1,
136+
1: 2,
137+
}, 2))
138+
assert.NotTrue(isMapHasKey(map[any]int{
139+
"a": 1,
140+
1: 2,
141+
}, "b"))
142+
assert.NotTrue(isMapHasKey(map[any]int{
143+
"a": 1,
144+
1: 2,
145+
}, 1.1))
146+
}
147+
148+
func TestIsMapHasValue(t *testing.T) {
149+
assert := New(t)
150+
151+
assert.NotTrue(isMapHasValue(nil, nil))
152+
assert.NotTrue(isMapHasValue(map[string]int{}, 3))
153+
assert.True(isMapHasValue(map[string]int{
154+
"a": 1,
155+
"b": 2,
156+
}, 1))
157+
assert.NotTrue(isMapHasValue(map[string]int{
158+
"a": 1,
159+
"b": 2,
160+
}, 3))
161+
assert.NotTrue(isMapHasValue(map[string]int{
162+
"a": 1,
163+
"b": 2,
164+
}, true))
165+
assert.True(isMapHasValue(map[any]any{
166+
"a": "b",
167+
1: 2,
168+
}, "b"))
169+
assert.True(isMapHasValue(map[any]any{
170+
"a": "b",
171+
1: 2,
172+
}, 2))
173+
assert.NotTrue(isMapHasValue(map[any]any{
174+
"a": "b",
175+
1: 2,
176+
}, "a"))
177+
assert.NotTrue(isMapHasValue(map[any]any{
178+
"a": "b",
179+
1: 2,
180+
}, 1))
181+
assert.NotTrue(isMapHasValue(map[any]any{
182+
"a": "b",
183+
1: 2,
184+
}, 1.1))
185+
}

0 commit comments

Comments
 (0)