-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
testscript: test custom conditions #175
base: master
Are you sure you want to change the base?
Changes from 11 commits
d0c991a
4c3f2b9
0d6efa6
4b4de17
90696b0
03e1881
10e516a
07717e8
9d14910
ff2730e
9f43ce3
527da36
70ca2ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,6 +121,33 @@ A condition can be negated: [!short] means to run the rest of the line | |
when testing.Short() is false. | ||
|
||
Additional conditions can be added by passing a function to Params.Condition. | ||
The function will only be called when all built-in conditions have been checked for. | ||
|
||
An example: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for this to be a separate paragraph, IMO. You can attach it to the previous paragraph. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed |
||
Condition: func(cond string) (bool, error) { | ||
// Assume condition name and args are separated by colon (":") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that parsing the condition here is somewhat overkill tbh, and makes the example a bit longer than it needs to be. I'm pretty sure that people writing conditions are up to the task of extrapolating from something a bit simpler. How about just something like:
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can do that, if everyone agrees. However, I wanted the example to include some text manipulation logic, because I was baffled when I first tried to define a condition. What was unclear to me was that custom commands are defined as a map of functions, while custom conditions are just one function for all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For what it's worth, I also feel this is likely to confuse people. But perhaps what this is really telling us is that the API should be a map of condition names to |
||
args := strings.Split(cond, ":") | ||
name := args[0] | ||
switch name { | ||
case "exists": | ||
if len(args) < 2 { | ||
return false, fmt.Errorf("syntax: [exists:file_name]") | ||
} | ||
_, err := os.Stat(args[1]) | ||
return !errors.Is(err, fs.ErrNotExist), nil | ||
case "long": | ||
return os.Getenv("TEST_LONG") != "", nil | ||
default: | ||
return false, fmt.Errorf("unrecognized condition %s", name) | ||
} | ||
}, | ||
|
||
With the conditions so defined, you can use them as follows: | ||
env file_name=/path/to/filename | ||
[exists:$file_name] exec echo 'file was found' | ||
env loops=1 | ||
[long] env loops=3 | ||
exec do_something $loops | ||
|
||
The predefined commands are: | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
[!exec:echo] skip | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to have a test that for the custom condition function returning an error, but that might be a bit awkward to do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't find a way to do that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UPDATE: I found a way to test the errors (see |
||
|
||
env upper_word=ABCD | ||
env lower_word=abcd | ||
|
||
[always_true] exec echo 'this is true' | ||
stdout 'this is true' | ||
|
||
exec echo '' | ||
|
||
[!always_true] exec echo 'this is true' | ||
! stdout . | ||
|
||
exec echo '' | ||
|
||
[always_false] exec echo 'this is false' | ||
! stdout . | ||
|
||
exec echo '' | ||
|
||
[!always_false] exec echo 'this is false' | ||
stdout 'this is false' | ||
|
||
exec echo '' | ||
|
||
[is_upper:ABCD] exec echo 'it is upper' | ||
stdout 'it is upper' | ||
|
||
exec echo '' | ||
|
||
[is_upper:$upper_word] exec echo 'it is again upper' | ||
stdout 'it is again upper' | ||
|
||
exec echo '' | ||
|
||
[is_upper:abcd] exec echo 'it is upper' | ||
! stdout . | ||
|
||
exec echo '' | ||
|
||
[is_upper:$lower_word] exec echo 'it is lower' | ||
! stdout . | ||
|
||
exec echo '' | ||
|
||
[!is_upper:ABCD] exec echo 'it is upper' | ||
! stdout . | ||
|
||
exec echo '' | ||
|
||
[is_lower:abcd] exec echo 'it is lower' | ||
stdout 'it is lower' | ||
|
||
exec echo '' | ||
|
||
[is_lower:$lower_word] exec echo 'it is again lower' | ||
stdout 'it is again lower' | ||
|
||
exec echo '' | ||
|
||
[is_lower:ABCD] exec echo 'it is lower' | ||
! stdout . | ||
|
||
exec echo '' | ||
|
||
[!is_lower:$lower_word] exec echo 'it is lower' | ||
! stdout . |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
env GOPATH=$WORK | ||
env GOCACHE=$WORK/.cache | ||
|
||
[!exec:echo] skip | ||
cd cond_errors | ||
exec go mod tidy | ||
! exec go test -run TestConditionErrors/is_upper-no-parameter | ||
stdout 'FAIL' | ||
stdout 'syntax: \[is_upper:word\]' | ||
|
||
! exec go test -run TestConditionErrors/is_lower-no-parameter | ||
stdout 'FAIL' | ||
stdout 'syntax: \[is_lower:word\]' | ||
|
||
! exec go test -run TestConditionErrors/unrecognized | ||
stdout 'FAIL' | ||
stdout 'unrecognized condition something' | ||
|
||
-- cond_errors/main_test.go -- | ||
package condition_errors | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/rogpeppe/go-internal/testscript" | ||
) | ||
|
||
func TestConditionErrors(t *testing.T) { | ||
testscript.Run(t, testscript.Params{ | ||
Dir: "testdata", | ||
Condition: func(cond string) (bool, error) { | ||
// Assume condition name and args are separated by colon (":") | ||
args := strings.Split(cond, ":") | ||
name := args[0] | ||
switch name { | ||
case "is_upper": | ||
if len(args) < 2 { | ||
return false, fmt.Errorf("syntax: [is_upper:word]") | ||
} | ||
return strings.ToUpper(args[1]) == args[1], nil | ||
case "is_lower": | ||
if len(args) < 2 { | ||
return false, fmt.Errorf("syntax: [is_lower:word]") | ||
} | ||
return strings.ToLower(args[1]) == args[1], nil | ||
case "always_true": | ||
return true, nil | ||
case "always_false": | ||
return false, nil | ||
default: | ||
return false, fmt.Errorf("unrecognized condition %s", name) | ||
} | ||
}, | ||
}) | ||
} | ||
-- cond_errors/go.mod -- | ||
module condition_errors | ||
|
||
go 1.18 | ||
|
||
require ( | ||
github.com/rogpeppe/go-internal v1.9.0 | ||
) | ||
|
||
-- cond_errors/testdata/is_upper-no-parameter.txt -- | ||
[is_upper] exec echo '' | ||
-- cond_errors/testdata/is_lower-no-parameter.txt -- | ||
[is_lower] exec echo '' | ||
-- cond_errors/testdata/unrecognized.txt -- | ||
[something] exec echo '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth mentioning this:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done