github.com/leanovate/gopter@v0.2.9/prop/check_condition_func.go (about) 1 package prop 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "runtime/debug" 8 9 "github.com/leanovate/gopter" 10 ) 11 12 func checkConditionFunc(check interface{}, numArgs int) (func([]reflect.Value) *gopter.PropResult, error) { 13 checkVal := reflect.ValueOf(check) 14 checkType := checkVal.Type() 15 16 if checkType.Kind() != reflect.Func { 17 return nil, fmt.Errorf("First param of ForrAll has to be a func: %v", checkVal.Kind()) 18 } 19 if checkType.NumIn() != numArgs { 20 return nil, fmt.Errorf("Number of parameters does not match number of generators: %d != %d", checkType.NumIn(), numArgs) 21 } 22 if checkType.NumOut() == 0 { 23 return nil, errors.New("At least one output parameters is required") 24 } else if checkType.NumOut() > 2 { 25 return nil, fmt.Errorf("No more than 2 output parameters are allowed: %d", checkType.NumOut()) 26 } else if checkType.NumOut() == 2 && !checkType.Out(1).Implements(typeOfError) { 27 return nil, fmt.Errorf("No 2 output has to be error: %v", checkType.Out(1).Kind()) 28 } else if checkType.NumOut() == 2 { 29 return func(values []reflect.Value) *gopter.PropResult { 30 results := checkVal.Call(values) 31 if results[1].IsNil() { 32 return convertResult(results[0].Interface(), nil) 33 } 34 return convertResult(results[0].Interface(), results[1].Interface().(error)) 35 }, nil 36 } 37 return func(values []reflect.Value) (result *gopter.PropResult) { 38 defer func() { 39 if r := recover(); r != nil { 40 result = &gopter.PropResult{ 41 Status: gopter.PropError, 42 Error: fmt.Errorf("Check paniced: %v", r), 43 ErrorStack: debug.Stack(), 44 } 45 } 46 }() 47 results := checkVal.Call(values) 48 return convertResult(results[0].Interface(), nil) 49 }, nil 50 }