github.com/google/go-github/v68@v68.0.0/github/repos_commits_test.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "net/url" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/google/go-cmp/cmp" 18 ) 19 20 func TestRepositoriesService_ListCommits(t *testing.T) { 21 t.Parallel() 22 client, mux, _ := setup(t) 23 24 // given 25 mux.HandleFunc("/repos/o/r/commits", func(w http.ResponseWriter, r *http.Request) { 26 testMethod(t, r, "GET") 27 testFormValues(t, r, 28 values{ 29 "sha": "s", 30 "path": "p", 31 "author": "a", 32 "since": "2013-08-01T00:00:00Z", 33 "until": "2013-09-03T00:00:00Z", 34 }) 35 fmt.Fprintf(w, `[{"sha": "s"}]`) 36 }) 37 38 opt := &CommitsListOptions{ 39 SHA: "s", 40 Path: "p", 41 Author: "a", 42 Since: time.Date(2013, time.August, 1, 0, 0, 0, 0, time.UTC), 43 Until: time.Date(2013, time.September, 3, 0, 0, 0, 0, time.UTC), 44 } 45 ctx := context.Background() 46 commits, _, err := client.Repositories.ListCommits(ctx, "o", "r", opt) 47 if err != nil { 48 t.Errorf("Repositories.ListCommits returned error: %v", err) 49 } 50 51 want := []*RepositoryCommit{{SHA: Ptr("s")}} 52 if !cmp.Equal(commits, want) { 53 t.Errorf("Repositories.ListCommits returned %+v, want %+v", commits, want) 54 } 55 56 const methodName = "ListCommits" 57 testBadOptions(t, methodName, func() (err error) { 58 _, _, err = client.Repositories.ListCommits(ctx, "\n", "\n", opt) 59 return err 60 }) 61 62 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 63 got, resp, err := client.Repositories.ListCommits(ctx, "o", "r", opt) 64 if got != nil { 65 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 66 } 67 return resp, err 68 }) 69 } 70 71 func TestRepositoriesService_GetCommit(t *testing.T) { 72 t.Parallel() 73 client, mux, _ := setup(t) 74 75 mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) { 76 testMethod(t, r, "GET") 77 testFormValues(t, r, values{"per_page": "2", "page": "2"}) 78 fmt.Fprintf(w, `{ 79 "sha": "s", 80 "commit": { "message": "m" }, 81 "author": { "login": "l" }, 82 "committer": { "login": "l" }, 83 "parents": [ { "sha": "s" } ], 84 "stats": { "additions": 104, "deletions": 4, "total": 108 }, 85 "files": [ 86 { 87 "filename": "f", 88 "additions": 10, 89 "deletions": 2, 90 "changes": 12, 91 "status": "s", 92 "patch": "p", 93 "blob_url": "b", 94 "raw_url": "r", 95 "contents_url": "c" 96 } 97 ] 98 }`) 99 }) 100 101 opts := &ListOptions{Page: 2, PerPage: 2} 102 ctx := context.Background() 103 commit, _, err := client.Repositories.GetCommit(ctx, "o", "r", "s", opts) 104 if err != nil { 105 t.Errorf("Repositories.GetCommit returned error: %v", err) 106 } 107 108 want := &RepositoryCommit{ 109 SHA: Ptr("s"), 110 Commit: &Commit{ 111 Message: Ptr("m"), 112 }, 113 Author: &User{ 114 Login: Ptr("l"), 115 }, 116 Committer: &User{ 117 Login: Ptr("l"), 118 }, 119 Parents: []*Commit{ 120 { 121 SHA: Ptr("s"), 122 }, 123 }, 124 Stats: &CommitStats{ 125 Additions: Ptr(104), 126 Deletions: Ptr(4), 127 Total: Ptr(108), 128 }, 129 Files: []*CommitFile{ 130 { 131 Filename: Ptr("f"), 132 Additions: Ptr(10), 133 Deletions: Ptr(2), 134 Changes: Ptr(12), 135 Status: Ptr("s"), 136 Patch: Ptr("p"), 137 BlobURL: Ptr("b"), 138 RawURL: Ptr("r"), 139 ContentsURL: Ptr("c"), 140 }, 141 }, 142 } 143 if !cmp.Equal(commit, want) { 144 t.Errorf("Repositories.GetCommit returned \n%+v, want \n%+v", commit, want) 145 } 146 147 const methodName = "GetCommit" 148 testBadOptions(t, methodName, func() (err error) { 149 _, _, err = client.Repositories.GetCommit(ctx, "\n", "\n", "\n", opts) 150 return err 151 }) 152 153 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 154 got, resp, err := client.Repositories.GetCommit(ctx, "o", "r", "s", opts) 155 if got != nil { 156 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 157 } 158 return resp, err 159 }) 160 } 161 162 func TestRepositoriesService_GetCommitRaw_diff(t *testing.T) { 163 t.Parallel() 164 client, mux, _ := setup(t) 165 166 const rawStr = "@@diff content" 167 168 mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) { 169 testMethod(t, r, "GET") 170 testHeader(t, r, "Accept", mediaTypeV3Diff) 171 fmt.Fprint(w, rawStr) 172 }) 173 174 ctx := context.Background() 175 got, _, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{Type: Diff}) 176 if err != nil { 177 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 178 } 179 want := rawStr 180 if got != want { 181 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 182 } 183 184 const methodName = "GetCommitRaw" 185 testBadOptions(t, methodName, func() (err error) { 186 _, _, err = client.Repositories.GetCommitRaw(ctx, "\n", "\n", "\n", RawOptions{Type: Diff}) 187 return err 188 }) 189 190 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 191 got, resp, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{Type: Diff}) 192 if got != "" { 193 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 194 } 195 return resp, err 196 }) 197 } 198 199 func TestRepositoriesService_GetCommitRaw_patch(t *testing.T) { 200 t.Parallel() 201 client, mux, _ := setup(t) 202 203 const rawStr = "@@patch content" 204 205 mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) { 206 testMethod(t, r, "GET") 207 testHeader(t, r, "Accept", mediaTypeV3Patch) 208 fmt.Fprint(w, rawStr) 209 }) 210 211 ctx := context.Background() 212 got, _, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{Type: Patch}) 213 if err != nil { 214 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 215 } 216 want := rawStr 217 if got != want { 218 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 219 } 220 } 221 222 func TestRepositoriesService_GetCommitRaw_invalid(t *testing.T) { 223 t.Parallel() 224 client, _, _ := setup(t) 225 226 ctx := context.Background() 227 _, _, err := client.Repositories.GetCommitRaw(ctx, "o", "r", "s", RawOptions{100}) 228 if err == nil { 229 t.Fatal("Repositories.GetCommitRaw should return error") 230 } 231 if !strings.Contains(err.Error(), "unsupported raw type") { 232 t.Error("Repositories.GetCommitRaw should return unsupported raw type error") 233 } 234 } 235 236 func TestRepositoriesService_GetCommitSHA1(t *testing.T) { 237 t.Parallel() 238 client, mux, _ := setup(t) 239 240 const sha1 = "01234abcde" 241 242 mux.HandleFunc("/repos/o/r/commits/master", func(w http.ResponseWriter, r *http.Request) { 243 testMethod(t, r, "GET") 244 testHeader(t, r, "Accept", mediaTypeV3SHA) 245 246 fmt.Fprint(w, sha1) 247 }) 248 249 ctx := context.Background() 250 got, _, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "master", "") 251 if err != nil { 252 t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) 253 } 254 255 want := sha1 256 if got != want { 257 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 258 } 259 260 mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { 261 testMethod(t, r, "GET") 262 testHeader(t, r, "Accept", mediaTypeV3SHA) 263 testHeader(t, r, "If-None-Match", `"`+sha1+`"`) 264 265 w.WriteHeader(http.StatusNotModified) 266 }) 267 268 got, _, err = client.Repositories.GetCommitSHA1(ctx, "o", "r", "tag", sha1) 269 if err == nil { 270 t.Errorf("Expected HTTP 304 response") 271 } 272 273 want = "" 274 if got != want { 275 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 276 } 277 278 const methodName = "GetCommitSHA1" 279 testBadOptions(t, methodName, func() (err error) { 280 _, _, err = client.Repositories.GetCommitSHA1(ctx, "\n", "\n", "\n", "\n") 281 return err 282 }) 283 284 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 285 got, resp, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "master", "") 286 if got != "" { 287 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 288 } 289 return resp, err 290 }) 291 } 292 293 func TestRepositoriesService_NonAlphabetCharacter_GetCommitSHA1(t *testing.T) { 294 t.Parallel() 295 client, mux, _ := setup(t) 296 297 const sha1 = "01234abcde" 298 299 mux.HandleFunc("/repos/o/r/commits/master%20hash", func(w http.ResponseWriter, r *http.Request) { 300 testMethod(t, r, "GET") 301 testHeader(t, r, "Accept", mediaTypeV3SHA) 302 303 fmt.Fprint(w, sha1) 304 }) 305 306 ctx := context.Background() 307 got, _, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "master%20hash", "") 308 if err != nil { 309 t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) 310 } 311 312 if want := sha1; got != want { 313 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 314 } 315 316 mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { 317 testMethod(t, r, "GET") 318 testHeader(t, r, "Accept", mediaTypeV3SHA) 319 testHeader(t, r, "If-None-Match", `"`+sha1+`"`) 320 321 w.WriteHeader(http.StatusNotModified) 322 }) 323 324 got, _, err = client.Repositories.GetCommitSHA1(ctx, "o", "r", "tag", sha1) 325 if err == nil { 326 t.Errorf("Expected HTTP 304 response") 327 } 328 329 if want := ""; got != want { 330 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 331 } 332 } 333 334 func TestRepositoriesService_TrailingPercent_GetCommitSHA1(t *testing.T) { 335 t.Parallel() 336 client, mux, _ := setup(t) 337 338 const sha1 = "01234abcde" 339 340 mux.HandleFunc("/repos/o/r/commits/comm%", func(w http.ResponseWriter, r *http.Request) { 341 testMethod(t, r, "GET") 342 testHeader(t, r, "Accept", mediaTypeV3SHA) 343 344 fmt.Fprint(w, sha1) 345 }) 346 347 ctx := context.Background() 348 got, _, err := client.Repositories.GetCommitSHA1(ctx, "o", "r", "comm%", "") 349 if err != nil { 350 t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err) 351 } 352 353 if want := sha1; got != want { 354 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 355 } 356 357 mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) { 358 testMethod(t, r, "GET") 359 testHeader(t, r, "Accept", mediaTypeV3SHA) 360 testHeader(t, r, "If-None-Match", `"`+sha1+`"`) 361 362 w.WriteHeader(http.StatusNotModified) 363 }) 364 365 got, _, err = client.Repositories.GetCommitSHA1(ctx, "o", "r", "tag", sha1) 366 if err == nil { 367 t.Errorf("Expected HTTP 304 response") 368 } 369 370 if want := ""; got != want { 371 t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want) 372 } 373 } 374 375 func TestRepositoriesService_CompareCommits(t *testing.T) { 376 t.Parallel() 377 testCases := []struct { 378 base string 379 head string 380 }{ 381 {base: "b", head: "h"}, 382 {base: "123base", head: "head123"}, 383 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 384 } 385 386 for i, sample := range testCases { 387 sample := sample 388 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 389 t.Parallel() 390 client, mux, _ := setup(t) 391 392 base := sample.base 393 head := sample.head 394 escapedBase := url.QueryEscape(base) 395 escapedHead := url.QueryEscape(head) 396 397 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", base, head) 398 399 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 400 testMethod(t, r, "GET") 401 testFormValues(t, r, values{"per_page": "2", "page": "2"}) 402 fmt.Fprintf(w, `{ 403 "base_commit": { 404 "sha": "s", 405 "commit": { 406 "author": { "name": "n" }, 407 "committer": { "name": "n" }, 408 "message": "m", 409 "tree": { "sha": "t" } 410 }, 411 "author": { "login": "l" }, 412 "committer": { "login": "l" }, 413 "parents": [ { "sha": "s" } ] 414 }, 415 "status": "s", 416 "ahead_by": 1, 417 "behind_by": 2, 418 "total_commits": 1, 419 "commits": [ 420 { 421 "sha": "s", 422 "commit": { "author": { "name": "n" } }, 423 "author": { "login": "l" }, 424 "committer": { "login": "l" }, 425 "parents": [ { "sha": "s" } ] 426 } 427 ], 428 "files": [ { "filename": "f" } ], 429 "html_url": "https://github.com/o/r/compare/%[1]v...%[2]v", 430 "permalink_url": "https://github.com/o/r/compare/o:bbcd538c8e72b8c175046e27cc8f907076331401...o:0328041d1152db8ae77652d1618a02e57f745f17", 431 "diff_url": "https://github.com/o/r/compare/%[1]v...%[2]v.diff", 432 "patch_url": "https://github.com/o/r/compare/%[1]v...%[2]v.patch", 433 "url": "https://api.github.com/repos/o/r/compare/%[1]v...%[2]v" 434 }`, escapedBase, escapedHead) 435 }) 436 437 opts := &ListOptions{Page: 2, PerPage: 2} 438 ctx := context.Background() 439 got, _, err := client.Repositories.CompareCommits(ctx, "o", "r", base, head, opts) 440 if err != nil { 441 t.Errorf("Repositories.CompareCommits returned error: %v", err) 442 } 443 444 want := &CommitsComparison{ 445 BaseCommit: &RepositoryCommit{ 446 SHA: Ptr("s"), 447 Commit: &Commit{ 448 Author: &CommitAuthor{Name: Ptr("n")}, 449 Committer: &CommitAuthor{Name: Ptr("n")}, 450 Message: Ptr("m"), 451 Tree: &Tree{SHA: Ptr("t")}, 452 }, 453 Author: &User{Login: Ptr("l")}, 454 Committer: &User{Login: Ptr("l")}, 455 Parents: []*Commit{ 456 { 457 SHA: Ptr("s"), 458 }, 459 }, 460 }, 461 Status: Ptr("s"), 462 AheadBy: Ptr(1), 463 BehindBy: Ptr(2), 464 TotalCommits: Ptr(1), 465 Commits: []*RepositoryCommit{ 466 { 467 SHA: Ptr("s"), 468 Commit: &Commit{ 469 Author: &CommitAuthor{Name: Ptr("n")}, 470 }, 471 Author: &User{Login: Ptr("l")}, 472 Committer: &User{Login: Ptr("l")}, 473 Parents: []*Commit{ 474 { 475 SHA: Ptr("s"), 476 }, 477 }, 478 }, 479 }, 480 Files: []*CommitFile{ 481 { 482 Filename: Ptr("f"), 483 }, 484 }, 485 HTMLURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v", escapedBase, escapedHead)), 486 PermalinkURL: Ptr("https://github.com/o/r/compare/o:bbcd538c8e72b8c175046e27cc8f907076331401...o:0328041d1152db8ae77652d1618a02e57f745f17"), 487 DiffURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v.diff", escapedBase, escapedHead)), 488 PatchURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v.patch", escapedBase, escapedHead)), 489 URL: Ptr(fmt.Sprintf("https://api.github.com/repos/o/r/compare/%v...%v", escapedBase, escapedHead)), 490 } 491 492 if !cmp.Equal(got, want) { 493 t.Errorf("Repositories.CompareCommits returned \n%+v, want \n%+v", got, want) 494 } 495 496 const methodName = "CompareCommits" 497 testBadOptions(t, methodName, func() (err error) { 498 _, _, err = client.Repositories.CompareCommits(ctx, "\n", "\n", "\n", "\n", opts) 499 return err 500 }) 501 502 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 503 got, resp, err := client.Repositories.CompareCommits(ctx, "o", "r", base, head, opts) 504 if got != nil { 505 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 506 } 507 return resp, err 508 }) 509 }) 510 } 511 } 512 513 func TestRepositoriesService_CompareCommitsRaw_diff(t *testing.T) { 514 t.Parallel() 515 testCases := []struct { 516 base string 517 head string 518 }{ 519 {base: "b", head: "h"}, 520 {base: "123base", head: "head123"}, 521 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 522 } 523 524 for i, sample := range testCases { 525 sample := sample 526 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 527 t.Parallel() 528 client, mux, _ := setup(t) 529 530 base := sample.base 531 head := sample.head 532 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", base, head) 533 const rawStr = "@@diff content" 534 535 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 536 testMethod(t, r, "GET") 537 testHeader(t, r, "Accept", mediaTypeV3Diff) 538 fmt.Fprint(w, rawStr) 539 }) 540 541 ctx := context.Background() 542 got, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Diff}) 543 if err != nil { 544 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 545 } 546 want := rawStr 547 if got != want { 548 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 549 } 550 551 const methodName = "CompareCommitsRaw" 552 testBadOptions(t, methodName, func() (err error) { 553 _, _, err = client.Repositories.CompareCommitsRaw(ctx, "\n", "\n", "\n", "\n", RawOptions{Type: Diff}) 554 return err 555 }) 556 557 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 558 got, resp, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Diff}) 559 if got != "" { 560 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 561 } 562 return resp, err 563 }) 564 }) 565 } 566 } 567 568 func TestRepositoriesService_CompareCommitsRaw_patch(t *testing.T) { 569 t.Parallel() 570 testCases := []struct { 571 base string 572 head string 573 }{ 574 {base: "b", head: "h"}, 575 {base: "123base", head: "head123"}, 576 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 577 } 578 579 for i, sample := range testCases { 580 sample := sample 581 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 582 t.Parallel() 583 client, mux, _ := setup(t) 584 585 base := sample.base 586 head := sample.head 587 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", base, head) 588 const rawStr = "@@patch content" 589 590 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 591 testMethod(t, r, "GET") 592 testHeader(t, r, "Accept", mediaTypeV3Patch) 593 fmt.Fprint(w, rawStr) 594 }) 595 596 ctx := context.Background() 597 got, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Patch}) 598 if err != nil { 599 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 600 } 601 want := rawStr 602 if got != want { 603 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 604 } 605 }) 606 } 607 } 608 609 func TestRepositoriesService_CompareCommitsRaw_invalid(t *testing.T) { 610 t.Parallel() 611 ctx := context.Background() 612 613 testCases := []struct { 614 base string 615 head string 616 }{ 617 {base: "b", head: "h"}, 618 {base: "123base", head: "head123"}, 619 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 620 } 621 622 for i, sample := range testCases { 623 sample := sample 624 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 625 t.Parallel() 626 client, _, _ := setup(t) 627 _, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", sample.base, sample.head, RawOptions{100}) 628 if err == nil { 629 t.Fatal("Repositories.GetCommitRaw should return error") 630 } 631 if !strings.Contains(err.Error(), "unsupported raw type") { 632 t.Error("Repositories.GetCommitRaw should return unsupported raw type error") 633 } 634 }) 635 } 636 } 637 638 func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) { 639 t.Parallel() 640 client, mux, _ := setup(t) 641 642 mux.HandleFunc("/repos/o/r/commits/s/branches-where-head", func(w http.ResponseWriter, r *http.Request) { 643 testMethod(t, r, "GET") 644 fmt.Fprintf(w, `[{"name": "b","commit":{"sha":"2e90302801c870f17b6152327d9b9a03c8eca0e2","url":"https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"},"protected":true}]`) 645 }) 646 647 ctx := context.Background() 648 branches, _, err := client.Repositories.ListBranchesHeadCommit(ctx, "o", "r", "s") 649 if err != nil { 650 t.Errorf("Repositories.ListBranchesHeadCommit returned error: %v", err) 651 } 652 653 want := []*BranchCommit{ 654 { 655 Name: Ptr("b"), 656 Commit: &Commit{ 657 SHA: Ptr("2e90302801c870f17b6152327d9b9a03c8eca0e2"), 658 URL: Ptr("https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"), 659 }, 660 Protected: Ptr(true), 661 }, 662 } 663 if !cmp.Equal(branches, want) { 664 t.Errorf("Repositories.ListBranchesHeadCommit returned %+v, want %+v", branches, want) 665 } 666 667 const methodName = "ListBranchesHeadCommit" 668 testBadOptions(t, methodName, func() (err error) { 669 _, _, err = client.Repositories.ListBranchesHeadCommit(ctx, "\n", "\n", "\n") 670 return err 671 }) 672 673 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 674 got, resp, err := client.Repositories.ListBranchesHeadCommit(ctx, "o", "r", "s") 675 if got != nil { 676 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 677 } 678 return resp, err 679 }) 680 } 681 682 func TestBranchCommit_Marshal(t *testing.T) { 683 t.Parallel() 684 testJSONMarshal(t, &BranchCommit{}, "{}") 685 686 r := &BranchCommit{ 687 Name: Ptr("n"), 688 Commit: &Commit{ 689 SHA: Ptr("s"), 690 Author: &CommitAuthor{ 691 Date: &Timestamp{referenceTime}, 692 Name: Ptr("n"), 693 Email: Ptr("e"), 694 Login: Ptr("u"), 695 }, 696 Committer: &CommitAuthor{ 697 Date: &Timestamp{referenceTime}, 698 Name: Ptr("n"), 699 Email: Ptr("e"), 700 Login: Ptr("u"), 701 }, 702 Message: Ptr("m"), 703 Tree: &Tree{ 704 SHA: Ptr("s"), 705 Entries: []*TreeEntry{{ 706 SHA: Ptr("s"), 707 Path: Ptr("p"), 708 Mode: Ptr("m"), 709 Type: Ptr("t"), 710 Size: Ptr(1), 711 Content: Ptr("c"), 712 URL: Ptr("u"), 713 }}, 714 Truncated: Ptr(false), 715 }, 716 Parents: nil, 717 HTMLURL: Ptr("h"), 718 URL: Ptr("u"), 719 Verification: &SignatureVerification{ 720 Verified: Ptr(false), 721 Reason: Ptr("r"), 722 Signature: Ptr("s"), 723 Payload: Ptr("p"), 724 }, 725 NodeID: Ptr("n"), 726 CommentCount: Ptr(1), 727 }, 728 Protected: Ptr(false), 729 } 730 731 want := `{ 732 "name": "n", 733 "commit": { 734 "sha": "s", 735 "author": { 736 "date": ` + referenceTimeStr + `, 737 "name": "n", 738 "email": "e", 739 "username": "u" 740 }, 741 "committer": { 742 "date": ` + referenceTimeStr + `, 743 "name": "n", 744 "email": "e", 745 "username": "u" 746 }, 747 "message": "m", 748 "tree": { 749 "sha": "s", 750 "tree": [ 751 { 752 "sha": "s", 753 "path": "p", 754 "mode": "m", 755 "type": "t", 756 "size": 1, 757 "content": "c", 758 "url": "u" 759 } 760 ], 761 "truncated": false 762 }, 763 "html_url": "h", 764 "url": "u", 765 "verification": { 766 "verified": false, 767 "reason": "r", 768 "signature": "s", 769 "payload": "p" 770 }, 771 "node_id": "n", 772 "comment_count": 1 773 }, 774 "protected": false 775 }` 776 777 testJSONMarshal(t, r, want) 778 } 779 780 func TestCommitsComparison_Marshal(t *testing.T) { 781 t.Parallel() 782 testJSONMarshal(t, &CommitsComparison{}, "{}") 783 784 r := &CommitsComparison{ 785 BaseCommit: &RepositoryCommit{NodeID: Ptr("nid")}, 786 MergeBaseCommit: &RepositoryCommit{NodeID: Ptr("nid")}, 787 Status: Ptr("status"), 788 AheadBy: Ptr(1), 789 BehindBy: Ptr(1), 790 TotalCommits: Ptr(1), 791 Commits: []*RepositoryCommit{ 792 { 793 NodeID: Ptr("nid"), 794 }, 795 }, 796 Files: []*CommitFile{ 797 { 798 SHA: Ptr("sha"), 799 }, 800 }, 801 HTMLURL: Ptr("hurl"), 802 PermalinkURL: Ptr("purl"), 803 DiffURL: Ptr("durl"), 804 PatchURL: Ptr("purl"), 805 URL: Ptr("url"), 806 } 807 808 want := `{ 809 "base_commit": { 810 "node_id": "nid" 811 }, 812 "merge_base_commit": { 813 "node_id": "nid" 814 }, 815 "status": "status", 816 "ahead_by": 1, 817 "behind_by": 1, 818 "total_commits": 1, 819 "commits": [ 820 { 821 "node_id": "nid" 822 } 823 ], 824 "files": [ 825 { 826 "sha": "sha" 827 } 828 ], 829 "html_url": "hurl", 830 "permalink_url": "purl", 831 "diff_url": "durl", 832 "patch_url": "purl", 833 "url": "url" 834 }` 835 836 testJSONMarshal(t, r, want) 837 } 838 839 func TestCommitFile_Marshal(t *testing.T) { 840 t.Parallel() 841 testJSONMarshal(t, &CommitFile{}, "{}") 842 843 r := &CommitFile{ 844 SHA: Ptr("sha"), 845 Filename: Ptr("fn"), 846 Additions: Ptr(1), 847 Deletions: Ptr(1), 848 Changes: Ptr(1), 849 Status: Ptr("status"), 850 Patch: Ptr("patch"), 851 BlobURL: Ptr("burl"), 852 RawURL: Ptr("rurl"), 853 ContentsURL: Ptr("curl"), 854 PreviousFilename: Ptr("pf"), 855 } 856 857 want := `{ 858 "sha": "sha", 859 "filename": "fn", 860 "additions": 1, 861 "deletions": 1, 862 "changes": 1, 863 "status": "status", 864 "patch": "patch", 865 "blob_url": "burl", 866 "raw_url": "rurl", 867 "contents_url": "curl", 868 "previous_filename": "pf" 869 }` 870 871 testJSONMarshal(t, r, want) 872 } 873 874 func TestCommitStats_Marshal(t *testing.T) { 875 t.Parallel() 876 testJSONMarshal(t, &CommitStats{}, "{}") 877 878 r := &CommitStats{ 879 Additions: Ptr(1), 880 Deletions: Ptr(1), 881 Total: Ptr(1), 882 } 883 884 want := `{ 885 "additions": 1, 886 "deletions": 1, 887 "total": 1 888 }` 889 890 testJSONMarshal(t, r, want) 891 } 892 893 func TestRepositoryCommit_Marshal(t *testing.T) { 894 t.Parallel() 895 testJSONMarshal(t, &RepositoryCommit{}, "{}") 896 897 r := &RepositoryCommit{ 898 NodeID: Ptr("nid"), 899 SHA: Ptr("sha"), 900 Commit: &Commit{ 901 Message: Ptr("m"), 902 }, 903 Author: &User{ 904 Login: Ptr("l"), 905 }, 906 Committer: &User{ 907 Login: Ptr("l"), 908 }, 909 Parents: []*Commit{ 910 { 911 SHA: Ptr("s"), 912 }, 913 }, 914 HTMLURL: Ptr("hurl"), 915 URL: Ptr("url"), 916 CommentsURL: Ptr("curl"), 917 Stats: &CommitStats{ 918 Additions: Ptr(104), 919 Deletions: Ptr(4), 920 Total: Ptr(108), 921 }, 922 Files: []*CommitFile{ 923 { 924 Filename: Ptr("f"), 925 Additions: Ptr(10), 926 Deletions: Ptr(2), 927 Changes: Ptr(12), 928 Status: Ptr("s"), 929 Patch: Ptr("p"), 930 BlobURL: Ptr("b"), 931 RawURL: Ptr("r"), 932 ContentsURL: Ptr("c"), 933 }, 934 }, 935 } 936 937 want := `{ 938 "node_id": "nid", 939 "sha": "sha", 940 "commit": { 941 "message": "m" 942 }, 943 "author": { 944 "login": "l" 945 }, 946 "committer": { 947 "login": "l" 948 }, 949 "parents": [ 950 { 951 "sha": "s" 952 } 953 ], 954 "html_url": "hurl", 955 "url": "url", 956 "comments_url": "curl", 957 "stats": { 958 "additions": 104, 959 "deletions": 4, 960 "total": 108 961 }, 962 "files": [ 963 { 964 "filename": "f", 965 "additions": 10, 966 "deletions": 2, 967 "changes": 12, 968 "status": "s", 969 "patch": "p", 970 "blob_url": "b", 971 "raw_url": "r", 972 "contents_url": "c" 973 } 974 ] 975 }` 976 977 testJSONMarshal(t, r, want) 978 }