github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/test/must/call.go (about)

     1  package must
     2  
     3  import (
     4  	"reflect"
     5  	"github.com/v2pro/plz/test"
     6  	"runtime"
     7  	"github.com/v2pro/plz/test/testify/assert"
     8  )
     9  
    10  type ReturnValue []interface{}
    11  
    12  var errorType = reflect.TypeOf((*error)(nil)).Elem()
    13  
    14  func Call(f interface{}, argObjs ...interface{}) ReturnValue {
    15  	fVal := reflect.ValueOf(f)
    16  	fType := fVal.Type()
    17  	argVals := make([]reflect.Value, len(argObjs))
    18  	for i := 0; i < len(argObjs); i++ {
    19  		if argObjs[i] == nil {
    20  			argVals[i] = reflect.New(fType.In(i)).Elem()
    21  		} else {
    22  			argVals[i] = reflect.ValueOf(argObjs[i])
    23  		}
    24  	}
    25  	retVals := fVal.Call(argVals)
    26  	retObjs := make([]interface{}, len(retVals))
    27  	for i := 0; i < len(retVals); i++ {
    28  		retObjs[i] = retVals[i].Interface()
    29  	}
    30  	if len(retVals) > 0 && retVals[len(retVals)-1].Type().Implements(errorType) {
    31  		errObj := retVals[len(retVals)-1].Interface()
    32  		err, _ := errObj.(error)
    33  		t := test.CurrentT()
    34  		if assert.NoError(t, err) {
    35  			return ReturnValue(retObjs)
    36  		}
    37  		test.Helper()
    38  		_, file, line, ok := runtime.Caller(1)
    39  		if !ok {
    40  			t.Fatal("check failed")
    41  			return ReturnValue(retObjs)
    42  		}
    43  		t.Fatal(test.ExtractFailedLines(file, line))
    44  	}
    45  	return ReturnValue(retObjs)
    46  }
    47  
    48  func (ret ReturnValue) Set(objs ...interface{}) {
    49  	for i, obj := range objs {
    50  		reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(ret[i]))
    51  	}
    52  }