update testify

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2015-05-26 19:01:09 -07:00
parent 6a0bf552e3
commit 0fb33f61d5
13 changed files with 430 additions and 79 deletions

4
Godeps/Godeps.json generated
View File

@ -118,11 +118,11 @@
}, },
{ {
"ImportPath": "github.com/stretchr/testify/assert", "ImportPath": "github.com/stretchr/testify/assert",
"Rev": "43d0eed2455ed136d33e9426cf52119371ca4596" "Rev": "dab07ac62d4905d3e48d17dc549c684ac3b7c15a"
}, },
{ {
"ImportPath": "github.com/stretchr/testify/mock", "ImportPath": "github.com/stretchr/testify/mock",
"Rev": "43d0eed2455ed136d33e9426cf52119371ca4596" "Rev": "dab07ac62d4905d3e48d17dc549c684ac3b7c15a"
}, },
{ {
"ImportPath": "golang.org/x/net/context", "ImportPath": "golang.org/x/net/context",

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"math"
"reflect" "reflect"
"regexp" "regexp"
"runtime" "runtime"
@ -36,13 +37,27 @@ func ObjectsAreEqual(expected, actual interface{}) bool {
return true return true
} }
// Last ditch effort return false
if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) {
}
// ObjectsAreEqualValues gets whether two objects are equal, or if their
// values are equal.
func ObjectsAreEqualValues(expected, actual interface{}) bool {
if ObjectsAreEqual(expected, actual) {
return true return true
} }
return false 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 /* CallerInfo is necessary because the assert functions use the testing object
@ -189,6 +204,23 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{})
} }
// 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
}
// Exactly asserts that two objects are equal is value and type. // Exactly asserts that two objects are equal is value and type.
// //
// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") // assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
@ -625,6 +657,14 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
} }
if math.IsNaN(af) {
return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...)
}
if math.IsNaN(bf) {
return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
}
dt := af - bf dt := af - bf
if dt < -delta || dt > delta { 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 Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
@ -633,6 +673,27 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
return true return true
} }
// InDeltaSlice is the same as InDelta, except it compares two slices.
func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
if expected == nil || actual == nil ||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
reflect.TypeOf(expected).Kind() != reflect.Slice {
return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
}
actualSlice := reflect.ValueOf(actual)
expectedSlice := reflect.ValueOf(expected)
for i := 0; i < actualSlice.Len(); i++ {
result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta)
if !result {
return result
}
}
return true
}
// min(|expected|, |actual|) * epsilon // min(|expected|, |actual|) * epsilon
func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 { func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 {
af, aok := toFloat(expected) af, aok := toFloat(expected)
@ -667,6 +728,27 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
return InDelta(t, expected, actual, delta, msgAndArgs...) return InDelta(t, expected, actual, delta, msgAndArgs...)
} }
// InEpsilonSlice is the same as InEpsilon, except it compares two slices.
func InEpsilonSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
if expected == nil || actual == nil ||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
reflect.TypeOf(expected).Kind() != reflect.Slice {
return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
}
actualSlice := reflect.ValueOf(actual)
expectedSlice := reflect.ValueOf(expected)
for i := 0; i < actualSlice.Len(); i++ {
result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta)
if !result {
return result
}
}
return true
}
/* /*
Errors Errors
*/ */

View File

