forked from samuel/go-zookeeper
-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
27bc0d6
commit 6d30b8b
Showing
2 changed files
with
211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Internal assertion library inspired by https://github.com/stretchr/testify. | ||
// "A little copying is better than a little dependency." - https://go-proverbs.github.io. | ||
// We don't want the library to have dependencies, so we write our own assertions. | ||
package assert | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
// TestingT is an interface wrapper around stdlib *testing.T. | ||
type TestingT interface { | ||
Errorf(format string, args ...interface{}) | ||
Helper() | ||
} | ||
|
||
// Equal asserts that expected is equal to actual. | ||
func Equal(t TestingT, want, got interface{}, msgAndArgs ...interface{}) { | ||
if !reflect.DeepEqual(want, got) { | ||
fail(t, fmt.Sprintf("not equal: want: %+v, got: %+v", want, got), msgAndArgs) | ||
} | ||
} | ||
|
||
// NoError asserts that the error is nil. | ||
func NoError(t TestingT, err error, msgAndArgs ...interface{}) { | ||
if err != nil { | ||
fail(t, fmt.Sprintf("unexpected error: %v", err), msgAndArgs) | ||
} | ||
} | ||
|
||
func fail(t TestingT, message string, msgAndArgs []interface{}) { | ||
t.Helper() | ||
userMessage := msgAndArgsToString(msgAndArgs) | ||
if userMessage != "" { | ||
message += ": " + userMessage | ||
} | ||
t.Errorf(message) | ||
} | ||
|
||
func msgAndArgsToString(msgAndArgs []interface{}) string { | ||
if len(msgAndArgs) == 0 { | ||
return "" | ||
} | ||
if len(msgAndArgs) == 1 { | ||
return fmt.Sprintf("%+v", msgAndArgs[0]) | ||
} | ||
if format, ok := msgAndArgs[0].(string); ok { | ||
return fmt.Sprintf(format, msgAndArgs[1:]...) | ||
} | ||
return fmt.Sprintf("%+v", msgAndArgs) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package assert | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
) | ||
|
||
type call struct { | ||
name string | ||
args []interface{} | ||
} | ||
|
||
// fakeT is a fake implementation of TestingT. | ||
// It records calls to its methods. | ||
// Its methods are not safe for concurrent use. | ||
type fakeT struct { | ||
calls []call | ||
} | ||
|
||
func (f *fakeT) Errorf(format string, args ...interface{}) { | ||
f.calls = append(f.calls, call{ | ||
name: "Errorf", | ||
args: append([]interface{}{format}, args...), | ||
}) | ||
} | ||
|
||
func (f *fakeT) Helper() { | ||
f.calls = append(f.calls, call{name: "Helper"}) | ||
} | ||
|
||
func TestEqual(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
giveWant interface{} | ||
giveGot interface{} | ||
giveMsgAndArgs []interface{} | ||
want []call | ||
}{ | ||
{ | ||
name: "equal", | ||
giveWant: 1, | ||
giveGot: 1, | ||
want: nil, | ||
}, | ||
{ | ||
name: "not equal shallow", | ||
giveWant: 1, | ||
giveGot: 2, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"not equal: want: 1, got: 2"}}, | ||
}, | ||
}, | ||
{ | ||
name: "not equal deep", | ||
giveWant: map[string]interface{}{"foo": struct{ bar string }{"baz"}}, | ||
giveGot: map[string]interface{}{"foo": struct{ bar string }{"foobar"}}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"not equal: want: map[foo:{bar:baz}], got: map[foo:{bar:foobar}]"}}, | ||
}, | ||
}, | ||
{ | ||
name: "with message", | ||
giveWant: 1, | ||
giveGot: 2, | ||
giveMsgAndArgs: []interface{}{"user message"}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"not equal: want: 1, got: 2: user message"}}, | ||
}, | ||
}, | ||
{ | ||
name: "with message and args", | ||
giveWant: 1, | ||
giveGot: 2, | ||
giveMsgAndArgs: []interface{}{"user message: %d %s", 1, "arg2"}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"not equal: want: 1, got: 2: user message: 1 arg2"}}, | ||
}, | ||
}, | ||
{ | ||
name: "only args", | ||
giveWant: 1, | ||
giveGot: 2, | ||
giveMsgAndArgs: []interface{}{1, "arg2"}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"not equal: want: 1, got: 2: [1 arg2]"}}, | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
var f fakeT | ||
Equal(&f, tt.giveWant, tt.giveGot, tt.giveMsgAndArgs...) | ||
// Since we're asserting ourselves it might be possible to introduce a subtle bug. | ||
// However, the code is straightforward so it's not a big deal. | ||
Equal(t, tt.want, f.calls) | ||
}) | ||
} | ||
} | ||
|
||
func TestNoError(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
giveErr error | ||
giveMsgAndArgs []interface{} | ||
want []call | ||
}{ | ||
{ | ||
name: "no error", | ||
giveErr: nil, | ||
want: nil, | ||
}, | ||
{ | ||
name: "with error", | ||
giveErr: errors.New("foo"), | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"unexpected error: foo"}}, | ||
}, | ||
}, | ||
{ | ||
name: "with message", | ||
giveErr: errors.New("foo"), | ||
giveMsgAndArgs: []interface{}{"user message"}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"unexpected error: foo: user message"}}, | ||
}, | ||
}, | ||
{ | ||
name: "with message and args", | ||
giveErr: errors.New("foo"), | ||
giveMsgAndArgs: []interface{}{"user message: %d %s", 1, "arg2"}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"unexpected error: foo: user message: 1 arg2"}}, | ||
}, | ||
}, | ||
{ | ||
name: "only args", | ||
giveErr: errors.New("foo"), | ||
giveMsgAndArgs: []interface{}{1, "arg2"}, | ||
want: []call{ | ||
{name: "Helper"}, | ||
{name: "Errorf", args: []interface{}{"unexpected error: foo: [1 arg2]"}}, | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
var f fakeT | ||
NoError(&f, tt.giveErr, tt.giveMsgAndArgs...) | ||
Equal(t, tt.want, f.calls) | ||
}) | ||
} | ||
} |