mirror of https://github.com/stretchr/testify.git
Merge branch 'master' of https://github.com/stretchr/testify
commit
384cc6617a
|
@ -4,6 +4,8 @@ go:
|
|||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- tip
|
||||
|
||||
script:
|
||||
|
|
20
README.md
20
README.md
|
@ -15,7 +15,7 @@ Features include:
|
|||
Get started:
|
||||
|
||||
* Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date)
|
||||
* For an introduction to writing test code in Go, see our [blog post article](http://blog.stretchr.com/2014/03/05/test-driven-development-specifically-in-golang/) or check out http://golang.org/doc/code.html#Testing
|
||||
* For an introduction to writing test code in Go, see http://golang.org/doc/code.html#Testing
|
||||
* Check out the API Documentation http://godoc.org/github.com/stretchr/testify
|
||||
* To make your testing life easier, check out our other project, [gorc](http://github.com/stretchr/gorc)
|
||||
* A little about [Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development)
|
||||
|
@ -99,8 +99,8 @@ func TestSomething(t *testing.T) {
|
|||
}
|
||||
```
|
||||
|
||||
`require` package
|
||||
-------------------------------------------------------------------------------------------
|
||||
[`require`](http://godoc.org/github.com/stretchr/testify/require "API documentation") package
|
||||
---------------------------------------------------------------------------------------------
|
||||
|
||||
The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test.
|
||||
|
||||
|
@ -212,7 +212,7 @@ func (suite *ExampleTestSuite) SetupTest() {
|
|||
// All methods that begin with "Test" are run as tests within a
|
||||
// suite.
|
||||
func (suite *ExampleTestSuite) TestExample() {
|
||||
assert.Equal(suite.T(), suite.VariableThatShouldStartAtFive, 5)
|
||||
assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
}
|
||||
|
||||
// In order for 'go test' to run this suite, we need to create
|
||||
|
@ -268,7 +268,8 @@ Installation
|
|||
|
||||
To install Testify, use `go get`:
|
||||
|
||||
go get github.com/stretchr/testify
|
||||
* Latest version: go get github.com/stretchr/testify
|
||||
* Specific version: go get gopkg.in/stretchr/testify.v1
|
||||
|
||||
This will then make the following packages available to you:
|
||||
|
||||
|
@ -298,9 +299,14 @@ func TestSomething(t *testing.T) {
|
|||
Staying up to date
|
||||
==================
|
||||
|
||||
To update Testify, use `go get -u`:
|
||||
To update Testify to the latest version, use `go get -u github.com/stretchr/testify`.
|
||||
|
||||
go get -u github.com/stretchr/testify
|
||||
------
|
||||
|
||||
Version History
|
||||
===============
|
||||
|
||||
* 1.0 - New package versioning strategy adopted.
|
||||
|
||||
------
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package assert
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
|
@ -10,6 +11,11 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
)
|
||||
|
||||
// TestingT is an interface wrapper around *testing.T
|
||||
|
@ -33,11 +39,7 @@ func ObjectsAreEqual(expected, actual interface{}) bool {
|
|||
return expected == actual
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(expected, actual) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return reflect.DeepEqual(expected, actual)
|
||||
|
||||
}
|
||||
|
||||
|
@ -49,12 +51,13 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool {
|
|||
}
|
||||
|
||||
actualType := reflect.TypeOf(actual)
|
||||
if actualType == nil {
|
||||
return false
|
||||
}
|
||||
expectedValue := reflect.ValueOf(expected)
|
||||
if expectedValue.Type().ConvertibleTo(actualType) {
|
||||
if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
|
||||
// Attempt comparison after type conversion
|
||||
if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) {
|
||||
return true
|
||||
}
|
||||
return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
|
||||
}
|
||||
|
||||
return false
|
||||
|
@ -64,28 +67,67 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool {
|
|||
internally, causing it to print the file:line of the assert method, rather than where
|
||||
the problem actually occured in calling code.*/
|
||||
|
||||
// CallerInfo returns a string containing the file and line number of the assert call
|
||||
// that failed.
|
||||
func CallerInfo() string {
|
||||
// CallerInfo returns an array of strings containing the file and line number
|
||||
// of each stack frame leading from the current test to the assert call that
|
||||
// failed.
|
||||
func CallerInfo() []string {
|
||||
|
||||
pc := uintptr(0)
|
||||
file := ""
|
||||
line := 0
|
||||
ok := false
|
||||
name := ""
|
||||
|
||||
callers := []string{}
|
||||
for i := 0; ; i++ {
|
||||
_, file, line, ok = runtime.Caller(i)
|
||||
pc, file, line, ok = runtime.Caller(i)
|
||||
if !ok {
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is a huge edge case, but it will panic if this is the case, see #180
|
||||
if file == "<autogenerated>" {
|
||||
break
|
||||
}
|
||||
|
||||
parts := strings.Split(file, "/")
|
||||
dir := parts[len(parts)-2]
|
||||
file = parts[len(parts)-1]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
}
|
||||
|
||||
f := runtime.FuncForPC(pc)
|
||||
if f == nil {
|
||||
break
|
||||
}
|
||||
name = f.Name()
|
||||
// Drop the package
|
||||
segments := strings.Split(name, ".")
|
||||
name = segments[len(segments)-1]
|
||||
if isTest(name, "Test") ||
|
||||
isTest(name, "Benchmark") ||
|
||||
isTest(name, "Example") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s:%d", file, line)
|
||||
return callers
|
||||
}
|
||||
|
||||
// Stolen from the `go test` tool.
|
||||
// isTest tells whether name looks like a test (or benchmark, according to prefix).
|
||||
// It is a Test (say) if there is a character after Test that is not a lower-case letter.
|
||||
// We don't want TesticularCancer.
|
||||
func isTest(name, prefix string) bool {
|
||||
if !strings.HasPrefix(name, prefix) {
|
||||
return false
|
||||
}
|
||||
if len(name) == len(prefix) { // "Test" is ok
|
||||
return true
|
||||
}
|
||||
rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
||||
return !unicode.IsLower(rune)
|
||||
}
|
||||
|
||||
// getWhitespaceString returns a string that is long enough to overwrite the default
|
||||
|
@ -144,19 +186,20 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
|||
|
||||
message := messageFromMsgAndArgs(msgAndArgs...)
|
||||
|
||||
errorTrace := strings.Join(CallerInfo(), "\n\r\t\t\t")
|
||||
if len(message) > 0 {
|
||||
t.Errorf("\r%s\r\tLocation:\t%s\n"+
|
||||
t.Errorf("\r%s\r\tError Trace:\t%s\n"+
|
||||
"\r\tError:%s\n"+
|
||||
"\r\tMessages:\t%s\n\r",
|
||||
getWhitespaceString(),
|
||||
CallerInfo(),
|
||||
errorTrace,
|
||||
indentMessageLines(failureMessage, 2),
|
||||
message)
|
||||
} else {
|
||||
t.Errorf("\r%s\r\tLocation:\t%s\n"+
|
||||
t.Errorf("\r%s\r\tError Trace:\t%s\n"+
|
||||
"\r\tError:%s\n\r",
|
||||
getWhitespaceString(),
|
||||
CallerInfo(),
|
||||
errorTrace,
|
||||
indentMessageLines(failureMessage, 2))
|
||||
}
|
||||
|
||||
|
@ -171,7 +214,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg
|
|||
interfaceType := reflect.TypeOf(interfaceObject).Elem()
|
||||
|
||||
if !reflect.TypeOf(object).Implements(interfaceType) {
|
||||
return Fail(t, fmt.Sprintf("Object must implement %v", interfaceType), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -196,8 +239,9 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
|
|||
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
if !ObjectsAreEqual(expected, actual) {
|
||||
diff := diff(expected, actual)
|
||||
return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+
|
||||
" != %#v (actual)", expected, actual), msgAndArgs...)
|
||||
" != %#v (actual)%s", expected, actual, diff), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -232,7 +276,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
|
|||
bType := reflect.TypeOf(actual)
|
||||
|
||||
if aType != bType {
|
||||
return Fail(t, "Types expected to match exactly", "%v != %v", aType, bType)
|
||||
return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...)
|
||||
}
|
||||
|
||||
return Equal(t, expected, actual, msgAndArgs...)
|
||||
|
@ -245,24 +289,10 @@ 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 {
|
||||
|
||||
success := true
|
||||
|
||||
if object == nil {
|
||||
success = false
|
||||
} else {
|
||||
value := reflect.ValueOf(object)
|
||||
kind := value.Kind()
|
||||
if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
|
||||
success = false
|
||||
}
|
||||
if !isNil(object) {
|
||||
return true
|
||||
}
|
||||
|
||||
if !success {
|
||||
Fail(t, "Expected not to be nil.", msgAndArgs...)
|
||||
}
|
||||
|
||||
return success
|
||||
return Fail(t, "Expected value not to be nil.", msgAndArgs...)
|
||||
}
|
||||
|
||||
// isNil checks if a specified object is nil or not, without Failing.
|
||||
|
@ -292,7 +322,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
|||
return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
|
||||
}
|
||||
|
||||
var zeros = []interface{}{
|
||||
var numericZeros = []interface{}{
|
||||
int(0),
|
||||
int8(0),
|
||||
int16(0),
|
||||
|
@ -318,7 +348,7 @@ func isEmpty(object interface{}) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
for _, v := range zeros {
|
||||
for _, v := range numericZeros {
|
||||
if object == v {
|
||||
return true
|
||||
}
|
||||
|
@ -335,6 +365,9 @@ func isEmpty(object interface{}) bool {
|
|||
}
|
||||
case reflect.Ptr:
|
||||
{
|
||||
if objValue.IsNil() {
|
||||
return true
|
||||
}
|
||||
switch object.(type) {
|
||||
case *time.Time:
|
||||
return object.(*time.Time).IsZero()
|
||||
|
@ -450,7 +483,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
|||
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
if ObjectsAreEqual(expected, actual) {
|
||||
return Fail(t, "Should not be equal", msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -476,6 +509,16 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
|
|||
return true, strings.Contains(listValue.String(), elementValue.String())
|
||||
}
|
||||
|
||||
if reflect.TypeOf(list).Kind() == reflect.Map {
|
||||
mapKeys := listValue.MapKeys()
|
||||
for i := 0; i < len(mapKeys); i++ {
|
||||
if ObjectsAreEqual(mapKeys[i].Interface(), element) {
|
||||
return true, true
|
||||
}
|
||||
}
|
||||
return true, false
|
||||
}
|
||||
|
||||
for i := 0; i < listValue.Len(); i++ {
|
||||
if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
|
||||
return true, true
|
||||
|
@ -485,11 +528,12 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
|
|||
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string or list(array, slice...) contains the
|
||||
// Contains asserts that the specified string, list(array, slice...) or map 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'")
|
||||
// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
@ -506,11 +550,12 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
|
|||
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string or list(array, slice...) does NOT contain the
|
||||
// NotContains asserts that the specified string, list(array, slice...) or map 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'")
|
||||
// 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 interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
@ -766,7 +811,7 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
return Fail(t, fmt.Sprintf("No error is expected but got %v", err), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("Received unexpected error %q", err), msgAndArgs...)
|
||||
}
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
|
@ -800,7 +845,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
|
|||
return false
|
||||
}
|
||||
s := "An error with value \"%s\" is expected but got \"%s\". %s"
|
||||
return Equal(t, theError.Error(), errString,
|
||||
return Equal(t, errString, theError.Error(),
|
||||
s, errString, theError.Error(), message)
|
||||
}
|
||||
|
||||
|
@ -851,3 +896,84 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
|
|||
return !match
|
||||
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
||||
if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
||||
return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
||||
if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
||||
return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||
var expectedJSONAsInterface, actualJSONAsInterface interface{}
|
||||
|
||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
|
||||
}
|
||||
|
||||
return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
|
||||
}
|
||||
|
||||
func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
|
||||
t := reflect.TypeOf(v)
|
||||
k := t.Kind()
|
||||
|
||||
if k == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
k = t.Kind()
|
||||
}
|
||||
return t, k
|
||||
}
|
||||
|
||||
// diff returns a diff of both values as long as both are of the same type and
|
||||
// are a struct, map, slice or array. Otherwise it returns an empty string.
|
||||
func diff(expected interface{}, actual interface{}) string {
|
||||
if expected == nil || actual == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
et, ek := typeAndKind(expected)
|
||||
at, _ := typeAndKind(actual)
|
||||
|
||||
if et != at {
|
||||
return ""
|
||||
}
|
||||
|
||||
if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
|
||||
return ""
|
||||
}
|
||||
|
||||
spew.Config.SortKeys = true
|
||||
e := spew.Sdump(expected)
|
||||
a := spew.Sdump(actual)
|
||||
|
||||
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
|
||||
A: difflib.SplitLines(e),
|
||||
B: difflib.SplitLines(a),
|
||||
FromFile: "Expected",
|
||||
FromDate: "",
|
||||
ToFile: "Actual",
|
||||
ToDate: "",
|
||||
Context: 1,
|
||||
})
|
||||
|
||||
return "\n\nDiff:\n" + diff
|
||||
}
|
||||
|
|
|
@ -2,12 +2,82 @@ package assert
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
i interface{}
|
||||
zeros = []interface{}{
|
||||
false,
|
||||
byte(0),
|
||||
complex64(0),
|
||||
complex128(0),
|
||||
float32(0),
|
||||
float64(0),
|
||||
int(0),
|
||||
int8(0),
|
||||
int16(0),
|
||||
int32(0),
|
||||
int64(0),
|
||||
rune(0),
|
||||
uint(0),
|
||||
uint8(0),
|
||||
uint16(0),
|
||||
uint32(0),
|
||||
uint64(0),
|
||||
uintptr(0),
|
||||
"",
|
||||
[0]interface{}{},
|
||||
[]interface{}(nil),
|
||||
struct{ x int }{},
|
||||
(*interface{})(nil),
|
||||
(func())(nil),
|
||||
nil,
|
||||
interface{}(nil),
|
||||
map[interface{}]interface{}(nil),
|
||||
(chan interface{})(nil),
|
||||
(<-chan interface{})(nil),
|
||||
(chan<- interface{})(nil),
|
||||
}
|
||||
nonZeros = []interface{}{
|
||||
true,
|
||||
byte(1),
|
||||
complex64(1),
|
||||
complex128(1),
|
||||
float32(1),
|
||||
float64(1),
|
||||
int(1),
|
||||
int8(1),
|
||||
int16(1),
|
||||
int32(1),
|
||||
int64(1),
|
||||
rune(1),
|
||||
uint(1),
|
||||
uint8(1),
|
||||
uint16(1),
|
||||
uint32(1),
|
||||
uint64(1),
|
||||
uintptr(1),
|
||||
"s",
|
||||
[1]interface{}{1},
|
||||
[]interface{}{},
|
||||
struct{ x int }{1},
|
||||
(*interface{})(&i),
|
||||
(func())(func() {}),
|
||||
interface{}(1),
|
||||
map[interface{}]interface{}{},
|
||||
(chan interface{})(make(chan interface{})),
|
||||
(<-chan interface{})(make(chan interface{})),
|
||||
(chan<- interface{})(make(chan interface{})),
|
||||
}
|
||||
)
|
||||
|
||||
// AssertionTesterInterface defines an interface to be used for testing assertion methods
|
||||
type AssertionTesterInterface interface {
|
||||
TestMethod()
|
||||
|
@ -62,6 +132,12 @@ func TestObjectsAreEqual(t *testing.T) {
|
|||
if !ObjectsAreEqualValues(uint32(10), int32(10)) {
|
||||
t.Error("ObjectsAreEqualValues should return true")
|
||||
}
|
||||
if ObjectsAreEqualValues(0, nil) {
|
||||
t.Fail()
|
||||
}
|
||||
if ObjectsAreEqualValues(nil, 0) {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -129,6 +205,9 @@ func TestNotNil(t *testing.T) {
|
|||
if NotNil(mockT, nil) {
|
||||
t.Error("NotNil should return false: object is nil")
|
||||
}
|
||||
if NotNil(mockT, (*struct{})(nil)) {
|
||||
t.Error("NotNil should return false: object is (*struct{})(nil)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -139,6 +218,9 @@ func TestNil(t *testing.T) {
|
|||
if !Nil(mockT, nil) {
|
||||
t.Error("Nil should return true: object is nil")
|
||||
}
|
||||
if !Nil(mockT, (*struct{})(nil)) {
|
||||
t.Error("Nil should return true: object is (*struct{})(nil)")
|
||||
}
|
||||
if Nil(mockT, new(AssertionTesterConformingObject)) {
|
||||
t.Error("Nil should return false: object is not nil")
|
||||
}
|
||||
|
@ -255,6 +337,7 @@ func TestContains(t *testing.T) {
|
|||
{"g", "h"},
|
||||
{"j", "k"},
|
||||
}
|
||||
simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
|
||||
|
||||
if !Contains(mockT, "Hello World", "Hello") {
|
||||
t.Error("Contains should return true: \"Hello World\" contains \"Hello\"")
|
||||
|
@ -275,12 +358,22 @@ func TestContains(t *testing.T) {
|
|||
if Contains(mockT, complexList, &A{"g", "e"}) {
|
||||
t.Error("Contains should return false: complexList contains {\"g\", \"e\"}")
|
||||
}
|
||||
if Contains(mockT, complexList, &A{"g", "e"}) {
|
||||
t.Error("Contains should return false: complexList contains {\"g\", \"e\"}")
|
||||
}
|
||||
if !Contains(mockT, simpleMap, "Foo") {
|
||||
t.Error("Contains should return true: \"{\"Foo\": \"Bar\"}\" contains \"Foo\"")
|
||||
}
|
||||
if Contains(mockT, simpleMap, "Bar") {
|
||||
t.Error("Contains should return false: \"{\"Foo\": \"Bar\"}\" does not contains \"Bar\"")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotContains(t *testing.T) {
|
||||
|
||||
mockT := new(testing.T)
|
||||
list := []string{"Foo", "Bar"}
|
||||
simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
|
||||
|
||||
if !NotContains(mockT, "Hello World", "Hello!") {
|
||||
t.Error("NotContains should return true: \"Hello World\" does not contain \"Hello!\"")
|
||||
|
@ -295,13 +388,19 @@ func TestNotContains(t *testing.T) {
|
|||
if NotContains(mockT, list, "Foo") {
|
||||
t.Error("NotContains should return false: \"[\"Foo\", \"Bar\"]\" contains \"Foo\"")
|
||||
}
|
||||
|
||||
if NotContains(mockT, simpleMap, "Foo") {
|
||||
t.Error("Contains should return true: \"{\"Foo\": \"Bar\"}\" contains \"Foo\"")
|
||||
}
|
||||
if !NotContains(mockT, simpleMap, "Bar") {
|
||||
t.Error("Contains should return false: \"{\"Foo\": \"Bar\"}\" does not contains \"Bar\"")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_includeElement(t *testing.T) {
|
||||
|
||||
list1 := []string{"Foo", "Bar"}
|
||||
list2 := []int{1, 2}
|
||||
simpleMap := map[interface{}]interface{}{"Foo": "Bar"}
|
||||
|
||||
ok, found := includeElement("Hello World", "World")
|
||||
True(t, ok)
|
||||
|
@ -335,10 +434,17 @@ func Test_includeElement(t *testing.T) {
|
|||
True(t, ok)
|
||||
False(t, found)
|
||||
|
||||
ok, found = includeElement(simpleMap, "Foo")
|
||||
True(t, ok)
|
||||
True(t, found)
|
||||
|
||||
ok, found = includeElement(simpleMap, "Bar")
|
||||
True(t, ok)
|
||||
False(t, found)
|
||||
|
||||
ok, found = includeElement(1433, "1")
|
||||
False(t, ok)
|
||||
False(t, found)
|
||||
|
||||
}
|
||||
|
||||
func TestCondition(t *testing.T) {
|
||||
|
@ -481,6 +587,9 @@ func TestEmpty(t *testing.T) {
|
|||
mockT := new(testing.T)
|
||||
chWithValue := make(chan struct{}, 1)
|
||||
chWithValue <- struct{}{}
|
||||
var ti *time.Time
|
||||
var s *string
|
||||
var f *os.File
|
||||
|
||||
True(t, Empty(mockT, ""), "Empty string is empty")
|
||||
True(t, Empty(mockT, nil), "Nil is empty")
|
||||
|
@ -488,6 +597,9 @@ func TestEmpty(t *testing.T) {
|
|||
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")
|
||||
True(t, Empty(mockT, s), "Nil string pointer is empty")
|
||||
True(t, Empty(mockT, f), "Nil os.File pointer is empty")
|
||||
True(t, Empty(mockT, ti), "Nil time.Time pointer 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")
|
||||
|
@ -789,3 +901,189 @@ func TestRegexp(t *testing.T) {
|
|||
True(t, NotRegexp(mockT, regexp.MustCompile(tc.rx), tc.str))
|
||||
}
|
||||
}
|
||||
|
||||
func testAutogeneratedFunction() {
|
||||
defer func() {
|
||||
if err := recover(); err == nil {
|
||||
panic("did not panic")
|
||||
}
|
||||
CallerInfo()
|
||||
}()
|
||||
t := struct {
|
||||
io.Closer
|
||||
}{}
|
||||
var c io.Closer
|
||||
c = t
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func TestCallerInfoWithAutogeneratedFunctions(t *testing.T) {
|
||||
NotPanics(t, func() {
|
||||
testAutogeneratedFunction()
|
||||
})
|
||||
}
|
||||
|
||||
func TestZero(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
for _, test := range zeros {
|
||||
True(t, Zero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
|
||||
}
|
||||
|
||||
for _, test := range nonZeros {
|
||||
False(t, Zero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotZero(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
for _, test := range zeros {
|
||||
False(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
|
||||
}
|
||||
|
||||
for _, test := range nonZeros {
|
||||
True(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_EqualSONString(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`))
|
||||
}
|
||||
|
||||
func TestJSONEq_EquivalentButNotEqual(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
|
||||
}
|
||||
|
||||
func TestJSONEq_HashOfArraysAndHashes(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
True(t, JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}"))
|
||||
}
|
||||
|
||||
func TestJSONEq_Array(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
True(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`))
|
||||
}
|
||||
|
||||
func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`))
|
||||
}
|
||||
|
||||
func TestJSONEq_HashesNotEquivalent(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
|
||||
}
|
||||
|
||||
func TestJSONEq_ActualIsNotJSON(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, `{"foo": "bar"}`, "Not JSON"))
|
||||
}
|
||||
|
||||
func TestJSONEq_ExpectedIsNotJSON(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`))
|
||||
}
|
||||
|
||||
func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, "Not JSON", "Not JSON"))
|
||||
}
|
||||
|
||||
func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`))
|
||||
}
|
||||
|
||||
func TestDiff(t *testing.T) {
|
||||
expected := `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -1,3 +1,3 @@
|
||||
(struct { foo string }) {
|
||||
- foo: (string) (len=5) "hello"
|
||||
+ foo: (string) (len=3) "bar"
|
||||
}
|
||||
`
|
||||
actual := diff(
|
||||
struct{ foo string }{"hello"},
|
||||
struct{ foo string }{"bar"},
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
|
||||
expected = `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -2,5 +2,5 @@
|
||||
(int) 1,
|
||||
- (int) 2,
|
||||
(int) 3,
|
||||
- (int) 4
|
||||
+ (int) 5,
|
||||
+ (int) 7
|
||||
}
|
||||
`
|
||||
actual = diff(
|
||||
[]int{1, 2, 3, 4},
|
||||
[]int{1, 3, 5, 7},
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
|
||||
expected = `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -2,4 +2,4 @@
|
||||
(int) 1,
|
||||
- (int) 2,
|
||||
- (int) 3
|
||||
+ (int) 3,
|
||||
+ (int) 5
|
||||
}
|
||||
`
|
||||
actual = diff(
|
||||
[]int{1, 2, 3, 4}[0:3],
|
||||
[]int{1, 3, 5, 7}[0:3],
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
|
||||
expected = `
|
||||
|
||||
Diff:
|
||||
--- Expected
|
||||
+++ Actual
|
||||
@@ -1,6 +1,6 @@
|
||||
(map[string]int) (len=4) {
|
||||
- (string) (len=4) "four": (int) 4,
|
||||
+ (string) (len=4) "five": (int) 5,
|
||||
(string) (len=3) "one": (int) 1,
|
||||
- (string) (len=5) "three": (int) 3,
|
||||
- (string) (len=3) "two": (int) 2
|
||||
+ (string) (len=5) "seven": (int) 7,
|
||||
+ (string) (len=5) "three": (int) 3
|
||||
}
|
||||
`
|
||||
|
||||
actual = diff(
|
||||
map[string]int{"one": 1, "two": 2, "three": 3, "four": 4},
|
||||
map[string]int{"one": 1, "three": 3, "five": 5, "seven": 7},
|
||||
)
|
||||
Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestDiffEmptyCases(t *testing.T) {
|
||||
Equal(t, "", diff(nil, nil))
|
||||
Equal(t, "", diff(struct{ foo string }{}, nil))
|
||||
Equal(t, "", diff(nil, struct{ foo string }{}))
|
||||
Equal(t, "", diff(1, 2))
|
||||
Equal(t, "", diff(1, 2))
|
||||
Equal(t, "", diff([]int{1}, []bool{true}))
|
||||
}
|
||||
|
|
111
assert/doc.go
111
assert/doc.go
|
@ -17,7 +17,7 @@
|
|||
//
|
||||
// }
|
||||
//
|
||||
// if you assert many times, use the below:
|
||||
// if you assert many times, use the format below:
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
|
@ -42,113 +42,4 @@
|
|||
//
|
||||
// Every assertion function also takes an optional string message as the final argument,
|
||||
// allowing custom error messages to be appended to the message the assertion method outputs.
|
||||
//
|
||||
// Here is an overview of the assert functions:
|
||||
//
|
||||
// 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.True(t, actualBool [, message [, format-args]])
|
||||
//
|
||||
// assert.False(t, actualBool [, message [, format-args]])
|
||||
//
|
||||
// assert.Nil(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// assert.NotNil(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// assert.Empty(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// 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, stringOrSlice, substringOrElement [, message [, format-args]])
|
||||
//
|
||||
// assert.NotContains(t, stringOrSlice, substringOrElement [, message [, format-args]])
|
||||
//
|
||||
// assert.Panics(t, func(){
|
||||
//
|
||||
// // call code that should panic
|
||||
//
|
||||
// } [, message [, format-args]])
|
||||
//
|
||||
// assert.NotPanics(t, func(){
|
||||
//
|
||||
// // call code that should not panic
|
||||
//
|
||||
// } [, 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.EqualValues(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
|
||||
|
|
|
@ -263,3 +263,22 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
|
|||
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotRegexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Zero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||
return JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
|
|
@ -509,3 +509,103 @@ func TestRegexpWrapper(t *testing.T) {
|
|||
True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
|
||||
}
|
||||
}
|
||||
|
||||
func TestZeroWrapper(t *testing.T) {
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
for _, test := range zeros {
|
||||
assert.True(mockAssert.Zero(test), "Zero should return true for %v", test)
|
||||
}
|
||||
|
||||
for _, test := range nonZeros {
|
||||
assert.False(mockAssert.Zero(test), "Zero should return false for %v", test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotZeroWrapper(t *testing.T) {
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
for _, test := range zeros {
|
||||
assert.False(mockAssert.NotZero(test), "Zero should return true for %v", test)
|
||||
}
|
||||
|
||||
for _, test := range nonZeros {
|
||||
assert.True(mockAssert.NotZero(test), "Zero should return false for %v", test)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EqualSONString(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_Array(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) {
|
||||
t.Error("JSONEq should return true")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`{"foo": "bar"}`, "Not JSON") {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq("Not JSON", "Not JSON") {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) {
|
||||
t.Error("JSONEq should return false")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
|
||||
// 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 {
|
||||
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int {
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
|
||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ func httpCode(handler http.HandlerFunc, mode, url string, values url.Values) int
|
|||
// 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)
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
return false
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values
|
|||
// 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)
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
return false
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, mode, url string, values
|
|||
// 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)
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
return false
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ func HTTPError(t TestingT, handler http.HandlerFunc, mode, url string, values ur
|
|||
|
||||
// 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 {
|
||||
func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil)
|
||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ func HTTPBody(handler http.HandlerFunc, mode, url string, values url.Values) str
|
|||
// 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)
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
body := HTTPBody(handler, method, url, values)
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if !contains {
|
||||
|
@ -94,8 +94,8 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, va
|
|||
// 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)
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
body := HTTPBody(handler, method, url, values)
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if contains {
|
||||
|
@ -114,8 +114,8 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string,
|
|||
// 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)
|
||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
return HTTPSuccess(a.t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
|
@ -123,8 +123,8 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, val
|
|||
// 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)
|
||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
return HTTPRedirect(a.t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
|
@ -132,8 +132,8 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, mode, url string, va
|
|||
// 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)
|
||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
return HTTPError(a.t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
|
@ -142,8 +142,8 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, mode, url string, value
|
|||
// 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)
|
||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
return HTTPBodyContains(a.t, handler, method, url, values, str)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
|
@ -152,6 +152,6 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, mode, url 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)
|
||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
return HTTPBodyNotContains(a.t, handler, method, url, values, str)
|
||||
}
|
||||
|
|
292
mock/mock.go
292
mock/mock.go
|
@ -2,13 +2,15 @@ package mock
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/objx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/objx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestingT is an interface wrapper around *testing.T
|
||||
|
@ -24,6 +26,7 @@ type TestingT interface {
|
|||
// Call represents a method call and is used for setting expectations,
|
||||
// as well as recording activity.
|
||||
type Call struct {
|
||||
Parent *Mock
|
||||
|
||||
// The name of the method that was or will be called.
|
||||
Method string
|
||||
|
@ -46,24 +49,113 @@ type Call struct {
|
|||
// 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)
|
||||
RunFn func(Arguments)
|
||||
}
|
||||
|
||||
func newCall(parent *Mock, methodName string, methodArguments ...interface{}) *Call {
|
||||
return &Call{
|
||||
Parent: parent,
|
||||
Method: methodName,
|
||||
Arguments: methodArguments,
|
||||
ReturnArguments: make([]interface{}, 0),
|
||||
Repeatability: 0,
|
||||
WaitFor: nil,
|
||||
RunFn: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Call) lock() {
|
||||
self.Parent.mutex.Lock()
|
||||
}
|
||||
|
||||
func (self *Call) unlock() {
|
||||
self.Parent.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (self *Call) Return(returnArguments ...interface{}) *Call {
|
||||
self.lock()
|
||||
defer self.unlock()
|
||||
|
||||
self.ReturnArguments = returnArguments
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// Once indicates that that the mock should only return the value once.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
|
||||
func (self *Call) Once() *Call {
|
||||
return self.Times(1)
|
||||
}
|
||||
|
||||
// Twice indicates that that the mock should only return the value twice.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
|
||||
func (self *Call) Twice() *Call {
|
||||
return self.Times(2)
|
||||
}
|
||||
|
||||
// Times indicates that that the mock should only return the indicated number
|
||||
// of times.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
|
||||
func (self *Call) Times(i int) *Call {
|
||||
self.lock()
|
||||
defer self.unlock()
|
||||
self.Repeatability = i
|
||||
return self
|
||||
}
|
||||
|
||||
// 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 (self *Call) WaitUntil(w <-chan time.Time) *Call {
|
||||
self.lock()
|
||||
defer self.unlock()
|
||||
self.WaitFor = w
|
||||
return self
|
||||
}
|
||||
|
||||
// After sets how long to block until the call returns
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
|
||||
func (self *Call) After(d time.Duration) *Call {
|
||||
return self.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 (self *Call) Run(fn func(Arguments)) *Call {
|
||||
self.lock()
|
||||
defer self.unlock()
|
||||
self.RunFn = fn
|
||||
return self
|
||||
}
|
||||
|
||||
// On chains a new expectation description onto the mocked interface. This
|
||||
// allows syntax like.
|
||||
//
|
||||
// Mock.
|
||||
// On("MyMethod", 1).Return(nil).
|
||||
// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
|
||||
func (self *Call) On(methodName string, arguments ...interface{}) *Call {
|
||||
return self.Parent.On(methodName, arguments...)
|
||||
}
|
||||
|
||||
// Mock is the workhorse used to track activity on another object.
|
||||
// For an example of its usage, refer to the "Example Usage" section at the top of this document.
|
||||
// For an example of its usage, refer to the "Example Usage" section at the top
|
||||
// of this document.
|
||||
type Mock struct {
|
||||
|
||||
// The method name that is currently
|
||||
// being referred to by the On method.
|
||||
onMethodName string
|
||||
|
||||
// An array of the arguments that are
|
||||
// currently being referred to by the On method.
|
||||
onMethodArguments Arguments
|
||||
|
||||
// Represents the calls that are expected of
|
||||
// an object.
|
||||
ExpectedCalls []Call
|
||||
ExpectedCalls []*Call
|
||||
|
||||
// Holds the calls that were made to this mocked object.
|
||||
Calls []Call
|
||||
|
@ -94,90 +186,33 @@ func (m *Mock) TestData() objx.Map {
|
|||
// being called.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2)
|
||||
func (m *Mock) On(methodName string, arguments ...interface{}) *Mock {
|
||||
m.onMethodName = methodName
|
||||
m.onMethodArguments = arguments
|
||||
|
||||
func (self *Mock) On(methodName string, arguments ...interface{}) *Call {
|
||||
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
|
||||
self.mutex.Lock()
|
||||
defer self.mutex.Unlock()
|
||||
c := newCall(self, methodName, arguments...)
|
||||
self.ExpectedCalls = append(self.ExpectedCalls, c)
|
||||
return c
|
||||
}
|
||||
|
||||
// Return finishes a description of an expectation of the method (and arguments)
|
||||
// specified in the most recent On method call.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2)
|
||||
func (m *Mock) Return(returnArguments ...interface{}) *Mock {
|
||||
m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0, nil, nil})
|
||||
return m
|
||||
}
|
||||
|
||||
// Once indicates that that the mock should only return the value once.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
|
||||
func (m *Mock) Once() {
|
||||
m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = 1
|
||||
}
|
||||
|
||||
// Twice indicates that that the mock should only return the value twice.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
|
||||
func (m *Mock) Twice() {
|
||||
m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = 2
|
||||
}
|
||||
|
||||
// Times indicates that that the mock should only return the indicated number
|
||||
// of times.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
|
||||
func (m *Mock) Times(i int) {
|
||||
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
|
||||
// */
|
||||
|
||||
func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
for i, call := range m.ExpectedCalls {
|
||||
if call.Method == method && call.Repeatability > -1 {
|
||||
|
||||
_, diffCount := call.Arguments.Diff(arguments)
|
||||
if diffCount == 0 {
|
||||
return i, &call
|
||||
return i, call
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -186,17 +221,16 @@ func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *
|
|||
}
|
||||
|
||||
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
|
||||
|
||||
diffCount := 0
|
||||
var closestCall *Call = nil
|
||||
|
||||
for _, call := range m.ExpectedCalls {
|
||||
for _, call := range m.expectedCalls() {
|
||||
if call.Method == method {
|
||||
|
||||
_, tempDiffCount := call.Arguments.Diff(arguments)
|
||||
if tempDiffCount < diffCount || diffCount == 0 {
|
||||
diffCount = tempDiffCount
|
||||
closestCall = &call
|
||||
closestCall = call
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -215,7 +249,7 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
|
|||
if includeArgumentValues {
|
||||
var argVals []string
|
||||
for argIndex, arg := range arguments {
|
||||
argVals = append(argVals, fmt.Sprintf("%d: %v", argIndex, arg))
|
||||
argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
|
||||
}
|
||||
argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
|
||||
}
|
||||
|
@ -228,22 +262,26 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
|
|||
// 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 {
|
||||
defer m.mutex.Unlock()
|
||||
m.mutex.Lock()
|
||||
|
||||
// get the calling function's name
|
||||
pc, _, _, ok := runtime.Caller(1)
|
||||
if !ok {
|
||||
panic("Couldn't get the caller information")
|
||||
}
|
||||
functionPath := runtime.FuncForPC(pc).Name()
|
||||
//Next four lines are required to use GCCGO function naming conventions.
|
||||
//For Ex: github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock
|
||||
//uses inteface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree
|
||||
//With GCCGO we need to remove interface information starting from pN<dd>.
|
||||
re := regexp.MustCompile("\\.pN\\d+_")
|
||||
if re.MatchString(functionPath) {
|
||||
functionPath = re.Split(functionPath, -1)[0]
|
||||
}
|
||||
parts := strings.Split(functionPath, ".")
|
||||
functionName := parts[len(parts)-1]
|
||||
|
||||
found, call := m.findExpectedCall(functionName, arguments...)
|
||||
|
||||
switch {
|
||||
case found < 0:
|
||||
if found < 0 {
|
||||
// we have to fail here - because we don't know what to do
|
||||
// as the return arguments. This is because:
|
||||
//
|
||||
|
@ -258,16 +296,22 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
|
|||
} else {
|
||||
panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", functionName, functionName, callString(functionName, arguments, true), assert.CallerInfo()))
|
||||
}
|
||||
case call.Repeatability == 1:
|
||||
call.Repeatability = -1
|
||||
m.ExpectedCalls[found] = *call
|
||||
case call.Repeatability > 1:
|
||||
call.Repeatability -= 1
|
||||
m.ExpectedCalls[found] = *call
|
||||
} else {
|
||||
m.mutex.Lock()
|
||||
switch {
|
||||
case call.Repeatability == 1:
|
||||
call.Repeatability = -1
|
||||
|
||||
case call.Repeatability > 1:
|
||||
call.Repeatability -= 1
|
||||
}
|
||||
m.mutex.Unlock()
|
||||
}
|
||||
|
||||
// add the call
|
||||
m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0, nil, nil})
|
||||
m.mutex.Lock()
|
||||
m.Calls = append(m.Calls, *newCall(m, functionName, arguments...))
|
||||
m.mutex.Unlock()
|
||||
|
||||
// block if specified
|
||||
if call.WaitFor != nil {
|
||||
|
@ -276,12 +320,11 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
|
|||
m.mutex.Lock()
|
||||
}
|
||||
|
||||
if call.Run != nil {
|
||||
call.Run(arguments)
|
||||
if call.RunFn != nil {
|
||||
call.RunFn(arguments)
|
||||
}
|
||||
|
||||
return call.ReturnArguments
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -304,27 +347,30 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
|
|||
// AssertExpectations asserts that everything specified with On and Return was
|
||||
// in fact called as expected. Calls may have occurred in any order.
|
||||
func (m *Mock) AssertExpectations(t TestingT) bool {
|
||||
|
||||
var somethingMissing bool = false
|
||||
var failedExpectations int = 0
|
||||
|
||||
// iterate through each expectation
|
||||
for _, expectedCall := range m.ExpectedCalls {
|
||||
switch {
|
||||
case !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments):
|
||||
expectedCalls := m.expectedCalls()
|
||||
for _, expectedCall := range expectedCalls {
|
||||
if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
case expectedCall.Repeatability > 0:
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
default:
|
||||
t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
} else {
|
||||
m.mutex.Lock()
|
||||
if expectedCall.Repeatability > 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
} else {
|
||||
t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
}
|
||||
m.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
if somethingMissing {
|
||||
t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(m.ExpectedCalls)-failedExpectations, len(m.ExpectedCalls), failedExpectations, assert.CallerInfo())
|
||||
t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(expectedCalls)-failedExpectations, len(expectedCalls), failedExpectations, assert.CallerInfo())
|
||||
}
|
||||
|
||||
return !somethingMissing
|
||||
|
@ -333,18 +379,18 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
|
|||
// AssertNumberOfCalls asserts that the method was called expectedCalls times.
|
||||
func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
|
||||
var actualCalls int = 0
|
||||
for _, call := range m.Calls {
|
||||
for _, call := range m.calls() {
|
||||
if call.Method == methodName {
|
||||
actualCalls++
|
||||
}
|
||||
}
|
||||
return assert.Equal(t, actualCalls, expectedCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
|
||||
return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
|
||||
}
|
||||
|
||||
// AssertCalled asserts that the method was called.
|
||||
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))) {
|
||||
t.Logf("%v", m.ExpectedCalls)
|
||||
t.Logf("%v", m.expectedCalls())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
@ -353,14 +399,14 @@ func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interfac
|
|||
// AssertNotCalled asserts that the method was not called.
|
||||
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))) {
|
||||
t.Logf("%v", m.ExpectedCalls)
|
||||
t.Logf("%v", m.expectedCalls())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
|
||||
for _, call := range m.Calls {
|
||||
for _, call := range m.calls() {
|
||||
if call.Method == methodName {
|
||||
|
||||
_, differences := Arguments(expected).Diff(call.Arguments)
|
||||
|
@ -376,6 +422,18 @@ func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m *Mock) expectedCalls() []*Call {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
return append([]*Call{}, m.ExpectedCalls...)
|
||||
}
|
||||
|
||||
func (m *Mock) calls() []Call {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
return append([]Call{}, m.Calls...)
|
||||
}
|
||||
|
||||
/*
|
||||
Arguments
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,7 @@ package mock
|
|||
import (
|
||||
"errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
@ -44,6 +45,16 @@ func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error)
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodVariadic(a ...int) error {
|
||||
args := i.Called(a)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodVariadicInterface(a ...interface{}) error {
|
||||
args := i.Called(a)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
type ExampleFuncType func(string) error
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType) error {
|
||||
|
@ -63,9 +74,7 @@ func Test_Mock_TestData(t *testing.T) {
|
|||
|
||||
mockedService.TestData().Set("something", 123)
|
||||
assert.Equal(t, 123, mockedService.TestData().Get("something").Data())
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_On(t *testing.T) {
|
||||
|
@ -73,9 +82,36 @@ func Test_Mock_On(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
assert.Equal(t, mockedService.On("TheExampleMethod"), &mockedService.Mock)
|
||||
assert.Equal(t, "TheExampleMethod", mockedService.onMethodName)
|
||||
c := mockedService.On("TheExampleMethod")
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, "TheExampleMethod", c.Method)
|
||||
}
|
||||
|
||||
func Test_Mock_Chained_On(t *testing.T) {
|
||||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
mockedService.
|
||||
On("TheExampleMethod", 1, 2, 3).
|
||||
Return(0).
|
||||
On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
|
||||
Return(nil)
|
||||
|
||||
expectedCalls := []*Call{
|
||||
&Call{
|
||||
Parent: &mockedService.Mock,
|
||||
Method: "TheExampleMethod",
|
||||
Arguments: []interface{}{1, 2, 3},
|
||||
ReturnArguments: []interface{}{0},
|
||||
},
|
||||
&Call{
|
||||
Parent: &mockedService.Mock,
|
||||
Method: "TheExampleMethod3",
|
||||
Arguments: []interface{}{AnythingOfType("*mock.ExampleType")},
|
||||
ReturnArguments: []interface{}{nil},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expectedCalls, mockedService.ExpectedCalls)
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithArgs(t *testing.T) {
|
||||
|
@ -83,12 +119,11 @@ func Test_Mock_On_WithArgs(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
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])
|
||||
c := mockedService.On("TheExampleMethod", 1, 2, 3, 4)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, "TheExampleMethod", c.Method)
|
||||
assert.Equal(t, Arguments{1, 2, 3, 4}, c.Arguments)
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithFuncArg(t *testing.T) {
|
||||
|
@ -96,12 +131,85 @@ 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])
|
||||
c := mockedService.
|
||||
On("TheExampleMethodFunc", AnythingOfType("func(string) error")).
|
||||
Return(nil)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, "TheExampleMethodFunc", c.Method)
|
||||
assert.Equal(t, 1, len(c.Arguments))
|
||||
assert.Equal(t, AnythingOfType("func(string) error"), c.Arguments[0])
|
||||
|
||||
fn := func(string) error { return nil }
|
||||
mockedService.TheExampleMethodFunc(fn)
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
mockedService.TheExampleMethodFunc(fn)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithVariadicFunc(t *testing.T) {
|
||||
|
||||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
c := mockedService.
|
||||
On("TheExampleMethodVariadic", []int{1, 2, 3}).
|
||||
Return(nil)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, 1, len(c.Arguments))
|
||||
assert.Equal(t, []int{1, 2, 3}, c.Arguments[0])
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
mockedService.TheExampleMethodVariadic(1, 2, 3)
|
||||
})
|
||||
assert.Panics(t, func() {
|
||||
mockedService.TheExampleMethodVariadic(1, 2)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithVariadicFuncWithInterface(t *testing.T) {
|
||||
|
||||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
c := mockedService.On("TheExampleMethodVariadicInterface", []interface{}{1, 2, 3}).
|
||||
Return(nil)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, 1, len(c.Arguments))
|
||||
assert.Equal(t, []interface{}{1, 2, 3}, c.Arguments[0])
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
mockedService.TheExampleMethodVariadicInterface(1, 2, 3)
|
||||
})
|
||||
assert.Panics(t, func() {
|
||||
mockedService.TheExampleMethodVariadicInterface(1, 2)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithVariadicFuncWithEmptyInterfaceArray(t *testing.T) {
|
||||
|
||||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
var expected []interface{}
|
||||
c := mockedService.
|
||||
On("TheExampleMethodVariadicInterface", expected).
|
||||
Return(nil)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, 1, len(c.Arguments))
|
||||
assert.Equal(t, expected, c.Arguments[0])
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
mockedService.TheExampleMethodVariadicInterface()
|
||||
})
|
||||
assert.Panics(t, func() {
|
||||
mockedService.TheExampleMethodVariadicInterface(1, 2)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
@ -119,13 +227,18 @@ 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])
|
||||
c := mockedService.
|
||||
On("TheExampleMethodFuncType", AnythingOfType("mock.ExampleFuncType")).
|
||||
Return(nil)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, 1, len(c.Arguments))
|
||||
assert.Equal(t, AnythingOfType("mock.ExampleFuncType"), c.Arguments[0])
|
||||
|
||||
fn := func(string) error { return nil }
|
||||
mockedService.TheExampleMethodFuncType(fn)
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
mockedService.TheExampleMethodFuncType(fn)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Mock_Return(t *testing.T) {
|
||||
|
@ -133,24 +246,23 @@ func Test_Mock_Return(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
assert.Equal(t, mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true), &mockedService.Mock)
|
||||
c := mockedService.
|
||||
On("TheExampleMethod", "A", "B", true).
|
||||
Return(1, "two", true)
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
|
||||
call := mockedService.ExpectedCalls[0]
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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.Nil(t, call.WaitFor)
|
||||
|
||||
}
|
||||
call := mockedService.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.Nil(t, call.WaitFor)
|
||||
}
|
||||
|
||||
func Test_Mock_Return_WaitUntil(t *testing.T) {
|
||||
|
@ -159,24 +271,25 @@ func Test_Mock_Return_WaitUntil(t *testing.T) {
|
|||
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)
|
||||
c := mockedService.Mock.
|
||||
On("TheExampleMethod", "A", "B", true).
|
||||
WaitUntil(ch).
|
||||
Return(1, "two", true)
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
|
||||
call := mockedService.Mock.ExpectedCalls[0]
|
||||
// assert that the call was created
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
call := mockedService.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) {
|
||||
|
@ -184,23 +297,24 @@ 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)
|
||||
c := mockedService.Mock.
|
||||
On("TheExampleMethod", "A", "B", true).
|
||||
Return(1, "two", true).
|
||||
After(time.Second)
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) {
|
||||
call := mockedService.Mock.ExpectedCalls[0]
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
|
@ -209,29 +323,56 @@ 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) {
|
||||
fn := 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)
|
||||
|
||||
}
|
||||
|
||||
c := mockedService.Mock.
|
||||
On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
|
||||
Return(nil).
|
||||
Run(fn)
|
||||
|
||||
require.Equal(t, []*Call{c}, mockedService.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_Run_Out_Of_Order(t *testing.T) {
|
||||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
f := func(args Arguments) {
|
||||
arg := args.Get(0).(*ExampleType)
|
||||
arg.ran = true
|
||||
}
|
||||
|
||||
c := mockedService.Mock.
|
||||
On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).
|
||||
Run(f).
|
||||
Return(nil)
|
||||
|
||||
require.Equal(t, []*Call{c}, mockedService.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)
|
||||
}
|
||||
|
||||
func Test_Mock_Return_Once(t *testing.T) {
|
||||
|
@ -239,24 +380,23 @@ func Test_Mock_Return_Once(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Once()
|
||||
c := mockedService.On("TheExampleMethod", "A", "B", true).
|
||||
Return(1, "two", true).
|
||||
Once()
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
|
||||
call := mockedService.ExpectedCalls[0]
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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, 1, call.Repeatability)
|
||||
assert.Nil(t, call.WaitFor)
|
||||
|
||||
}
|
||||
call := mockedService.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, 1, call.Repeatability)
|
||||
assert.Nil(t, call.WaitFor)
|
||||
}
|
||||
|
||||
func Test_Mock_Return_Twice(t *testing.T) {
|
||||
|
@ -264,24 +404,24 @@ func Test_Mock_Return_Twice(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Twice()
|
||||
c := mockedService.
|
||||
On("TheExampleMethod", "A", "B", true).
|
||||
Return(1, "two", true).
|
||||
Twice()
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
|
||||
call := mockedService.ExpectedCalls[0]
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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, 2, call.Repeatability)
|
||||
assert.Nil(t, call.WaitFor)
|
||||
|
||||
}
|
||||
call := mockedService.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, 2, call.Repeatability)
|
||||
assert.Nil(t, call.WaitFor)
|
||||
}
|
||||
|
||||
func Test_Mock_Return_Times(t *testing.T) {
|
||||
|
@ -289,24 +429,24 @@ func Test_Mock_Return_Times(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
mockedService.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).Times(5)
|
||||
c := mockedService.
|
||||
On("TheExampleMethod", "A", "B", true).
|
||||
Return(1, "two", true).
|
||||
Times(5)
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
|
||||
call := mockedService.ExpectedCalls[0]
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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, 5, call.Repeatability)
|
||||
assert.Nil(t, call.WaitFor)
|
||||
|
||||
}
|
||||
call := mockedService.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, 5, call.Repeatability)
|
||||
assert.Nil(t, call.WaitFor)
|
||||
}
|
||||
|
||||
func Test_Mock_Return_Nothing(t *testing.T) {
|
||||
|
@ -314,20 +454,19 @@ func Test_Mock_Return_Nothing(t *testing.T) {
|
|||
// make a test impl object
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
assert.Equal(t, mockedService.On("TheExampleMethod", "A", "B", true).Return(), &mockedService.Mock)
|
||||
c := mockedService.
|
||||
On("TheExampleMethod", "A", "B", true).
|
||||
Return()
|
||||
|
||||
// ensure the call was created
|
||||
if assert.Equal(t, 1, len(mockedService.ExpectedCalls)) {
|
||||
call := mockedService.ExpectedCalls[0]
|
||||
require.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
|
||||
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, 0, len(call.ReturnArguments))
|
||||
|
||||
}
|
||||
call := mockedService.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, 0, len(call.ReturnArguments))
|
||||
}
|
||||
|
||||
func Test_Mock_findExpectedCall(t *testing.T) {
|
||||
|
@ -452,8 +591,13 @@ func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) {
|
|||
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
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)
|
||||
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.Called(1, 2, 3)
|
||||
returnArguments2 := mockedService.Called(1, 2, 3)
|
||||
|
@ -651,7 +795,9 @@ func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) {
|
|||
|
||||
var mockedService *TestExampleImplementation = new(TestExampleImplementation)
|
||||
|
||||
mockedService.On("Test_Mock_AssertCalled_WithAnythingOfTypeArgument", Anything, Anything, Anything).Return()
|
||||
mockedService.
|
||||
On("Test_Mock_AssertCalled_WithAnythingOfTypeArgument", Anything, Anything, Anything).
|
||||
Return()
|
||||
|
||||
mockedService.Called(1, "two", []uint8("three"))
|
||||
|
||||
|
|
|
@ -24,54 +24,4 @@
|
|||
//
|
||||
// Every assertion function also takes an optional string message as the final argument,
|
||||
// allowing custom error messages to be appended to the message the assertion method outputs.
|
||||
//
|
||||
// Here is an overview of the assert functions:
|
||||
//
|
||||
// require.Equal(t, expected, actual [, message [, format-args])
|
||||
//
|
||||
// require.NotEqual(t, notExpected, actual [, message [, format-args]])
|
||||
//
|
||||
// require.True(t, actualBool [, message [, format-args]])
|
||||
//
|
||||
// require.False(t, actualBool [, message [, format-args]])
|
||||
//
|
||||
// require.Nil(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// require.NotNil(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// require.Empty(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// require.NotEmpty(t, actualObject [, message [, format-args]])
|
||||
//
|
||||
// require.Error(t, errorObject [, message [, format-args]])
|
||||
//
|
||||
// require.NoError(t, errorObject [, message [, format-args]])
|
||||
//
|
||||
// require.EqualError(t, theError, errString [, message [, format-args]])
|
||||
//
|
||||
// require.Implements(t, (*MyInterface)(nil), new(MyObject) [,message [, format-args]])
|
||||
//
|
||||
// require.IsType(t, expectedObject, actualObject [, message [, format-args]])
|
||||
//
|
||||
// require.Contains(t, string, substring [, message [, format-args]])
|
||||
//
|
||||
// require.NotContains(t, string, substring [, message [, format-args]])
|
||||
//
|
||||
// require.Panics(t, func(){
|
||||
//
|
||||
// // call code that should panic
|
||||
//
|
||||
// } [, message [, format-args]])
|
||||
//
|
||||
// require.NotPanics(t, func(){
|
||||
//
|
||||
// // call code that should not panic
|
||||
//
|
||||
// } [, message [, format-args]])
|
||||
//
|
||||
// require.WithinDuration(t, timeA, timeB, deltaTime, [, message [, format-args]])
|
||||
//
|
||||
// require.InDelta(t, numA, numB, delta, [, message [, format-args]])
|
||||
//
|
||||
// require.InEpsilon(t, numA, numB, epsilon, [, message [, format-args]])
|
||||
package require
|
||||
|
|
|
@ -209,3 +209,22 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
|
|||
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
|
||||
NotRegexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
|
||||
Zero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
|
||||
NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {
|
||||
JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
|
|
@ -258,3 +258,128 @@ func TestInDeltaWrapper(t *testing.T) {
|
|||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestZeroWrapper(t *testing.T) {
|
||||
require := New(t)
|
||||
require.Zero(0)
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
mockRequire.Zero(1)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotZeroWrapper(t *testing.T) {
|
||||
require := New(t)
|
||||
require.NotZero(1)
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
mockRequire.NotZero(0)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EqualSONString(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_Array(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`{"foo": "bar"}`, "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq("Not JSON", "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
mockRequire.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package require
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -136,9 +137,12 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{
|
|||
}
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string contains the specified substring.
|
||||
// Contains asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// require.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
// require.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
|
||||
// require.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
|
||||
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.Contains(t, s, contains, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
|
@ -228,6 +232,25 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
|
|||
}
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
|
||||
var expectedJSONAsInterface, actualJSONAsInterface interface{}
|
||||
|
||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
|
||||
}
|
||||
|
||||
/*
|
||||
Errors
|
||||
*/
|
||||
|
@ -269,3 +292,17 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
|
|||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.Zero(t, i, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.NotZero(t, i, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,3 +264,106 @@ func TestInDelta(t *testing.T) {
|
|||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestZero(t *testing.T) {
|
||||
|
||||
Zero(t, "")
|
||||
|
||||
mockT := new(MockT)
|
||||
Zero(mockT, "x")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotZero(t *testing.T) {
|
||||
|
||||
NotZero(t, "x")
|
||||
|
||||
mockT := new(MockT)
|
||||
NotZero(mockT, "")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_EqualSONString(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_EquivalentButNotEqual(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_HashOfArraysAndHashes(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_Array(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
|
||||
if mockT.Failed {
|
||||
t.Error("Check should pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_HashesNotEquivalent(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_ActualIsNotJSON(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"foo": "bar"}`, "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_ExpectedIsNotJSON(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, "Not JSON", "Not JSON")
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
// // All methods that begin with "Test" are run as tests within a
|
||||
// // suite.
|
||||
// func (suite *ExampleTestSuite) TestExample() {
|
||||
// assert.Equal(suite.T(), suite.VariableThatShouldStartAtFive, 5)
|
||||
// suite.Equal(suite.VariableThatShouldStartAtFive, 5)
|
||||
// assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
// suite.Equal(5, suite.VariableThatShouldStartAtFive)
|
||||
// }
|
||||
//
|
||||
// // In order for 'go test' to run this suite, we need to create
|
||||
|
|
|
@ -31,6 +31,7 @@ func (suite *Suite) T() *testing.T {
|
|||
func (suite *Suite) SetT(t *testing.T) {
|
||||
suite.t = t
|
||||
suite.Assertions = assert.New(t)
|
||||
suite.require = require.New(t)
|
||||
}
|
||||
|
||||
// Require returns a require context for suite.
|
||||
|
|
|
@ -9,6 +9,37 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// SuiteRequireTwice is intended to test the usage of suite.Require in two
|
||||
// different tests
|
||||
type SuiteRequireTwice struct{ Suite }
|
||||
|
||||
// TestSuiteRequireTwice checks for regressions of issue #149 where
|
||||
// suite.requirements was not initialised in suite.SetT()
|
||||
// A regression would result on these tests panicking rather than failing.
|
||||
func TestSuiteRequireTwice(t *testing.T) {
|
||||
ok := testing.RunTests(
|
||||
func(_, _ string) (bool, error) { return true, nil },
|
||||
[]testing.InternalTest{{
|
||||
Name: "TestSuiteRequireTwice",
|
||||
F: func(t *testing.T) {
|
||||
suite := new(SuiteRequireTwice)
|
||||
Run(t, suite)
|
||||
},
|
||||
}},
|
||||
)
|
||||
assert.Equal(t, false, ok)
|
||||
}
|
||||
|
||||
func (s *SuiteRequireTwice) TestRequireOne() {
|
||||
r := s.Require()
|
||||
r.Equal(1, 2)
|
||||
}
|
||||
|
||||
func (s *SuiteRequireTwice) TestRequireTwo() {
|
||||
r := s.Require()
|
||||
r.Equal(1, 2)
|
||||
}
|
||||
|
||||
// This suite is intended to store values to make sure that only
|
||||
// testing-suite-related methods are run. It's also a fully
|
||||
// functional example of a testing suite, using setup/teardown methods
|
||||
|
|
Loading…
Reference in New Issue