-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Repo commits #49
Repo commits #49
Conversation
we have such code repreated in a few places
it also has a Stats field in the case of repos/commits
@@ -13,7 +13,7 @@ import ( | |||
// RepositoryComment represents a comment for a commit, file, or line in a repository. | |||
type RepositoryComment struct { | |||
HTMLURL *string `json:"html_url,omitempty"` | |||
URL *string `json:"url,omitempty"` | |||
URL *string `json:"url,omitempty"` // todo: I thought we're skipping urls? - ktoso |
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.
yeah, I've basically given up on that. While I still don't think the URLs are terribly useful, I've stopped asking people to remove them. It's certainly simpler if our structs just include everything.
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.
ok, removed comment then.
A general note here about your tests... I intentionally don't include the full example from the GitHub docs. That's because it isn't really meaningful to do so because of what we're actually testing here. The portion of the test where we are parsing a sample response is doing two things: 1) verify that we can parse it into the expected data type and 2) verify that our To satisfy number 1, the simplest possible response body will do, which is what most of our tests contain. This is primarily checking the JSON type of the outermost element of the response... making sure we're not trying to unmarshall a JSON object into a Go slice, for example. Number 2 is not being fully covered in mosts of our tests right now (I talk about that in my recent blog post here). For that, we do need at least one test that includes all of the fields for a given type. It doesn't actually matter what the value is for all of those fields, because we're not actually testing for that. Therefore, I always use the shortest value possible (for example, for strings I use a single character, normally using the first letter of the field name). The shorter values makes tests easier to read, and makes it clear that we're not doing any validation on values. Additionally, there is no need to include all of the fields for nested structs if there are other tests that cover them. For example, a Additionally, if we're going to try and cover number 2 (which I think is certainly is a good thing) we only need to do it for a single test... any more than that is just duplicating effort with no additional benefit. I would prefer we do it on the "Get" method for each type, since that is the most discrete test for checking a single resource of the type. So applying that logic results in:
|
Hey Will, I've updated the sources according to the comments (no parameters.go, smaller tests - I'm testing new types introduced only in one place, etc.). PS: Sorry about the weird delays in PR / fixes - I was in the middle of moving flats. |
hey, no worries... I just really appreciate you taking the time to do this. :) A few more inline comments forthcoming (mainly things I missed previously, I guess)... |
// RepositoriesService.RepositoriesList method. | ||
type CommitsListOptions struct { | ||
// Sha or branch to start listing commits from. | ||
SHA *string |
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.
fields on Options structs don't need to be pointers... only data structures that are JSON encoded.
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.
Hm... this Options struct is rather big, don't we have to use pointers to make some options "optional"? I can imagine people wanting to not specify Since for example.
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.
I just noticed none of your tests pass a CommitsListOptions
.. they all pass nil
. I'm pretty sure that you will get an error trying to dereference these pointers if they are unset down around line 87, since you're not doing nil checks.
As far as I know, there are no cases in the GitHub API where the zero value is meaningful for these optional parameters. If there are, then of course we're going to run into the same problem that we have for data structures. But if not, then we can just leave them as non-pointer values, and let the zero values through. Today, they will be included in the query string, but with no value.... e.g. ?sha=&path=&author=
, etc. I'm not actually sure what will happen with the since time. I think I typically check for !IsZero()
before adding it to the url.Values
. When I handle #50, we can easily strip all of these zero value params.
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.
Right, that convinces me :-) For Times I have the IsZero checks so we're fine there. Moving away from pointers.
} | ||
|
||
// when | ||
commits, _, err := client.Repositories.ListCommits("o", "r", &CommitsListOptions{ |
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.
well you still gotta actually test the option values :) testFormValues
makes this really simple... see https://github.com/google/go-github/blob/master/github/users_test.go#L94-L104
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.
oh how nice, included it :) sorry and thanks again :)
Should be nicely cleaned up now. Thanks a lot for the feedback :) |
merged (together with some other changes I forgot about) as 1eaf383 thanks for pushing through this one... this was definitely one of the hairier parts of the API in terms of data structures. |
ktoso kind of shamed me with his extensive resource tests in #49 :), so I'm finally starting to setup a structure for more general testing of this type. This change adds the `testJSONMarshal` helper function, and adds tests for the `User` type. This includes two checks: - check that an empty resource produces an empty JSON object. This effectively verifies that all fields include 'omitempty' so that we're not unintentionally sending additional data over the wire. - check that a full resource with every field populated produces the expected JSON. This verifies that the JSON field mappings are correct. In this case, it might be okay to use resource samples from the GitHub docs, though I do still prefer very simple field values since it makes tests easier to read. When these tests are added for each resource type, we can reduce all of our other tests to return bare minimal response bodies, since the resource fields are already being tested at that point.
Author *User `json:"author,omitempty"` | ||
Committer *User `json:"committer,omitempty"` | ||
Parents []Commit `json:"parents,omitempty"` | ||
Message *string `json:"message,omitempty"` |
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.
I suspect Message
field was added here erroneously. It should only be inside Commit
, not RepositoryCommit
.
From what I can tell, it's not actually ever present in the GitHub API responses. Does anyone have counter-examples? If not, I'll make a PR to remove it. Edit: It has been done in #492.
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.
SGTM. Thanks, @shurcooL.
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.
This field is unused. There is no "commit message" inside of RepositoryCommit (higher level GitHub object), it's only inside of Commit (lower level git commit). It was added accidentally in #49 and not caught via test due to #491. Followup to #49. See https://github.com/google/go-github/pull/49/files#r92034462.
This field is unused. There is no "commit message" inside of RepositoryCommit (higher level GitHub object), it's only inside of Commit (lower level git object). It was added accidentally in #49 and not caught via test due to #491. Followup to #49. See https://github.com/google/go-github/pull/49/files#r92034462.
This field is unused. There is no "commit message" inside of RepositoryCommit (higher level GitHub object), it's only inside of Commit (lower level git object). It was added accidentally in #49 and not caught via test due to #491. Followup to #49. See https://github.com/google/go-github/pull/49/files#r92034462.
This field is unused. There is no "commit message" inside of RepositoryCommit (higher level GitHub object), it's only inside of Commit (lower level git object). It was added accidentally in google#49 and not caught via test due to google#491. Followup to google#49. See https://github.com/google/go-github/pull/49/files#r92034462.
The long awaited commit with
repo/commits
API.The API is different than
git/commit
in having more detailed information about the commit itself - for example lists of files, and authors etc.The tests are a bit verbose. I've tested against the example jsons from the github api page, but that saved me from overlooking a field or two when updating the structs.
I've also moved this code to the new style that we've started using in the lib recently (pointers everywhere).
I skipped the URL fields as we did before, though not sure if maybe for the "compare commits" case the URL may be helpful - they're for patches etc.
Looking forward to your comments guys :)
Implements one of the APIs mentioned in #37