-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
skip: deprecate skip.If and replace it with assert.SkipIf
Instead of a very small page it should be fine to move this one exported function to the assert package.
- Loading branch information
Showing
11 changed files
with
299 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package assert | ||
|
||
import ( | ||
"fmt" | ||
"path" | ||
"reflect" | ||
"runtime" | ||
"strings" | ||
|
||
"gotest.tools/v3/internal/format" | ||
"gotest.tools/v3/internal/source" | ||
) | ||
|
||
// SkipT is the interface accepted by SkipIf to skip tests. It is implemented by | ||
// testing.T, and testing.B. | ||
type SkipT interface { | ||
Skip(args ...interface{}) | ||
Log(args ...interface{}) | ||
} | ||
|
||
// SkipResult may be returned by a function used with SkipIf to provide a | ||
// detailed message to use as part of the skip message. | ||
type SkipResult interface { | ||
Skip() bool | ||
Message() string | ||
} | ||
|
||
// BoolOrCheckFunc can be a bool, func() bool, or func() SkipResult. Other | ||
// types will panic. See SkipIf for details about how this type is used. | ||
type BoolOrCheckFunc interface{} | ||
|
||
// SkipIf skips the test if the condition evaluates to true. If the condition | ||
// evaluates to false then SkipIf does nothing. SkipIf is a convenient way of | ||
// skipping tests and using the literal source of the condition as the text of | ||
// the skip message. | ||
// | ||
// For example, this usage would produce the following skip message: | ||
// | ||
// assert.SkipIf(t, runtime.GOOS == "windows", "not supported") | ||
// // filename.go:11: runtime.GOOS == "windows": not supported | ||
// | ||
// The condition argument may be one of the following: | ||
// | ||
// bool | ||
// The test will be skipped if the value is true. The literal source of the | ||
// expression passed to SkipIf will be used as the skip message. | ||
// | ||
// func() bool | ||
// The test will be skipped if the function returns true. The name of the | ||
// function will be used as the skip message. | ||
// | ||
// func() SkipResult | ||
// The test will be skipped if SkipResult.Skip return true. Both the name | ||
// of the function and the return value of SkipResult.Message will be used | ||
// as the skip message. | ||
// | ||
// Extra details can be added to the skip message using msgAndArgs. msgAndArgs | ||
// may be either a single string, or a format string and args that will be | ||
// passed to fmt.Sprintf. | ||
func SkipIf(t SkipT, condition BoolOrCheckFunc, msgAndArgs ...interface{}) { | ||
if ht, ok := t.(helperT); ok { | ||
ht.Helper() | ||
} | ||
switch check := condition.(type) { | ||
case bool: | ||
ifCondition(t, check, msgAndArgs...) | ||
case func() bool: | ||
if check() { | ||
t.Skip(format.WithCustomMessage(getFunctionName(check), msgAndArgs...)) | ||
} | ||
case func() SkipResult: | ||
result := check() | ||
if result.Skip() { | ||
msg := getFunctionName(check) + ": " + result.Message() | ||
t.Skip(format.WithCustomMessage(msg, msgAndArgs...)) | ||
} | ||
default: | ||
panic(fmt.Sprintf("invalid type for condition arg: %T", check)) | ||
} | ||
} | ||
|
||
func getFunctionName(function interface{}) string { | ||
funcPath := runtime.FuncForPC(reflect.ValueOf(function).Pointer()).Name() | ||
return strings.SplitN(path.Base(funcPath), ".", 2)[1] | ||
} | ||
|
||
func ifCondition(t SkipT, condition bool, msgAndArgs ...interface{}) { | ||
if ht, ok := t.(helperT); ok { | ||
ht.Helper() | ||
} | ||
if !condition { | ||
return | ||
} | ||
const ( | ||
stackIndex = 2 | ||
argPos = 1 | ||
) | ||
source, err := source.FormattedCallExprArg(stackIndex, argPos) | ||
if err != nil { | ||
t.Log(err.Error()) | ||
t.Skip(format.Message(msgAndArgs...)) | ||
} | ||
t.Skip(format.WithCustomMessage(source, msgAndArgs...)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package assert_test | ||
|
||
import ( | ||
"gotest.tools/v3/assert" | ||
) | ||
|
||
var apiVersion = "" | ||
|
||
type env struct{} | ||
|
||
func (e env) hasFeature(_ string) bool { return false } | ||
|
||
var testEnv = env{} | ||
|
||
func MissingFeature() bool { return false } | ||
|
||
func ExampleSkipIf() { | ||
assert.SkipIf(t, MissingFeature) | ||
// --- SKIP: TestName (0.00s) | ||
// skip.go:18: MissingFeature | ||
|
||
assert.SkipIf(t, MissingFeature, "coming soon") | ||
// --- SKIP: TestName (0.00s) | ||
// skip.go:22: MissingFeature: coming soon | ||
} | ||
|
||
func ExampleSkipIf_withExpression() { | ||
assert.SkipIf(t, apiVersion < version("v1.24")) | ||
// --- SKIP: TestName (0.00s) | ||
// skip.go:28: apiVersion < version("v1.24") | ||
|
||
assert.SkipIf(t, !testEnv.hasFeature("build"), "coming soon") | ||
// --- SKIP: TestName (0.00s) | ||
// skip.go:32: !textenv.hasFeature("build"): coming soon | ||
} | ||
|
||
func version(v string) string { | ||
return v | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package assert | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"testing" | ||
|
||
"gotest.tools/v3/assert/cmp" | ||
) | ||
|
||
type fakeSkipT struct { | ||
reason string | ||
logs []string | ||
} | ||
|
||
func (f *fakeSkipT) Skip(args ...interface{}) { | ||
buf := new(bytes.Buffer) | ||
for _, arg := range args { | ||
buf.WriteString(fmt.Sprintf("%s", arg)) | ||
} | ||
f.reason = buf.String() | ||
} | ||
|
||
func (f *fakeSkipT) Log(args ...interface{}) { | ||
f.logs = append(f.logs, fmt.Sprintf("%s", args[0])) | ||
} | ||
|
||
func (f *fakeSkipT) Helper() {} | ||
|
||
func version(v string) string { | ||
return v | ||
} | ||
|
||
func TestSkipIFCondition(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
apiVersion := "v1.4" | ||
SkipIf(skipT, apiVersion < version("v1.6")) | ||
|
||
Equal(t, `apiVersion < version("v1.6")`, skipT.reason) | ||
Assert(t, cmp.Len(skipT.logs, 0)) | ||
} | ||
|
||
func TestSkipIfConditionWithMessage(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
apiVersion := "v1.4" | ||
SkipIf(skipT, apiVersion < "v1.6", "see notes") | ||
|
||
Equal(t, `apiVersion < "v1.6": see notes`, skipT.reason) | ||
Assert(t, cmp.Len(skipT.logs, 0)) | ||
} | ||
|
||
func TestSkipIfConditionMultiline(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
apiVersion := "v1.4" | ||
SkipIf( | ||
skipT, | ||
apiVersion < "v1.6") | ||
|
||
Equal(t, `apiVersion < "v1.6"`, skipT.reason) | ||
Assert(t, cmp.Len(skipT.logs, 0)) | ||
} | ||
|
||
func TestSkipIfConditionMultilineWithMessage(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
apiVersion := "v1.4" | ||
SkipIf( | ||
skipT, | ||
apiVersion < "v1.6", | ||
"see notes") | ||
|
||
Equal(t, `apiVersion < "v1.6": see notes`, skipT.reason) | ||
Assert(t, cmp.Len(skipT.logs, 0)) | ||
} | ||
|
||
func TestSkipIfConditionNoSkip(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
SkipIf(skipT, false) | ||
|
||
Equal(t, "", skipT.reason) | ||
Assert(t, cmp.Len(skipT.logs, 0)) | ||
} | ||
|
||
func SkipBecauseISaidSo() bool { | ||
return true | ||
} | ||
|
||
func TestSkipIf(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
SkipIf(skipT, SkipBecauseISaidSo) | ||
|
||
Equal(t, "SkipBecauseISaidSo", skipT.reason) | ||
} | ||
|
||
func TestSkipIfWithMessage(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
SkipIf(skipT, SkipBecauseISaidSo, "see notes") | ||
|
||
Equal(t, "SkipBecauseISaidSo: see notes", skipT.reason) | ||
} | ||
|
||
func TestSkipIf_InvalidCondition(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
Assert(t, cmp.Panics(func() { | ||
SkipIf(skipT, "just a string") | ||
})) | ||
} | ||
|
||
func TestSkipIfWithSkipResultFunc(t *testing.T) { | ||
t.Run("no extra message", func(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
SkipIf(skipT, alwaysSkipWithMessage) | ||
|
||
Equal(t, "alwaysSkipWithMessage: skip because I said so!", skipT.reason) | ||
}) | ||
t.Run("with extra message", func(t *testing.T) { | ||
skipT := &fakeSkipT{} | ||
SkipIf(skipT, alwaysSkipWithMessage, "also %v", 4) | ||
|
||
Equal(t, "alwaysSkipWithMessage: skip because I said so!: also 4", skipT.reason) | ||
}) | ||
} | ||
|
||
func alwaysSkipWithMessage() SkipResult { | ||
return skipResult{} | ||
} | ||
|
||
type skipResult struct{} | ||
|
||
func (s skipResult) Skip() bool { | ||
return true | ||
} | ||
|
||
func (s skipResult) Message() string { | ||
return "skip because I said so!" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.