...

Source file src/gotest.tools/v3/x/subtest/context.go

Documentation: gotest.tools/v3/x/subtest

     1  /*
     2  Package subtest provides a TestContext to subtests which handles cleanup, and
     3  provides a testing.TB, and context.Context.
     4  
     5  This package was inspired by github.com/frankban/quicktest.
     6  
     7  # DEPRECATED
     8  
     9  With the addition of T.Cleanup() in go1.14 this package provides very
    10  little value. A context.Context can be managed by tests that need it with
    11  little enough boilerplate that it doesn't make sense to wrap testing.T in a
    12  TestContext.
    13  */
    14  package subtest // import "gotest.tools/v3/x/subtest"
    15  
    16  import (
    17  	"context"
    18  	"testing"
    19  
    20  	"gotest.tools/v3/internal/cleanup"
    21  )
    22  
    23  type testcase struct {
    24  	testing.TB
    25  	ctx          context.Context
    26  	cleanupFuncs []cleanupFunc
    27  }
    28  
    29  type cleanupFunc func()
    30  
    31  func (tc *testcase) Ctx() context.Context {
    32  	if tc.ctx == nil {
    33  		var cancel func()
    34  		tc.ctx, cancel = context.WithCancel(context.Background())
    35  		cleanup.Cleanup(tc, cancel)
    36  	}
    37  	return tc.ctx
    38  }
    39  
    40  // cleanup runs all cleanup functions. Functions are run in the opposite order
    41  // in which they were added. Cleanup is called automatically before Run exits.
    42  func (tc *testcase) cleanup() {
    43  	for _, f := range tc.cleanupFuncs {
    44  		// Defer all cleanup functions so they all run even if one calls
    45  		// t.FailNow() or panics. Deferring them also runs them in reverse order.
    46  		defer f()
    47  	}
    48  	tc.cleanupFuncs = nil
    49  }
    50  
    51  func (tc *testcase) AddCleanup(f func()) {
    52  	tc.cleanupFuncs = append(tc.cleanupFuncs, f)
    53  }
    54  
    55  func (tc *testcase) Parallel() {
    56  	tp, ok := tc.TB.(parallel)
    57  	if !ok {
    58  		panic("Parallel called with a testing.B")
    59  	}
    60  	tp.Parallel()
    61  }
    62  
    63  type parallel interface {
    64  	Parallel()
    65  }
    66  
    67  // Run a subtest. When subtest exits, every cleanup function added with
    68  // TestContext.AddCleanup will be run.
    69  func Run(t *testing.T, name string, subtest func(t TestContext)) bool {
    70  	return t.Run(name, func(t *testing.T) {
    71  		tc := &testcase{TB: t}
    72  		defer tc.cleanup()
    73  		subtest(tc)
    74  	})
    75  }
    76  
    77  // TestContext provides a testing.TB and a context.Context for a test case.
    78  type TestContext interface {
    79  	testing.TB
    80  	// AddCleanup function which will be run when before Run returns.
    81  	//
    82  	// Deprecated: Go 1.14+ now includes a testing.TB.Cleanup(func()) which
    83  	// should be used instead. AddCleanup will be removed in a future release.
    84  	AddCleanup(f func())
    85  	// Ctx returns a context for the test case. Multiple calls from the same subtest
    86  	// will return the same context. The context is cancelled when Run
    87  	// returns.
    88  	Ctx() context.Context
    89  	// Parallel calls t.Parallel on the testing.TB. Panics if testing.TB does
    90  	// not implement Parallel.
    91  	Parallel()
    92  }
    93  
    94  var _ TestContext = &testcase{}
    95  

View as plain text