@ -2,6 +2,7 @@ package assert
import ( import (
"errors" "errors"
"math"
"regexp" "regexp"
"testing" "testing"
"time" "time"
@ -55,6 +56,12 @@ func TestObjectsAreEqual(t *testing.T) {
if ObjectsAreEqual(0.1, 0) { if ObjectsAreEqual(0.1, 0) {
t.Error("objectsAreEqual should return false") 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")
}
} }
@ -109,10 +116,6 @@ func TestEqual(t *testing.T) {
if !Equal(mockT, uint64(123), uint64(123)) { if !Equal(mockT, uint64(123), uint64(123)) {
t.Error("Equal should return true") t.Error("Equal should return true")
} }
funcA := func() int { return 42 }
if !Equal(mockT, funcA, funcA) {
t.Error("Equal should return true")
}
} }
@ -400,19 +403,6 @@ func TestNotPanics(t *testing.T) {
} }
func TestEqual_Funcs(t *testing.T) {
type f func() int
f1 := func() int { return 1 }
f2 := func() int { return 2 }
f1Copy := f1
Equal(t, f1Copy, f1, "Funcs are the same and should be considered equal")
NotEqual(t, f1, f2, "f1 and f2 are different")
}
func TestNoError(t *testing.T) { func TestNoError(t *testing.T) {
mockT := new(testing.T) mockT := new(testing.T)
@ -663,6 +653,8 @@ func TestInDelta(t *testing.T) {
False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail") 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, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail")
False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail") False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail")
False(t, InDelta(mockT, 42, math.NaN(), 0.01), "Expected NaN for actual to fail")
False(t, InDelta(mockT, math.NaN(), 42, 0.01), "Expected NaN for expected to fail")
cases := []struct { cases := []struct {
a, b interface{} a, b interface{}
@ -688,6 +680,27 @@ func TestInDelta(t *testing.T) {
} }
} }
func TestInDeltaSlice(t *testing.T) {
mockT := new(testing.T)
True(t, InDeltaSlice(mockT,
[]float64{1.001, 0.999},
[]float64{1, 1},
0.1), "{1.001, 0.009} is element-wise close to {1, 1} in delta=0.1")
True(t, InDeltaSlice(mockT,
[]float64{1, 2},
[]float64{0, 3},
1), "{1, 2} is element-wise close to {0, 3} in delta=1")
False(t, InDeltaSlice(mockT,
[]float64{1, 2},
[]float64{0, 3},
0.1), "{1, 2} is not element-wise close to {0, 3} in delta=0.1")
False(t, InDeltaSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
}
func TestInEpsilon(t *testing.T) { func TestInEpsilon(t *testing.T) {
mockT := new(testing.T) mockT := new(testing.T)
@ -727,6 +740,22 @@ func TestInEpsilon(t *testing.T) {
} }
func TestInEpsilonSlice(t *testing.T) {
mockT := new(testing.T)
True(t, InEpsilonSlice(mockT,
[]float64{2.2, 2.0},
[]float64{2.1, 2.1},
0.06), "{2.2, 2.0} is element-wise close to {2.1, 2.1} in espilon=0.06")
False(t, InEpsilonSlice(mockT,
[]float64{2.2, 2.0},
[]float64{2.1, 2.1},
0.04), "{2.2, 2.0} is not element-wise close to {2.1, 2.1} in espilon=0.04")
False(t, InEpsilonSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
}
func TestRegexp(t *testing.T) { func TestRegexp(t *testing.T) {
mockT := new(testing.T) mockT := new(testing.T)

View File

@ -1,4 +1,4 @@
// A set of comprehensive testing tools for use with the normal Go testing system. // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
// //
// Example Usage // Example Usage
// //
@ -45,7 +45,9 @@
// //
// Here is an overview of the assert functions: // Here is an overview of the assert functions:
// //
// assert.Equal(t, expected, actual [, message [, format-args]) // assert.Equal(t, expected, actual [, message [, format-args]])
//
// assert.EqualValues(t, expected, actual [, message [, format-args]])
// //
// assert.NotEqual(t, notExpected, actual [, message [, format-args]]) // assert.NotEqual(t, notExpected, actual [, message [, format-args]])
// //
@ -98,7 +100,9 @@
// assert package contains Assertions object. it has assertion methods. // assert package contains Assertions object. it has assertion methods.
// //
// Here is an overview of the assert functions: // Here is an overview of the assert functions:
// assert.Equal(expected, actual [, message [, format-args]) // assert.Equal(expected, actual [, message [, format-args]])
//
// assert.EqualValues(expected, actual [, message [, format-args]])
// //
// assert.NotEqual(notExpected, actual [, message [, format-args]]) // assert.NotEqual(notExpected, actual [, message [, format-args]])
// //

View File

@ -2,10 +2,13 @@ package assert
import "time" import "time"
// Assertions provides assertion methods around the
// TestingT interface.
type Assertions struct { type Assertions struct {
t TestingT t TestingT
} }
// New makes a new Assertions object for the specified TestingT.
func New(t TestingT) *Assertions { func New(t TestingT) *Assertions {
return &Assertions{ return &Assertions{
t: t, t: t,
@ -38,6 +41,16 @@ func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface
return Equal(a.t, expected, actual, msgAndArgs...) 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. // Exactly asserts that two objects are equal is value and type.
// //
// assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") // assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
@ -75,7 +88,7 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
return Empty(a.t, object, msgAndArgs...) return Empty(a.t, object, msgAndArgs...)
} }
// Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a
// slice with len == 0. // slice with len == 0.
// //
// if assert.NotEmpty(obj) { // if assert.NotEmpty(obj) {
@ -142,7 +155,7 @@ func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interfac
return NotContains(a.t, s, contains, msgAndArgs...) return NotContains(a.t, s, contains, msgAndArgs...)
} }
// Uses a Comparison to assert a complex condition. // Condition uses a Comparison to assert a complex condition.
func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
return Condition(a.t, comp, msgAndArgs...) return Condition(a.t, comp, msgAndArgs...)
} }

View File

@ -50,6 +50,14 @@ func TestEqualWrapper(t *testing.T) {
} }
} }
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) { func TestNotNilWrapper(t *testing.T) {
assert := New(new(testing.T)) assert := New(new(testing.T))
@ -251,27 +259,12 @@ func TestNotPanicsWrapper(t *testing.T) {
} }
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) { func TestNoErrorWrapper(t *testing.T) {
assert := New(t) assert := New(t)
mockAssert := New(new(testing.T)) mockAssert := New(new(testing.T))
// start with a nil error // start with a nil error
var err error = nil var err error
assert.True(mockAssert.NoError(err), "NoError should return True for nil arg") assert.True(mockAssert.NoError(err), "NoError should return True for nil arg")
@ -287,7 +280,7 @@ func TestErrorWrapper(t *testing.T) {
mockAssert := New(new(testing.T)) mockAssert := New(new(testing.T))
// start with a nil error // start with a nil error
var err error = nil var err error
assert.False(mockAssert.Error(err), "Error should return False for nil arg") assert.False(mockAssert.Error(err), "Error should return False for nil arg")

View File

@ -22,7 +22,7 @@ func httpCode(handler http.HandlerFunc, mode, url string, values url.Values) int
// HTTPSuccess asserts that a specified handler returns a success status code. // HTTPSuccess asserts that a specified handler returns a success status code.
// //
// assert.HTTPSuccess(t, myHandler, "POST", http://www.google.com", nil) // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
// //
// Returns whether the assertion was successful (true) or not (false). // Returns whether the assertion was successful (true) or not (false).
func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool { func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool {
@ -59,9 +59,9 @@ func HTTPError(t TestingT, handler http.HandlerFunc, mode, url string, values ur
return code >= http.StatusBadRequest return code >= http.StatusBadRequest
} }
// HttpBody is a helper that returns HTTP body of the response. It returns // HTTPBody is a helper that returns HTTP body of the response. It returns
// empty string if building a new request fails. // empty string if building a new request fails.
func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) string { func HTTPBody(handler http.HandlerFunc, mode, url string, values url.Values) string {
w := httptest.NewRecorder() w := httptest.NewRecorder()
req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil) req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
if err != nil { if err != nil {
@ -78,7 +78,7 @@ func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) str
// //
// Returns whether the assertion was successful (true) or not (false). // 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 { func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
body := HttpBody(handler, mode, url, values) body := HTTPBody(handler, mode, url, values)
contains := strings.Contains(body, fmt.Sprint(str)) contains := strings.Contains(body, fmt.Sprint(str))
if !contains { if !contains {
@ -95,7 +95,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, va
// //
// Returns whether the assertion was successful (true) or not (false). // 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 { func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool {
body := HttpBody(handler, mode, url, values) body := HTTPBody(handler, mode, url, values)
contains := strings.Contains(body, fmt.Sprint(str)) contains := strings.Contains(body, fmt.Sprint(str))
if contains { if contains {
@ -111,7 +111,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string,
// HTTPSuccess asserts that a specified handler returns a success status code. // HTTPSuccess asserts that a specified handler returns a success status code.
// //
// assert.HTTPSuccess(myHandler, "POST", http://www.google.com", nil) // assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
// //
// Returns whether the assertion was successful (true) or not (false). // Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, values url.Values) bool { func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, values url.Values) bool {

View File

@ -8,6 +8,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
"time"
) )
// TestingT is an interface wrapper around *testing.T // TestingT is an interface wrapper around *testing.T
@ -37,6 +38,15 @@ type Call struct {
// The number of times to return the return arguments when setting // The number of times to return the return arguments when setting
// expectations. 0 means to always return the value. // expectations. 0 means to always return the value.
Repeatability int Repeatability int
// Holds a channel that will be used to block the Return until it either
// recieves a message or is closed. nil means it returns immediately.
WaitFor <-chan time.Time
// Holds a handler used to manipulate arguments content that are passed by
// reference. It's useful when mocking methods such as unmarshalers or
// decoders.
Run func(Arguments)
} }
// Mock is the workhorse used to track activity on another object. // Mock is the workhorse used to track activity on another object.
@ -87,6 +97,13 @@ func (m *Mock) TestData() objx.Map {
func (m *Mock) On(methodName string, arguments ...interface{}) *Mock { func (m *Mock) On(methodName string, arguments ...interface{}) *Mock {
m.onMethodName = methodName m.onMethodName = methodName
m.onMethodArguments = arguments m.onMethodArguments = arguments
for _, arg := range arguments {
if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
}
}
return m return m
} }
@ -95,7 +112,7 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Mock {
// //
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2) // Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2)
func (m *Mock) Return(returnArguments ...interface{}) *Mock { func (m *Mock) Return(returnArguments ...interface{}) *Mock {
m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0}) m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0, nil, nil})
return m return m
} }
@ -121,6 +138,35 @@ func (m *Mock) Times(i int) {
m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = i m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = i
} }
// WaitUntil sets the channel that will block the mock's return until its closed
// or a message is received.
//
// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
func (m *Mock) WaitUntil(w <-chan time.Time) *Mock {
m.ExpectedCalls[len(m.ExpectedCalls)-1].WaitFor = w
return m
}
// After sets how long to block until the call returns
//
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
func (m *Mock) After(d time.Duration) *Mock {
return m.WaitUntil(time.After(d))
}
// Run sets a handler to be called before returning. It can be used when
// mocking a method such as unmarshalers that takes a pointer to a struct and
// sets properties in such struct
//
// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}").Return().Run(function(args Arguments) {
// arg := args.Get(0).(*map[string]interface{})
// arg["foo"] = "bar"
// })
func (m *Mock) Run(fn func(Arguments)) *Mock {
m.ExpectedCalls[len(m.ExpectedCalls)-1].Run = fn
return m
}
/* /*
Recording and responding to activity Recording and responding to activity
*/ */
@ -180,6 +226,7 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
// Called tells the mock object that a method has been called, and gets an array // Called tells the mock object that a method has been called, and gets an array
// of arguments to return. Panics if the call is unexpected (i.e. not preceeded by // of arguments to return. Panics if the call is unexpected (i.e. not preceeded by
// appropriate .On .Return() calls) // appropriate .On .Return() calls)
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
func (m *Mock) Called(arguments ...interface{}) Arguments { func (m *Mock) Called(arguments ...interface{}) Arguments {
defer m.mutex.Unlock() defer m.mutex.Unlock()
m.mutex.Lock() m.mutex.Lock()
@ -220,7 +267,16 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
} }
// add the call // add the call
m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0}) m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0, nil, nil})
// block if specified
if call.WaitFor != nil {
<-call.WaitFor
}
if call.Run != nil {
call.Run(arguments)
}
return call.ReturnArguments return call.ReturnArguments
@ -286,7 +342,7 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls
// AssertCalled asserts that the method was called. // AssertCalled asserts that the method was called.
func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool { func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) { if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) {
t.Logf("%s", m.ExpectedCalls) t.Logf("%v", m.ExpectedCalls)
return false return false
} }
return true return true
@ -295,7 +351,7 @@ func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interfac
// AssertNotCalled asserts that the method was not called. // AssertNotCalled asserts that the method was not called.
func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool { func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) { if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) {
t.Logf("%s", m.ExpectedCalls) t.Logf("%v", m.ExpectedCalls)
return false return false
} }
return true return true

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"testing" "testing"
"time"
) )
/* /*
@ -29,13 +30,27 @@ func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) {
i.Called(yesorno) i.Called(yesorno)
} }
type ExampleType struct{} type ExampleType struct {
ran bool
}
func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error { func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
args := i.Called(et) args := i.Called(et)
return args.Error(0) return args.Error(0)
} }
func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error {
args := i.Called(fn)
return args.Error(0)
}
type ExampleFuncType func(string) error
func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType) error {
args := i.Called(fn)
return args.Error(0)
}
/* /*
Mock Mock
*/ */
@ -76,6 +91,43 @@ func Test_Mock_On_WithArgs(t *testing.T) {
} }
func Test_Mock_On_WithFuncArg(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.On("TheExampleMethodFunc", AnythingOfType("func(string) error")).Return(nil), &mockedService.Mock)
assert.Equal(t, "TheExampleMethodFunc", mockedService.onMethodName)
assert.Equal(t, AnythingOfType("func(string) error"), mockedService.onMethodArguments[0])
fn := func(string) error { return nil }
mockedService.TheExampleMethodFunc(fn)
}
func Test_Mock_On_WithFuncPanics(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Panics(t, func() {
mockedService.On("TheExampleMethodFunc", func(string) error { return nil })
})
}
func Test_Mock_On_WithFuncTypeArg(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.On("TheExampleMethodFuncType", AnythingOfType("mock.ExampleFuncType")).Return(nil), &mockedService.Mock)
assert.Equal(t, "TheExampleMethodFuncType", mockedService.onMethodName)
assert.Equal(t, AnythingOfType("mock.ExampleFuncType"), mockedService.onMethodArguments[0])
fn := func(string) error { return nil }
mockedService.TheExampleMethodFuncType(fn)
}
func Test_Mock_Return(t *testing.T) { func Test_Mock_Return(t *testing.T) {
// make a test impl object // make a test impl object
@ -95,11 +147,93 @@ func Test_Mock_Return(t *testing.T) {
assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, "two", call.ReturnArguments[1])
assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, true, call.ReturnArguments[2])
assert.Equal(t, 0, call.Repeatability) assert.Equal(t, 0, call.Repeatability)
assert.Nil(t, call.WaitFor)
} }
} }
func Test_Mock_Return_WaitUntil(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
ch := time.After(time.Second)
assert.Equal(t, mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).WaitUntil(ch), &mockedService.Mock)
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
assert.Equal(t, "B", call.Arguments[1])
assert.Equal(t, true, call.Arguments[2])
assert.Equal(t, 1, call.ReturnArguments[0])
assert.Equal(t, "two", call.ReturnArguments[1])
assert.Equal(t, true, call.ReturnArguments[2])
assert.Equal(t, 0, call.Repeatability)
assert.Equal(t, ch, call.WaitFor)
}
}
func Test_Mock_Return_After(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).After(time.Second), &mockedService.Mock)
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod", call.Method)
assert.Equal(t, "A", call.Arguments[0])
assert.Equal(t, "B", call.Arguments[1])
assert.Equal(t, true, call.Arguments[2])
assert.Equal(t, 1, call.ReturnArguments[0])
assert.Equal(t, "two", call.ReturnArguments[1])
assert.Equal(t, true, call.ReturnArguments[2])
assert.Equal(t, 0, call.Repeatability)
assert.NotEqual(t, nil, call.WaitFor)
}
}
func Test_Mock_Return_Run(t *testing.T) {
// make a test impl object
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
assert.Equal(t, mockedService.Mock.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Run(func(args Arguments) {
arg := args.Get(0).(*ExampleType)
arg.ran = true
}), &mockedService.Mock)
// ensure the call was created
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
call := mockedService.Mock.ExpectedCalls[0]
assert.Equal(t, "TheExampleMethod3", call.Method)
assert.Equal(t, AnythingOfType("*mock.ExampleType"), call.Arguments[0])
assert.Equal(t, nil, call.ReturnArguments[0])
assert.Equal(t, 0, call.Repeatability)
assert.NotEqual(t, nil, call.WaitFor)
assert.NotNil(t, call.Run)
}
et := ExampleType{}
assert.Equal(t, false, et.ran)
mockedService.TheExampleMethod3(&et)
assert.Equal(t, true, et.ran)
}
func Test_Mock_Return_Once(t *testing.T) { func Test_Mock_Return_Once(t *testing.T) {
// make a test impl object // make a test impl object
@ -119,6 +253,7 @@ func Test_Mock_Return_Once(t *testing.T) {
assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, "two", call.ReturnArguments[1])
assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, true, call.ReturnArguments[2])
assert.Equal(t, 1, call.Repeatability) assert.Equal(t, 1, call.Repeatability)
assert.Nil(t, call.WaitFor)
} }
@ -143,6 +278,7 @@ func Test_Mock_Return_Twice(t *testing.T) {
assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, "two", call.ReturnArguments[1])
assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, true, call.ReturnArguments[2])
assert.Equal(t, 2, call.Repeatability) assert.Equal(t, 2, call.Repeatability)
assert.Nil(t, call.WaitFor)
} }
@ -167,6 +303,7 @@ func Test_Mock_Return_Times(t *testing.T) {
assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, "two", call.ReturnArguments[1])
assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, true, call.ReturnArguments[2])
assert.Equal(t, 5, call.Repeatability) assert.Equal(t, 5, call.Repeatability)
assert.Nil(t, call.WaitFor)
} }
@ -274,6 +411,43 @@ func Test_Mock_Called(t *testing.T) {
} }
func asyncCall(m *Mock, ch chan Arguments) {
ch <- m.Called(1, 2, 3)
}
func Test_Mock_Called_blocks(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
mockedService.Mock.On("asyncCall", 1, 2, 3).Return(5, "6", true).After(2 * time.Millisecond)
ch := make(chan Arguments)
go asyncCall(&mockedService.Mock, ch)
select {
case <-ch:
t.Fatal("should have waited")
case <-time.After(1 * time.Millisecond):
}
returnArguments := <-ch
if assert.Equal(t, 1, len(mockedService.Mock.Calls)) {
assert.Equal(t, "asyncCall", 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, 3, len(returnArguments)) {
assert.Equal(t, 5, returnArguments[0])
assert.Equal(t, "6", returnArguments[1])
assert.Equal(t, true, returnArguments[2])
}
}
func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) { func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) {
var mockedService *TestExampleImplementation = new(TestExampleImplementation) var mockedService *TestExampleImplementation = new(TestExampleImplementation)

View File

@ -65,8 +65,8 @@ func TestEngineCpusMemory(t *testing.T) {
assert.True(t, engine.isConnected()) assert.True(t, engine.isConnected())
assert.True(t, engine.IsHealthy()) assert.True(t, engine.IsHealthy())
assert.Equal(t, engine.UsedCpus(), 0) assert.Equal(t, engine.UsedCpus(), int64(0))
assert.Equal(t, engine.UsedMemory(), 0) assert.Equal(t, engine.UsedMemory(), int64(0))
client.Mock.AssertExpectations(t) client.Mock.AssertExpectations(t)
} }
@ -196,19 +196,19 @@ func TestCreateContainer(t *testing.T) {
func TestTotalMemory(t *testing.T) { func TestTotalMemory(t *testing.T) {
engine := NewEngine("test", 0.05) engine := NewEngine("test", 0.05)
engine.Memory = 1024 engine.Memory = 1024
assert.Equal(t, engine.TotalMemory(), 1024+1024*5/100) assert.Equal(t, engine.TotalMemory(), int64(1024+1024*5/100))
engine = NewEngine("test", 0) engine = NewEngine("test", 0)
engine.Memory = 1024 engine.Memory = 1024
assert.Equal(t, engine.TotalMemory(), 1024) assert.Equal(t, engine.TotalMemory(), int64(1024))
} }
func TestTotalCpus(t *testing.T) { func TestTotalCpus(t *testing.T) {
engine := NewEngine("test", 0.05) engine := NewEngine("test", 0.05)
engine.Cpus = 2 engine.Cpus = 2
assert.Equal(t, engine.TotalCpus(), 2+2*5/100) assert.Equal(t, engine.TotalCpus(), int64(2+2*5/100))
engine = NewEngine("test", 0) engine = NewEngine("test", 0)
engine.Cpus = 2 engine.Cpus = 2
assert.Equal(t, engine.TotalCpus(), 2) assert.Equal(t, engine.TotalCpus(), int64(2))
} }

View File

@ -46,27 +46,27 @@ func TestInt(t *testing.T) {
val, ok := opts.Int("foo1", "") val, ok := opts.Int("foo1", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, 0) assert.Equal(t, val, int64(0))
val, ok = opts.Int("foo2", "") val, ok = opts.Int("foo2", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, -5) assert.Equal(t, val, int64(-5))
val, ok = opts.Int("foo3", "") val, ok = opts.Int("foo3", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, 7) assert.Equal(t, val, int64(7))
val, ok = opts.Int("foo4", "") val, ok = opts.Int("foo4", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, 0) assert.Equal(t, val, int64(0))
val, ok = opts.Int("", "FOO_4") val, ok = opts.Int("", "FOO_4")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, 0) assert.Equal(t, val, int64(0))
val, ok = opts.Int("invalid", "") val, ok = opts.Int("invalid", "")
assert.False(t, ok) assert.False(t, ok)
assert.Equal(t, val, 0) assert.Equal(t, val, int64(0))
} }
func TestUint(t *testing.T) { func TestUint(t *testing.T) {
@ -75,27 +75,27 @@ func TestUint(t *testing.T) {
val, ok := opts.Uint("foo1", "") val, ok := opts.Uint("foo1", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, uint(0)) assert.Equal(t, val, uint64(0))
val, ok = opts.Uint("foo2", "") val, ok = opts.Uint("foo2", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, uint(0)) assert.Equal(t, val, uint64(0))
val, ok = opts.Uint("foo3", "") val, ok = opts.Uint("foo3", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, uint(7)) assert.Equal(t, val, uint64(7))
val, ok = opts.Uint("foo4", "") val, ok = opts.Uint("foo4", "")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, uint(0)) assert.Equal(t, val, uint64(0))
val, ok = opts.Uint("", "FOO_4") val, ok = opts.Uint("", "FOO_4")
assert.True(t, ok) assert.True(t, ok)
assert.Equal(t, val, uint(0)) assert.Equal(t, val, uint64(0))
val, ok = opts.Uint("invalid", "") val, ok = opts.Uint("invalid", "")
assert.False(t, ok) assert.False(t, ok)
assert.Equal(t, val, uint(0)) assert.Equal(t, val, uint64(0))
} }
func TestFloat(t *testing.T) { func TestFloat(t *testing.T) {

View File

@ -79,7 +79,7 @@ func TestPlaceContainerMemory(t *testing.T) {
node1, err := s.PlaceContainer(config, nodes) node1, err := s.PlaceContainer(config, nodes)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, node1.AddContainer(createContainer("c1", config))) assert.NoError(t, node1.AddContainer(createContainer("c1", config)))
assert.Equal(t, node1.UsedMemory, 1024*1024*1024) assert.Equal(t, node1.UsedMemory, int64(1024*1024*1024))
// add another container 1G // add another container 1G
config = createConfig(1, 0) config = createConfig(1, 0)
@ -106,14 +106,14 @@ func TestPlaceContainerCPU(t *testing.T) {
node1, err := s.PlaceContainer(config, nodes) node1, err := s.PlaceContainer(config, nodes)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, node1.AddContainer(createContainer("c1", config))) assert.NoError(t, node1.AddContainer(createContainer("c1", config)))
assert.Equal(t, node1.UsedCpus, 1) assert.Equal(t, node1.UsedCpus, int64(1))
// add another container 1CPU // add another container 1CPU
config = createConfig(0, 1) config = createConfig(0, 1)
node2, err := s.PlaceContainer(config, nodes) node2, err := s.PlaceContainer(config, nodes)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, node2.AddContainer(createContainer("c2", config))) assert.NoError(t, node2.AddContainer(createContainer("c2", config)))
assert.Equal(t, node2.UsedCpus, 2) assert.Equal(t, node2.UsedCpus, int64(2))
// check that both containers ended on the same node // check that both containers ended on the same node
assert.Equal(t, node1.ID, node2.ID) assert.Equal(t, node1.ID, node2.ID)

View File

@ -53,7 +53,7 @@ func TestSpreadPlaceContainerMemory(t *testing.T) {
node1, err := s.PlaceContainer(config, nodes) node1, err := s.PlaceContainer(config, nodes)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, node1.AddContainer(createContainer("c1", config))) assert.NoError(t, node1.AddContainer(createContainer("c1", config)))
assert.Equal(t, node1.UsedMemory, 1024*1024*1024) assert.Equal(t, node1.UsedMemory, int64(1024*1024*1024))
// add another container 1G // add another container 1G
config = createConfig(1, 0) config = createConfig(1, 0)
@ -80,14 +80,14 @@ func TestSpreadPlaceContainerCPU(t *testing.T) {
node1, err := s.PlaceContainer(config, nodes) node1, err := s.PlaceContainer(config, nodes)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, node1.AddContainer(createContainer("c1", config))) assert.NoError(t, node1.AddContainer(createContainer("c1", config)))
assert.Equal(t, node1.UsedCpus, 1) assert.Equal(t, node1.UsedCpus, int64(1))
// add another container 1CPU // add another container 1CPU
config = createConfig(0, 1) config = createConfig(0, 1)
node2, err := s.PlaceContainer(config, nodes) node2, err := s.PlaceContainer(config, nodes)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, node2.AddContainer(createContainer("c2", config))) assert.NoError(t, node2.AddContainer(createContainer("c2", config)))
assert.Equal(t, node2.UsedCpus, 1) assert.Equal(t, node2.UsedCpus, int64(1))
// check that both containers ended on different node // check that both containers ended on different node
assert.NotEqual(t, node1.ID, node2.ID) assert.NotEqual(t, node1.ID, node2.ID)