Merge pull request #5004 from vmarmol/gc-0

Updating github.com/stretchr/testify godep.
This commit is contained in:
Eric Tune 2015-03-03 16:30:14 -08:00
commit 6f6218cc1e
12 changed files with 1951 additions and 145 deletions

4
Godeps/Godeps.json generated
View File

@ -265,11 +265,11 @@
},
{
"ImportPath": "github.com/stretchr/testify/assert",
"Rev": "37614ac27794505bf7867ca93aac883cadb6a5f7"
"Rev": "e4ec8152c15fc46bd5056ce65997a07c7d415325"
},
{
"ImportPath": "github.com/stretchr/testify/mock",
"Rev": "37614ac27794505bf7867ca93aac883cadb6a5f7"
"Rev": "e4ec8152c15fc46bd5056ce65997a07c7d415325"
},
{
"ImportPath": "github.com/vaughan0/go-ini",

View File

@ -1,8 +1,11 @@
package assert
import (
"bufio"
"bytes"
"fmt"
"reflect"
"regexp"
"runtime"
"strings"
"time"
@ -25,11 +28,11 @@ type Comparison func() (success bool)
// This function does no assertion of any kind.
func ObjectsAreEqual(expected, actual interface{}) bool {
if reflect.DeepEqual(expected, actual) {
return true
if expected == nil || actual == nil {
return expected == actual
}
if reflect.ValueOf(expected) == reflect.ValueOf(actual) {
if reflect.DeepEqual(expected, actual) {
return true
}
@ -42,6 +45,23 @@ func ObjectsAreEqual(expected, actual interface{}) bool {
}
func ObjectsAreEqualValues(expected, actual interface{}) bool {
if ObjectsAreEqual(expected, actual) {
return true
}
actualType := reflect.TypeOf(actual)
expectedValue := reflect.ValueOf(expected)
if expectedValue.Type().ConvertibleTo(actualType) {
// Attempt comparison after type conversion
if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) {
return true
}
}
return false
}
/* CallerInfo is necessary because the assert functions use the testing object
internally, causing it to print the file:line of the assert method, rather than where
the problem actually occured in calling code.*/
@ -62,7 +82,7 @@ func CallerInfo() string {
parts := strings.Split(file, "/")
dir := parts[len(parts)-2]
file = parts[len(parts)-1]
if (dir != "assert" && dir != "mock") || file == "mock_test.go" {
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
break
}
}
@ -98,15 +118,48 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
return ""
}
// Indents all lines of the message by appending a number of tabs to each line, in an output format compatible with Go's
// test printing (see inner comment for specifics)
func indentMessageLines(message string, tabs int) string {
outBuf := new(bytes.Buffer)
for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
if i != 0 {
outBuf.WriteRune('\n')
}
for ii := 0; ii < tabs; ii++ {
outBuf.WriteRune('\t')
// Bizarrely, all lines except the first need one fewer tabs prepended, so deliberately advance the counter
// by 1 prematurely.
if ii == 0 && i > 0 {
ii++
}
}
outBuf.WriteString(scanner.Text())
}
return outBuf.String()
}
// Fail reports a failure through
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
message := messageFromMsgAndArgs(msgAndArgs...)
if len(message) > 0 {
t.Errorf("\r%s\r\tLocation:\t%s\n\r\tError:\t\t%s\n\r\tMessages:\t%s\n\r", getWhitespaceString(), CallerInfo(), failureMessage, message)
t.Errorf("\r%s\r\tLocation:\t%s\n"+
"\r\tError:%s\n"+
"\r\tMessages:\t%s\n\r",
getWhitespaceString(),
CallerInfo(),
indentMessageLines(failureMessage, 2),
message)
} else {
t.Errorf("\r%s\r\tLocation:\t%s\n\r\tError:\t\t%s\n\r", getWhitespaceString(), CallerInfo(), failureMessage)
t.Errorf("\r%s\r\tLocation:\t%s\n"+
"\r\tError:%s\n\r",
getWhitespaceString(),
CallerInfo(),
indentMessageLines(failureMessage, 2))
}
return false
@ -145,7 +198,25 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
if !ObjectsAreEqual(expected, actual) {
return Fail(t, fmt.Sprintf("Not equal: %#v != %#v", expected, actual), msgAndArgs...)
return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+
" != %#v (actual)", expected, actual), msgAndArgs...)
}
return true
}
// EqualValues asserts that two objects are equal or convertable to the same types
// and equal.
//
// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
if !ObjectsAreEqualValues(expected, actual) {
return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+
" != %#v (actual)", expected, actual), msgAndArgs...)
}
return true
@ -177,7 +248,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
// Returns whether the assertion was successful (true) or not (false).
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
var success bool = true
success := true
if object == nil {
success = false
@ -196,26 +267,48 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
return success
}
// isNil checks if a specified object is nil or not, without Failing.
func isNil(object interface{}) bool {
if object == nil {
return true
}
value := reflect.ValueOf(object)
kind := value.Kind()
if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
return true
}
return false
}
// Nil asserts that the specified object is nil.
//
// assert.Nil(t, err, "err should be nothing")
//
// Returns whether the assertion was successful (true) or not (false).
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
if object == nil {
if isNil(object) {
return true
} else {
value := reflect.ValueOf(object)
kind := value.Kind()
if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
return true
}
}
return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
}
var zeros = []interface{}{
int(0),
int8(0),
int16(0),
int32(0),
int64(0),
uint(0),
uint8(0),
uint16(0),
uint32(0),
uint64(0),
float32(0),
float64(0),
}
// isEmpty gets whether the specified object is considered empty or not.
func isEmpty(object interface{}) bool {
@ -223,28 +316,40 @@ func isEmpty(object interface{}) bool {
return true
} else if object == "" {
return true
} else if object == 0 {
return true
} else if object == false {
return true
}
objValue := reflect.ValueOf(object)
switch objValue.Kind() {
case reflect.Map:
fallthrough
case reflect.Slice:
{
return (objValue.Len() == 0)
for _, v := range zeros {
if object == v {
return true
}
}
return false
objValue := reflect.ValueOf(object)
switch objValue.Kind() {
case reflect.Map:
fallthrough
case reflect.Slice, reflect.Chan:
{
return (objValue.Len() == 0)
}
case reflect.Ptr:
{
switch object.(type) {
case *time.Time:
return object.(*time.Time).IsZero()
default:
return false
}
}
}
return false
}
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a
// slice with len == 0.
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// a slice or a channel with len == 0.
//
// assert.Empty(t, obj)
//
@ -260,8 +365,8 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
}
// Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
// slice with len == 0.
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
//
// if assert.NotEmpty(t, obj) {
// assert.Equal(t, "two", obj[1])
@ -279,6 +384,36 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
}
// getLen try to get length of object.
// return (false, 0) if impossible.
func getLen(x interface{}) (ok bool, length int) {
v := reflect.ValueOf(x)
defer func() {
if e := recover(); e != nil {
ok = false
}
}()
return true, v.Len()
}
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
// assert.Len(t, mySlice, 3, "The size of slice is not 3")
//
// Returns whether the assertion was successful (true) or not (false).
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
ok, l := getLen(object)
if !ok {
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
}
if l != length {
return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
}
return true
}
// True asserts that the specified value is true.
//
// assert.True(t, myBool, "myBool should be true")
@ -324,14 +459,48 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{
}
// Contains asserts that the specified string contains the specified substring.
// containsElement try loop over the list check if the list includes the element.
// return (false, false) if impossible.
// return (true, false) if element was not found.
// return (true, true) if element was found.
func includeElement(list interface{}, element interface{}) (ok, found bool) {
listValue := reflect.ValueOf(list)
elementValue := reflect.ValueOf(element)
defer func() {
if e := recover(); e != nil {
ok = false
found = false
}
}()
if reflect.TypeOf(list).Kind() == reflect.String {
return true, strings.Contains(listValue.String(), elementValue.String())
}
for i := 0; i < listValue.Len(); i++ {
if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
return true, true
}
}
return true, false
}
// Contains asserts that the specified string or list(array, slice...) contains the
// specified substring or element.
//
// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
//
// Returns whether the assertion was successful (true) or not (false).
func Contains(t TestingT, s, contains string, msgAndArgs ...interface{}) bool {
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
if !strings.Contains(s, contains) {
ok, found := includeElement(s, contains)
if !ok {
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
}
if !found {
return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...)
}
@ -339,14 +508,20 @@ func Contains(t TestingT, s, contains string, msgAndArgs ...interface{}) bool {
}
// NotContains asserts that the specified string does NOT contain the specified substring.
// NotContains asserts that the specified string or list(array, slice...) does NOT contain the
// specified substring or element.
//
// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
//
// Returns whether the assertion was successful (true) or not (false).
func NotContains(t TestingT, s, contains string, msgAndArgs ...interface{}) bool {
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
if strings.Contains(s, contains) {
ok, found := includeElement(s, contains)
if !ok {
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
}
if found {
return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
}
@ -354,7 +529,7 @@ func NotContains(t TestingT, s, contains string, msgAndArgs ...interface{}) bool
}
// Uses a Comparison to assert a complex condition.
// Condition uses a Comparison to assert a complex condition.
func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
result := comp()
if !result {
@ -370,7 +545,7 @@ type PanicTestFunc func()
// didPanic returns true if the function passed to it panics. Otherwise, it returns false.
func didPanic(f PanicTestFunc) (bool, interface{}) {
var didPanic bool = false
didPanic := false
var message interface{}
func() {
@ -430,12 +605,102 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration,
dt := expected.Sub(actual)
if dt < -delta || dt > delta {
return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, dt, delta), msgAndArgs...)
return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
}
return true
}
func toFloat(x interface{}) (float64, bool) {
var xf float64
xok := true
switch xn := x.(type) {
case uint8:
xf = float64(xn)
case uint16:
xf = float64(xn)
case uint32:
xf = float64(xn)
case uint64:
xf = float64(xn)
case int:
xf = float64(xn)
case int8:
xf = float64(xn)
case int16:
xf = float64(xn)
case int32:
xf = float64(xn)
case int64:
xf = float64(xn)
case float32:
xf = float64(xn)
case float64:
xf = float64(xn)
default:
xok = false
}
return xf, xok
}
// InDelta asserts that the two numerals are within delta of each other.
//
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
//
// Returns whether the assertion was successful (true) or not (false).
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
af, aok := toFloat(expected)
bf, bok := toFloat(actual)
if !aok || !bok {
return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
}
dt := af - bf
if dt < -delta || dt > delta {
return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
}
return true
}
// min(|expected|, |actual|) * epsilon
func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 {
af, aok := toFloat(expected)
bf, bok := toFloat(actual)
if !aok || !bok {
// invalid input
return 0
}
if af < 0 {
af = -af
}
if bf < 0 {
bf = -bf
}
var delta float64
if af < bf {
delta = af * epsilon
} else {
delta = bf * epsilon
}
return delta
}
// InEpsilon asserts that expected and actual have a relative error less than epsilon
//
// Returns whether the assertion was successful (true) or not (false).
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
delta := calcEpsilonDelta(expected, actual, epsilon)
return InDelta(t, expected, actual, delta, msgAndArgs...)
}
/*
Errors
*/
@ -449,10 +714,11 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration,
//
// Returns whether the assertion was successful (true) or not (false).
func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
if isNil(err) {
return true
}
message := messageFromMsgAndArgs(msgAndArgs...)
return Nil(t, err, "No error is expected but got %v %s", err, message)
return Fail(t, fmt.Sprintf("No error is expected but got %v", err), msgAndArgs...)
}
// Error asserts that a function returned an error (i.e. not `nil`).
@ -470,7 +736,8 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
}
// Error asserts that a function returned an error (i.e. not `nil`).
// EqualError asserts that a function returned an error (i.e. not `nil`)
// and that it is equal to the provided error.
//
// actualObj, err := SomeFunction()
// if assert.Error(t, err, "An error was expected") {
@ -488,3 +755,51 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
return Equal(t, theError.Error(), errString,
s, errString, theError.Error(), message)
}
// matchRegexp return true if a specified regexp matches a string.
func matchRegexp(rx interface{}, str interface{}) bool {
var r *regexp.Regexp
if rr, ok := rx.(*regexp.Regexp); ok {
r = rr
} else {
r = regexp.MustCompile(fmt.Sprint(rx))
}
return (r.FindStringIndex(fmt.Sprint(str)) != nil)
}
// Regexp asserts that a specified regexp matches a string.
//
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
// assert.Regexp(t, "start...$", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
match := matchRegexp(rx, str)
if !match {
Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...)
}
return match
}
// NotRegexp asserts that a specified regexp does not match a string.
//
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
// assert.NotRegexp(t, "^start", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
match := matchRegexp(rx, str)
if match {
Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...)
}
return !match
}

