blob: 8fcb2df41cb2efd088230fb310c0ceddf6c936d4 [file] [log] [blame]
package assert
import (
"fmt"
"testing"
gocmp "github.com/google/go-cmp/cmp"
"github.com/gotestyourself/gotestyourself/assert/cmp"
)
type fakeTestingT struct {
failNowed bool
failed bool
msgs []string
}
func (f *fakeTestingT) FailNow() {
f.failNowed = true
}
func (f *fakeTestingT) Fail() {
f.failed = true
}
func (f *fakeTestingT) Log(args ...interface{}) {
f.msgs = append(f.msgs, args[0].(string))
}
func (f *fakeTestingT) Helper() {}
func TestAssertWithBoolFailure(t *testing.T) {
fakeT := &fakeTestingT{}
Assert(fakeT, 1 == 6)
expectFailNowed(t, fakeT, "assertion failed: expression is false: 1 == 6")
}
func TestAssertWithBoolFailureNotEqual(t *testing.T) {
fakeT := &fakeTestingT{}
var err error
Assert(fakeT, err != nil)
expectFailNowed(t, fakeT, "assertion failed: err is nil")
}
func TestAssertWithBoolFailureNotTrue(t *testing.T) {
fakeT := &fakeTestingT{}
badNews := true
Assert(fakeT, !badNews)
expectFailNowed(t, fakeT, "assertion failed: badNews is true")
}
func TestAssertWithBoolFailureAndExtraMessage(t *testing.T) {
fakeT := &fakeTestingT{}
Assert(fakeT, 1 > 5, "sometimes things fail")
expectFailNowed(t, fakeT,
"assertion failed: expression is false: 1 > 5: sometimes things fail")
}
func TestAssertWithBoolSuccess(t *testing.T) {
fakeT := &fakeTestingT{}
Assert(fakeT, 1 < 5)
expectSuccess(t, fakeT)
}
func TestAssertWithBoolMultiLineFailure(t *testing.T) {
fakeT := &fakeTestingT{}
Assert(fakeT, func() bool {
for range []int{1, 2, 3, 4} {
}
return false
}())
expectFailNowed(t, fakeT, `assertion failed: expression is false: func() bool {
for range []int{1, 2, 3, 4} {
}
return false
}()`)
}
type exampleComparison struct {
success bool
message string
}
func (c exampleComparison) Compare() (bool, string) {
return c.success, c.message
}
func TestAssertWithComparisonSuccess(t *testing.T) {
fakeT := &fakeTestingT{}
cmp := exampleComparison{success: true}
Assert(fakeT, cmp.Compare)
expectSuccess(t, fakeT)
}
func TestAssertWithComparisonFailure(t *testing.T) {
fakeT := &fakeTestingT{}
cmp := exampleComparison{message: "oops, not good"}
Assert(fakeT, cmp.Compare)
expectFailNowed(t, fakeT, "assertion failed: oops, not good")
}
func TestAssertWithComparisonAndExtraMessage(t *testing.T) {
fakeT := &fakeTestingT{}
cmp := exampleComparison{message: "oops, not good"}
Assert(fakeT, cmp.Compare, "extra stuff %v", true)
expectFailNowed(t, fakeT, "assertion failed: oops, not good: extra stuff true")
}
type customError struct{}
func (e *customError) Error() string {
return "custom error"
}
func TestNilErrorSuccess(t *testing.T) {
fakeT := &fakeTestingT{}
var err error
NilError(fakeT, err)
expectSuccess(t, fakeT)
NilError(fakeT, nil)
expectSuccess(t, fakeT)
var customErr *customError
NilError(fakeT, customErr)
}
func TestNilErrorFailure(t *testing.T) {
fakeT := &fakeTestingT{}
NilError(fakeT, fmt.Errorf("this is the error"))
expectFailNowed(t, fakeT, "assertion failed: error is not nil: this is the error")
}
func TestCheckFailure(t *testing.T) {
fakeT := &fakeTestingT{}
if Check(fakeT, 1 == 2) {
t.Error("expected check to return false on failure")
}
expectFailed(t, fakeT, "assertion failed: expression is false: 1 == 2")
}
func TestCheckSuccess(t *testing.T) {
fakeT := &fakeTestingT{}
if !Check(fakeT, 1 == 1) {
t.Error("expected check to return true on success")
}
expectSuccess(t, fakeT)
}
func TestCheckEqualFailure(t *testing.T) {
fakeT := &fakeTestingT{}
actual, expected := 5, 9
Check(fakeT, cmp.Equal(actual, expected))
expectFailed(t, fakeT, "assertion failed: 5 (actual int) != 9 (expected int)")
}
func TestEqualSuccess(t *testing.T) {
fakeT := &fakeTestingT{}
Equal(fakeT, 1, 1)
expectSuccess(t, fakeT)
Equal(fakeT, "abcd", "abcd")
expectSuccess(t, fakeT)
}
func TestEqualFailure(t *testing.T) {
fakeT := &fakeTestingT{}
actual, expected := 1, 3
Equal(fakeT, actual, expected)
expectFailNowed(t, fakeT, "assertion failed: 1 (actual int) != 3 (expected int)")
}
func TestEqualFailureTypes(t *testing.T) {
fakeT := &fakeTestingT{}
Equal(fakeT, 3, uint(3))
expectFailNowed(t, fakeT, `assertion failed: 3 (int) != 3 (uint)`)
}
func TestEqualFailureWithSelectorArgument(t *testing.T) {
fakeT := &fakeTestingT{}
type tc struct {
expected string
}
var testcase = tc{expected: "foo"}
Equal(fakeT, "ok", testcase.expected)
expectFailNowed(t, fakeT,
"assertion failed: ok (string) != foo (testcase.expected string)")
}
func TestEqualFailureWithIndexExpr(t *testing.T) {
fakeT := &fakeTestingT{}
expected := map[string]string{"foo": "bar"}
Equal(fakeT, "ok", expected["foo"])
expectFailNowed(t, fakeT,
`assertion failed: ok (string) != bar (expected["foo"] string)`)
}
func TestEqualFailureWithCallExprArgument(t *testing.T) {
fakeT := &fakeTestingT{}
ce := customError{}
Equal(fakeT, "", ce.Error())
expectFailNowed(t, fakeT,
"assertion failed: (string) != custom error (string)")
}
func TestAssertFailureWithOfflineComparison(t *testing.T) {
fakeT := &fakeTestingT{}
a := 1
b := 2
// store comparison in a variable, so ast lookup can't find it
comparison := cmp.Equal(a, b)
Assert(fakeT, comparison)
// expected value wont have variable names
expectFailNowed(t, fakeT, "assertion failed: 1 (int) != 2 (int)")
}
type testingT interface {
Errorf(msg string, args ...interface{})
Fatalf(msg string, args ...interface{})
}
func expectFailNowed(t testingT, fakeT *fakeTestingT, expected string) {
if ht, ok := t.(helperT); ok {
ht.Helper()
}
if fakeT.failed {
t.Errorf("should not have failed, got messages %s", fakeT.msgs)
}
if !fakeT.failNowed {
t.Fatalf("should have failNowed with message %s", expected)
}
if fakeT.msgs[0] != expected {
t.Fatalf("should have failure message %q, got %q", expected, fakeT.msgs[0])
}
}
// nolint: unparam
func expectFailed(t testingT, fakeT *fakeTestingT, expected string) {
if ht, ok := t.(helperT); ok {
ht.Helper()
}
if fakeT.failNowed {
t.Errorf("should not have failNowed, got messages %s", fakeT.msgs)
}
if !fakeT.failed {
t.Fatalf("should have failed with message %s", expected)
}
if fakeT.msgs[0] != expected {
t.Fatalf("should have failure message %q, got %q", expected, fakeT.msgs[0])
}
}
func expectSuccess(t testingT, fakeT *fakeTestingT) {
if ht, ok := t.(helperT); ok {
ht.Helper()
}
if fakeT.failNowed {
t.Errorf("should not have failNowed, got messages %s", fakeT.msgs)
}
if fakeT.failed {
t.Errorf("should not have failed, got messages %s", fakeT.msgs)
}
}
type stub struct {
a string
b int
}
func TestDeepEqualSuccess(t *testing.T) {
actual := stub{"ok", 1}
expected := stub{"ok", 1}
fakeT := &fakeTestingT{}
DeepEqual(fakeT, actual, expected, gocmp.AllowUnexported(stub{}))
expectSuccess(t, fakeT)
}
func TestDeepEqualFailure(t *testing.T) {
actual := stub{"ok", 1}
expected := stub{"ok", 2}
fakeT := &fakeTestingT{}
DeepEqual(fakeT, actual, expected, gocmp.AllowUnexported(stub{}))
expectFailNowed(t, fakeT, "assertion failed: "+`
{assert.stub}.b:
-: 1
+: 2
`)
}