From 80bea5c00561eb055c78e8abf5319a59ae911f32 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Thu, 28 Apr 2016 12:23:50 -0700 Subject: [PATCH] Tidy assert package. + Rename some functions to make sense: + Error now asserts that an error *did* occur. + NoError was added to assert that an error did *not* occur. + Error2 has been renamed ErrorEq. + More documentation added to clarify things. + Certain functions take optional strings to describe what went wrong. --- assert/assert.go | 92 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 17 deletions(-) diff --git a/assert/assert.go b/assert/assert.go index d46a6cd..b42f25b 100644 --- a/assert/assert.go +++ b/assert/assert.go @@ -1,41 +1,81 @@ // Package assert provides C-like assertions for Go. For more // information, see assert(3) (e.g. `man 3 assert`). +// +// The T variants operating on *testing.T values; instead of killing +// the program, they call the Fatal method. package assert import ( "fmt" "os" "runtime" + "strings" "testing" ) // NoDebug, if set to true, will cause all asserts to be ignored. var NoDebug bool -func die(what string) { +func die(what string, a ...string) { _, file, line, ok := runtime.Caller(2) if !ok { panic(what) } else { - fmt.Fprintf(os.Stderr, "%s\n", what) + fmt.Fprintf(os.Stderr, "%s", what) + if len(a) > 0 { + s := strings.Join(a, ", ") + fmt.Fprintln(os.Stderr, ":"+s) + } else { + fmt.Fprintf(os.Stderr, "\n") + } fmt.Fprintf(os.Stderr, "\t%s line %d\n", file, line) os.Exit(1) } } // Bool asserts that cond is false. -func Bool(cond bool) { +// +// For example, this would replace +// if x < 0 { +// log.Fatal("x is subzero") +// } +// +// The same assertion would be +// assert.Bool(x, "x is subzero") +func Bool(cond bool, s ...string) { if NoDebug { return } if !cond { - die("assert.Bool failed") + die("assert.Bool failed", s...) } } -// Error asserts that err is nil. -func Error(err error) { +// Error asserts that err is not nil, e.g. that an error has occurred. +// +// For example, +// if err == nil { +// log.Fatal("call to should have failed") +// } +// // becomes +// assert.Error(err, "call to should have failed") +func Error(err error, s ...string) { + if NoDebug { + return + } else if nil != err { + return + } + + if len(s) == 0 { + die("error expected, but no error returned") + } else { + die(strings.Join(s, ", ")) + } +} + +// NoError asserts that err is nil, e.g. that no error has occurred. +func NoError(err error, s ...string) { if NoDebug { return } @@ -45,14 +85,14 @@ func Error(err error) { } } -// Error2 asserts that the actual error is the expected error. -func Error2(expected, actual error) { +// ErrorEq asserts that the actual error is the expected error. +func ErrorEq(expected, actual error) { if NoDebug || (expected == actual) { return } if expected == nil { - die(fmt.Sprintf("assert.Error2: %s", actual.Error())) + die(fmt.Sprintf("assert.ErrorEq: %s", actual.Error())) } var should string @@ -62,28 +102,46 @@ func Error2(expected, actual error) { should = fmt.Sprintf("have '%s'", actual) } - die(fmt.Sprintf("assert.Error2: expected '%s', but %s", expected, should)) + die(fmt.Sprintf("assert.ErrorEq: expected '%s', but %s", expected, should)) } // BoolT checks a boolean condition, calling Fatal on t if it is // false. -func BoolT(t *testing.T, cond bool) { +func BoolT(t *testing.T, cond bool, s ...string) { if !cond { - t.Fatal("assert.Bool failed") + what := strings.Join(s, ", ") + if len(what) > 0 { + what = ": " + what + } + t.Fatalf("assert.Bool failed%s", what) } } -// ErrorT checks whether the error is nil, calling Fatal on t if it -// isn't. -func ErrorT(t *testing.T, err error) { +// ErrorT asserts that err is not nil, e.g. asserting that an error +// has occurred. See also NoErrorT. +func ErrorT(t *testing.T, err error, s ...string) { + if nil != err { + return + } + + if len(s) == 0 { + t.Fatal("error expected, but no error returned") + } else { + t.Fatal(strings.Join(s, ", ")) + } +} + +// NoErrorT asserts that err is nil, e.g. asserting that no error has +// occurred. See also ErrorT. +func NoErrorT(t *testing.T, err error) { if nil != err { t.Fatalf("%s", err) } } -// Error2T compares a pair of errors, calling Fatal on it if they +// ErrorEqT compares a pair of errors, calling Fatal on it if they // don't match. -func Error2T(t *testing.T, expected, actual error) { +func ErrorEqT(t *testing.T, expected, actual error) { if NoDebug || (expected == actual) { return }