View File

@ -2,6 +2,7 @@ package assert
import (
"errors"
"regexp"
"testing"
"time"
)
@ -39,6 +40,27 @@ func TestObjectsAreEqual(t *testing.T) {
if !ObjectsAreEqual(nil, nil) {
t.Error("objectsAreEqual should return true")
}
if ObjectsAreEqual(map[int]int{5: 10}, map[int]int{10: 20}) {
t.Error("objectsAreEqual should return false")
}
if ObjectsAreEqual('x', "x") {
t.Error("objectsAreEqual should return false")
}
if ObjectsAreEqual("x", 'x') {
t.Error("objectsAreEqual should return false")
}
if ObjectsAreEqual(0, 0.1) {
t.Error("objectsAreEqual should return false")
}
if ObjectsAreEqual(0.1, 0) {
t.Error("objectsAreEqual should return false")
}
if ObjectsAreEqual(uint32(10), int32(10)) {
t.Error("objectsAreEqual should return false")
}
if !ObjectsAreEqualValues(uint32(10), int32(10)) {
t.Error("ObjectsAreEqualValues should return true")
}
}
@ -87,6 +109,16 @@ func TestEqual(t *testing.T) {
if !Equal(mockT, nil, nil) {
t.Error("Equal should return true")
}
if !Equal(mockT, int32(123), int32(123)) {
t.Error("Equal should return true")
}
if !Equal(mockT, uint64(123), uint64(123)) {
t.Error("Equal should return true")
}
funcA := func() int { return 42 }
if !Equal(mockT, funcA, funcA) {
t.Error("Equal should return true")
}
}
@ -189,11 +221,43 @@ func TestNotEqual(t *testing.T) {
if !NotEqual(mockT, nil, new(AssertionTesterConformingObject)) {
t.Error("NotEqual should return true")
}
funcA := func() int { return 23 }
funcB := func() int { return 42 }
if !NotEqual(mockT, funcA, funcB) {
t.Error("NotEqual should return true")
}
if NotEqual(mockT, "Hello World", "Hello World") {
t.Error("NotEqual should return false")
}
if NotEqual(mockT, 123, 123) {
t.Error("NotEqual should return false")
}
if NotEqual(mockT, 123.5, 123.5) {
t.Error("NotEqual should return false")
}
if NotEqual(mockT, []byte("Hello World"), []byte("Hello World")) {
t.Error("NotEqual should return false")
}
if NotEqual(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
t.Error("NotEqual should return false")
}
}
type A struct {
Name, Value string
}
func TestContains(t *testing.T) {
mockT := new(testing.T)
list := []string{"Foo", "Bar"}
complexList := []*A{
{"b", "c"},
{"d", "e"},
{"g", "h"},
{"j", "k"},
}
if !Contains(mockT, "Hello World", "Hello") {
t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
@ -202,11 +266,24 @@ func TestContains(t *testing.T) {
t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"")
}
if !Contains(mockT, list, "Bar") {
t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Bar\"")
}
if Contains(mockT, list, "Salut") {
t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"")
}
if !Contains(mockT, complexList, &A{"g", "h"}) {
t.Error("Contains should return true: complexList contains {\"g\", \"h\"}")
}
if Contains(mockT, complexList, &A{"g", "e"}) {
t.Error("Contains should return false: complexList contains {\"g\", \"e\"}")
}
}
func TestNotContains(t *testing.T) {
mockT := new(testing.T)
list := []string{"Foo", "Bar"}
if !NotContains(mockT, "Hello World", "Hello!") {
t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
@ -215,6 +292,69 @@ func TestNotContains(t *testing.T) {
t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"")
}
if !NotContains(mockT, list, "Foo!") {
t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"")
}
if NotContains(mockT, list, "Foo") {
t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
}
}
func Test_includeElement(t *testing.T) {
list1 := []string{"Foo", "Bar"}
list2 := []int{1, 2}
ok, found := includeElement("Hello World", "World")
True(t, ok)
True(t, found)
ok, found = includeElement(list1, "Foo")
True(t, ok)
True(t, found)
ok, found = includeElement(list1, "Bar")
True(t, ok)
True(t, found)
ok, found = includeElement(list2, 1)
True(t, ok)
True(t, found)
ok, found = includeElement(list2, 2)
True(t, ok)
True(t, found)
ok, found = includeElement(list1, "Foo!")
True(t, ok)
False(t, found)
ok, found = includeElement(list2, 3)
True(t, ok)
False(t, found)
ok, found = includeElement(list2, "1")
True(t, ok)
False(t, found)
ok, found = includeElement(1433, "1")
False(t, ok)
False(t, found)
}
func TestCondition(t *testing.T) {
mockT := new(testing.T)
if !Condition(mockT, func() bool { return true }, "Truth") {
t.Error("Condition should return true")
}
if Condition(mockT, func() bool { return false }, "Lie") {
t.Error("Condition should return false")
}
}
func TestDidPanic(t *testing.T) {
@ -269,12 +409,12 @@ func TestNotPanics(t *testing.T) {
func TestEqual_Funcs(t *testing.T) {
type f func() int
var f1 f = func() int { return 1 }
var f2 f = func() int { return 2 }
f1 := func() int { return 1 }
f2 := func() int { return 2 }
var f1_copy f = f1
f1Copy := f1
Equal(t, f1_copy, f1, "Funcs are the same and should be considered equal")
Equal(t, f1Copy, f1, "Funcs are the same and should be considered equal")
NotEqual(t, f1, f2, "f1 and f2 are different")
}
@ -284,12 +424,12 @@ func TestNoError(t *testing.T) {
mockT := new(testing.T)
// start with a nil error
var err error = nil
var err error
True(t, NoError(mockT, err), "NoError should return True for nil arg")
// now set an error
err = errors.New("Some error")
err = errors.New("some error")
False(t, NoError(mockT, err), "NoError with error should return False")
@ -300,12 +440,12 @@ func TestError(t *testing.T) {
mockT := new(testing.T)
// start with a nil error
var err error = nil
var err error
False(t, Error(mockT, err), "Error should return False for nil arg")
// now set an error
err = errors.New("Some error")
err = errors.New("some error")
True(t, Error(mockT, err), "Error with error should return True")
@ -315,70 +455,190 @@ func TestEqualError(t *testing.T) {
mockT := new(testing.T)
// start with a nil error
var err error = nil
var err error
False(t, EqualError(mockT, err, ""),
"EqualError should return false for nil arg")
// now set an error
err = errors.New("Some error")
err = errors.New("some error")
False(t, EqualError(mockT, err, "Not some error"),
"EqualError should return false for different error string")
True(t, EqualError(mockT, err, "Some error"),
True(t, EqualError(mockT, err, "some error"),
"EqualError should return true")
}
func Test_isEmpty(t *testing.T) {
chWithValue := make(chan struct{}, 1)
chWithValue <- struct{}{}
True(t, isEmpty(""))
True(t, isEmpty(nil))
True(t, isEmpty([]string{}))
True(t, isEmpty(0))
True(t, isEmpty(int32(0)))
True(t, isEmpty(int64(0)))
True(t, isEmpty(false))
True(t, isEmpty(map[string]string{}))
True(t, isEmpty(new(time.Time)))
True(t, isEmpty(make(chan struct{})))
False(t, isEmpty("something"))
False(t, isEmpty(errors.New("something")))
False(t, isEmpty([]string{"something"}))
False(t, isEmpty(1))
False(t, isEmpty(true))
False(t, isEmpty(map[string]string{"Hello": "World"}))
False(t, isEmpty(chWithValue))
}
func TestEmpty(t *testing.T) {
mockT := new(testing.T)
chWithValue := make(chan struct{}, 1)
chWithValue <- struct{}{}
True(t, Empty(mockT, ""), "Empty string is empty")
True(t, Empty(mockT, nil), "Nil is empty")
True(t, Empty(mockT, []string{}), "Empty string array is empty")
True(t, Empty(mockT, 0), "Zero int value is empty")
True(t, Empty(mockT, false), "False value is empty")
True(t, Empty(mockT, make(chan struct{})), "Channel without values is empty")
False(t, Empty(mockT, "something"), "Non Empty string is not empty")
False(t, Empty(mockT, errors.New("something")), "Non nil object is not empty")
False(t, Empty(mockT, []string{"something"}), "Non empty string array is not empty")
False(t, Empty(mockT, 1), "Non-zero int value is not empty")
False(t, Empty(mockT, true), "True value is not empty")
False(t, Empty(mockT, chWithValue), "Channel with values is not empty")
}
func TestNotEmpty(t *testing.T) {
mockT := new(testing.T)
chWithValue := make(chan struct{}, 1)
chWithValue <- struct{}{}
False(t, NotEmpty(mockT, ""), "Empty string is empty")
False(t, NotEmpty(mockT, nil), "Nil is empty")
False(t, NotEmpty(mockT, []string{}), "Empty string array is empty")
False(t, NotEmpty(mockT, 0), "Zero int value is empty")
False(t, NotEmpty(mockT, false), "False value is empty")
False(t, NotEmpty(mockT, make(chan struct{})), "Channel without values is empty")
True(t, NotEmpty(mockT, "something"), "Non Empty string is not empty")
True(t, NotEmpty(mockT, errors.New("something")), "Non nil object is not empty")
True(t, NotEmpty(mockT, []string{"something"}), "Non empty string array is not empty")
True(t, NotEmpty(mockT, 1), "Non-zero int value is not empty")
True(t, NotEmpty(mockT, true), "True value is not empty")
True(t, NotEmpty(mockT, chWithValue), "Channel with values is not empty")
}
func Test_getLen(t *testing.T) {
falseCases := []interface{}{
nil,
0,
true,
false,
'A',
struct{}{},
}
for _, v := range falseCases {
ok, l := getLen(v)
False(t, ok, "Expected getLen fail to get length of %#v", v)
Equal(t, 0, l, "getLen should return 0 for %#v", v)
}
ch := make(chan int, 5)
ch <- 1
ch <- 2
ch <- 3
trueCases := []struct {
v interface{}
l int
}{
{[]int{1, 2, 3}, 3},
{[...]int{1, 2, 3}, 3},
{"ABC", 3},
{map[int]int{1: 2, 2: 4, 3: 6}, 3},
{ch, 3},
{[]int{}, 0},
{map[int]int{}, 0},
{make(chan int), 0},
{[]int(nil), 0},
{map[int]int(nil), 0},
{(chan int)(nil), 0},
}
for _, c := range trueCases {
ok, l := getLen(c.v)
True(t, ok, "Expected getLen success to get length of %#v", c.v)
Equal(t, c.l, l)
}
}
func TestLen(t *testing.T) {
mockT := new(testing.T)
False(t, Len(mockT, nil, 0), "nil does not have length")
False(t, Len(mockT, 0, 0), "int does not have length")
False(t, Len(mockT, true, 0), "true does not have length")
False(t, Len(mockT, false, 0), "false does not have length")
False(t, Len(mockT, 'A', 0), "Rune does not have length")
False(t, Len(mockT, struct{}{}, 0), "Struct does not have length")
ch := make(chan int, 5)
ch <- 1
ch <- 2
ch <- 3
cases := []struct {
v interface{}
l int
}{
{[]int{1, 2, 3}, 3},
{[...]int{1, 2, 3}, 3},
{"ABC", 3},
{map[int]int{1: 2, 2: 4, 3: 6}, 3},
{ch, 3},
{[]int{}, 0},
{map[int]int{}, 0},
{make(chan int), 0},
{[]int(nil), 0},
{map[int]int(nil), 0},
{(chan int)(nil), 0},
}
for _, c := range cases {
True(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
}
cases = []struct {
v interface{}
l int
}{
{[]int{1, 2, 3}, 4},
{[...]int{1, 2, 3}, 2},
{"ABC", 2},
{map[int]int{1: 2, 2: 4, 3: 6}, 4},
{ch, 2},
{[]int{}, 1},
{map[int]int{}, 1},
{make(chan int), 1},
{[]int(nil), 1},
{map[int]int(nil), 1},
{(chan int)(nil), 1},
}
for _, c := range cases {
False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
}
}
func TestWithinDuration(t *testing.T) {
@ -399,3 +659,110 @@ func TestWithinDuration(t *testing.T) {
False(t, WithinDuration(mockT, a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
False(t, WithinDuration(mockT, b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
}
func TestInDelta(t *testing.T) {
mockT := new(testing.T)
True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
True(t, InDelta(mockT, 1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
True(t, InDelta(mockT, 1, 2, 1), "|1 - 2| <= 1")
False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail")
cases := []struct {
a, b interface{}
delta float64
}{
{uint8(2), uint8(1), 1},
{uint16(2), uint16(1), 1},
{uint32(2), uint32(1), 1},
{uint64(2), uint64(1), 1},
{int(2), int(1), 1},
{int8(2), int8(1), 1},
{int16(2), int16(1), 1},
{int32(2), int32(1), 1},
{int64(2), int64(1), 1},
{float32(2), float32(1), 1},
{float64(2), float64(1), 1},
}
for _, tc := range cases {
True(t, InDelta(mockT, tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
}
}
func TestInEpsilon(t *testing.T) {
mockT := new(testing.T)
cases := []struct {
a, b interface{}
epsilon float64
}{
{uint8(2), uint16(2), .001},
{2.1, 2.2, 0.1},
{2.2, 2.1, 0.1},
{-2.1, -2.2, 0.1},
{-2.2, -2.1, 0.1},
{uint64(100), uint8(101), 0.01},
{0.1, -0.1, 2},
}
for _, tc := range cases {
True(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
}
cases = []struct {
a, b interface{}
epsilon float64
}{
{uint8(2), int16(-2), .001},
{uint64(100), uint8(102), 0.01},
{2.1, 2.2, 0.001},
{2.2, 2.1, 0.001},
{2.1, -2.2, 1},
{2.1, "bla-bla", 0},
{0.1, -0.1, 1.99},
}
for _, tc := range cases {
False(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
}
}
func TestRegexp(t *testing.T) {
mockT := new(testing.T)
cases := []struct {
rx, str string
}{
{"^start", "start of the line"},
{"end$", "in the end"},
{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"},
}
for _, tc := range cases {
True(t, Regexp(mockT, tc.rx, tc.str))
True(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str))
False(t, NotRegexp(mockT, tc.rx, tc.str))
False(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
}
cases = []struct {
rx, str string
}{
{"^asdfastart", "Not the start of the line"},
{"end$", "in the end."},
{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"},
}
for _, tc := range cases {
False(t, Regexp(mockT, tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
False(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str))
True(t, NotRegexp(mockT, tc.rx, tc.str))
True(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
}
}

View File

@ -17,6 +17,22 @@
//
// }
//
// if you assert many times, use the below:
//
// import (
// "testing"
// "github.com/stretchr/testify/assert"
// )
//
// func TestSomething(t *testing.T) {
// assert := assert.New(t)
//
// var a string = "Hello"
// var b string = "Hello"
//
// assert.Equal(a, b, "The two words should be the same.")
// }
//
// Assertions
//
// Assertions allow you to easily write test code, and are global funcs in the `assert` package.
@ -45,17 +61,21 @@
//
// assert.NotEmpty(t, actualObject [, message [, format-args]])
//
// assert.Len(t, actualObject, expectedLength, [, message [, format-args]])
//
// assert.Error(t, errorObject [, message [, format-args]])
//
// assert.NoError(t, errorObject [, message [, format-args]])
//
// assert.EqualError(t, theError, errString [, message [, format-args]])
//
// assert.Implements(t, (*MyInterface)(nil), new(MyObject) [,message [, format-args]])
//
// assert.IsType(t, expectedObject, actualObject [, message [, format-args]])
//
// assert.Contains(t, string, substring [, message [, format-args]])
// assert.Contains(t, stringOrSlice, substringOrElement [, message [, format-args]])
//
// assert.NotContains(t, string, substring [, message [, format-args]])
// assert.NotContains(t, stringOrSlice, substringOrElement [, message [, format-args]])
//
// assert.Panics(t, func(){
//
@ -70,5 +90,61 @@
// } [, message [, format-args]])
//
// assert.WithinDuration(t, timeA, timeB, deltaTime, [, message [, format-args]])
//
// assert.InDelta(t, numA, numB, delta, [, message [, format-args]])
//
// assert.InEpsilon(t, numA, numB, epsilon, [, message [, format-args]])
//
// assert package contains Assertions object. it has assertion methods.
//
// Here is an overview of the assert functions:
// assert.Equal(expected, actual [, message [, format-args])
//
// assert.NotEqual(notExpected, actual [, message [, format-args]])
//
// assert.True(actualBool [, message [, format-args]])
//
// assert.False(actualBool [, message [, format-args]])
//
// assert.Nil(actualObject [, message [, format-args]])
//
// assert.NotNil(actualObject [, message [, format-args]])
//
// assert.Empty(actualObject [, message [, format-args]])
//
// assert.NotEmpty(actualObject [, message [, format-args]])
//
// assert.Len(actualObject, expectedLength, [, message [, format-args]])
//
// assert.Error(errorObject [, message [, format-args]])
//
// assert.NoError(errorObject [, message [, format-args]])
//
// assert.EqualError(theError, errString [, message [, format-args]])
//
// assert.Implements((*MyInterface)(nil), new(MyObject) [,message [, format-args]])
//
// assert.IsType(expectedObject, actualObject [, message [, format-args]])
//
// assert.Contains(stringOrSlice, substringOrElement [, message [, format-args]])
//
// assert.NotContains(stringOrSlice, substringOrElement [, message [, format-args]])
//
// assert.Panics(func(){
//
// // call code that should panic
//
// } [, message [, format-args]])
//
// assert.NotPanics(func(){
//
// // call code that should not panic
//
// } [, message [, format-args]])
//
// assert.WithinDuration(timeA, timeB, deltaTime, [, message [, format-args]])
//
// assert.InDelta(numA, numB, delta, [, message [, format-args]])
//
// assert.InEpsilon(numA, numB, epsilon, [, message [, format-args]])
package assert

View File

@ -7,4 +7,4 @@ import (
// AnError is an error instance useful for testing. If the code does not care
// about error specifics, and only needs to return the error for example, this
// error should be used to make the test code more readable.
var AnError error = errors.New("assert.AnError general error for testing.")
var AnError = errors.New("assert.AnError general error for testing")

View File

@ -0,0 +1,262 @@
package assert
import "time"
type Assertions struct {
t TestingT
}
func New(t TestingT) *Assertions {
return &Assertions{
t: t,
}
}
// Fail reports a failure through
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
return Fail(a.t, failureMessage, msgAndArgs...)
}
// Implements asserts that an object is implemented by the specified interface.
//
// assert.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
return Implements(a.t, interfaceObject, object, msgAndArgs...)
}
// IsType asserts that the specified objects are of the same type.
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
return IsType(a.t, expectedType, object, msgAndArgs...)
}
// Equal asserts that two objects are equal.
//
// assert.Equal(123, 123, "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) bool {
return Equal(a.t, expected, actual, msgAndArgs...)
}
// EqualValues asserts that two objects are equal or convertable to the same types
// and equal.
//
// assert.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) EqualValues(expected, actual interface{}, msgAndArgs ...interface{}) bool {
return EqualValues(a.t, expected, actual, msgAndArgs...)
}
// Exactly asserts that two objects are equal is value and type.
//
// assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Exactly(expected, actual interface{}, msgAndArgs ...interface{}) bool {
return Exactly(a.t, expected, actual, msgAndArgs...)
}
// NotNil asserts that the specified object is not nil.
//
// assert.NotNil(err, "err should be something")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
return NotNil(a.t, object, msgAndArgs...)
}
// Nil asserts that the specified object is nil.
//
// assert.Nil(err, "err should be nothing")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
return Nil(a.t, object, msgAndArgs...)
}
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a
// slice with len == 0.
//
// assert.Empty(obj)
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
return Empty(a.t, object, msgAndArgs...)
}
// Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
// slice with len == 0.
//
// if assert.NotEmpty(obj) {
// assert.Equal("two", obj[1])
// }
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
return NotEmpty(a.t, object, msgAndArgs...)
}
// Len asserts that the specified object has specific length.
// Len also fails if the object has a type that len() not accept.
//
// assert.Len(mySlice, 3, "The size of slice is not 3")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
return Len(a.t, object, length, msgAndArgs...)
}
// True asserts that the specified value is true.
//
// assert.True(myBool, "myBool should be true")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
return True(a.t, value, msgAndArgs...)
}
// False asserts that the specified value is true.
//
// assert.False(myBool, "myBool should be false")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
return False(a.t, value, msgAndArgs...)
}
// NotEqual asserts that the specified values are NOT equal.
//
// assert.NotEqual(obj1, obj2, "two objects shouldn't be equal")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NotEqual(expected, actual interface{}, msgAndArgs ...interface{}) bool {
return NotEqual(a.t, expected, actual, msgAndArgs...)
}
// Contains asserts that the specified string contains the specified substring.
//
// assert.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Contains(s, contains interface{}, msgAndArgs ...interface{}) bool {
return Contains(a.t, s, contains, msgAndArgs...)
}
// NotContains asserts that the specified string does NOT contain the specified substring.
//
// assert.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interface{}) bool {
return NotContains(a.t, s, contains, msgAndArgs...)
}
// Uses a Comparison to assert a complex condition.
func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
return Condition(a.t, comp, msgAndArgs...)
}
// Panics asserts that the code inside the specified PanicTestFunc panics.
//
// assert.Panics(func(){
// GoCrazy()
// }, "Calling GoCrazy() should panic")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
return Panics(a.t, f, msgAndArgs...)
}
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
//
// assert.NotPanics(func(){
// RemainCalm()
// }, "Calling RemainCalm() should NOT panic")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
return NotPanics(a.t, f, msgAndArgs...)
}
// WithinDuration asserts that the two times are within duration delta of each other.
//
// assert.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
}
// InDelta asserts that the two numerals are within delta of each other.
//
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
}
// InEpsilon asserts that expected and actual have a relative error less than epsilon
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
}
// NoError asserts that a function returned no error (i.e. `nil`).
//
// actualObj, err := SomeFunction()
// if assert.NoError(err) {
// assert.Equal(actualObj, expectedObj)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NoError(theError error, msgAndArgs ...interface{}) bool {
return NoError(a.t, theError, msgAndArgs...)
}
// Error asserts that a function returned an error (i.e. not `nil`).
//
// actualObj, err := SomeFunction()
// if assert.Error(err, "An error was expected") {
// assert.Equal(err, expectedError)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) bool {
return Error(a.t, theError, msgAndArgs...)
}
// EqualError asserts that a function returned an error (i.e. not `nil`)
// and that it is equal to the provided error.
//
// actualObj, err := SomeFunction()
// if assert.Error(err, "An error was expected") {
// assert.Equal(err, expectedError)
// }
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
return EqualError(a.t, theError, errString, msgAndArgs...)
}
// Regexp asserts that a specified regexp matches a string.
//
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
// assert.Regexp(t, "start...$", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
return Regexp(a.t, rx, str, msgAndArgs...)
}
// NotRegexp asserts that a specified regexp does not match a string.
//
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
// assert.NotRegexp(t, "^start", "it's not starting")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
return NotRegexp(a.t, rx, str, msgAndArgs...)
}

