Adds testutils/assert and testutils/require (#6563)

* testutils/assert

* adds assertion tb mock

* testutil/require

* gazelle

* comment public types

* set TestOnly attribute

* fixes package name

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Victor Farazdagi 2020-07-13 18:19:52 +03:00 committed by GitHub
parent f2b4f91419
commit 77d1a6c698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 719 additions and 0 deletions

View File

@ -5,6 +5,7 @@ go_library(
name = "go_default_library",
testonly = True,
srcs = [
"assertions.go",
"block.go",
"deposits.go",
"helpers.go",

View File

@ -0,0 +1,18 @@
load("@io_bazel_rules_go//go:def.bzl", "go_test")
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
testonly = True,
srcs = ["assertions.go"],
importpath = "github.com/prysmaticlabs/prysm/shared/testutil/assert",
visibility = ["//visibility:public"],
deps = ["//shared/testutil:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["assertions_test.go"],
embed = [":go_default_library"],
deps = ["//shared/testutil:go_default_library"],
)

View File

@ -0,0 +1,30 @@
package assert
import (
"github.com/prysmaticlabs/prysm/shared/testutil"
)
// Equal compares values using comparison operator.
func Equal(tb testutil.AssertionTestingTB, expected, actual interface{}, msg ...string) {
testutil.Equal(tb.Errorf, expected, actual, msg...)
}
// DeepEqual compares values using DeepEqual.
func DeepEqual(tb testutil.AssertionTestingTB, expected, actual interface{}, msg ...string) {
testutil.DeepEqual(tb.Errorf, expected, actual, msg...)
}
// NoError asserts that error is nil.
func NoError(tb testutil.AssertionTestingTB, err error, msg ...string) {
testutil.NoError(tb.Errorf, err, msg...)
}
// ErrorContains asserts that actual error contains wanted message.
func ErrorContains(tb testutil.AssertionTestingTB, want string, err error, msg ...string) {
testutil.ErrorContains(tb.Errorf, want, err, msg...)
}
// NotNil asserts that passed value is not nil.
func NotNil(tb testutil.AssertionTestingTB, obj interface{}, msg ...string) {
testutil.NotNil(tb.Errorf, obj, msg...)
}

View File

@ -0,0 +1,268 @@
package assert
import (
"errors"
"strings"
"testing"
"github.com/prysmaticlabs/prysm/shared/testutil"
)
func TestAssert_Equal(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
expected interface{}
actual interface{}
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: 42,
actual: 42,
},
},
{
name: "non-equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: 42,
actual: 41,
},
expectedErr: "Values are not equal, got: 41, want: 42",
},
{
name: "custom error message",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: 42,
actual: 41,
msg: []string{"Custom values are not equal"},
},
expectedErr: "Custom values are not equal, got: 41, want: 42",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Equal(tt.args.tb, tt.args.expected, tt.args.actual, tt.args.msg...)
if !strings.Contains(tt.args.tb.ErrorfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.ErrorfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_DeepEqual(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
expected interface{}
actual interface{}
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: struct{ i int }{42},
actual: struct{ i int }{42},
},
},
{
name: "non-equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: struct{ i int }{42},
actual: struct{ i int }{41},
},
expectedErr: "Values are not equal, got: {41}, want: {42}",
},
{
name: "custom error message",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: struct{ i int }{42},
actual: struct{ i int }{41},
msg: []string{"Custom values are not equal"},
},
expectedErr: "Custom values are not equal, got: {41}, want: {42}",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
DeepEqual(tt.args.tb, tt.args.expected, tt.args.actual, tt.args.msg...)
if !strings.Contains(tt.args.tb.ErrorfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.ErrorfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_NoError(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
err error
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
},
},
{
name: "non-nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
err: errors.New("failed"),
},
expectedErr: "Unexpected error: failed",
},
{
name: "non-nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
err: errors.New("failed"),
msg: []string{"Custom error message"},
},
expectedErr: "Custom error message: failed",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
NoError(tt.args.tb, tt.args.err, tt.args.msg...)
if !strings.Contains(tt.args.tb.ErrorfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.ErrorfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_ErrorContains(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
want string
err error
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "some error",
},
expectedErr: "Expected error not returned, got: <nil>, want: some error",
},
{
name: "unexpected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "another error",
err: errors.New("failed"),
},
expectedErr: "Expected error not returned, got: failed, want: another error",
},
{
name: "expected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "failed",
err: errors.New("failed"),
},
expectedErr: "",
},
{
name: "custom unexpected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "another error",
err: errors.New("failed"),
msg: []string{"Something wrong"},
},
expectedErr: "Something wrong, got: failed, want: another error",
},
{
name: "expected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "failed",
err: errors.New("failed"),
msg: []string{"Something wrong"},
},
expectedErr: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ErrorContains(tt.args.tb, tt.args.want, tt.args.err, tt.args.msg...)
if !strings.Contains(tt.args.tb.ErrorfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.ErrorfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_NotNil(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
obj interface{}
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "nil",
args: args{
tb: &testutil.AssertionsTBMock{},
},
expectedErr: "Unexpected nil value",
},
{
name: "nil custom message",
args: args{
tb: &testutil.AssertionsTBMock{},
msg: []string{"This should not be nil"},
},
expectedErr: "This should not be nil",
},
{
name: "not nil",
args: args{
tb: &testutil.AssertionsTBMock{},
obj: "some value",
},
expectedErr: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
NotNil(tt.args.tb, tt.args.obj, tt.args.msg...)
if !strings.Contains(tt.args.tb.ErrorfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.ErrorfMsg, tt.expectedErr)
}
})
}
}

