143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestHandleReturnValue(t *testing.T) {
|
|
// one value
|
|
v, err := handleReturnValue([]reflect.Value{reflect.ValueOf(1)})
|
|
if v.(int) != 1 {
|
|
t.Fatal("expected value")
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Nil value
|
|
v, err = handleReturnValue([]reflect.Value{reflect.ValueOf(nil)})
|
|
if v != nil {
|
|
t.Fatal("expected no value")
|
|
}
|
|
if err == nil {
|
|
t.Fatal("expected an error")
|
|
}
|
|
|
|
// Nil value, nil err
|
|
v, err = handleReturnValue([]reflect.Value{reflect.ValueOf(nil), reflect.ValueOf(nil)})
|
|
if v != nil {
|
|
t.Fatal("expected no value")
|
|
}
|
|
if err == nil {
|
|
t.Fatal("expected an error")
|
|
}
|
|
|
|
// two values
|
|
v, err = handleReturnValue([]reflect.Value{reflect.ValueOf(1), reflect.ValueOf(nil)})
|
|
if v, ok := v.(int); !ok || v != 1 {
|
|
t.Fatalf("expected value of 1, got %v", v)
|
|
}
|
|
if err != nil {
|
|
t.Fatal("expected no error")
|
|
}
|
|
|
|
// an error
|
|
myError := errors.New("my error")
|
|
_, err = handleReturnValue([]reflect.Value{reflect.ValueOf(1), reflect.ValueOf(myError)})
|
|
if err != myError {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for _, vals := range [][]reflect.Value{
|
|
{reflect.ValueOf(1), reflect.ValueOf("not an error")},
|
|
{},
|
|
{reflect.ValueOf(1), reflect.ValueOf(myError), reflect.ValueOf(myError)},
|
|
} {
|
|
func() {
|
|
defer func() { recover() }()
|
|
handleReturnValue(vals)
|
|
t.Fatal("expected a panic")
|
|
}()
|
|
}
|
|
}
|
|
|
|
type foo interface {
|
|
foo() foo
|
|
}
|
|
|
|
var fooType = reflect.TypeOf((*foo)(nil)).Elem()
|
|
|
|
func TestCheckReturnType(t *testing.T) {
|
|
for i, fn := range []interface{}{
|
|
func() { panic("") },
|
|
func() error { panic("") },
|
|
func() (error, error) { panic("") },
|
|
func() (foo, error, error) { panic("") },
|
|
func() (foo, foo) { panic("") },
|
|
} {
|
|
if checkReturnType(reflect.TypeOf(fn), fooType) == nil {
|
|
t.Errorf("expected falure for case %d (type %T)", i, fn)
|
|
}
|
|
}
|
|
|
|
for i, fn := range []interface{}{
|
|
func() foo { panic("") },
|
|
func() (foo, error) { panic("") },
|
|
} {
|
|
if err := checkReturnType(reflect.TypeOf(fn), fooType); err != nil {
|
|
t.Errorf("expected success for case %d (type %T), got: %s", i, fn, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func constructFoo() foo {
|
|
return nil
|
|
}
|
|
|
|
type fooImpl struct{}
|
|
|
|
func (f *fooImpl) foo() foo { return nil }
|
|
|
|
func TestCallConstructor(t *testing.T) {
|
|
_, err := callConstructor(reflect.ValueOf(constructFoo), nil)
|
|
if err == nil {
|
|
t.Fatal("expected constructor to fail")
|
|
}
|
|
|
|
if !strings.Contains(err.Error(), "constructFoo") {
|
|
t.Errorf("expected error to contain the constructor name: %s", err)
|
|
}
|
|
|
|
v, err := callConstructor(reflect.ValueOf(func() foo { return &fooImpl{} }), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := v.(*fooImpl); !ok {
|
|
t.Fatal("expected a fooImpl")
|
|
}
|
|
|
|
v, err = callConstructor(reflect.ValueOf(func() *fooImpl { return new(fooImpl) }), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := v.(*fooImpl); !ok {
|
|
t.Fatal("expected a fooImpl")
|
|
}
|
|
|
|
_, err = callConstructor(reflect.ValueOf(func() (*fooImpl, error) { return nil, nil }), nil)
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
|
|
v, err = callConstructor(reflect.ValueOf(func() (*fooImpl, error) { return new(fooImpl), nil }), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := v.(*fooImpl); !ok {
|
|
t.Fatal("expected a fooImpl")
|
|
}
|
|
}
|