View File

@ -0,0 +1,526 @@
package assert
import (
"errors"
"regexp"
"testing"
"time"
)
func TestImplementsWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) {
t.Error("Implements method should return true: AssertionTesterConformingObject implements AssertionTesterInterface")
}
if assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
}
}
func TestIsTypeWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
t.Error("IsType should return true: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject")
}
if assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) {
t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject")
}
}
func TestEqualWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.Equal("Hello World", "Hello World") {
t.Error("Equal should return true")
}
if !assert.Equal(123, 123) {
t.Error("Equal should return true")
}
if !assert.Equal(123.5, 123.5) {
t.Error("Equal should return true")
}
if !assert.Equal([]byte("Hello World"), []byte("Hello World")) {
t.Error("Equal should return true")
}
if !assert.Equal(nil, nil) {
t.Error("Equal should return true")
}
}
func TestEqualValuesWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.EqualValues(uint32(10), int32(10)) {
t.Error("EqualValues should return true")
}
}
func TestNotNilWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.NotNil(new(AssertionTesterConformingObject)) {
t.Error("NotNil should return true: object is not nil")
}
if assert.NotNil(nil) {
t.Error("NotNil should return false: object is nil")
}
}
func TestNilWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.Nil(nil) {
t.Error("Nil should return true: object is nil")
}
if assert.Nil(new(AssertionTesterConformingObject)) {
t.Error("Nil should return false: object is not nil")
}
}
func TestTrueWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.True(true) {
t.Error("True should return true")
}
if assert.True(false) {
t.Error("True should return false")
}
}
func TestFalseWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.False(false) {
t.Error("False should return true")
}
if assert.False(true) {
t.Error("False should return false")
}
}
func TestExactlyWrapper(t *testing.T) {
assert := New(new(testing.T))
a := float32(1)
b := float64(1)
c := float32(1)
d := float32(2)
if assert.Exactly(a, b) {
t.Error("Exactly should return false")
}
if assert.Exactly(a, d) {
t.Error("Exactly should return false")
}
if !assert.Exactly(a, c) {
t.Error("Exactly should return true")
}
if assert.Exactly(nil, a) {
t.Error("Exactly should return false")
}
if assert.Exactly(a, nil) {
t.Error("Exactly should return false")
}
}
func TestNotEqualWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.NotEqual("Hello World", "Hello World!") {
t.Error("NotEqual should return true")
}
if !assert.NotEqual(123, 1234) {
t.Error("NotEqual should return true")
}
if !assert.NotEqual(123.5, 123.55) {
t.Error("NotEqual should return true")
}
if !assert.NotEqual([]byte("Hello World"), []byte("Hello World!")) {
t.Error("NotEqual should return true")
}
if !assert.NotEqual(nil, new(AssertionTesterConformingObject)) {
t.Error("NotEqual should return true")
}
}
func TestContainsWrapper(t *testing.T) {
assert := New(new(testing.T))
list := []string{"Foo", "Bar"}
if !assert.Contains("Hello World", "Hello") {
t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
}
if assert.Contains("Hello World", "Salut") {
t.Error("Contains should return false: \"Hello World\" does not contain \"Salut\"")
}
if !assert.Contains(list, "Foo") {
t.Error("Contains should return true: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
}
if assert.Contains(list, "Salut") {
t.Error("Contains should return false: \"[\"Foo\", \"Bar\"]\" does not contain \"Salut\"")
}
}
func TestNotContainsWrapper(t *testing.T) {
assert := New(new(testing.T))
list := []string{"Foo", "Bar"}
if !assert.NotContains("Hello World", "Hello!") {
t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
}
if assert.NotContains("Hello World", "Hello") {
t.Error("NotContains should return false: \"Hello World\" contains \"Hello\"")
}
if !assert.NotContains(list, "Foo!") {
t.Error("NotContains should return true: \"[\"Foo\", \"Bar\"]\" does not contain \"Foo!\"")
}
if assert.NotContains(list, "Foo") {
t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
}
}
func TestConditionWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.Condition(func() bool { return true }, "Truth") {
t.Error("Condition should return true")
}
if assert.Condition(func() bool { return false }, "Lie") {
t.Error("Condition should return false")
}
}
func TestDidPanicWrapper(t *testing.T) {
if funcDidPanic, _ := didPanic(func() {
panic("Panic!")
}); !funcDidPanic {
t.Error("didPanic should return true")
}
if funcDidPanic, _ := didPanic(func() {
}); funcDidPanic {
t.Error("didPanic should return false")
}
}
func TestPanicsWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.Panics(func() {
panic("Panic!")
}) {
t.Error("Panics should return true")
}
if assert.Panics(func() {
}) {
t.Error("Panics should return false")
}
}
func TestNotPanicsWrapper(t *testing.T) {
assert := New(new(testing.T))
if !assert.NotPanics(func() {
}) {
t.Error("NotPanics should return true")
}
if assert.NotPanics(func() {
panic("Panic!")
}) {
t.Error("NotPanics should return false")
}
}
func TestEqualWrapper_Funcs(t *testing.T) {
assert := New(t)
type f func() int
var f1 f = func() int { return 1 }
var f2 f = func() int { return 2 }
var f1_copy f = f1
assert.Equal(f1_copy, f1, "Funcs are the same and should be considered equal")
assert.NotEqual(f1, f2, "f1 and f2 are different")
}
func TestNoErrorWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
// start with a nil error
var err error = nil
assert.True(mockAssert.NoError(err), "NoError should return True for nil arg")
// now set an error
err = errors.New("Some error")
assert.False(mockAssert.NoError(err), "NoError with error should return False")
}
func TestErrorWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
// start with a nil error
var err error = nil
assert.False(mockAssert.Error(err), "Error should return False for nil arg")
// now set an error
err = errors.New("Some error")
assert.True(mockAssert.Error(err), "Error with error should return True")
}
func TestEqualErrorWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
// start with a nil error
var err error
assert.False(mockAssert.EqualError(err, ""),
"EqualError should return false for nil arg")
// now set an error
err = errors.New("some error")
assert.False(mockAssert.EqualError(err, "Not some error"),
"EqualError should return false for different error string")
assert.True(mockAssert.EqualError(err, "some error"),
"EqualError should return true")
}
func TestEmptyWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
assert.True(mockAssert.Empty(""), "Empty string is empty")
assert.True(mockAssert.Empty(nil), "Nil is empty")
assert.True(mockAssert.Empty([]string{}), "Empty string array is empty")
assert.True(mockAssert.Empty(0), "Zero int value is empty")
assert.True(mockAssert.Empty(false), "False value is empty")
assert.False(mockAssert.Empty("something"), "Non Empty string is not empty")
assert.False(mockAssert.Empty(errors.New("something")), "Non nil object is not empty")
assert.False(mockAssert.Empty([]string{"something"}), "Non empty string array is not empty")
assert.False(mockAssert.Empty(1), "Non-zero int value is not empty")
assert.False(mockAssert.Empty(true), "True value is not empty")
}
func TestNotEmptyWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
assert.False(mockAssert.NotEmpty(""), "Empty string is empty")
assert.False(mockAssert.NotEmpty(nil), "Nil is empty")
assert.False(mockAssert.NotEmpty([]string{}), "Empty string array is empty")
assert.False(mockAssert.NotEmpty(0), "Zero int value is empty")
assert.False(mockAssert.NotEmpty(false), "False value is empty")
assert.True(mockAssert.NotEmpty("something"), "Non Empty string is not empty")
assert.True(mockAssert.NotEmpty(errors.New("something")), "Non nil object is not empty")
assert.True(mockAssert.NotEmpty([]string{"something"}), "Non empty string array is not empty")
assert.True(mockAssert.NotEmpty(1), "Non-zero int value is not empty")
assert.True(mockAssert.NotEmpty(true), "True value is not empty")
}
func TestLenWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
assert.False(mockAssert.Len(nil, 0), "nil does not have length")
assert.False(mockAssert.Len(0, 0), "int does not have length")
assert.False(mockAssert.Len(true, 0), "true does not have length")
assert.False(mockAssert.Len(false, 0), "false does not have length")
assert.False(mockAssert.Len('A', 0), "Rune does not have length")
assert.False(mockAssert.Len(struct{}{}, 0), "Struct does not have length")
ch := make(chan int, 5)
ch <- 1
ch <- 2
ch <- 3
cases := []struct {
v interface{}
l int
}{
{[]int{1, 2, 3}, 3},
{[...]int{1, 2, 3}, 3},
{"ABC", 3},
{map[int]int{1: 2, 2: 4, 3: 6}, 3},
{ch, 3},
{[]int{}, 0},
{map[int]int{}, 0},
{make(chan int), 0},
{[]int(nil), 0},
{map[int]int(nil), 0},
{(chan int)(nil), 0},
}
for _, c := range cases {
assert.True(mockAssert.Len(c.v, c.l), "%#v have %d items", c.v, c.l)
}
}
func TestWithinDurationWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
a := time.Now()
b := a.Add(10 * time.Second)
assert.True(mockAssert.WithinDuration(a, b, 10*time.Second), "A 10s difference is within a 10s time difference")
assert.True(mockAssert.WithinDuration(b, a, 10*time.Second), "A 10s difference is within a 10s time difference")
assert.False(mockAssert.WithinDuration(a, b, 9*time.Second), "A 10s difference is not within a 9s time difference")
assert.False(mockAssert.WithinDuration(b, a, 9*time.Second), "A 10s difference is not within a 9s time difference")
assert.False(mockAssert.WithinDuration(a, b, -9*time.Second), "A 10s difference is not within a 9s time difference")
assert.False(mockAssert.WithinDuration(b, a, -9*time.Second), "A 10s difference is not within a 9s time difference")
assert.False(mockAssert.WithinDuration(a, b, -11*time.Second), "A 10s difference is not within a 9s time difference")
assert.False(mockAssert.WithinDuration(b, a, -11*time.Second), "A 10s difference is not within a 9s time difference")
}
func TestInDeltaWrapper(t *testing.T) {
assert := New(new(testing.T))
True(t, assert.InDelta(1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
True(t, assert.InDelta(1, 1.001, 0.01), "|1 - 1.001| <= 0.01")
True(t, assert.InDelta(1, 2, 1), "|1 - 2| <= 1")
False(t, assert.InDelta(1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail")
False(t, assert.InDelta(2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
False(t, assert.InDelta("", nil, 1), "Expected non numerals to fail")
cases := []struct {
a, b interface{}
delta float64
}{
{uint8(2), uint8(1), 1},
{uint16(2), uint16(1), 1},
{uint32(2), uint32(1), 1},
{uint64(2), uint64(1), 1},
{int(2), int(1), 1},
{int8(2), int8(1), 1},
{int16(2), int16(1), 1},
{int32(2), int32(1), 1},
{int64(2), int64(1), 1},
{float32(2), float32(1), 1},
{float64(2), float64(1), 1},
}
for _, tc := range cases {
True(t, assert.InDelta(tc.a, tc.b, tc.delta), "Expected |%V - %V| <= %v", tc.a, tc.b, tc.delta)
}
}
func TestInEpsilonWrapper(t *testing.T) {
assert := New(new(testing.T))
cases := []struct {
a, b interface{}
epsilon float64
}{
{uint8(2), uint16(2), .001},
{2.1, 2.2, 0.1},
{2.2, 2.1, 0.1},
{-2.1, -2.2, 0.1},
{-2.2, -2.1, 0.1},
{uint64(100), uint8(101), 0.01},
{0.1, -0.1, 2},
}
for _, tc := range cases {
True(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
}
cases = []struct {
a, b interface{}
epsilon float64
}{
{uint8(2), int16(-2), .001},
{uint64(100), uint8(102), 0.01},
{2.1, 2.2, 0.001},
{2.2, 2.1, 0.001},
{2.1, -2.2, 1},
{2.1, "bla-bla", 0},
{0.1, -0.1, 1.99},
}
for _, tc := range cases {
False(t, assert.InEpsilon(tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon))
}
}
func TestRegexpWrapper(t *testing.T) {
assert := New(new(testing.T))
cases := []struct {
rx, str string
}{
{"^start", "start of the line"},
{"end$", "in the end"},
{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12.34"},
}
for _, tc := range cases {
True(t, assert.Regexp(tc.rx, tc.str))
True(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
False(t, assert.NotRegexp(tc.rx, tc.str))
False(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
}
cases = []struct {
rx, str string
}{
{"^asdfastart", "Not the start of the line"},
{"end$", "in the end."},
{"[0-9]{3}[.-]?[0-9]{2}[.-]?[0-9]{2}", "My phone number is 650.12a.34"},
}
for _, tc := range cases {
False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
True(t, assert.NotRegexp(tc.rx, tc.str))
True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
}
}

View File

@ -0,0 +1,157 @@
package assert
import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"strings"
)
// httpCode is a helper that returns HTTP code of the response. It returns -1
// if building a new request fails.
func httpCode(handler http.HandlerFunc, mode, url string, values url.Values) int {
w := httptest.NewRecorder()
req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
if err != nil {
return -1
}
handler(w, req)
return w.Code
}
// HTTPSuccess asserts that a specified handler returns a success status code.
//
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
code := httpCode(handler, mode, url, values)
if code == -1 {
return false
}
return code >= http.StatusOK && code <= http.StatusPartialContent
}
// HTTPRedirect asserts that a specified handler returns a redirect status code.
//
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPRedirect(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
code := httpCode(handler, mode, url, values)
if code == -1 {
return false
}
return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
}
// HTTPError asserts that a specified handler returns an error status code.
//
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPError(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
code := httpCode(handler, mode, url, values)
if code == -1 {
return false
}
return code >= http.StatusBadRequest
}
// HttpBody is a helper that returns HTTP body of the response. It returns
// empty string if building a new request fails.
func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) string {
w := httptest.NewRecorder()
req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
if err != nil {
return ""
}
handler(w, req)
return w.Body.String()
}
// HTTPBodyContains asserts that a specified handler returns a
// body that contains a string.
//
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
body := HttpBody(handler, mode, url, values)
contains := strings.Contains(body, fmt.Sprint(str))
if !contains {
Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
}
return contains
}
// HTTPBodyNotContains asserts that a specified handler returns a
// body that does not contain a string.
//
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
body := HttpBody(handler, mode, url, values)
contains := strings.Contains(body, fmt.Sprint(str))
if contains {
Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)
}
return !contains
}
//
// Assertions Wrappers
//
// HTTPSuccess asserts that a specified handler returns a success status code.
//
// assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, values url.Values) bool {
return HTTPSuccess(a.t, handler, mode, url, values)
}
// HTTPRedirect asserts that a specified handler returns a redirect status code.
//
// assert.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, mode, url string, values url.Values) bool {
return HTTPRedirect(a.t, handler, mode, url, values)
}
// HTTPError asserts that a specified handler returns an error status code.
//
// assert.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPError(handler http.HandlerFunc, mode, url string, values url.Values) bool {
return HTTPError(a.t, handler, mode, url, values)
}
// HTTPBodyContains asserts that a specified handler returns a
// body that contains a string.
//
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
return HTTPBodyContains(a.t, handler, mode, url, values, str)
}
// HTTPBodyNotContains asserts that a specified handler returns a
// body that does not contain a string.
//
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
return HTTPBodyNotContains(a.t, handler, mode, url, values, str)
}

