go-approval-tests
go-approval-tests copied to clipboard
bug: use CallerFrames to find the filename instead of traversing program counter
Regarding findFileName
Go runtime docs discourage traversing PC or FuncForPC on any returned PCs as they can't account for inlining or return program counter adjustment.
This sometimes returns the wrong file name.
Something like this would be a better alternative:
func findFileName() (*string, error) {
pc := make([]uintptr, 100)
count := runtime.Callers(0, pc)
frames := runtime.CallersFrames(pc[:count])
var lastFrame *runtime.Frame
var testFrame *runtime.Frame
for {
frame, more := frames.Next()
if !more {
break
}
if isTestRunnerFrame(&frame) {
testFrame = &frame
break
}
lastFrame = &frame
}
if !isTestRunnerFrame(testFrame) {
return nil, fmt.Errorf("approvals: could not find the test method")
}
return &lastFrame.File, nil
}
func isTestRunnerFrame(f *runtime.Frame) bool {
return f != nil && f.Function == "testing.tRunner" || f.Function == "testing.runExample"
}
What do you think?