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 }