docs(godoc): improve godoc comments for all *T methods

This commit is contained in:
2021-11-22 03:07:18 +00:00
parent a892f8eea7
commit b5bae7b65d

130
t.go
View File

@@ -18,14 +18,20 @@ type TestingT interface {
Fatal(args ...interface{})
}
// T is a fake/mock implementation of testing.T. It records all actions
// performed via all methods on the testing.T interface, so they can be
// inspected and asserted.
// T is a fake/mock implementation of *testing.T. All methods available on
// *testing.T are available on *T with the exception of Run(), which has a
// slightly different func type.
//
// It is specifically intended for testing test helpers which accept a
// *testing.T or *testing.B, so you can verify that the helpers call Fatal(),
// Error(), etc, as they need.
// All method calls against *T are recorded, so they can be inspected and
// asserted later. To be able to pass in *testing.T or *mocktesting.T, functions
// will need to use an interface instead of *testing.T explicitly.
//
// For basic use cases, the testing.TB interface should suffice. For more
// advanced use cases, create a custom interface that exactly specifies the
// methods of *testing.T which are needed, and then freely pass *testing.T or
// *mocktesting.T.
type T struct {
// Settings - These fields control the behavior of T.
name string
abort bool
baseTempdir string
@@ -33,6 +39,7 @@ type T struct {
deadline time.Time
timeout bool
// State - Fields which record how T has been modified via method calls.
mux sync.RWMutex
skipped bool
failed int
@@ -179,47 +186,71 @@ func (t *T) internalError(err error) {
}
}
// Name returns the name given to the *T instance.
func (t *T) Name() string {
return t.name
}
// Name returns the time at which the *T instance is set to timeout. If no
// timeout is set, the bool return value is false, otherwise it is true.
func (t *T) Deadline() (time.Time, bool) {
return t.deadline, t.timeout
}
// Error logs the given args with Log(), and then calls Fail() to mark the *T
// instance as failed.
func (t *T) Error(args ...interface{}) {
t.Log(args...)
t.Fail()
}
// Errorf logs the given format and args with Logf(), and then calls Fail() to
// mark the *T instance as failed.
func (t *T) Errorf(format string, args ...interface{}) {
t.Logf(format, args...)
t.Fail()
}
// Fail marks the *T instance as having failed. You can check if the *T instance
// has been failed with Failed(), or how many times it has been failed with
// FailedCount().
func (t *T) Fail() {
t.failed++
}
// FailNow marks the *T instance as having failed, and also aborts the current
// goroutine with runtime.Goexit(). If the WithNoAbort() option was used when
// initializing the *T instance, runtime.Goexit() will not be called.
func (t *T) FailNow() {
t.Fail()
t.goexit()
}
// Failed returns true if the *T instance has been marked as failed.
func (t *T) Failed() bool {
return t.failed > 0
}
// Fatal logs the given args with Log(), and then calls FailNow() to fail the *T
// instance and abort the current goroutine.
//
// See FailNow() and WithNoAbort() for details about how abort works.
func (t *T) Fatal(args ...interface{}) {
t.Log(args...)
t.FailNow()
}
// Fatalf logs the given format and args with Logf(), and then calls FailNow()
// to fail the *T instance and abort the current goroutine.
//
// See FailNow() and WithNoAbort() for details about how abort works.
func (t *T) Fatalf(format string, args ...interface{}) {
t.Logf(format, args...)
t.FailNow()
}
// Log renders given args to a string with fmt.Sprintln() and stores the result
// in a string slice which can be accessed with Output().
func (t *T) Log(args ...interface{}) {
t.mux.Lock()
defer t.mux.Unlock()
@@ -227,6 +258,8 @@ func (t *T) Log(args ...interface{}) {
t.output = append(t.output, fmt.Sprintln(args...))
}
// Logf renders given format and args to a string with fmt.Sprintf() and stores
// the result in a string slice which can be accessed with Output().
func (t *T) Logf(format string, args ...interface{}) {
t.mux.Lock()
defer t.mux.Unlock()
@@ -237,29 +270,51 @@ func (t *T) Logf(format string, args ...interface{}) {
t.output = append(t.output, fmt.Sprintf(format, args...))
}
// Parallel marks the *T instance to indicate Parallel() has been called.
// Use Paralleled() to check if Parallel() has been called.
func (t *T) Parallel() {
t.parallel = true
}
// Skip logs the given args with Log(), and then uses SkipNow() to mark the *T
// instance as skipped and aborts the current goroutine.
//
// See SkipNow() for more details about aborting the current goroutine.
func (t *T) Skip(args ...interface{}) {
t.Log(args...)
t.SkipNow()
}
// Skipf logs the given format and args with Logf(), and then uses SkipNow() to
// mark the *T instance as skipped and aborts the current goroutine.
//
// See SkipNow() for more details about aborting the current goroutine.
func (t *T) Skipf(format string, args ...interface{}) {
t.Logf(format, args...)
t.SkipNow()
}
// SkipNow marks the *T instance as skipped, and then aborts the current
// goroutine with runtime.Goexit(). If the WithNoAbort() option was used when
// initializing the *T instance, runtime.Goexit() will not be called.
func (t *T) SkipNow() {
t.skipped = true
t.goexit()
}
// Skipped returns true if the *T instance has been marked as skipped, otherwise
// it returns false.
func (t *T) Skipped() bool {
return t.skipped
}
// Helper marks the function that is calling Helper() as a helper function.
// Within *T it simply stores a reference to the function.
//
// The list of functions which have called Helper() can be inspected with
// HelperNames(). The names are resolved using runtime.FuncForPC(), meaning they
// include the absolute Go package path to the function, along with the function
// name itself.
func (t *T) Helper() {
pc, _, _, ok := runtime.Caller(1)
if !ok {
@@ -274,6 +329,9 @@ func (t *T) Helper() {
t.helpers = append(t.helpers, fnName)
}
// Cleanup registers a cleanup function. *T does not run cleanup functions, it
// simply records them for the purpose of later inspection via CleanupFuncs() or
// CleanupNames().
func (t *T) Cleanup(f func()) {
t.mux.Lock()
defer t.mux.Unlock()
@@ -281,8 +339,23 @@ func (t *T) Cleanup(f func()) {
t.cleanups = append(t.cleanups, f)
}
// TempDir creates an actual temporary directory on the system using
// ioutil.TempDir(). This actually does perform a action, rather than just
// recording the fact the method was called list most other *T methods.
//
// This is because returning a string that is not the path to a real directory,
// would most likely be useless. Hence it does create a real temporary
// directory.
//
// It is important to note that the temporary directory is not cleaned up by
// mocktesting. But it is created via ioutil.TempDir(), so the operating system
// should eventually clean it up.
//
// A string slice of temporary directory paths created by calls to TempDir() can
// be accessed with TempDirs().
func (t *T) TempDir() string {
// Allow setting MkdirTemp function for testing purposes.
// Allow setting MkdirTemp function for the purpose of testing mocktesting
// itself..
f := t.mkdirTempFunc
if f == nil {
f = ioutil.TempDir
@@ -301,6 +374,22 @@ func (t *T) TempDir() string {
return dir
}
// Run allows running sub-tests just very much like *testing.T. The one
// difference is that the function argument accepts a testing.TB instead of
// *testing.T type. This is to allow passing a *mocktesting.T to the sub-test
// function instead of a *testing.T.
//
// Sub-test functions are executed in a separate blocking goroutine, so calls to
// SkipNow() and FailNow() abort the new goroutine that the sub-test is running
// in, rather than the gorouting which is executing Run().
//
// The sub-test function will receive a new instance of *T which is a sub-test,
// which name and other attributes set accordingly.
//
// If any sub-test *T is marked as failed, the parent *T instance will also
// be marked as failed.
//
// The list of sub-test *T instances can be accessed with Subtests().
func (t *T) Run(name string, f func(testing.TB)) bool {
name = t.newSubTestName(name)
fullname := name
@@ -357,8 +446,8 @@ func (t *T) newSubTestName(name string) string {
// Inspection Methods which are not part of the testing.TB interface.
//
// Output returns a string slice of all output produced by calls to Log(),
// Logf(), Error(), Errorf(), Fatal(), Fatalf(), Skip(), and Skipf().
// Output returns a string slice of all output produced by calls to Log() and
// Logf().
func (t *T) Output() []string {
t.mux.RLock()
defer t.mux.RUnlock()
@@ -374,7 +463,10 @@ func (t *T) CleanupFuncs() []func() {
return t.cleanups
}
// CleanupNames returns a string slice of function names given to Cleanup().
// CleanupNames returns a string slice of function names given to Cleanup(). The
// names are resolved using runtime.FuncForPC(), meaning they include the
// absolute Go package path to the function, along with the function name
// itself.
func (t *T) CleanupNames() []string {
r := make([]string, 0, len(t.cleanups))
for _, f := range t.cleanups {
@@ -385,19 +477,25 @@ func (t *T) CleanupNames() []string {
return r
}
// FailedCount returns the number of times Error(), Errorf(), Fail(), Failf(),
// FailNow(), Fatal(), and Fatalf() were called.
// FailedCount returns the number of times the *T instance has been marked as
// failed.
func (t *T) FailedCount() int {
return t.failed
}
// Aborted returns true if the TB instance aborted the current goroutine via
// Aborted returns true if the *T instance aborted the current goroutine via
// runtime.Goexit(), which is called by FailNow() and SkipNow().
//
// This returns true even if *T was initialized using the WithNoAbort() option.
// Because the test was still instructed to abort, which is a separate matter
// than that *T was specifically set to not abort the current goroutine.
func (t *T) Aborted() bool {
return t.aborted
}
// HelperNames returns a list of function names which called Helper().
// HelperNames returns a list of function names which called Helper(). The names
// are resolved using runtime.FuncForPC(), meaning they include the absolute Go
// package path to the function, along with the function name itself.
func (t *T) HelperNames() []string {
t.mux.RLock()
defer t.mux.RUnlock()
@@ -410,8 +508,8 @@ func (t *T) Paralleled() bool {
return t.parallel
}
// Subtests returns a list map of *TB instances for any subtests executed via
// Run().
// Subtests returns a slice of *T instances created for any subtests executed
// via Run().
func (t *T) Subtests() []*T {
if t.subtests == nil {
t.mux.Lock()