96 lines
1.7 KiB
Go
96 lines
1.7 KiB
Go
|
package assert
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
// Contains asserts that a contains b.
|
||
|
func Contains(t testing.TB, a any, b any) {
|
||
|
if contains(a, b) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
t.Errorf(`
|
||
|
file: %s
|
||
|
assert: Contains
|
||
|
container:%v
|
||
|
element: %v`, file(t), a, b)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// NotContains asserts that a doesn't contain b.
|
||
|
func NotContains(t testing.TB, a any, b any) {
|
||
|
if !contains(a, b) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
t.Errorf(`
|
||
|
file: %s
|
||
|
assert: NotContains
|
||
|
container:%v
|
||
|
element: %v`, file(t), a, b)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// contains returns whether container contains the given the element.
|
||
|
// It works with strings, maps and slices.
|
||
|
func contains(container any, element any) bool {
|
||
|
containerValue := reflect.ValueOf(container)
|
||
|
|
||
|
switch containerValue.Kind() {
|
||
|
case reflect.String:
|
||
|
elementValue := reflect.ValueOf(element)
|
||
|
return strings.Contains(containerValue.String(), elementValue.String())
|
||
|
|
||
|
case reflect.Map:
|
||
|
keys := containerValue.MapKeys()
|
||
|
|
||
|
for _, key := range keys {
|
||
|
if key.Interface() == element {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case reflect.Slice:
|
||
|
elementValue := reflect.ValueOf(element)
|
||
|
|
||
|
if elementValue.Kind() == reflect.Slice {
|
||
|
elementLength := elementValue.Len()
|
||
|
|
||
|
if elementLength == 0 {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
if elementLength > containerValue.Len() {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
matchingElements := 0
|
||
|
|
||
|
for i := 0; i < containerValue.Len(); i++ {
|
||
|
if containerValue.Index(i).Interface() == elementValue.Index(matchingElements).Interface() {
|
||
|
matchingElements++
|
||
|
} else {
|
||
|
matchingElements = 0
|
||
|
}
|
||
|
|
||
|
if matchingElements == elementLength {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for i := 0; i < containerValue.Len(); i++ {
|
||
|
if containerValue.Index(i).Interface() == element {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|