-
Notifications
You must be signed in to change notification settings - Fork 609
More info when do func has wrong signature #173
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
module github.com/golang/mock | ||
|
||
require golang.org/x/tools v0.0.0-20190425150028-36563e24a262 | ||
require ( | ||
github.com/pkg/errors v0.8.1 | ||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262 | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ package gomock | |
import ( | ||
"fmt" | ||
"reflect" | ||
"runtime" | ||
"strconv" | ||
"strings" | ||
) | ||
|
@@ -149,6 +150,27 @@ func (c *Call) Do(f interface{}) *Call { | |
vargs[i] = reflect.Zero(ft.In(i)) | ||
} | ||
} | ||
defer func() { | ||
if r := recover(); r != nil { | ||
errMsg, ok := r.(string) | ||
|
||
// We only handle a very specific panic | ||
// If it's not that one, then we "rethrow" the panic | ||
// This allows users to use functions that panic in their tests | ||
if !ok { | ||
panic(r) | ||
} | ||
if !strings.Contains(errMsg, "reflect: Call using") && | ||
!strings.Contains(errMsg, "reflect.Set: value of") { | ||
panic(r) | ||
} | ||
skipFrames := 8 | ||
stackTraceStr := "\n\n" + currentStackTrace(skipFrames) | ||
funcPC := v.Pointer() | ||
file, line := runtime.FuncForPC(funcPC).FileLine(funcPC) | ||
c.t.Fatalf("%s (incorrect func args at %s:%d?)%+v", errMsg, file, line, stackTraceStr) | ||
} | ||
}() | ||
v.Call(vargs) | ||
return nil | ||
}) | ||
|
@@ -239,6 +261,25 @@ func (c *Call) SetArg(n int, value interface{}) *Call { | |
case reflect.Slice: | ||
setSlice(args[n], v) | ||
default: | ||
defer func() { | ||
if r := recover(); r != nil { | ||
errMsg, ok := r.(string) | ||
|
||
// We only handle a very specific panic | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question as above. |
||
// If it's not that one, then we "rethrow" the panic | ||
// This allows users to use functions that panic in their tests | ||
if !ok { | ||
panic(r) | ||
} | ||
if !strings.Contains(errMsg, "reflect: Call using") && | ||
!strings.Contains(errMsg, "reflect.Set: value of") { | ||
panic(r) | ||
} | ||
skipFrames := 8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add some docs where |
||
stackTraceStr := "\n\n" + currentStackTrace(skipFrames) | ||
c.t.Fatalf("%s%+v", errMsg, stackTraceStr) | ||
} | ||
}() | ||
reflect.ValueOf(args[n]).Elem().Set(v) | ||
} | ||
return nil | ||
|
@@ -382,7 +423,7 @@ func (c *Call) matches(args []interface{}) error { | |
|
||
// Check that the call is not exhausted. | ||
if c.exhausted() { | ||
return fmt.Errorf("Expected call at %s has already been called the max number of times.", c.origin) | ||
return fmt.Errorf("Expected call at %s has already been called the max number of times (%d).", c.origin, c.maxCalls) | ||
} | ||
|
||
return nil | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package gomock | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
const skipFrames = 2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add some docs around this magic number? |
||
|
||
type stackTracer interface { | ||
StackTrace() errors.StackTrace | ||
} | ||
|
||
func stackTraceStringFromError(err error, skipFrames int) string { | ||
if err, ok := err.(stackTracer); ok { | ||
return stackTraceString(err.StackTrace(), skipFrames) | ||
} | ||
return "" | ||
} | ||
|
||
func currentStackTrace(skipFrames int) string { | ||
err := errors.New("fake error just to get stack") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use the |
||
if err, ok := err.(stackTracer); ok { | ||
return stackTraceString(err.StackTrace(), skipFrames) | ||
} | ||
return "" | ||
} | ||
|
||
func stackTraceString(stackTrace errors.StackTrace, skipFrames int) string { | ||
buffer := bytes.NewBufferString("") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: It doesn't look like we need to use the function |
||
for i := skipFrames + 1; i < len(stackTrace); i++ { | ||
frame := stackTrace[i] | ||
buffer.WriteString(fmt.Sprintf("%+v\n", frame)) | ||
filename := fmt.Sprintf("%s", frame) | ||
if strings.Contains(filename, "_test.go") { | ||
break | ||
} | ||
} | ||
return buffer.String() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you see a use case where a user might want to panic instead of failing the test?
If not, WDYTA letting
fmt.Sprint
do some work here (https://play.golang.org/p/SJh50xjMu_8) and allow more than just strings?