View File

@ -0,0 +1,86 @@
package assert
import (
"fmt"
"net/http"
"net/url"
"testing"
)
func httpOK(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func httpRedirect(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusTemporaryRedirect)
}
func httpError(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}
func TestHTTPStatuses(t *testing.T) {
assert := New(t)
mockT := new(testing.T)
assert.Equal(HTTPSuccess(mockT, httpOK, "GET", "/", nil), true)
assert.Equal(HTTPSuccess(mockT, httpRedirect, "GET", "/", nil), false)
assert.Equal(HTTPSuccess(mockT, httpError, "GET", "/", nil), false)
assert.Equal(HTTPRedirect(mockT, httpOK, "GET", "/", nil), false)
assert.Equal(HTTPRedirect(mockT, httpRedirect, "GET", "/", nil), true)
assert.Equal(HTTPRedirect(mockT, httpError, "GET", "/", nil), false)
assert.Equal(HTTPError(mockT, httpOK, "GET", "/", nil), false)
assert.Equal(HTTPError(mockT, httpRedirect, "GET", "/", nil), false)
assert.Equal(HTTPError(mockT, httpError, "GET", "/", nil), true)
}
func TestHTTPStatusesWrapper(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
assert.Equal(mockAssert.HTTPSuccess(httpOK, "GET", "/", nil), true)
assert.Equal(mockAssert.HTTPSuccess(httpRedirect, "GET", "/", nil), false)
assert.Equal(mockAssert.HTTPSuccess(httpError, "GET", "/", nil), false)
assert.Equal(mockAssert.HTTPRedirect(httpOK, "GET", "/", nil), false)
assert.Equal(mockAssert.HTTPRedirect(httpRedirect, "GET", "/", nil), true)
assert.Equal(mockAssert.HTTPRedirect(httpError, "GET", "/", nil), false)
assert.Equal(mockAssert.HTTPError(httpOK, "GET", "/", nil), false)
assert.Equal(mockAssert.HTTPError(httpRedirect, "GET", "/", nil), false)
assert.Equal(mockAssert.HTTPError(httpError, "GET", "/", nil), true)
}
func httpHelloName(w http.ResponseWriter, r *http.Request) {
name := r.FormValue("name")
w.Write([]byte(fmt.Sprintf("Hello, %s!", name)))
}
func TestHttpBody(t *testing.T) {
assert := New(t)
mockT := new(testing.T)
assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
assert.False(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
assert.True(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
}
func TestHttpBodyWrappers(t *testing.T) {
assert := New(t)
mockAssert := New(new(testing.T))
assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
assert.True(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
assert.False(mockAssert.HTTPBodyContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
assert.True(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
}

View File

@ -19,7 +19,7 @@
// the year of their birth or an error, you might write this:
//
// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) {
// args := o.Mock.Called(firstname, lastname, age)
// args := o.Called(firstname, lastname, age)
// return args.Int(0), args.Error(1)
// }
//

View File

@ -7,6 +7,7 @@ import (
"reflect"
"runtime"
"strings"
"sync"
)
// TestingT is an interface wrapper around *testing.T
@ -60,6 +61,8 @@ type Mock struct {
// TestData holds any data that might be useful for testing. Testify ignores
// this data completely allowing you to do whatever you like with it.
testData objx.Map
mutex sync.Mutex
}
// TestData holds any data that might be useful for testing. Testify ignores
@ -178,6 +181,8 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
// of arguments to return. Panics if the call is unexpected (i.e. not preceeded by
// appropriate .On .Return() calls)
func (m *Mock) Called(arguments ...interface{}) Arguments {
defer m.mutex.Unlock()
m.mutex.Lock()
// get the calling function's name
pc, _, _, ok := runtime.Caller(1)
@ -296,11 +301,11 @@ func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...inter
return true
}
func (m *Mock) methodWasCalled(methodName string, arguments []interface{}) bool {
func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
for _, call := range m.Calls {
if call.Method == methodName {
_, differences := call.Arguments.Diff(arguments)
_, differences := Arguments(expected).Diff(call.Arguments)
if differences == 0 {
// found the expected call
@ -473,7 +478,7 @@ func (args Arguments) Int(index int) int {
var s int
var ok bool
if s, ok = args.Get(index).(int); !ok {
panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %s", index, args.Get(index)))
panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
}
return s
}
@ -488,7 +493,7 @@ func (args Arguments) Error(index int) error {
return nil
}
if s, ok = obj.(error); !ok {
panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %s", index, args.Get(index)))
panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
}
return s
}
@ -499,7 +504,7 @@ func (args Arguments) Bool(index int) bool {
var s bool
var ok bool
if s, ok = args.Get(index).(bool); !ok {
panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %s", index, args.Get(index)))
panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
}
return s
}

View File

@ -21,18 +21,18 @@ type TestExampleImplementation struct {
}
func (i *TestExampleImplementation) TheExampleMethod(a, b, c int) (int, error) {
args := i.Mock.Called(a, b, c)
args := i.Called(a, b, c)
return args.Int(0), errors.New("Whoops")
}
func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) {
i.Mock.Called(yesorno)
i.Called(yesorno)
}
type ExampleType struct{}
func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
args := i.Mock.Called(et)
args := i.Called(et)
return args.Error(0)
}
@ -58,8 +58,8 @@ func Test_Mock_On(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.Mock.On("TheExampleMethod"), &mockedService.Mock)
assert.Equal(t, "TheExampleMethod", mockedService.Mock.onMethodName)
assert.Equal(t, mockedService.On("TheExampleMethod"), &mockedService.Mock)
assert.Equal(t, "TheExampleMethod", mockedService.onMethodName)
}
@ -68,11 +68,11 @@ func Test_Mock_On_WithArgs(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.Mock.On("TheExampleMethod", 1, 2, 3), &mockedService.Mock)
assert.Equal(t, "TheExampleMethod", mockedService.Mock.onMethodName)
assert.Equal(t, 1, mockedService.Mock.onMethodArguments[0])
assert.Equal(t, 2, mockedService.Mock.onMethodArguments[1])
assert.Equal(t, 3, mockedService.Mock.onMethodArguments[2])
assert.Equal(t, mockedService.On("TheExampleMethod", 1, 2, 3), &mockedService.Mock)
assert.Equal(t, "TheExampleMethod", mockedService.onMethodName)
assert.Equal(t, 1, mockedService.onMethodArguments[0])
assert.Equal(t, 2, mockedService.onMethodArguments[1])
assert.Equal(t, 3, mockedService.onMethodArguments[2])
}
@ -81,11 +81,11 @@ func Test_Mock_Return(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true), &mockedService.Mock)
assert.Equal(t, mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true), &mockedService.Mock)
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
call := mockedService.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
@ -105,11 +105,11 @@ func Test_Mock_Return_Once(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Once()
mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Once()
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
call := mockedService.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
@ -129,11 +129,11 @@ func Test_Mock_Return_Twice(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Twice()
mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Twice()
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
call := mockedService.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
@ -153,11 +153,11 @@ func Test_Mock_Return_Times(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Times(5)
mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Times(5)
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
call := mockedService.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
@ -177,11 +177,11 @@ func Test_Mock_Return_Nothing(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(), &mockedService.Mock)
assert.Equal(t, mockedService.On("TheExampleMethod", "A", "B", true).Return(), &mockedService.Mock)
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
call := mockedService.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
@ -255,15 +255,15 @@ func Test_Mock_Called(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_Called", 1, 2, 3).Return(5, "6", true)
mockedService.On("Test_Mock_Called", 1, 2, 3).Return(5, "6", true)
returnArguments := mockedService.Mock.Called(1, 2, 3)
returnArguments := mockedService.Called(1, 2, 3)
if assert.Equal(t, 1, len(mockedService.Mock.Calls)) {
assert.Equal(t, "Test_Mock_Called", mockedService.Mock.Calls[0].Method)
assert.Equal(t, 1, mockedService.Mock.Calls[0].Arguments[0])
assert.Equal(t, 2, mockedService.Mock.Calls[0].Arguments[1])
assert.Equal(t, 3, mockedService.Mock.Calls[0].Arguments[2])
if assert.Equal(t, 1, len(mockedService.Calls)) {
assert.Equal(t, "Test_Mock_Called", mockedService.Calls[0].Method)
assert.Equal(t, 1, mockedService.Calls[0].Arguments[0])
assert.Equal(t, 2, mockedService.Calls[0].Arguments[1])
assert.Equal(t, 3, mockedService.Calls[0].Arguments[2])
}
if assert.Equal(t, 3, len(returnArguments)) {
@ -278,22 +278,22 @@ func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).Return(5, "6", true).Once()
mockedService.Mock.On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).Return(-1, "hi", false)
mockedService.On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).Return(5, "6", true).Once()
mockedService.On("Test_Mock_Called_For_Bounded_Repeatability", 1, 2, 3).Return(-1, "hi", false)
returnArguments1 := mockedService.Mock.Called(1, 2, 3)
returnArguments2 := mockedService.Mock.Called(1, 2, 3)
returnArguments1 := mockedService.Called(1, 2, 3)
returnArguments2 := mockedService.Called(1, 2, 3)
if assert.Equal(t, 2, len(mockedService.Mock.Calls)) {
assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Mock.Calls[0].Method)
assert.Equal(t, 1, mockedService.Mock.Calls[0].Arguments[0])
assert.Equal(t, 2, mockedService.Mock.Calls[0].Arguments[1])
assert.Equal(t, 3, mockedService.Mock.Calls[0].Arguments[2])
if assert.Equal(t, 2, len(mockedService.Calls)) {
assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[0].Method)
assert.Equal(t, 1, mockedService.Calls[0].Arguments[0])
assert.Equal(t, 2, mockedService.Calls[0].Arguments[1])
assert.Equal(t, 3, mockedService.Calls[0].Arguments[2])
assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Mock.Calls[1].Method)
assert.Equal(t, 1, mockedService.Mock.Calls[1].Arguments[0])
assert.Equal(t, 2, mockedService.Mock.Calls[1].Arguments[1])
assert.Equal(t, 3, mockedService.Mock.Calls[1].Arguments[2])
assert.Equal(t, "Test_Mock_Called_For_Bounded_Repeatability", mockedService.Calls[1].Method)
assert.Equal(t, 1, mockedService.Calls[1].Arguments[0])
assert.Equal(t, 2, mockedService.Calls[1].Arguments[1])
assert.Equal(t, 3, mockedService.Calls[1].Arguments[2])
}
if assert.Equal(t, 3, len(returnArguments1)) {
@ -314,7 +314,7 @@ func Test_Mock_Called_For_SetTime_Expectation(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("TheExampleMethod", 1, 2, 3).Return(5, "6", true).Times(4)
mockedService.On("TheExampleMethod", 1, 2, 3).Return(5, "6", true).Times(4)
mockedService.TheExampleMethod(1, 2, 3)
mockedService.TheExampleMethod(1, 2, 3)
@ -332,7 +332,7 @@ func Test_Mock_Called_Unexpected(t *testing.T) {
// make sure it panics if no expectation was made
assert.Panics(t, func() {
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
}, "Calling unexpected method should panic")
}
@ -343,9 +343,9 @@ func Test_AssertExpectationsForObjects_Helper(t *testing.T) {
var mockedService2 *TestExampleImplementation = new(TestExampleImplementation)
var mockedService3 *TestExampleImplementation = new(TestExampleImplementation)
mockedService1.Mock.On("Test_AssertExpectationsForObjects_Helper", 1).Return()
mockedService2.Mock.On("Test_AssertExpectationsForObjects_Helper", 2).Return()
mockedService3.Mock.On("Test_AssertExpectationsForObjects_Helper", 3).Return()
mockedService1.On("Test_AssertExpectationsForObjects_Helper", 1).Return()
mockedService2.On("Test_AssertExpectationsForObjects_Helper", 2).Return()
mockedService3.On("Test_AssertExpectationsForObjects_Helper", 3).Return()
mockedService1.Called(1)
mockedService2.Called(2)
@ -361,9 +361,9 @@ func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) {
var mockedService2 *TestExampleImplementation = new(TestExampleImplementation)
var mockedService3 *TestExampleImplementation = new(TestExampleImplementation)
mockedService1.Mock.On("Test_AssertExpectationsForObjects_Helper_Failed", 1).Return()
mockedService2.Mock.On("Test_AssertExpectationsForObjects_Helper_Failed", 2).Return()
mockedService3.Mock.On("Test_AssertExpectationsForObjects_Helper_Failed", 3).Return()
mockedService1.On("Test_AssertExpectationsForObjects_Helper_Failed", 1).Return()
mockedService2.On("Test_AssertExpectationsForObjects_Helper_Failed", 2).Return()
mockedService3.On("Test_AssertExpectationsForObjects_Helper_Failed", 3).Return()
mockedService1.Called(1)
mockedService3.Called(3)
@ -377,13 +377,13 @@ func Test_Mock_AssertExpectations(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertExpectations", 1, 2, 3).Return(5, 6, 7)
mockedService.On("Test_Mock_AssertExpectations", 1, 2, 3).Return(5, 6, 7)
tt := new(testing.T)
assert.False(t, mockedService.AssertExpectations(tt))
// make the call now
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
// now assert expectations
assert.True(t, mockedService.AssertExpectations(tt))
@ -394,7 +394,7 @@ func Test_Mock_AssertExpectationsCustomType(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Once()
mockedService.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Once()
tt := new(testing.T)
assert.False(t, mockedService.AssertExpectations(tt))
@ -411,17 +411,17 @@ func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertExpectations_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Twice()
mockedService.On("Test_Mock_AssertExpectations_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Twice()
tt := new(testing.T)
assert.False(t, mockedService.AssertExpectations(tt))
// make the call now
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
assert.False(t, mockedService.AssertExpectations(tt))
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
// now assert expectations
assert.True(t, mockedService.AssertExpectations(tt))
@ -432,15 +432,15 @@ func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_TwoCallsWithDifferentArguments", 1, 2, 3).Return(5, 6, 7)
mockedService.Mock.On("Test_Mock_TwoCallsWithDifferentArguments", 4, 5, 6).Return(5, 6, 7)
mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 1, 2, 3).Return(5, 6, 7)
mockedService.On("Test_Mock_TwoCallsWithDifferentArguments", 4, 5, 6).Return(5, 6, 7)
args1 := mockedService.Mock.Called(1, 2, 3)
args1 := mockedService.Called(1, 2, 3)
assert.Equal(t, 5, args1.Int(0))
assert.Equal(t, 6, args1.Int(1))
assert.Equal(t, 7, args1.Int(2))
args2 := mockedService.Mock.Called(4, 5, 6)
args2 := mockedService.Called(4, 5, 6)
assert.Equal(t, 5, args2.Int(0))
assert.Equal(t, 6, args2.Int(1))
assert.Equal(t, 7, args2.Int(2))
@ -451,12 +451,12 @@ func Test_Mock_AssertNumberOfCalls(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertNumberOfCalls", 1, 2, 3).Return(5, 6, 7)
mockedService.On("Test_Mock_AssertNumberOfCalls", 1, 2, 3).Return(5, 6, 7)
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 1))
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
assert.True(t, mockedService.AssertNumberOfCalls(t, "Test_Mock_AssertNumberOfCalls", 2))
}
@ -465,21 +465,33 @@ func Test_Mock_AssertCalled(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertCalled", 1, 2, 3).Return(5, 6, 7)
mockedService.On("Test_Mock_AssertCalled", 1, 2, 3).Return(5, 6, 7)
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled", 1, 2, 3))
}
func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.On("Test_Mock_AssertCalled_WithAnythingOfTypeArgument", Anything, Anything, Anything).Return()
mockedService.Called(1, "two", []uint8("three"))
assert.True(t, mockedService.AssertCalled(t, "Test_Mock_AssertCalled_WithAnythingOfTypeArgument", AnythingOfType("int"), AnythingOfType("string"), AnythingOfType("[]uint8")))
}
func Test_Mock_AssertCalled_WithArguments(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertCalled_WithArguments", 1, 2, 3).Return(5, 6, 7)
mockedService.On("Test_Mock_AssertCalled_WithArguments", 1, 2, 3).Return(5, 6, 7)
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
tt := new(testing.T)
assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments", 1, 2, 3))
@ -491,11 +503,11 @@ func Test_Mock_AssertCalled_WithArguments_With_Repeatability(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Once()
mockedService.Mock.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4).Return(5, 6, 7).Once()
mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3).Return(5, 6, 7).Once()
mockedService.On("Test_Mock_AssertCalled_WithArguments_With_Repeatability", 2, 3, 4).Return(5, 6, 7).Once()
mockedService.Mock.Called(1, 2, 3)
mockedService.Mock.Called(2, 3, 4)
mockedService.Called(1, 2, 3)
mockedService.Called(2, 3, 4)
tt := new(testing.T)
assert.True(t, mockedService.AssertCalled(tt, "Test_Mock_AssertCalled_WithArguments_With_Repeatability", 1, 2, 3))
@ -508,9 +520,9 @@ func Test_Mock_AssertNotCalled(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("Test_Mock_AssertNotCalled", 1, 2, 3).Return(5, 6, 7)
mockedService.On("Test_Mock_AssertNotCalled", 1, 2, 3).Return(5, 6, 7)
mockedService.Mock.Called(1, 2, 3)
mockedService.Called(1, 2, 3)
assert.True(t, mockedService.AssertNotCalled(t, "Test_Mock_NotCalled"))