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.
This commit is contained in:
Kyle Isom 2016-04-28 12:23:50 -07:00
parent 6e4239649a
commit 80bea5c005
1 changed files with 75 additions and 17 deletions

View File

@ -1,41 +1,81 @@
// Package assert provides C-like assertions for Go. For more // Package assert provides C-like assertions for Go. For more
// information, see assert(3) (e.g. `man 3 assert`). // 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 package assert
import ( import (
"fmt" "fmt"
"os" "os"
"runtime" "runtime"
"strings"
"testing" "testing"
) )
// NoDebug, if set to true, will cause all asserts to be ignored. // NoDebug, if set to true, will cause all asserts to be ignored.
var NoDebug bool var NoDebug bool
func die(what string) { func die(what string, a ...string) {
_, file, line, ok := runtime.Caller(2) _, file, line, ok := runtime.Caller(2)
if !ok { if !ok {
panic(what) panic(what)
} else { } 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) fmt.Fprintf(os.Stderr, "\t%s line %d\n", file, line)
os.Exit(1) os.Exit(1)
} }
} }
// Bool asserts that cond is false. // 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 { if NoDebug {
return return
} }
if !cond { if !cond {
die("assert.Bool failed") die("assert.Bool failed", s...)
} }
} }
// Error asserts that err is nil. // Error asserts that err is not nil, e.g. that an error has occurred.
func Error(err error) { //
// For example,
// if err == nil {
// log.Fatal("call to <something> should have failed")
// }
// // becomes
// assert.Error(err, "call to <something> 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 { if NoDebug {
return return
} }
@ -45,14 +85,14 @@ func Error(err error) {
} }
} }
// Error2 asserts that the actual error is the expected error. // ErrorEq asserts that the actual error is the expected error.
func Error2(expected, actual error) { func ErrorEq(expected, actual error) {
if NoDebug || (expected == actual) { if NoDebug || (expected == actual) {
return return
} }
if expected == nil { if expected == nil {
die(fmt.Sprintf("assert.Error2: %s", actual.Error())) die(fmt.Sprintf("assert.ErrorEq: %s", actual.Error()))
} }
var should string var should string
@ -62,28 +102,46 @@ func Error2(expected, actual error) {
should = fmt.Sprintf("have '%s'", actual) 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 // BoolT checks a boolean condition, calling Fatal on t if it is
// false. // false.
func BoolT(t *testing.T, cond bool) { func BoolT(t *testing.T, cond bool, s ...string) {
if !cond { 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 // ErrorT asserts that err is not nil, e.g. asserting that an error
// isn't. // has occurred. See also NoErrorT.
func ErrorT(t *testing.T, err error) { 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 { if nil != err {
t.Fatalf("%s", 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. // don't match.
func Error2T(t *testing.T, expected, actual error) { func ErrorEqT(t *testing.T, expected, actual error) {
if NoDebug || (expected == actual) { if NoDebug || (expected == actual) {
return return
} }