commit
0e18bb6492
15 changed files with 237 additions and 4 deletions
|
|
@ -21,7 +21,7 @@ type graphQLResponse struct {
|
|||
}
|
||||
|
||||
/*
|
||||
graphQL usage
|
||||
GraphQL: Declared as an external variable so it can be mocked in tests
|
||||
|
||||
type repoResponse struct {
|
||||
Repository struct {
|
||||
|
|
@ -45,7 +45,7 @@ if err != nil {
|
|||
|
||||
fmt.Printf("%+v\n", resp)
|
||||
*/
|
||||
func graphQL(query string, variables map[string]string, data interface{}) error {
|
||||
var GraphQL = func(query string, variables map[string]string, data interface{}) error {
|
||||
url := "https://api.github.com/graphql"
|
||||
reqBody, err := json.Marshal(map[string]interface{}{"query": query, "variables": variables})
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ func PullRequests() (PullRequestsPayload, error) {
|
|||
}
|
||||
|
||||
var resp response
|
||||
err := graphQL(query, variables, &resp)
|
||||
err := GraphQL(query, variables, &resp)
|
||||
if err != nil {
|
||||
return PullRequestsPayload{}, err
|
||||
}
|
||||
|
|
@ -133,7 +133,6 @@ func project() github.Project {
|
|||
if error != nil {
|
||||
panic(error)
|
||||
}
|
||||
|
||||
for _, remote := range remotes {
|
||||
if project, error := remote.Project(); error == nil {
|
||||
return *project
|
||||
|
|
|
|||
34
command/pr_test.go
Normal file
34
command/pr_test.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/github/gh-cli/test"
|
||||
)
|
||||
|
||||
func TestPRList(t *testing.T) {
|
||||
teardown := test.MockGraphQLResponse("test/fixtures/pr.json")
|
||||
defer teardown()
|
||||
|
||||
gitRepo := test.UseTempGitRepo()
|
||||
defer gitRepo.TearDown()
|
||||
|
||||
output, err := test.RunCommand(RootCmd, "pr list")
|
||||
if err != nil {
|
||||
t.Errorf("error running command `pr list`: %v", err)
|
||||
}
|
||||
|
||||
expectedPrs := []*regexp.Regexp{
|
||||
regexp.MustCompile(`#8.*\[strawberries\]`),
|
||||
regexp.MustCompile(`#9.*\[apples\]`),
|
||||
regexp.MustCompile(`#10.*\[blueberries\]`),
|
||||
regexp.MustCompile(`#11.*\[figs\]`),
|
||||
}
|
||||
|
||||
for _, r := range expectedPrs {
|
||||
if !r.MatchString(output) {
|
||||
t.Errorf("output did not match regexp /%s/", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
50
test/fixtures/pr.json
vendored
Normal file
50
test/fixtures/pr.json
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"repository": {
|
||||
"pullRequests": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 10,
|
||||
"title": "Blueberries are a good fruit",
|
||||
"url": "https://github.com/github/gh-cli/pull/10",
|
||||
"headRefName": "[blueberries]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"viewerCreated": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 8,
|
||||
"title": "Strawberries are not actually berries",
|
||||
"url": "https://github.com/github/gh-cli/pull/8",
|
||||
"headRefName": "[strawberries]"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pageInfo": { "hasNextPage": false }
|
||||
},
|
||||
"reviewRequested": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"number": 9,
|
||||
"title": "Apples are tasty",
|
||||
"url": "https://github.com/github/gh-cli/pull/9",
|
||||
"headRefName": "[apples]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"number": 11,
|
||||
"title": "Figs are my favorite",
|
||||
"url": "https://github.com/github/gh-cli/pull/1",
|
||||
"headRefName": "[figs]"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pageInfo": { "hasNextPage": false }
|
||||
}
|
||||
}
|
||||
1
test/fixtures/test.git/HEAD
vendored
Normal file
1
test/fixtures/test.git/HEAD
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
ref: refs/heads/master
|
||||
6
test/fixtures/test.git/config
vendored
Normal file
6
test/fixtures/test.git/config
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = true
|
||||
ignorecase = true
|
||||
precomposeunicode = false
|
||||
6
test/fixtures/test.git/info/exclude
vendored
Normal file
6
test/fixtures/test.git/info/exclude
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
3
test/fixtures/test.git/objects/08/f4b7b6513dffc6245857e497cfd6101dc47818
vendored
Normal file
3
test/fixtures/test.git/objects/08/f4b7b6513dffc6245857e497cfd6101dc47818
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
x<01><>M
|
||||
Â0F]çseb~œ€ˆnÝx™¦cMi¨)^ß 7pó>xðñbÉ9UÐä7ub{ŽÖbgÙ´í‘ă#h8<68>÷<01>âµ>Ë×4o™áöÅ
|
||||
Çñ'ÊyÈœ¦],ùÚ„½Fkœ†-¢j¶U«üûW—¾‡*¯z¤IÔ)”;â
|
||||
BIN
test/fixtures/test.git/objects/8a/1cdac440b4a3c44b988e300758a903a9866905
vendored
Normal file
BIN
test/fixtures/test.git/objects/8a/1cdac440b4a3c44b988e300758a903a9866905
vendored
Normal file
Binary file not shown.
3
test/fixtures/test.git/objects/9b/5a719a3d76ac9dc2fa635d9b1f34fd73994c06
vendored
Normal file
3
test/fixtures/test.git/objects/9b/5a719a3d76ac9dc2fa635d9b1f34fd73994c06
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
x<01><>K
|
||||
1D]η}¥3ι$qεBΟ<>dq&#^ίρs7UPΕ«XΖqhΠ/ZM Άw*<2A>cbc±G”3ΩΛ½ΦYηΠI<CEA0>βζk<CEB6> g
|
||||
6-U<>s4iΦ6‘³1χFΆμ#Y–,ό£<CF8C>K…ύ0<CF8D><30>i‚γG°Ύ|ƒ²=<3D>~Έ®b7 •λ$’b
KdD1§3eK<65>φΕn¨χο™Z<>C©σΥ<CF83>{Nm
|
||||
BIN
test/fixtures/test.git/objects/9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4
vendored
Normal file
BIN
test/fixtures/test.git/objects/9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/test.git/objects/ca/93b49848670d03b3968c8a481eca55f5fb2150
vendored
Normal file
BIN
test/fixtures/test.git/objects/ca/93b49848670d03b3968c8a481eca55f5fb2150
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
vendored
Normal file
BIN
test/fixtures/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
vendored
Normal file
Binary file not shown.
1
test/fixtures/test.git/refs/heads/master
vendored
Normal file
1
test/fixtures/test.git/refs/heads/master
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
9b5a719a3d76ac9dc2fa635d9b1f34fd73994c06
|
||||
130
test/helpers.go
Normal file
130
test/helpers.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/github/gh-cli/api"
|
||||
"github.com/github/gh-cli/github"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type TempGitRepo struct {
|
||||
Remote string
|
||||
TearDown func()
|
||||
}
|
||||
|
||||
func UseTempGitRepo() *TempGitRepo {
|
||||
github.CreateTestConfigs("mario", "i-love-peach")
|
||||
|
||||
pwd, _ := os.Getwd()
|
||||
oldEnv := make(map[string]string)
|
||||
overrideEnv := func(name, value string) {
|
||||
oldEnv[name] = os.Getenv(name)
|
||||
os.Setenv(name, value)
|
||||
}
|
||||
|
||||
remotePath := filepath.Join(pwd, "..", "test", "fixtures", "test.git")
|
||||
home, err := ioutil.TempDir("", "test-repo")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
overrideEnv("HOME", home)
|
||||
overrideEnv("XDG_CONFIG_HOME", "")
|
||||
overrideEnv("XDG_CONFIG_DIRS", "")
|
||||
|
||||
targetPath := filepath.Join(home, "test.git")
|
||||
cmd := exec.Command("git", "clone", remotePath, targetPath)
|
||||
if output, err := cmd.Output(); err != nil {
|
||||
panic(fmt.Errorf("error running %s\n%s\n%s", cmd, err, output))
|
||||
}
|
||||
|
||||
if err = os.Chdir(targetPath); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Our libs expect the origin to be a github url
|
||||
cmd = exec.Command("git", "remote", "set-url", "origin", "https://github.com/github/FAKE-GITHUB-REPO-NAME")
|
||||
if output, err := cmd.Output(); err != nil {
|
||||
panic(fmt.Errorf("error running %s\n%s\n%s", cmd, err, output))
|
||||
}
|
||||
|
||||
tearDown := func() {
|
||||
if err := os.Chdir(pwd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for name, value := range oldEnv {
|
||||
os.Setenv(name, value)
|
||||
}
|
||||
if err = os.RemoveAll(home); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return &TempGitRepo{Remote: remotePath, TearDown: tearDown}
|
||||
}
|
||||
|
||||
func MockGraphQLResponse(fixturePath string) (teardown func()) {
|
||||
pwd, _ := os.Getwd()
|
||||
fixturePath = filepath.Join(pwd, "..", fixturePath)
|
||||
|
||||
originalGraphQL := api.GraphQL
|
||||
api.GraphQL = func(query string, variables map[string]string, v interface{}) error {
|
||||
contents, err := ioutil.ReadFile(fixturePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
json.Unmarshal(contents, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return func() {
|
||||
api.GraphQL = originalGraphQL
|
||||
}
|
||||
}
|
||||
|
||||
func RunCommand(root *cobra.Command, s string) (string, error) {
|
||||
var err error
|
||||
output := captureOutput(func() {
|
||||
root.SetArgs(strings.Split(s, " "))
|
||||
_, err = root.ExecuteC()
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func captureOutput(f func()) string {
|
||||
originalStdout := os.Stdout
|
||||
defer func() {
|
||||
os.Stdout = originalStdout
|
||||
}()
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
panic("failed to pipe stdout")
|
||||
}
|
||||
os.Stdout = w
|
||||
|
||||
f()
|
||||
|
||||
w.Close()
|
||||
out, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
panic("failed to read captured input from stdout")
|
||||
}
|
||||
|
||||
return string(out)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue