mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-23 14:50:24 +00:00
55 lines
1.6 KiB
Go
55 lines
1.6 KiB
Go
|
package matchers
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"reflect"
|
||
|
|
||
|
"github.com/onsi/gomega/format"
|
||
|
"github.com/onsi/gomega/types"
|
||
|
)
|
||
|
|
||
|
const maxIndirections = 31
|
||
|
|
||
|
type HaveValueMatcher struct {
|
||
|
Matcher types.GomegaMatcher // the matcher to apply to the "resolved" actual value.
|
||
|
resolvedActual interface{} // the ("resolved") value.
|
||
|
}
|
||
|
|
||
|
func (m *HaveValueMatcher) Match(actual interface{}) (bool, error) {
|
||
|
val := reflect.ValueOf(actual)
|
||
|
for allowedIndirs := maxIndirections; allowedIndirs > 0; allowedIndirs-- {
|
||
|
// return an error if value isn't valid. Please note that we cannot
|
||
|
// check for nil here, as we might not deal with a pointer or interface
|
||
|
// at this point.
|
||
|
if !val.IsValid() {
|
||
|
return false, errors.New(format.Message(
|
||
|
actual, "not to be <nil>"))
|
||
|
}
|
||
|
switch val.Kind() {
|
||
|
case reflect.Ptr, reflect.Interface:
|
||
|
// resolve pointers and interfaces to their values, then rinse and
|
||
|
// repeat.
|
||
|
if val.IsNil() {
|
||
|
return false, errors.New(format.Message(
|
||
|
actual, "not to be <nil>"))
|
||
|
}
|
||
|
val = val.Elem()
|
||
|
continue
|
||
|
default:
|
||
|
// forward the final value to the specified matcher.
|
||
|
m.resolvedActual = val.Interface()
|
||
|
return m.Matcher.Match(m.resolvedActual)
|
||
|
}
|
||
|
}
|
||
|
// too many indirections: extreme star gazing, indeed...?
|
||
|
return false, errors.New(format.Message(actual, "too many indirections"))
|
||
|
}
|
||
|
|
||
|
func (m *HaveValueMatcher) FailureMessage(_ interface{}) (message string) {
|
||
|
return m.Matcher.FailureMessage(m.resolvedActual)
|
||
|
}
|
||
|
|
||
|
func (m *HaveValueMatcher) NegatedFailureMessage(_ interface{}) (message string) {
|
||
|
return m.Matcher.NegatedFailureMessage(m.resolvedActual)
|
||
|
}
|