func (parent *scope) exit() { if problem := recover(); problem != nil { if strings.HasPrefix(fmt.Sprintf("%v", problem), extraGoTest) { panic(problem) } parent.panicked = true parent.reporter.Report(reporting.NewErrorReport(problem)) } parent.reporter.Exit() }
// conveyInner is the function which actually executes the user's anonymous test // function body. At this point, Convey or RootConvey has decided that this // function should actually run. func (ctx *context) conveyInner(situation string, f func(C)) { // Record/Reset state for next time. defer func() { ctx.executedOnce = true // This is only needed at the leaves, but there's no harm in also setting it // when returning from branch Convey's *ctx.expectChildRun = false }() // Set up+tear down our scope for the reporter ctx.reporter.Enter(reporting.NewScopeReport(situation)) defer ctx.reporter.Exit() // Recover from any panics in f, and assign the `complete` status for this // node of the tree. defer func() { ctx.complete = true if problem := recover(); problem != nil { if problem, ok := problem.(*conveyErr); ok { panic(problem) } if problem != failureHalt { ctx.reporter.Report(reporting.NewErrorReport(problem)) } } else { for _, child := range ctx.children { if !child.complete { ctx.complete = false return } } } }() // Resets are registered as the `f` function executes, so nil them here. // All resets are run in registration order (FIFO). ctx.resets = []func(){} defer func() { for _, r := range ctx.resets { // panics handled by the previous defer r() } }() if f == nil { // if f is nil, this was either a Convey(..., nil), or a SkipConvey ctx.reporter.Report(reporting.NewSkipReport()) } else { f(ctx) } }