...

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

Documentation: github.com/onsi/gomega/matchers

     1  package matchers
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"github.com/onsi/gomega/format"
     9  )
    10  
    11  type MatchErrorMatcher struct {
    12  	Expected           any
    13  	FuncErrDescription []any
    14  	isFunc             bool
    15  }
    16  
    17  func (matcher *MatchErrorMatcher) Match(actual any) (success bool, err error) {
    18  	matcher.isFunc = false
    19  
    20  	if isNil(actual) {
    21  		return false, fmt.Errorf("Expected an error, got nil")
    22  	}
    23  
    24  	if !isError(actual) {
    25  		return false, fmt.Errorf("Expected an error.  Got:\n%s", format.Object(actual, 1))
    26  	}
    27  
    28  	actualErr := actual.(error)
    29  	expected := matcher.Expected
    30  
    31  	if isError(expected) {
    32  		// first try the built-in errors.Is
    33  		if errors.Is(actualErr, expected.(error)) {
    34  			return true, nil
    35  		}
    36  		// if not, try DeepEqual along the error chain
    37  		for unwrapped := actualErr; unwrapped != nil; unwrapped = errors.Unwrap(unwrapped) {
    38  			if reflect.DeepEqual(unwrapped, expected) {
    39  				return true, nil
    40  			}
    41  		}
    42  		return false, nil
    43  	}
    44  
    45  	if isString(expected) {
    46  		return actualErr.Error() == expected, nil
    47  	}
    48  
    49  	v := reflect.ValueOf(expected)
    50  	t := v.Type()
    51  	errorInterface := reflect.TypeOf((*error)(nil)).Elem()
    52  	if t.Kind() == reflect.Func && t.NumIn() == 1 && t.In(0).Implements(errorInterface) && t.NumOut() == 1 && t.Out(0).Kind() == reflect.Bool {
    53  		if len(matcher.FuncErrDescription) == 0 {
    54  			return false, fmt.Errorf("MatchError requires an additional description when passed a function")
    55  		}
    56  		matcher.isFunc = true
    57  		return v.Call([]reflect.Value{reflect.ValueOf(actualErr)})[0].Bool(), nil
    58  	}
    59  
    60  	var subMatcher omegaMatcher
    61  	var hasSubMatcher bool
    62  	if expected != nil {
    63  		subMatcher, hasSubMatcher = (expected).(omegaMatcher)
    64  		if hasSubMatcher {
    65  			return subMatcher.Match(actualErr.Error())
    66  		}
    67  	}
    68  
    69  	return false, fmt.Errorf(
    70  		"MatchError must be passed an error, a string, or a Matcher that can match on strings. Got:\n%s",
    71  		format.Object(expected, 1))
    72  }
    73  
    74  func (matcher *MatchErrorMatcher) FailureMessage(actual interface{}) (message string) {
    75  	if matcher.isFunc {
    76  		return format.Message(actual, fmt.Sprintf("to match error function %s", matcher.FuncErrDescription[0]))
    77  	}
    78  	return format.Message(actual, "to match error", matcher.Expected)
    79  }
    80  
    81  func (matcher *MatchErrorMatcher) NegatedFailureMessage(actual interface{}) (message string) {
    82  	if matcher.isFunc {
    83  		return format.Message(actual, fmt.Sprintf("not to match error function %s", matcher.FuncErrDescription[0]))
    84  	}
    85  	return format.Message(actual, "not to match error", matcher.Expected)
    86  }
    87  

View as plain text