From c17251d106a8c368c75c2e4dd6944a2c98033afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 27 Mar 2020 13:52:31 +0100 Subject: [PATCH 1/3] Add table-driven test for `repoFromURL` --- internal/ghrepo/repo_test.go | 76 +++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/internal/ghrepo/repo_test.go b/internal/ghrepo/repo_test.go index 6ff775c84..cc0f231b8 100644 --- a/internal/ghrepo/repo_test.go +++ b/internal/ghrepo/repo_test.go @@ -1,40 +1,60 @@ package ghrepo import ( + "errors" + "fmt" "net/url" "testing" ) func Test_repoFromURL(t *testing.T) { - u, _ := url.Parse("http://github.com/monalisa/octo-cat.git") - repo, err := FromURL(u) - if err != nil { - t.Fatalf("got error %q", err) + tests := []struct { + name string + input string + result string + err error + }{ + { + name: "github.com URL", + input: "https://github.com/monalisa/octo-cat.git", + result: "monalisa/octo-cat", + err: nil, + }, + { + name: "unsupported hostname", + input: "https://example.com/one/two", + result: "", + err: errors.New("unsupported hostname: example.com"), + }, + { + name: "filesystem path", + input: "/path/to/file", + result: "", + err: errors.New("unsupported hostname: "), + }, } - if repo.RepoOwner() != "monalisa" { - t.Errorf("got owner %q", repo.RepoOwner()) - } - if repo.RepoName() != "octo-cat" { - t.Errorf("got name %q", repo.RepoName()) - } -} -func Test_repoFromURL_invalid(t *testing.T) { - cases := [][]string{ - []string{ - "https://example.com/one/two", - "unsupported hostname: example.com", - }, - []string{ - "/path/to/disk", - "unsupported hostname: ", - }, - } - for _, c := range cases { - u, _ := url.Parse(c[0]) - _, err := FromURL(u) - if err == nil || err.Error() != c[1] { - t.Errorf("got %q", err) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u, err := url.Parse(tt.input) + if err != nil { + t.Fatalf("got error %q", err) + } + + repo, err := FromURL(u) + if err != nil { + if tt.err == nil { + t.Fatalf("got error %q", err) + } else if tt.err.Error() == err.Error() { + return + } + t.Fatalf("got error %q", err) + } + + got := fmt.Sprintf("%s/%s", repo.RepoOwner(), repo.RepoName()) + if tt.result != got { + t.Errorf("expected %q, got %q", tt.result, got) + } + }) } } From 303f60815f72f9fc1b7d449eb3dbf503c89d9ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 27 Mar 2020 13:55:16 +0100 Subject: [PATCH 2/3] Support `www.github.com` git remote URLs --- internal/ghrepo/repo.go | 2 +- internal/ghrepo/repo_test.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/ghrepo/repo.go b/internal/ghrepo/repo.go index f683d9249..fe3a0eba7 100644 --- a/internal/ghrepo/repo.go +++ b/internal/ghrepo/repo.go @@ -33,7 +33,7 @@ func FromFullName(nwo string) Interface { } func FromURL(u *url.URL) (Interface, error) { - if !strings.EqualFold(u.Hostname(), defaultHostname) { + if !strings.EqualFold(u.Hostname(), defaultHostname) && !strings.EqualFold(u.Hostname(), "www."+defaultHostname) { return nil, fmt.Errorf("unsupported hostname: %s", u.Hostname()) } parts := strings.SplitN(strings.TrimPrefix(u.Path, "/"), "/", 3) diff --git a/internal/ghrepo/repo_test.go b/internal/ghrepo/repo_test.go index cc0f231b8..fef04fb8c 100644 --- a/internal/ghrepo/repo_test.go +++ b/internal/ghrepo/repo_test.go @@ -20,6 +20,12 @@ func Test_repoFromURL(t *testing.T) { result: "monalisa/octo-cat", err: nil, }, + { + name: "www.github.com URL", + input: "http://www.GITHUB.com/monalisa/octo-cat.git", + result: "monalisa/octo-cat", + err: nil, + }, { name: "unsupported hostname", input: "https://example.com/one/two", From 894899c71d666d48c90a1bad53d1568ccab92ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Fri, 27 Mar 2020 13:58:50 +0100 Subject: [PATCH 3/3] Add code docs for `ghrepo` package --- internal/ghrepo/repo.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/ghrepo/repo.go b/internal/ghrepo/repo.go index fe3a0eba7..a4bfa82d6 100644 --- a/internal/ghrepo/repo.go +++ b/internal/ghrepo/repo.go @@ -8,21 +8,26 @@ import ( const defaultHostname = "github.com" +// Interface describes an object that represents a GitHub repository type Interface interface { RepoName() string RepoOwner() string } +// New instantiates a GitHub repository from owner and name arguments func New(owner, repo string) Interface { return &ghRepo{ owner: owner, name: repo, } } + +// FullName serializes a GitHub repository into an "OWNER/REPO" string func FullName(r Interface) string { return fmt.Sprintf("%s/%s", r.RepoOwner(), r.RepoName()) } +// FromFullName extracts the GitHub repository inforation from an "OWNER/REPO" string func FromFullName(nwo string) Interface { var r ghRepo parts := strings.SplitN(nwo, "/", 2) @@ -32,6 +37,7 @@ func FromFullName(nwo string) Interface { return &r } +// FromURL extracts the GitHub repository information from a URL func FromURL(u *url.URL) (Interface, error) { if !strings.EqualFold(u.Hostname(), defaultHostname) && !strings.EqualFold(u.Hostname(), "www."+defaultHostname) { return nil, fmt.Errorf("unsupported hostname: %s", u.Hostname()) @@ -43,6 +49,7 @@ func FromURL(u *url.URL) (Interface, error) { return New(parts[0], strings.TrimSuffix(parts[1], ".git")), nil } +// IsSame compares two GitHub repositories func IsSame(a, b Interface) bool { return strings.EqualFold(a.RepoOwner(), b.RepoOwner()) && strings.EqualFold(a.RepoName(), b.RepoName())