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 }