github.com/petergtz/pegomock@v2.9.1-0.20230424204322-eb0e044013df+incompatible/panic_with_message_matcher_test.go (about)

     1  package pegomock_test
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/onsi/gomega/format"
     8  	"github.com/onsi/gomega/types"
     9  	"github.com/petergtz/pegomock/internal/verify"
    10  )
    11  
    12  type PanicWithMatcher struct {
    13  	expectedWith interface{}
    14  	actualWith   interface{}
    15  }
    16  
    17  func PanicWith(object interface{}) types.GomegaMatcher {
    18  	verify.Argument(object != nil, "You must provide a non-nil object to PanicWith")
    19  	return &PanicWithMatcher{expectedWith: object}
    20  }
    21  
    22  func (matcher *PanicWithMatcher) Match(actual interface{}) (success bool, err error) {
    23  	if actual == nil {
    24  		return false, fmt.Errorf("PanicWithMatcher expects a non-nil actual.")
    25  	}
    26  
    27  	actualType := reflect.TypeOf(actual)
    28  	if actualType.Kind() != reflect.Func {
    29  		return false, fmt.Errorf("PanicWithMatcher expects a function.  Got:\n%s", format.Object(actual, 1))
    30  	}
    31  	if !(actualType.NumIn() == 0 && actualType.NumOut() == 0) {
    32  		return false, fmt.Errorf("PanicWithMatcher expects a function with no arguments and no return value.  Got:\n%s", format.Object(actual, 1))
    33  	}
    34  
    35  	success = false
    36  	defer func() {
    37  		if object := recover(); object == matcher.expectedWith {
    38  			success = true
    39  		} else {
    40  			matcher.actualWith = object
    41  		}
    42  	}()
    43  
    44  	reflect.ValueOf(actual).Call([]reflect.Value{})
    45  
    46  	return
    47  }
    48  
    49  func (matcher *PanicWithMatcher) FailureMessage(actual interface{}) (message string) {
    50  	if matcher.actualWith == "" {
    51  		return format.Message(actual, "to panic")
    52  	} else {
    53  		// TODO: can we reuse format.Message somehow?
    54  		return fmt.Sprintf("Expected\n\t<func ()>: %v\n\tpanicking with <%T>: %v\n\nto panic with\n\t<%T>: %v",
    55  			actual, matcher.actualWith, matcher.actualWith, matcher.expectedWith, matcher.expectedWith)
    56  	}
    57  }
    58  
    59  func (matcher *PanicWithMatcher) NegatedFailureMessage(actual interface{}) (message string) {
    60  	if matcher.actualWith == "" {
    61  		return format.Message(actual, "not to panic")
    62  	} else {
    63  		return fmt.Sprintf("Expected\n\t<func ()>: %v\n\tpanicking with <%T>: %v\n\nnot to panic with\n\t<%T>: %v",
    64  			actual, matcher.actualWith, matcher.actualWith, matcher.expectedWith, matcher.expectedWith)
    65  	}
    66  
    67  }