1/*Package skip provides functions for skipping a test and printing the source code 2of the condition used to skip the test. 3*/ 4package skip // import "gotest.tools/skip" 5 6import ( 7 "fmt" 8 "path" 9 "reflect" 10 "runtime" 11 "strings" 12 13 "gotest.tools/internal/format" 14 "gotest.tools/internal/source" 15) 16 17type skipT interface { 18 Skip(args ...interface{}) 19 Log(args ...interface{}) 20} 21 22type helperT interface { 23 Helper() 24} 25 26// BoolOrCheckFunc can be a bool or func() bool, other types will panic 27type BoolOrCheckFunc interface{} 28 29// If the condition expression evaluates to true, or the condition function returns 30// true, skip the test. 31// The skip message will contain the source code of the expression. 32// Extra message text can be passed as a format string with args 33func If(t skipT, condition BoolOrCheckFunc, msgAndArgs ...interface{}) { 34 if ht, ok := t.(helperT); ok { 35 ht.Helper() 36 } 37 switch check := condition.(type) { 38 case bool: 39 ifCondition(t, check, msgAndArgs...) 40 case func() bool: 41 if check() { 42 t.Skip(format.WithCustomMessage(getFunctionName(check), msgAndArgs...)) 43 } 44 default: 45 panic(fmt.Sprintf("invalid type for condition arg: %T", check)) 46 } 47} 48 49func getFunctionName(function func() bool) string { 50 funcPath := runtime.FuncForPC(reflect.ValueOf(function).Pointer()).Name() 51 return strings.SplitN(path.Base(funcPath), ".", 2)[1] 52} 53 54func ifCondition(t skipT, condition bool, msgAndArgs ...interface{}) { 55 if ht, ok := t.(helperT); ok { 56 ht.Helper() 57 } 58 if !condition { 59 return 60 } 61 const ( 62 stackIndex = 2 63 argPos = 1 64 ) 65 source, err := source.FormattedCallExprArg(stackIndex, argPos) 66 if err != nil { 67 t.Log(err.Error()) 68 t.Skip(format.Message(msgAndArgs...)) 69 } 70 t.Skip(format.WithCustomMessage(source, msgAndArgs...)) 71} 72