View File

@ -0,0 +1,86 @@
package testutil
import (
"fmt"
"path/filepath"
"reflect"
"runtime"
"strings"
)
// AssertionTestingTB exposes enough testing.TB methods for assertions.
type AssertionTestingTB interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
type assertionLoggerFn func(string, ...interface{})
// Equal compares values using comparison operator.
func Equal(loggerFn assertionLoggerFn, expected, actual interface{}, msg ...string) {
errMsg := parseMsg("Values are not equal", msg...)
if expected != actual {
_, file, line, _ := runtime.Caller(1)
loggerFn("%s:%d %s, got: %v, want: %v", file, line, errMsg, actual, expected)
}
}
// DeepEqual compares values using DeepEqual.
func DeepEqual(loggerFn assertionLoggerFn, expected, actual interface{}, msg ...string) {
errMsg := parseMsg("Values are not equal", msg...)
if !reflect.DeepEqual(expected, actual) {
_, file, line, _ := runtime.Caller(1)
loggerFn("%s:%d %s, got: %v, want: %v", file, line, errMsg, actual, expected)
}
}
// NoError asserts that error is nil.
func NoError(loggerFn assertionLoggerFn, err error, msg ...string) {
errMsg := parseMsg("Unexpected error", msg...)
if err != nil {
_, file, line, _ := runtime.Caller(1)
loggerFn("%s:%d %s: %v", filepath.Base(file), line, errMsg, err)
}
}
// ErrorContains asserts that actual error contains wanted message.
func ErrorContains(loggerFn assertionLoggerFn, want string, err error, msg ...string) {
errMsg := parseMsg("Expected error not returned", msg...)
if err == nil || !strings.Contains(err.Error(), want) {
_, file, line, _ := runtime.Caller(1)
loggerFn("%s:%d %s, got: %v, want: %s", filepath.Base(file), line, errMsg, err, want)
}
}
// NotNil asserts that passed value is not nil.
func NotNil(loggerFn assertionLoggerFn, obj interface{}, msg ...string) {
errMsg := parseMsg("Unexpected nil value", msg...)
if obj == nil {
_, file, line, _ := runtime.Caller(1)
loggerFn("%s:%d %s", filepath.Base(file), line, errMsg)
}
}
func parseMsg(defaultMsg string, msg ...string) string {
msgString := defaultMsg
if len(msg) == 1 {
msgString = msg[0]
}
return msgString
}
// AssertionsTBMock exposes enough testing.TB methods for assertions.
type AssertionsTBMock struct {
ErrorfMsg string
FatalfMsg string
}
// Errorf writes testing logs to ErrorfMsg.
func (tb *AssertionsTBMock) Errorf(format string, args ...interface{}) {
tb.ErrorfMsg = fmt.Sprintf(format, args...)
}
// Fatalf writes testing logs to FatalfMsg.
func (tb *AssertionsTBMock) Fatalf(format string, args ...interface{}) {
tb.FatalfMsg = fmt.Sprintf(format, args...)
}

View File

@ -0,0 +1,18 @@
load("@io_bazel_rules_go//go:def.bzl", "go_test")
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
testonly = True,
srcs = ["requires.go"],
importpath = "github.com/prysmaticlabs/prysm/shared/testutil/require",
visibility = ["//visibility:public"],
deps = ["//shared/testutil:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["requires_test.go"],
embed = [":go_default_library"],
deps = ["//shared/testutil:go_default_library"],
)

View File

