-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinternal.go
More file actions
138 lines (113 loc) · 2.72 KB
/
internal.go
File metadata and controls
138 lines (113 loc) · 2.72 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
package assert
import (
"fmt"
"math"
"reflect"
"strings"
)
func equal[T Comparable](actual, expected T) bool {
return reflect.DeepEqual(actual, expected)
}
func equalDelta[T Numeric](actual, expected, delta T) bool {
if delta < 0 {
panic("delta must be positive")
}
if expected == actual {
return true
}
actualFloat := float64(actual)
expectedFloat := float64(expected)
if math.IsNaN(actualFloat) && math.IsNaN(expectedFloat) {
return true
} else if math.IsNaN(actualFloat) || math.IsNaN(expectedFloat) {
return false
}
diff := expectedFloat - actualFloat
deltaFloat := float64(delta)
if diff < -deltaFloat || diff > deltaFloat {
return false
}
return true
}
func same[T Reference](actual, expected T) (valid bool, ok bool) {
valueOfActual := reflect.ValueOf(actual)
valueOfExpected := reflect.ValueOf(expected)
switch valueOfActual.Kind() {
case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func:
return valueOfActual.Pointer() == valueOfExpected.Pointer(), true
default:
return false, false
}
}
func length[S Iterable[any]](object S) int {
return reflect.ValueOf(object).Len()
}
func contains[S Iterable[E], E Comparable](object S, element E) (found bool, ok bool) {
valueOf := reflect.ValueOf(object)
typeOf := reflect.TypeOf(object)
if typeOf == nil {
return false, false
}
kind := typeOf.Kind()
if kind == reflect.String {
elementValue := reflect.ValueOf(element)
return strings.Contains(valueOf.String(), elementValue.String()), true
}
if kind == reflect.Map {
for _, key := range valueOf.MapKeys() {
value, valid := valueOf.MapIndex(key).Interface().(E)
if !valid {
return false, false
}
if equal(value, element) {
return true, true
}
}
return false, true
}
for i := 0; i < valueOf.Len(); i++ {
value, valid := valueOf.Index(i).Interface().(E)
if !valid {
return false, false
}
if equal(value, element) {
return true, true
}
}
return false, true
}
func panics(fn func()) (panicked bool, value any) {
defer func() {
if r := recover(); r != nil {
panicked = true
value = r
}
}()
fn()
return false, nil
}
func isNilError(err error) bool {
if err == nil {
return true
}
val := reflect.ValueOf(err)
switch val.Kind() {
case reflect.Ptr, reflect.Interface:
return val.IsNil()
}
return false
}
func message(message []string) string {
return strings.Join(message, "")
}
func print(object any) string {
valueOf := reflect.ValueOf(object)
switch valueOf.Kind() {
case reflect.Pointer:
return fmt.Sprintf("[%p] %#v", object, valueOf.Elem().Interface())
case reflect.Slice, reflect.Map, reflect.Chan, reflect.Func:
return fmt.Sprintf("[%[1]p] %#[1]v", object)
default:
return fmt.Sprintf("%#v", object)
}
}