Merge branch 'trunk' into jtmcg/577

This commit is contained in:
Tyler McGoffin 2024-10-15 12:56:43 -07:00 committed by GitHub
commit 2d0b742cb3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 146 additions and 8 deletions

View file

@ -38,11 +38,16 @@ completions: bin/gh$(EXE)
bin/gh$(EXE) completion -s fish > ./share/fish/vendor_completions.d/gh.fish
bin/gh$(EXE) completion -s zsh > ./share/zsh/site-functions/_gh
# just a convenience task around `go test`
# just convenience tasks around `go test`
.PHONY: test
test:
go test ./...
# For more information, see https://github.com/cli/cli/blob/trunk/acceptance/README.md
.PHONY: acceptance
acceptance:
go test -tags acceptance ./acceptance
## Site-related tasks are exclusively intended for use by the GitHub CLI team and for our release automation.
site:

View file

@ -32,6 +32,12 @@ A full example invocation can be found below:
GH_ACCEPTANCE_HOST=<host> GH_ACCEPTANCE_ORG=<org> GH_ACCEPTANCE_TOKEN=<token> go test -tags=acceptance ./acceptance
```
While writing a new test, it can be useful to target that specific script by providing the `GH_ACCEPTANCE_SCRIPT` env var in combination with the `-run` flag, for example:
```
GH_ACCEPTANCE_SCRIPT=pr-view.txtar GH_ACCEPTANCE_HOST=<host> GH_ACCEPTANCE_ORG=<org> GH_ACCEPTANCE_TOKEN=<token> go test -tags=acceptance -run ^TestPullRequests$ ./acceptance
```
#### Code Coverage
To get code coverage, `go test` can be invoked with `coverpkg` and `coverprofile` like so:

View file

@ -28,17 +28,35 @@ func TestMain(m *testing.M) {
func TestPullRequests(t *testing.T) {
var tsEnv testScriptEnv
if err := tsEnv.fromEnv(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
t.Fatal(err)
}
testscript.Run(t, testScriptParamsFor(tsEnv, "pr"))
}
func testScriptParamsFor(tsEnv testScriptEnv, dir string) testscript.Params {
func TestIssues(t *testing.T) {
var tsEnv testScriptEnv
if err := tsEnv.fromEnv(); err != nil {
t.Fatal(err)
}
testscript.Run(t, testScriptParamsFor(tsEnv, "pr"))
}
func testScriptParamsFor(tsEnv testScriptEnv, command string) testscript.Params {
var files []string
if tsEnv.script != "" {
files = []string{path.Join("testdata", command, tsEnv.script)}
}
var dir string
if len(files) == 0 {
dir = path.Join("testdata", command)
}
return testscript.Params{
Dir: path.Join("testdata", dir),
Files: []string{},
Dir: dir,
Files: files,
Setup: sharedSetup(tsEnv),
Cmds: sharedCmds(tsEnv),
RequireExplicitExec: true,
@ -47,6 +65,8 @@ func testScriptParamsFor(tsEnv testScriptEnv, dir string) testscript.Params {
}
}
var keyT struct{}
func sharedSetup(tsEnv testScriptEnv) func(ts *testscript.Env) error {
return func(ts *testscript.Env) error {
scriptName, ok := extractScriptName(ts.Vars)
@ -62,6 +82,8 @@ func sharedSetup(tsEnv testScriptEnv) func(ts *testscript.Env) error {
ts.Setenv("GH_TOKEN", tsEnv.token)
ts.Setenv("RANDOM_STRING", randomString(10))
ts.Values[keyT] = ts.T()
return nil
}
}
@ -78,8 +100,21 @@ func sharedCmds(tsEnv testScriptEnv) map[string]func(ts *testscript.TestScript,
return
}
tt, ok := ts.Value(keyT).(testscript.T)
if !ok {
ts.Fatalf("%v is not a testscript.T", ts.Value(keyT))
}
ts.Defer(func() {
ts.Check(ts.Exec(args[0], args[1:]...))
// If you're wondering why we're not using ts.Check here, it's because it raises a panic, and testscript
// only catches the panics directly from commands, not from the deferred functions. So what we do
// instead is grab the `t` in the setup function and store it as a value. It's important that we use
// `t` from the setup function because it represents the subtest created for each individual script,
// rather than each top-level test.
// See: https://github.com/rogpeppe/go-internal/issues/276
if err := ts.Exec(args[0], args[1:]...); err != nil {
tt.FailNow()
}
})
},
"stdout2env": func(ts *testscript.TestScript, neg bool, args []string) {
@ -120,7 +155,7 @@ type missingEnvError struct {
}
func (e missingEnvError) Error() string {
return fmt.Sprintf("environment variables %s must be set and non-empty", strings.Join(e.missingEnvs, ", "))
return fmt.Sprintf("environment variable(s) %s must be set and non-empty", strings.Join(e.missingEnvs, ", "))
}
type testScriptEnv struct {
@ -128,6 +163,8 @@ type testScriptEnv struct {
org string
token string
script string
skipDefer bool
preserveWorkDir bool
}
@ -164,6 +201,7 @@ func (e *testScriptEnv) fromEnv() error {
e.org = envMap["GH_ACCEPTANCE_ORG"]
e.token = envMap["GH_ACCEPTANCE_TOKEN"]
e.script = os.Getenv("GH_ACCEPTANCE_SCRIPT")
e.preserveWorkDir = os.Getenv("GH_ACCEPTANCE_PRESERVE_WORK_DIR") == "true"
e.skipDefer = os.Getenv("GH_ACCEPTANCE_SKIP_DEFER") == "true"

View file

@ -0,0 +1,20 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Create an issue in the repo
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh issue create --title 'Feature Request' --body 'Feature Body'
stdout2env ISSUE_URL
# Comment on the issue
exec gh issue comment $ISSUE_URL --body 'Looks like a great feature!'
# View the issue
exec gh issue view $ISSUE_URL --comments
stdout 'Looks like a great feature!'

View file

@ -0,0 +1,17 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Create an issue in the repo
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh issue create --title 'Feature Request' --body 'Feature Body'
stdout2env ISSUE_URL
# Check the issue was created
exec gh issue view $ISSUE_URL
stdout 'title:\tFeature Request$'

View file

@ -0,0 +1,19 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Create an issue in the repo
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh issue create --title 'Feature Request' --body 'Feature Body' --assignee '@me' --label 'bug'
stdout2env ISSUE_URL
# Check the issue was create
exec gh issue view $ISSUE_URL
stdout 'title:\tFeature Request$'
stdout 'assignees:\t.+$'
stdout 'labels:\tbug$'

View file

@ -0,0 +1,16 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Create an issue in the repo
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh issue create --title 'Feature Request' --body 'Feature Body'
# Check the issue is included in the list output
exec gh issue list
stdout 'OPEN\tFeature Request'

View file

@ -0,0 +1,17 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private
# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING
# Create an issue in the repo
cd $SCRIPT_NAME-$RANDOM_STRING
exec gh issue create --title 'Feature Request' --body 'Feature Body'
stdout2env ISSUE_URL
# Check the issue was created
exec gh issue view $ISSUE_URL
stdout 'title:\tFeature Request$'