Repository: google/go-github
Pull request #1144 (2019-04-02 20:10:41)

test cases for JSON marshalling
Related Issue: #55



codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/1144?src=pr&el=h1) Report
> Merging [#1144](https://codecov.io/gh/google/go-github/pull/1144?src=pr&el=desc) into [master](https://codecov.io/gh/google/go-github/commit/14c49e15859cee6aa620bfac2dad50899379c20e?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/google/go-github/pull/1144/graphs/tree.svg?width=650&token=EgYjGjZlI0&height=150&src=pr)](https://codecov.io/gh/google/go-github/pull/1144?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #1144   +/-   ##
=======================================
  Coverage   70.18%   70.18%           
=======================================
  Files          84       84           
  Lines        5792     5792           
=======================================
  Hits         4065     4065           
  Misses        947      947           
  Partials      780      780
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/google/go-github/pull/1144?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/google/go-github/pull/1144?src=pr&el=footer). Last update [14c49e1...0fc28f5](https://codecov.io/gh/google/go-github/pull/1144?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

vaibhavsingh97: @gmlewis All test case passes, still travis failed 😞. Please let me know the possible fix
gmlewis: Without looking at the Travis CI logs, I can see that at least the first file has not been run through `gofmt`.

Please see [CONTRIBUTING.md](https://github.com/google/go-github/blob/master/CONTRIBUTING.md) and follow the directions there.  Thanks.
vaibhavsingh97: @gmlewis I already ran `go fmt ./...` on my patch
gmlewis: Looking at the logs from Travis CI, it says:

```
$ diff -u <(echo -n) <(gofmt -d -s .)
--- /dev/fd/63	2019-04-02 22:46:57.657608030 +0000
+++ /dev/fd/62	2019-04-02 22:46:57.657608030 +0000
@@ -0,0 +1,12 @@
+diff -u github/gists_test.go.orig github/gists_test.go
+--- github/gists_test.go.orig	2019-04-02 22:46:57.721579604 +0000
++++ github/gists_test.go	2019-04-02 22:46:57.721579604 +0000
+@@ -43,7 +43,7 @@
+ 			URL:         String("u"),
+ 		},
+ 		Files: map[GistFilename]GistFile{
+-			"gistfile.py": GistFile{
++			"gistfile.py": {
+ 				Size:     Int(167),
+ 				Filename: String("gistfile.py"),
+ 				Language: String("Python"),
The command "diff -u <(echo -n) <(gofmt -d -s .)" exited with 1.
```

What version of `go` are you using?
After running `go fmt ./...`, did you remember to commit the changes before pushing to your PR?
What does `git status` say in your repo?
vaibhavsingh97: go version go1.11.5

![image](https://user-images.githubusercontent.com/8705386/55475221-f2985800-5630-11e9-87fe-f8dd60892ec6.png)

I did commit the changes, before sending the PR. Should I retrigger travis, might be there was some issue?
gmlewis: No, there is no need, as it is obviously not formatted properly.
Click on the `Files changed` tab in GitHub and scroll down... you will see misalignments in many places.
Try pushing to the PR again with the correctly-formatted code.
gmlewis: Here's an example:
![Screenshot from 2019-04-03 07-34-51](https://user-images.githubusercontent.com/6598971/55475914-2ba9db80-55e3-11e9-9ecd-3131e93d672a.png)

vaibhavsingh97: Gotcha! Will update after proper formatting the code 👍 

Patch:
diff --git a/AUTHORS b/AUTHORS
index 1bde5b1f..c738851a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -54,6 +54,7 @@ Charlie Yan <charlieyan08@gmail.com>
 Chris King <chriskingnet@gmail.com>
 Chris Roche <chris@vsco.co>
 Chris Schaefer <chris@dtzq.com>
+chrisforrette <chris@chrisforrette.com>
 Christoph Sassenberg <defsprite@gmail.com>
 Colin Misare <github.com/cmisare>
 Craig Peterson <cpeterson@stackoverflow.com>
@@ -117,6 +118,7 @@ Joan Saum <joan.saum@epitech.eu>
 Joe Tsai <joetsai@digital-static.net>
 John Barton <jrbarton@gmail.com>
 John Engelman <john.r.engelman@gmail.com>
+Jordan Brockopp <jdbro94@gmail.com>
 Jordan Sussman <jordansail22@gmail.com>
 Joshua Bezaleel Abednego <joshua.bezaleel@gmail.com>
 JP Phillips <jonphill9@gmail.com>
@@ -137,6 +139,7 @@ Kookheon Kwon <kucuny@gmail.com>
 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
 Kshitij Saraogi <KshitijSaraogi@gmail.com>
 kyokomi <kyoko1220adword@gmail.com>
+Liam Galvin <liam@liam-galvin.co.uk>
 Lovro Mažgon <lovro.mazgon@gmail.com>
 Lucas Alcantara <lucasalcantaraf@gmail.com>
 Luke Evers <me@lukevers.com>
@@ -180,6 +183,7 @@ Rackspace US, Inc.
 Radek Simko <radek.simko@gmail.com>
 Radliński Ignacy <radlinsk@student.agh.edu.pl>
 Rajendra arora <rajendraarora16@yahoo.com>
+Ranbir Singh <binkkatal.r@gmail.com>
 RaviTeja Pothana <ravi-teja@live.com>
 rc1140 <jameel@republiccommandos.co.za>
 Red Hat, Inc.
@@ -214,6 +218,7 @@ Thomas Bruyelle <thomas.bruyelle@gmail.com>
 Timothée Peignier <timothee.peignier@tryphon.org>
 Trey Tacon <ttacon@gmail.com>
 ttacon <ttacon@gmail.com>
+Vaibhav Singh <vaibhav.singh.14cse@bml.edu.in>
 Varadarajan Aravamudhan <varadaraajan@gmail.com>
 Victor Castell <victor@victorcastell.com>
 Victor Vrantchan <vrancean+github@gmail.com>
@@ -225,5 +230,6 @@ xibz <impactbchang@gmail.com>
 Yann Malet <yann.malet@gmail.com>
 Yannick Utard <yannickutard@gmail.com>
 Yicheng Qin <qycqycqycqycqyc@gmail.com>
+Yosuke Akatsuka <yosuke.akatsuka@access-company.com>
 Yumikiyo Osanai <yumios.art@gmail.com>
 Zach Latta <zach@zachlatta.com>
diff --git a/github/apps.go b/github/apps.go
index ae3aabda..1ad9a981 100644
--- a/github/apps.go
+++ b/github/apps.go
@@ -62,6 +62,13 @@ type Installation struct {
 	UpdatedAt           *Timestamp               `json:"updated_at,omitempty"`
 }
 
+// Attachment represents a GitHub Apps attachment.
+type Attachment struct {
+	ID    *int64  `json:"id,omitempty"`
+	Title *string `json:"title,omitempty"`
+	Body  *string `json:"body,omitempty"`
+}
+
 func (i Installation) String() string {
 	return Stringify(i)
 }
@@ -183,6 +190,29 @@ func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64) (*I
 	return t, resp, nil
 }
 
+// Create a new attachment on user comment containing a url.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#create-a-content-attachment
+func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) {
+	u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID)
+	payload := &Attachment{Title: String(title), Body: String(body)}
+	req, err := s.client.NewRequest("POST", u, payload)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Attachment{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
 // FindOrganizationInstallation finds the organization's installation information.
 //
 // GitHub API docs: https://developer.github.com/v3/apps/#find-organization-installation
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 10015590..d8ca5deb 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -188,6 +188,30 @@ func (a *App) GetUpdatedAt() time.Time {
 	return *a.UpdatedAt
 }
 
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (a *Attachment) GetBody() string {
+	if a == nil || a.Body == nil {
+		return ""
+	}
+	return *a.Body
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (a *Attachment) GetID() int64 {
+	if a == nil || a.ID == nil {
+		return 0
+	}
+	return *a.ID
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (a *Attachment) GetTitle() string {
+	if a == nil || a.Title == nil {
+		return ""
+	}
+	return *a.Title
+}
+
 // GetApp returns the App field.
 func (a *Authorization) GetApp() *AuthorizationApp {
 	if a == nil {


Test patch:
diff --git a/github/apps_test.go b/github/apps_test.go
index a594eab3..8456662b 100644
--- a/github/apps_test.go
+++ b/github/apps_test.go
@@ -185,6 +185,28 @@ func TestAppsService_CreateInstallationToken(t *testing.T) {
 	}
 }
 
+func TestAppsService_CreateAttachement(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/content_references/11/attachments", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+
+		w.WriteHeader(http.StatusOK)
+		w.Write([]byte(`{"id":1,"title":"title1","body":"body1"}`))
+	})
+
+	got, _, err := client.Apps.CreateAttachment(context.Background(), 11, "title1", "body1")
+	if err != nil {
+		t.Errorf("CreateAttachment returned error: %v", err)
+	}
+
+	want := &Attachment{ID: Int64(1), Title: String("title1"), Body: String("body1")}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("CreateAttachment = %+v, want %+v", got, want)
+	}
+}
 func TestAppsService_FindOrganizationInstallation(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/gists_comments_test.go b/github/gists_comments_test.go
index d2f5a953..b4345c40 100644
--- a/github/gists_comments_test.go
+++ b/github/gists_comments_test.go
@@ -12,8 +12,64 @@ import (
 	"net/http"
 	"reflect"
 	"testing"
+	"time"
 )
 
+func TestGistComments_marshall(t *testing.T) {
+	testJSONMarshal(t, &GistComment{}, "{}")
+
+	createdAt := time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)
+
+	u := &GistComment{
+		ID:   Int64(1),
+		URL:  String("u"),
+		Body: String("test gist comment"),
+		User: &User{
+			Login:       String("ll"),
+			ID:          Int64(123),
+			AvatarURL:   String("a"),
+			GravatarID:  String("g"),
+			Name:        String("n"),
+			Company:     String("c"),
+			Blog:        String("b"),
+			Location:    String("l"),
+			Email:       String("e"),
+			Hireable:    Bool(true),
+			PublicRepos: Int(1),
+			Followers:   Int(1),
+			Following:   Int(1),
+			CreatedAt:   &Timestamp{referenceTime},
+			URL:         String("u"),
+		},
+		CreatedAt: &createdAt,
+	}
+
+	want := `{
+		"id": 1,
+		"url": "u",
+		"body": "test gist comment",
+		"user": {
+			"login": "ll",
+			"id": 123,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"created_at": "2002-02-10T15:30:00Z"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
 func TestGistsService_ListComments(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/gists_test.go b/github/gists_test.go
index 3d31c9ac..2d79b8c5 100644
--- a/github/gists_test.go
+++ b/github/gists_test.go
@@ -15,6 +15,215 @@ import (
 	"time"
 )
 
+func TestGist_marshall(t *testing.T) {
+	testJSONMarshal(t, &Gist{}, "{}")
+
+	createdAt := time.Date(2010, time.February, 10, 10, 10, 0, 0, time.UTC)
+	updatedAt := time.Date(2010, time.February, 10, 10, 10, 0, 0, time.UTC)
+
+	u := &Gist{
+		ID:          String("i"),
+		Description: String("description"),
+		Public:      Bool(true),
+		Owner: &User{
+			Login:       String("ll"),
+			ID:          Int64(123),
+			AvatarURL:   String("a"),
+			GravatarID:  String("g"),
+			Name:        String("n"),
+			Company:     String("c"),
+			Blog:        String("b"),
+			Location:    String("l"),
+			Email:       String("e"),
+			Hireable:    Bool(true),
+			PublicRepos: Int(1),
+			Followers:   Int(1),
+			Following:   Int(1),
+			CreatedAt:   &Timestamp{referenceTime},
+			URL:         String("u"),
+		},
+		Files: map[GistFilename]GistFile{
+			"gistfile.py": {
+				Size:     Int(167),
+				Filename: String("gistfile.py"),
+				Language: String("Python"),
+				Type:     String("application/x-python"),
+				RawURL:   String("raw-url"),
+				Content:  String("c"),
+			},
+		},
+		Comments:   Int(1),
+		HTMLURL:    String("html-url"),
+		GitPullURL: String("gitpull-url"),
+		GitPushURL: String("gitpush-url"),
+		CreatedAt:  &createdAt,
+		UpdatedAt:  &updatedAt,
+		NodeID:     String("node"),
+	}
+
+	want := `{
+		"id": "i",
+		"description": "description",
+		"public": true,
+		"owner": {
+			"login": "ll",
+			"id": 123,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"files": {
+			"gistfile.py": {
+				"size": 167,
+				"filename": "gistfile.py",
+				"language": "Python",
+				"type": "application/x-python",
+				"raw_url": "raw-url",
+				"content": "c"
+			}
+		},
+		"comments": 1,
+		"html_url": "html-url",
+		"git_pull_url": "gitpull-url",
+		"git_push_url": "gitpush-url",
+		"created_at": "2010-02-10T10:10:00Z",
+		"updated_at": "2010-02-10T10:10:00Z",
+		"node_id": "node"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestGistCommit_marshall(t *testing.T) {
+	testJSONMarshal(t, &GistCommit{}, "{}")
+
+	u := &GistCommit{
+		URL:     String("u"),
+		Version: String("v"),
+		User: &User{
+			Login:       String("ll"),
+			ID:          Int64(123),
+			AvatarURL:   String("a"),
+			GravatarID:  String("g"),
+			Name:        String("n"),
+			Company:     String("c"),
+			Blog:        String("b"),
+			Location:    String("l"),
+			Email:       String("e"),
+			Hireable:    Bool(true),
+			PublicRepos: Int(1),
+			Followers:   Int(1),
+			Following:   Int(1),
+			CreatedAt:   &Timestamp{referenceTime},
+			URL:         String("u"),
+		},
+		ChangeStatus: &CommitStats{
+			Additions: Int(1),
+			Deletions: Int(1),
+			Total:     Int(2),
+		},
+		CommittedAt: &Timestamp{referenceTime},
+		NodeID:      String("node"),
+	}
+
+	want := `{
+		"url": "u",
+		"version": "v",
+		"user": {
+			"login": "ll",
+			"id": 123,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"change_status": {
+			"additions": 1,
+			"deletions": 1,
+			"total": 2
+		},
+		"committed_at": ` + referenceTimeStr + `,
+		"node_id": "node"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestGistFork_marshall(t *testing.T) {
+	testJSONMarshal(t, &GistFork{}, "{}")
+
+	u := &GistFork{
+		URL: String("u"),
+		User: &User{
+			Login:       String("ll"),
+			ID:          Int64(123),
+			AvatarURL:   String("a"),
+			GravatarID:  String("g"),
+			Name:        String("n"),
+			Company:     String("c"),
+			Blog:        String("b"),
+			Location:    String("l"),
+			Email:       String("e"),
+			Hireable:    Bool(true),
+			PublicRepos: Int(1),
+			Followers:   Int(1),
+			Following:   Int(1),
+			CreatedAt:   &Timestamp{referenceTime},
+			URL:         String("u"),
+		},
+		ID:        String("id"),
+		CreatedAt: &Timestamp{referenceTime},
+		UpdatedAt: &Timestamp{referenceTime},
+		NodeID:    String("node"),
+	}
+
+	want := `{
+		"url": "u",
+		"user": {
+			"login": "ll",
+			"id": 123,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"id": "id",
+		"created_at": ` + referenceTimeStr + `,
+		"updated_at": ` + referenceTimeStr + `,
+		"node_id": "node"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
 func TestGistsService_List_specifiedUser(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/pulls_comments_test.go b/github/pulls_comments_test.go
index 76b78cf7..b07b2cd9 100644
--- a/github/pulls_comments_test.go
+++ b/github/pulls_comments_test.go
@@ -15,6 +15,106 @@ import (
 	"time"
 )
 
+func TestPullComments_marshall(t *testing.T) {
+	testJSONMarshal(t, &PullRequestComment{}, "{}")
+
+	createdAt := time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)
+	updatedAt := time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)
+	reactions := &Reactions{
+		TotalCount: Int(1),
+		PlusOne:    Int(1),
+		MinusOne:   Int(0),
+		Laugh:      Int(0),
+		Confused:   Int(0),
+		Heart:      Int(0),
+		Hooray:     Int(0),
+		URL:        String("u"),
+	}
+
+	u := &PullRequestComment{
+		ID:                  Int64(10),
+		InReplyTo:           Int64(8),
+		Body:                String("Test comment"),
+		Path:                String("file1.txt"),
+		DiffHunk:            String("@@ -16,33 +16,40 @@ fmt.Println()"),
+		PullRequestReviewID: Int64(42),
+		Position:            Int(1),
+		OriginalPosition:    Int(4),
+		CommitID:            String("ab"),
+		OriginalCommitID:    String("9c"),
+		User: &User{
+			Login:       String("ll"),
+			ID:          Int64(123),
+			AvatarURL:   String("a"),
+			GravatarID:  String("g"),
+			Name:        String("n"),
+			Company:     String("c"),
+			Blog:        String("b"),
+			Location:    String("l"),
+			Email:       String("e"),
+			Hireable:    Bool(true),
+			PublicRepos: Int(1),
+			Followers:   Int(1),
+			Following:   Int(1),
+			CreatedAt:   &Timestamp{referenceTime},
+			URL:         String("u"),
+		},
+		Reactions:      reactions,
+		CreatedAt:      &createdAt,
+		UpdatedAt:      &updatedAt,
+		URL:            String("pullrequestcommentUrl"),
+		HTMLURL:        String("pullrequestcommentHTMLUrl"),
+		PullRequestURL: String("pullrequestcommentPullRequestURL"),
+	}
+
+	want := `{
+		"id": 10,
+		"in_reply_to_id": 8,
+		"body": "Test comment",
+		"path": "file1.txt",
+		"diff_hunk": "@@ -16,33 +16,40 @@ fmt.Println()",
+		"pull_request_review_id": 42,
+		"position": 1,
+		"original_position": 4,
+		"commit_id": "ab",
+		"original_commit_id": "9c",
+		"user": {
+			"login": "ll",
+			"id": 123,
+			"avatar_url": "a",
+			"gravatar_id": "g",
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "l",
+			"email": "e",
+			"hireable": true,
+			"public_repos": 1,
+			"followers": 1,
+			"following": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"url": "u"
+		},
+		"reactions": {
+			"total_count": 1,
+			"+1": 1,
+			"-1": 0,
+			"laugh": 0,
+			"confused": 0,
+			"heart": 0,
+			"hooray": 0,
+			"url": "u"
+		},
+		"created_at": "2002-02-10T15:30:00Z",
+		"updated_at": "2002-02-10T15:30:00Z",
+		"url": "pullrequestcommentUrl",
+		"html_url": "pullrequestcommentHTMLUrl",
+		"pull_request_url": "pullrequestcommentPullRequestURL"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
 func TestPullRequestsService_ListComments_allPulls(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()