From 4abcf49bac45b3674880becbf3bd4812f0ee5c74 Mon Sep 17 00:00:00 2001 From: Quinn Slack Date: Thu, 7 Nov 2013 03:03:51 -0800 Subject: [PATCH] Use RepositorySpec parameter type for repository methods to allow both owner/name and ID repository specification schemes --- github/repos.go | 42 +++++++++++++++++++++++++++------- github/repos_test.go | 54 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/github/repos.go b/github/repos.go index 5fb7a3e0a3e..1e823f542fc 100644 --- a/github/repos.go +++ b/github/repos.go @@ -51,6 +51,34 @@ func (r Repository) String() string { return Stringify(r) } +// RepositorySpec specifies a repository. +type RepositorySpec interface { + Path() string +} + +// RepositoryName identifies a repository by its owner and name. +type RepositoryName struct { + // Owner is the user login of the repository's owner. + Owner string + + // Name is the repository's name (not including the owner). + Name string +} + +// Path implements RepositorySpec. +func (r RepositoryName) Path() string { + return fmt.Sprintf("repos/%v/%v", r.Owner, r.Name) +} + +// RepositoryID is a numeric ID for a repository. GitHub repository IDs remain +// unchanged even if the repository is renamed. +type RepositoryID int64 + +// Path implements RepositorySpec. +func (r RepositoryID) Path() string { + return fmt.Sprintf("repositories/%d", r) +} + // RepositoryListOptions specifies the optional parameters to the // RepositoriesService.List method. type RepositoryListOptions struct { @@ -195,9 +223,8 @@ func (s *RepositoriesService) Create(org string, repo *Repository) (*Repository, // Get fetches a repository. // // GitHub API docs: http://developer.github.com/v3/repos/#get -func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, error) { - u := fmt.Sprintf("repos/%v/%v", owner, repo) - req, err := s.client.NewRequest("GET", u, nil) +func (s *RepositoriesService) Get(spec RepositorySpec) (*Repository, *Response, error) { + req, err := s.client.NewRequest("GET", spec.Path(), nil) if err != nil { return nil, nil, err } @@ -214,9 +241,8 @@ func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, e // Edit updates a repository. // // GitHub API docs: http://developer.github.com/v3/repos/#edit -func (s *RepositoriesService) Edit(owner, repo string, repository *Repository) (*Repository, *Response, error) { - u := fmt.Sprintf("repos/%v/%v", owner, repo) - req, err := s.client.NewRequest("PATCH", u, repository) +func (s *RepositoriesService) Edit(spec RepositorySpec, repository *Repository) (*Repository, *Response, error) { + req, err := s.client.NewRequest("PATCH", spec.Path(), repository) if err != nil { return nil, nil, err } @@ -240,8 +266,8 @@ func (s *RepositoriesService) Edit(owner, repo string, repository *Repository) ( // } // // GitHub API Docs: http://developer.github.com/v3/repos/#list-languages -func (s *RepositoriesService) ListLanguages(owner string, repository string) (map[string]int, *Response, error) { - u := fmt.Sprintf("/repos/%v/%v/languages", owner, repository) +func (s *RepositoriesService) ListLanguages(spec RepositorySpec) (map[string]int, *Response, error) { + u := spec.Path() + "/languages" req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err diff --git a/github/repos_test.go b/github/repos_test.go index d30d32c5508..c5cb4421782 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -189,12 +189,14 @@ func TestRepositoriesService_Get(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + h := func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"}}`) - }) + } + mux.HandleFunc("/repos/o/r", h) + mux.HandleFunc("/repositories/1", h) - repo, _, err := client.Repositories.Get("o", "r") + repo, _, err := client.Repositories.Get(RepositoryName{"o", "r"}) if err != nil { t.Errorf("Repositories.Get returned error: %v", err) } @@ -203,6 +205,14 @@ func TestRepositoriesService_Get(t *testing.T) { if !reflect.DeepEqual(repo, want) { t.Errorf("Repositories.Get returned %+v, want %+v", repo, want) } + + repo, _, err = client.Repositories.Get(RepositoryID(1)) + if err != nil { + t.Errorf("Repositories.Get returned error: %v", err) + } + if !reflect.DeepEqual(repo, want) { + t.Errorf("Repositories.Get returned %+v, want %+v", repo, want) + } } func TestRepositoriesService_Edit(t *testing.T) { @@ -212,7 +222,7 @@ func TestRepositoriesService_Edit(t *testing.T) { i := true input := &Repository{HasIssues: &i} - mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { + h := func(w http.ResponseWriter, r *http.Request) { v := new(Repository) json.NewDecoder(r.Body).Decode(v) @@ -221,9 +231,11 @@ func TestRepositoriesService_Edit(t *testing.T) { t.Errorf("Request body = %+v, want %+v", v, input) } fmt.Fprint(w, `{"id":1}`) - }) + } + mux.HandleFunc("/repos/o/r", h) + mux.HandleFunc("/repositories/1", h) - repo, _, err := client.Repositories.Edit("o", "r", input) + repo, _, err := client.Repositories.Edit(RepositoryName{"o", "r"}, input) if err != nil { t.Errorf("Repositories.Edit returned error: %v", err) } @@ -232,15 +244,23 @@ func TestRepositoriesService_Edit(t *testing.T) { if !reflect.DeepEqual(repo, want) { t.Errorf("Repositories.Edit returned %+v, want %+v", repo, want) } + + repo, _, err = client.Repositories.Edit(RepositoryID(1), input) + if err != nil { + t.Errorf("Repositories.Edit returned error: %v", err) + } + if !reflect.DeepEqual(repo, want) { + t.Errorf("Repositories.Edit returned %+v, want %+v", repo, want) + } } func TestRepositoriesService_Get_invalidOwner(t *testing.T) { - _, _, err := client.Repositories.Get("%", "r") + _, _, err := client.Repositories.Get(RepositoryName{"%", "r"}) testURLParseError(t, err) } func TestRepositoriesService_Edit_invalidOwner(t *testing.T) { - _, _, err := client.Repositories.Edit("%", "r", nil) + _, _, err := client.Repositories.Edit(RepositoryName{"%", "r"}, nil) testURLParseError(t, err) } @@ -248,12 +268,14 @@ func TestRepositoriesService_ListLanguages(t *testing.T) { setup() defer teardown() - mux.HandleFunc("/repos/o/r/languages", func(w http.ResponseWriter, r *http.Request) { + h := func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") fmt.Fprint(w, `{"go":1}`) - }) + } + mux.HandleFunc("/repos/o/r/languages", h) + mux.HandleFunc("/repositories/1/languages", h) - languages, _, err := client.Repositories.ListLanguages("o", "r") + languages, _, err := client.Repositories.ListLanguages(RepositoryName{"o", "r"}) if err != nil { t.Errorf("Repositories.ListLanguages returned error: %v", err) } @@ -262,9 +284,17 @@ func TestRepositoriesService_ListLanguages(t *testing.T) { if !reflect.DeepEqual(languages, want) { t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want) } + + languages, _, err = client.Repositories.ListLanguages(RepositoryID(1)) + if err != nil { + t.Errorf("Repositories.ListLanguages returned error: %v", err) + } + if !reflect.DeepEqual(languages, want) { + t.Errorf("Repositories.ListLanguages returned %+v, want %+v", languages, want) + } } func TestRepositoriesService_ListLanguages_invalidOwner(t *testing.T) { - _, _, err := client.Repositories.ListLanguages("%", "%") + _, _, err := client.Repositories.ListLanguages(RepositoryName{"%", "%"}) testURLParseError(t, err) }