Skip to content

Commit

Permalink
docs: clarify panic(nil) case since go 1.21 introduced a change
Browse files Browse the repository at this point in the history
See https://pkg.go.dev/runtime#PanicNilError for details.

Signed-off-by: Maxime Soulé <btik-git@scoubidou.com>
  • Loading branch information
maxatome committed Oct 18, 2023
1 parent 5a65b31 commit 6a1fb6b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 8 deletions.
30 changes: 25 additions & 5 deletions td/cmp_funcs_misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
// [fmt.Fprintf] is used to compose the name, else args are passed to
// [fmt.Fprint]. Do not forget it is the name of the test, not the
// reason of a potential failure.
//
// See also [CmpFalse].
func CmpTrue(t TestingT, got bool, args ...any) bool {
t.Helper()
return Cmp(t, got, true, args...)
Expand All @@ -47,6 +49,8 @@ func CmpTrue(t TestingT, got bool, args ...any) bool {
// [fmt.Fprintf] is used to compose the name, else args are passed to
// [fmt.Fprint]. Do not forget it is the name of the test, not the
// reason of a potential failure.
//
// See also [CmpTrue].
func CmpFalse(t TestingT, got bool, args ...any) bool {
t.Helper()
return Cmp(t, got, false, args...)
Expand Down Expand Up @@ -103,6 +107,8 @@ func cmpNoError(ctx ctxerr.Context, t TestingT, got error, args ...any) bool {
// [fmt.Fprintf] is used to compose the name, else args are passed to
// [fmt.Fprint]. Do not forget it is the name of the test, not the
// reason of a potential failure.
//
// See also [CmpNoError].
func CmpError(t TestingT, got error, args ...any) bool {
t.Helper()
return cmpError(newContext(t), t, got, args...)
Expand All @@ -121,6 +127,8 @@ func CmpError(t TestingT, got error, args ...any) bool {
// [fmt.Fprintf] is used to compose the name, else args are passed to
// [fmt.Fprint]. Do not forget it is the name of the test, not the
// reason of a potential failure.
//
// See also [CmpError].
func CmpNoError(t TestingT, got error, args ...any) bool {
t.Helper()
return cmpNoError(newContext(t), t, got, args...)
Expand Down Expand Up @@ -212,8 +220,12 @@ func cmpNotPanic(ctx ctxerr.Context, t TestingT, fn func(), args ...any) bool {
// expectedPanic parameter. It returns true only if both conditions
// are fulfilled.
//
// Note that calling panic(nil) in fn body is detected as a panic
// (in this case expectedPanic has to be nil).
// Note that calling panic(nil) in fn body is always detected as a
// panic. [runtime] package says: before Go 1.21, programs that called
// panic(nil) observed recover returning nil. Starting in Go 1.21,
// programs that call panic(nil) observe recover returning a
// [*runtime.PanicNilError]. Programs can change back to the old
// behavior by setting GODEBUG=panicnil=1.
//
// td.CmpPanic(t,
// func() { panic("I am panicking!") },
Expand All @@ -233,8 +245,9 @@ func cmpNotPanic(ctx ctxerr.Context, t TestingT, fn func(), args ...any) bool {
// [fmt.Fprintf] is used to compose the name, else args are passed to
// [fmt.Fprint]. Do not forget it is the name of the test, not the
// reason of a potential failure.
func CmpPanic(t TestingT, fn func(), expectedPanic any,
args ...any) bool {
//
// See also [CmpNotPanic].
func CmpPanic(t TestingT, fn func(), expectedPanic any, args ...any) bool {
t.Helper()
return cmpPanic(newContext(t), t, fn, expectedPanic, args...)
}
Expand All @@ -243,7 +256,12 @@ func CmpPanic(t TestingT, fn func(), expectedPanic any,
// occurred false is returned then the panic() parameter and the stack
// trace appear in the test report.
//
// Note that calling panic(nil) in fn body is detected as a panic.
// Note that calling panic(nil) in fn body is always detected as a
// panic. [runtime] package says: before Go 1.21, programs that called
// panic(nil) observed recover returning nil. Starting in Go 1.21,
// programs that call panic(nil) observe recover returning a
// [*runtime.PanicNilError]. Programs can change back to the old
// behavior by setting GODEBUG=panicnil=1.
//
// td.CmpNotPanic(t, func() {}) // succeeds as function does not panic
//
Expand All @@ -256,6 +274,8 @@ func CmpPanic(t TestingT, fn func(), expectedPanic any,
// [fmt.Fprintf] is used to compose the name, else args are passed to
// [fmt.Fprint]. Do not forget it is the name of the test, not the
// reason of a potential failure.
//
// See also [CmpPanic].
func CmpNotPanic(t TestingT, fn func(), args ...any) bool {
t.Helper()
return cmpNotPanic(newContext(t), t, fn, args...)
Expand Down
5 changes: 5 additions & 0 deletions td/cmp_funcs_misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ func ExampleCmpPanic() {
fmt.Println("checks panic() sub-string:", ok)

// Can detect panic(nil)
// Before Go 1.21, programs that called panic(nil) observed recover
// returning nil. Starting in Go 1.21, programs that call panic(nil)
// observe recover returning a *PanicNilError. Programs can change
// back to the old behavior by setting GODEBUG=panicnil=1.
// See https://pkg.go.dev/runtime#PanicNilError
ok = td.CmpPanic(t, func() { panic(nil) }, nil, "Checks for panic(nil)")
fmt.Println("checks for panic(nil):", ok)

Expand Down
15 changes: 12 additions & 3 deletions td/t_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,12 @@ func (t *T) CmpNoError(got error, args ...any) bool {
// expectedPanic parameter. It returns true only if both conditions
// are fulfilled.
//
// Note that calling panic(nil) in fn body is detected as a panic
// (in this case expectedPanic has to be nil).
// Note that calling panic(nil) in fn body is always detected as a
// panic. [runtime] package says: before Go 1.21, programs that called
// panic(nil) observed recover returning nil. Starting in Go 1.21,
// programs that call panic(nil) observe recover returning a
// [*runtime.PanicNilError]. Programs can change back to the old
// behavior by setting GODEBUG=panicnil=1.
//
// t.CmpPanic(func() { panic("I am panicking!") },
// "I am panicking!",
Expand Down Expand Up @@ -596,7 +600,12 @@ func (t *T) CmpPanic(fn func(), expected any, args ...any) bool {
// occurred false is returned then the panic() parameter and the stack
// trace appear in the test report.
//
// Note that calling panic(nil) in fn body is detected as a panic.
// Note that calling panic(nil) in fn body is always detected as a
// panic. [runtime] package says: before Go 1.21, programs that called
// panic(nil) observed recover returning nil. Starting in Go 1.21,
// programs that call panic(nil) observe recover returning a
// [*runtime.PanicNilError]. Programs can change back to the old
// behavior by setting GODEBUG=panicnil=1.
//
// t.CmpNotPanic(func() {}) // succeeds as function does not panic
//
Expand Down

0 comments on commit 6a1fb6b

Please sign in to comment.