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