github.com/onsi/gomega@v1.32.0/matchers/have_value.go (about) 1 package matchers 2 3 import ( 4 "errors" 5 "reflect" 6 7 "github.com/onsi/gomega/format" 8 "github.com/onsi/gomega/types" 9 ) 10 11 const maxIndirections = 31 12 13 type HaveValueMatcher struct { 14 Matcher types.GomegaMatcher // the matcher to apply to the "resolved" actual value. 15 resolvedActual interface{} // the ("resolved") value. 16 } 17 18 func (m *HaveValueMatcher) Match(actual interface{}) (bool, error) { 19 val := reflect.ValueOf(actual) 20 for allowedIndirs := maxIndirections; allowedIndirs > 0; allowedIndirs-- { 21 // return an error if value isn't valid. Please note that we cannot 22 // check for nil here, as we might not deal with a pointer or interface 23 // at this point. 24 if !val.IsValid() { 25 return false, errors.New(format.Message( 26 actual, "not to be <nil>")) 27 } 28 switch val.Kind() { 29 case reflect.Ptr, reflect.Interface: 30 // resolve pointers and interfaces to their values, then rinse and 31 // repeat. 32 if val.IsNil() { 33 return false, errors.New(format.Message( 34 actual, "not to be <nil>")) 35 } 36 val = val.Elem() 37 continue 38 default: 39 // forward the final value to the specified matcher. 40 m.resolvedActual = val.Interface() 41 return m.Matcher.Match(m.resolvedActual) 42 } 43 } 44 // too many indirections: extreme star gazing, indeed...? 45 return false, errors.New(format.Message(actual, "too many indirections")) 46 } 47 48 func (m *HaveValueMatcher) FailureMessage(_ interface{}) (message string) { 49 return m.Matcher.FailureMessage(m.resolvedActual) 50 } 51 52 func (m *HaveValueMatcher) NegatedFailureMessage(_ interface{}) (message string) { 53 return m.Matcher.NegatedFailureMessage(m.resolvedActual) 54 }