...

Source file src/github.com/onsi/gomega/matchers/satisfy_matcher.go

Documentation: github.com/onsi/gomega/matchers

     1  package matchers
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/onsi/gomega/format"
     8  )
     9  
    10  type SatisfyMatcher struct {
    11  	Predicate interface{}
    12  
    13  	// cached type
    14  	predicateArgType reflect.Type
    15  }
    16  
    17  func NewSatisfyMatcher(predicate interface{}) *SatisfyMatcher {
    18  	if predicate == nil {
    19  		panic("predicate cannot be nil")
    20  	}
    21  	predicateType := reflect.TypeOf(predicate)
    22  	if predicateType.Kind() != reflect.Func {
    23  		panic("predicate must be a function")
    24  	}
    25  	if predicateType.NumIn() != 1 {
    26  		panic("predicate must have 1 argument")
    27  	}
    28  	if predicateType.NumOut() != 1 || predicateType.Out(0).Kind() != reflect.Bool {
    29  		panic("predicate must return bool")
    30  	}
    31  
    32  	return &SatisfyMatcher{
    33  		Predicate:        predicate,
    34  		predicateArgType: predicateType.In(0),
    35  	}
    36  }
    37  
    38  func (m *SatisfyMatcher) Match(actual interface{}) (success bool, err error) {
    39  	// prepare a parameter to pass to the predicate
    40  	var param reflect.Value
    41  	if actual != nil && reflect.TypeOf(actual).AssignableTo(m.predicateArgType) {
    42  		// The dynamic type of actual is compatible with the predicate argument.
    43  		param = reflect.ValueOf(actual)
    44  
    45  	} else if actual == nil && m.predicateArgType.Kind() == reflect.Interface {
    46  		// The dynamic type of actual is unknown, so there's no way to make its
    47  		// reflect.Value. Create a nil of the predicate argument, which is known.
    48  		param = reflect.Zero(m.predicateArgType)
    49  
    50  	} else {
    51  		return false, fmt.Errorf("predicate expects '%s' but we have '%T'", m.predicateArgType, actual)
    52  	}
    53  
    54  	// call the predicate with `actual`
    55  	fn := reflect.ValueOf(m.Predicate)
    56  	result := fn.Call([]reflect.Value{param})
    57  	return result[0].Bool(), nil
    58  }
    59  
    60  func (m *SatisfyMatcher) FailureMessage(actual interface{}) (message string) {
    61  	return format.Message(actual, "to satisfy predicate", m.Predicate)
    62  }
    63  
    64  func (m *SatisfyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
    65  	return format.Message(actual, "to not satisfy predicate", m.Predicate)
    66  }
    67  

View as plain text