@ -0,0 +1,30 @@
package require
import (
"github.com/prysmaticlabs/prysm/shared/testutil"
)
// Equal compares values using comparison operator.
func Equal(tb testutil.AssertionTestingTB, expected, actual interface{}, msg ...string) {
testutil.Equal(tb.Fatalf, expected, actual, msg...)
}
// DeepEqual compares values using DeepEqual.
func DeepEqual(tb testutil.AssertionTestingTB, expected, actual interface{}, msg ...string) {
testutil.DeepEqual(tb.Fatalf, expected, actual, msg...)
}
// NoError asserts that error is nil.
func NoError(tb testutil.AssertionTestingTB, err error, msg ...string) {
testutil.NoError(tb.Fatalf, err, msg...)
}
// ErrorContains asserts that actual error contains wanted message.
func ErrorContains(tb testutil.AssertionTestingTB, want string, err error, msg ...string) {
testutil.ErrorContains(tb.Fatalf, want, err, msg...)
}
// NotNil asserts that passed value is not nil.
func NotNil(tb testutil.AssertionTestingTB, obj interface{}, msg ...string) {
testutil.NotNil(tb.Fatalf, obj, msg...)
}

View File

@ -0,0 +1,268 @@
package require
import (
"errors"
"strings"
"testing"
"github.com/prysmaticlabs/prysm/shared/testutil"
)
func TestAssert_Equal(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
expected interface{}
actual interface{}
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: 42,
actual: 42,
},
},
{
name: "non-equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: 42,
actual: 41,
},
expectedErr: "Values are not equal, got: 41, want: 42",
},
{
name: "custom error message",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: 42,
actual: 41,
msg: []string{"Custom values are not equal"},
},
expectedErr: "Custom values are not equal, got: 41, want: 42",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Equal(tt.args.tb, tt.args.expected, tt.args.actual, tt.args.msg...)
if !strings.Contains(tt.args.tb.FatalfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.FatalfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_DeepEqual(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
expected interface{}
actual interface{}
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: struct{ i int }{42},
actual: struct{ i int }{42},
},
},
{
name: "non-equal values",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: struct{ i int }{42},
actual: struct{ i int }{41},
},
expectedErr: "Values are not equal, got: {41}, want: {42}",
},
{
name: "custom error message",
args: args{
tb: &testutil.AssertionsTBMock{},
expected: struct{ i int }{42},
actual: struct{ i int }{41},
msg: []string{"Custom values are not equal"},
},
expectedErr: "Custom values are not equal, got: {41}, want: {42}",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
DeepEqual(tt.args.tb, tt.args.expected, tt.args.actual, tt.args.msg...)
if !strings.Contains(tt.args.tb.FatalfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.FatalfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_NoError(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
err error
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
},
},
{
name: "non-nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
err: errors.New("failed"),
},
expectedErr: "Unexpected error: failed",
},
{
name: "non-nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
err: errors.New("failed"),
msg: []string{"Custom error message"},
},
expectedErr: "Custom error message: failed",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
NoError(tt.args.tb, tt.args.err, tt.args.msg...)
if !strings.Contains(tt.args.tb.FatalfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.FatalfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_ErrorContains(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
want string
err error
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "nil error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "some error",
},
expectedErr: "Expected error not returned, got: <nil>, want: some error",
},
{
name: "unexpected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "another error",
err: errors.New("failed"),
},
expectedErr: "Expected error not returned, got: failed, want: another error",
},
{
name: "expected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "failed",
err: errors.New("failed"),
},
expectedErr: "",
},
{
name: "custom unexpected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "another error",
err: errors.New("failed"),
msg: []string{"Something wrong"},
},
expectedErr: "Something wrong, got: failed, want: another error",
},
{
name: "expected error",
args: args{
tb: &testutil.AssertionsTBMock{},
want: "failed",
err: errors.New("failed"),
msg: []string{"Something wrong"},
},
expectedErr: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ErrorContains(tt.args.tb, tt.args.want, tt.args.err, tt.args.msg...)
if !strings.Contains(tt.args.tb.FatalfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.FatalfMsg, tt.expectedErr)
}
})
}
}
func TestAssert_NotNil(t *testing.T) {
type args struct {
tb *testutil.AssertionsTBMock
obj interface{}
msg []string
}
tests := []struct {
name string
args args
expectedErr string
}{
{
name: "nil",
args: args{
tb: &testutil.AssertionsTBMock{},
},
expectedErr: "Unexpected nil value",
},
{
name: "nil custom message",
args: args{
tb: &testutil.AssertionsTBMock{},
msg: []string{"This should not be nil"},
},
expectedErr: "This should not be nil",
},
{
name: "not nil",
args: args{
tb: &testutil.AssertionsTBMock{},
obj: "some value",
},
expectedErr: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
NotNil(tt.args.tb, tt.args.obj, tt.args.msg...)
if !strings.Contains(tt.args.tb.FatalfMsg, tt.expectedErr) {
t.Errorf("got: %q, want: %q", tt.args.tb.FatalfMsg, tt.expectedErr)
}
})
}
}