vendor.github.com.smarty.assertions.equal_method.go Maven / Gradle / Ivy
The newest version!
package assertions
import "reflect"
type equalityMethodSpecification struct{}
func (this equalityMethodSpecification) assertable(a, b any) bool {
if !bothAreSameType(a, b) {
return false
}
if !typeHasEqualMethod(a) {
return false
}
if !equalMethodReceivesSameTypeForComparison(a) {
return false
}
if !equalMethodReturnsBool(a) {
return false
}
return true
}
func bothAreSameType(a, b any) bool {
aType := reflect.TypeOf(a)
if aType == nil {
return false
}
if aType.Kind() == reflect.Ptr {
aType = aType.Elem()
}
bType := reflect.TypeOf(b)
return aType == bType
}
func typeHasEqualMethod(a any) bool {
aInstance := reflect.ValueOf(a)
equalMethod := aInstance.MethodByName("Equal")
return equalMethod != reflect.Value{}
}
func equalMethodReceivesSameTypeForComparison(a any) bool {
aType := reflect.TypeOf(a)
if aType.Kind() == reflect.Ptr {
aType = aType.Elem()
}
aInstance := reflect.ValueOf(a)
equalMethod := aInstance.MethodByName("Equal")
signature := equalMethod.Type()
return signature.NumIn() == 1 && signature.In(0) == aType
}
func equalMethodReturnsBool(a any) bool {
aInstance := reflect.ValueOf(a)
equalMethod := aInstance.MethodByName("Equal")
signature := equalMethod.Type()
return signature.NumOut() == 1 && signature.Out(0) == reflect.TypeOf(true)
}
func (this equalityMethodSpecification) passes(A, B any) bool {
a := reflect.ValueOf(A)
b := reflect.ValueOf(B)
return areEqual(a, b) && areEqual(b, a)
}
func areEqual(receiver reflect.Value, argument reflect.Value) bool {
equalMethod := receiver.MethodByName("Equal")
argumentList := []reflect.Value{argument}
result := equalMethod.Call(argumentList)
return result[0].Bool()
}