github.com/google/go-github/v74@v74.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.Fprint(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.Fprint(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.Error("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%2520hash", 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.Error("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.Error("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 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 388 t.Parallel() 389 client, mux, _ := setup(t) 390 391 base := sample.base 392 head := sample.head 393 394 encodedBase := url.PathEscape(base) 395 encodedHead := url.PathEscape(head) 396 397 escapedBase := url.QueryEscape(base) 398 escapedHead := url.QueryEscape(head) 399 400 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", encodedBase, encodedHead) 401 402 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 403 testMethod(t, r, "GET") 404 testFormValues(t, r, values{"per_page": "2", "page": "2"}) 405 fmt.Fprintf(w, `{ 406 "base_commit": { 407 "sha": "s", 408 "commit": { 409 "author": { "name": "n" }, 410 "committer": { "name": "n" }, 411 "message": "m", 412 "tree": { "sha": "t" } 413 }, 414 "author": { "login": "l" }, 415 "committer": { "login": "l" }, 416 "parents": [ { "sha": "s" } ] 417 }, 418 "status": "s", 419 "ahead_by": 1, 420 "behind_by": 2, 421 "total_commits": 1, 422 "commits": [ 423 { 424 "sha": "s", 425 "commit": { "author": { "name": "n" } }, 426 "author": { "login": "l" }, 427 "committer": { "login": "l" }, 428 "parents": [ { "sha": "s" } ] 429 } 430 ], 431 "files": [ { "filename": "f" } ], 432 "html_url": "https://github.com/o/r/compare/%[1]v...%[2]v", 433 "permalink_url": "https://github.com/o/r/compare/o:bbcd538c8e72b8c175046e27cc8f907076331401...o:0328041d1152db8ae77652d1618a02e57f745f17", 434 "diff_url": "https://github.com/o/r/compare/%[1]v...%[2]v.diff", 435 "patch_url": "https://github.com/o/r/compare/%[1]v...%[2]v.patch", 436 "url": "https://api.github.com/repos/o/r/compare/%[1]v...%[2]v" 437 }`, escapedBase, escapedHead) 438 }) 439 440 opts := &ListOptions{Page: 2, PerPage: 2} 441 ctx := context.Background() 442 got, _, err := client.Repositories.CompareCommits(ctx, "o", "r", base, head, opts) 443 if err != nil { 444 t.Errorf("Repositories.CompareCommits returned error: %v", err) 445 } 446 447 want := &CommitsComparison{ 448 BaseCommit: &RepositoryCommit{ 449 SHA: Ptr("s"), 450 Commit: &Commit{ 451 Author: &CommitAuthor{Name: Ptr("n")}, 452 Committer: &CommitAuthor{Name: Ptr("n")}, 453 Message: Ptr("m"), 454 Tree: &Tree{SHA: Ptr("t")}, 455 }, 456 Author: &User{Login: Ptr("l")}, 457 Committer: &User{Login: Ptr("l")}, 458 Parents: []*Commit{ 459 { 460 SHA: Ptr("s"), 461 }, 462 }, 463 }, 464 Status: Ptr("s"), 465 AheadBy: Ptr(1), 466 BehindBy: Ptr(2), 467 TotalCommits: Ptr(1), 468 Commits: []*RepositoryCommit{ 469 { 470 SHA: Ptr("s"), 471 Commit: &Commit{ 472 Author: &CommitAuthor{Name: Ptr("n")}, 473 }, 474 Author: &User{Login: Ptr("l")}, 475 Committer: &User{Login: Ptr("l")}, 476 Parents: []*Commit{ 477 { 478 SHA: Ptr("s"), 479 }, 480 }, 481 }, 482 }, 483 Files: []*CommitFile{ 484 { 485 Filename: Ptr("f"), 486 }, 487 }, 488 HTMLURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v", escapedBase, escapedHead)), 489 PermalinkURL: Ptr("https://github.com/o/r/compare/o:bbcd538c8e72b8c175046e27cc8f907076331401...o:0328041d1152db8ae77652d1618a02e57f745f17"), 490 DiffURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v.diff", escapedBase, escapedHead)), 491 PatchURL: Ptr(fmt.Sprintf("https://github.com/o/r/compare/%v...%v.patch", escapedBase, escapedHead)), 492 URL: Ptr(fmt.Sprintf("https://api.github.com/repos/o/r/compare/%v...%v", escapedBase, escapedHead)), 493 } 494 495 if !cmp.Equal(got, want) { 496 t.Errorf("Repositories.CompareCommits returned \n%+v, want \n%+v", got, want) 497 } 498 499 const methodName = "CompareCommits" 500 testBadOptions(t, methodName, func() (err error) { 501 _, _, err = client.Repositories.CompareCommits(ctx, "\n", "\n", "\n", "\n", opts) 502 return err 503 }) 504 505 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 506 got, resp, err := client.Repositories.CompareCommits(ctx, "o", "r", base, head, opts) 507 if got != nil { 508 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 509 } 510 return resp, err 511 }) 512 }) 513 } 514 } 515 516 func TestRepositoriesService_CompareCommitsRaw_diff(t *testing.T) { 517 t.Parallel() 518 testCases := []struct { 519 base string 520 head string 521 }{ 522 {base: "b", head: "h"}, 523 {base: "123base", head: "head123"}, 524 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 525 } 526 527 for i, sample := range testCases { 528 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 529 t.Parallel() 530 client, mux, _ := setup(t) 531 532 base := sample.base 533 head := sample.head 534 535 encodedBase := url.PathEscape(base) 536 encodedHead := url.PathEscape(head) 537 538 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", encodedBase, encodedHead) 539 const rawStr = "@@diff content" 540 541 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 542 testMethod(t, r, "GET") 543 testHeader(t, r, "Accept", mediaTypeV3Diff) 544 fmt.Fprint(w, rawStr) 545 }) 546 547 ctx := context.Background() 548 got, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Diff}) 549 if err != nil { 550 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 551 } 552 want := rawStr 553 if got != want { 554 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 555 } 556 557 const methodName = "CompareCommitsRaw" 558 testBadOptions(t, methodName, func() (err error) { 559 _, _, err = client.Repositories.CompareCommitsRaw(ctx, "\n", "\n", "\n", "\n", RawOptions{Type: Diff}) 560 return err 561 }) 562 563 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 564 got, resp, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Diff}) 565 if got != "" { 566 t.Errorf("testNewRequestAndDoFailure %v = %#v, want ''", methodName, got) 567 } 568 return resp, err 569 }) 570 }) 571 } 572 } 573 574 func TestRepositoriesService_CompareCommitsRaw_patch(t *testing.T) { 575 t.Parallel() 576 testCases := []struct { 577 base string 578 head string 579 }{ 580 {base: "b", head: "h"}, 581 {base: "123base", head: "head123"}, 582 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 583 } 584 585 for i, sample := range testCases { 586 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 587 t.Parallel() 588 client, mux, _ := setup(t) 589 590 base := sample.base 591 head := sample.head 592 593 encodedBase := url.PathEscape(base) 594 encodedHead := url.PathEscape(head) 595 596 pattern := fmt.Sprintf("/repos/o/r/compare/%v...%v", encodedBase, encodedHead) 597 const rawStr = "@@patch content" 598 599 mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 600 testMethod(t, r, "GET") 601 testHeader(t, r, "Accept", mediaTypeV3Patch) 602 fmt.Fprint(w, rawStr) 603 }) 604 605 ctx := context.Background() 606 got, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", base, head, RawOptions{Type: Patch}) 607 if err != nil { 608 t.Fatalf("Repositories.GetCommitRaw returned error: %v", err) 609 } 610 want := rawStr 611 if got != want { 612 t.Errorf("Repositories.GetCommitRaw returned %s want %s", got, want) 613 } 614 }) 615 } 616 } 617 618 func TestRepositoriesService_CompareCommitsRaw_invalid(t *testing.T) { 619 t.Parallel() 620 ctx := context.Background() 621 622 testCases := []struct { 623 base string 624 head string 625 }{ 626 {base: "b", head: "h"}, 627 {base: "123base", head: "head123"}, 628 {base: "`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+123base", head: "head123`~!@#$%^&*()_+-=[]\\{}|;':\",./<>?/*-+"}, 629 } 630 631 for i, sample := range testCases { 632 t.Run(fmt.Sprintf("case #%v", i+1), func(t *testing.T) { 633 t.Parallel() 634 client, _, _ := setup(t) 635 _, _, err := client.Repositories.CompareCommitsRaw(ctx, "o", "r", sample.base, sample.head, RawOptions{100}) 636 if err == nil { 637 t.Fatal("Repositories.GetCommitRaw should return error") 638 } 639 if !strings.Contains(err.Error(), "unsupported raw type") { 640 t.Error("Repositories.GetCommitRaw should return unsupported raw type error") 641 } 642 }) 643 } 644 } 645 646 func TestRepositoriesService_ListBranchesHeadCommit(t *testing.T) { 647 t.Parallel() 648 client, mux, _ := setup(t) 649 650 mux.HandleFunc("/repos/o/r/commits/s/branches-where-head", func(w http.ResponseWriter, r *http.Request) { 651 testMethod(t, r, "GET") 652 fmt.Fprint(w, `[{"name": "b","commit":{"sha":"2e90302801c870f17b6152327d9b9a03c8eca0e2","url":"https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"},"protected":true}]`) 653 }) 654 655 ctx := context.Background() 656 branches, _, err := client.Repositories.ListBranchesHeadCommit(ctx, "o", "r", "s") 657 if err != nil { 658 t.Errorf("Repositories.ListBranchesHeadCommit returned error: %v", err) 659 } 660 661 want := []*BranchCommit{ 662 { 663 Name: Ptr("b"), 664 Commit: &Commit{ 665 SHA: Ptr("2e90302801c870f17b6152327d9b9a03c8eca0e2"), 666 URL: Ptr("https://api.github.com/repos/google/go-github/commits/2e90302801c870f17b6152327d9b9a03c8eca0e2"), 667 }, 668 Protected: Ptr(true), 669 }, 670 } 671 if !cmp.Equal(branches, want) { 672 t.Errorf("Repositories.ListBranchesHeadCommit returned %+v, want %+v", branches, want) 673 } 674 675 const methodName = "ListBranchesHeadCommit" 676 testBadOptions(t, methodName, func() (err error) { 677 _, _, err = client.Repositories.ListBranchesHeadCommit(ctx, "\n", "\n", "\n") 678 return err 679 }) 680 681 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 682 got, resp, err := client.Repositories.ListBranchesHeadCommit(ctx, "o", "r", "s") 683 if got != nil { 684 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 685 } 686 return resp, err 687 }) 688 } 689 690 func TestBranchCommit_Marshal(t *testing.T) { 691 t.Parallel() 692 testJSONMarshal(t, &BranchCommit{}, "{}") 693 694 r := &BranchCommit{ 695 Name: Ptr("n"), 696 Commit: &Commit{ 697 SHA: Ptr("s"), 698 Author: &CommitAuthor{ 699 Date: &Timestamp{referenceTime}, 700 Name: Ptr("n"), 701 Email: Ptr("e"), 702 Login: Ptr("u"), 703 }, 704 Committer: &CommitAuthor{ 705 Date: &Timestamp{referenceTime}, 706 Name: Ptr("n"), 707 Email: Ptr("e"), 708 Login: Ptr("u"), 709 }, 710 Message: Ptr("m"), 711 Tree: &Tree{ 712 SHA: Ptr("s"), 713 Entries: []*TreeEntry{{ 714 SHA: Ptr("s"), 715 Path: Ptr("p"), 716 Mode: Ptr("m"), 717 Type: Ptr("t"), 718 Size: Ptr(1), 719 Content: Ptr("c"), 720 URL: Ptr("u"), 721 }}, 722 Truncated: Ptr(false), 723 }, 724 Parents: nil, 725 HTMLURL: Ptr("h"), 726 URL: Ptr("u"), 727 Verification: &SignatureVerification{ 728 Verified: Ptr(false), 729 Reason: Ptr("r"), 730 Signature: Ptr("s"), 731 Payload: Ptr("p"), 732 }, 733 NodeID: Ptr("n"), 734 CommentCount: Ptr(1), 735 }, 736 Protected: Ptr(false), 737 } 738 739 want := `{ 740 "name": "n", 741 "commit": { 742 "sha": "s", 743 "author": { 744 "date": ` + referenceTimeStr + `, 745 "name": "n", 746 "email": "e", 747 "username": "u" 748 }, 749 "committer": { 750 "date": ` + referenceTimeStr + `, 751 "name": "n", 752 "email": "e", 753 "username": "u" 754 }, 755 "message": "m", 756 "tree": { 757 "sha": "s", 758 "tree": [ 759 { 760 "sha": "s", 761 "path": "p", 762 "mode": "m", 763 "type": "t", 764 "size": 1, 765 "content": "c", 766 "url": "u" 767 } 768 ], 769 "truncated": false 770 }, 771 "html_url": "h", 772 "url": "u", 773 "verification": { 774 "verified": false, 775 "reason": "r", 776 "signature": "s", 777 "payload": "p" 778 }, 779 "node_id": "n", 780 "comment_count": 1 781 }, 782 "protected": false 783 }` 784 785 testJSONMarshal(t, r, want) 786 } 787 788 func TestCommitsComparison_Marshal(t *testing.T) { 789 t.Parallel() 790 testJSONMarshal(t, &CommitsComparison{}, "{}") 791 792 r := &CommitsComparison{ 793 BaseCommit: &RepositoryCommit{NodeID: Ptr("nid")}, 794 MergeBaseCommit: &RepositoryCommit{NodeID: Ptr("nid")}, 795 Status: Ptr("status"), 796 AheadBy: Ptr(1), 797 BehindBy: Ptr(1), 798 TotalCommits: Ptr(1), 799 Commits: []*RepositoryCommit{ 800 { 801 NodeID: Ptr("nid"), 802 }, 803 }, 804 Files: []*CommitFile{ 805 { 806 SHA: Ptr("sha"), 807 }, 808 }, 809 HTMLURL: Ptr("hurl"), 810 PermalinkURL: Ptr("purl"), 811 DiffURL: Ptr("durl"), 812 PatchURL: Ptr("purl"), 813 URL: Ptr("url"), 814 } 815 816 want := `{ 817 "base_commit": { 818 "node_id": "nid" 819 }, 820 "merge_base_commit": { 821 "node_id": "nid" 822 }, 823 "status": "status", 824 "ahead_by": 1, 825 "behind_by": 1, 826 "total_commits": 1, 827 "commits": [ 828 { 829 "node_id": "nid" 830 } 831 ], 832 "files": [ 833 { 834 "sha": "sha" 835 } 836 ], 837 "html_url": "hurl", 838 "permalink_url": "purl", 839 "diff_url": "durl", 840 "patch_url": "purl", 841 "url": "url" 842 }` 843 844 testJSONMarshal(t, r, want) 845 } 846 847 func TestCommitFile_Marshal(t *testing.T) { 848 t.Parallel() 849 testJSONMarshal(t, &CommitFile{}, "{}") 850 851 r := &CommitFile{ 852 SHA: Ptr("sha"), 853 Filename: Ptr("fn"), 854 Additions: Ptr(1), 855 Deletions: Ptr(1), 856 Changes: Ptr(1), 857 Status: Ptr("status"), 858 Patch: Ptr("patch"), 859 BlobURL: Ptr("burl"), 860 RawURL: Ptr("rurl"), 861 ContentsURL: Ptr("curl"), 862 PreviousFilename: Ptr("pf"), 863 } 864 865 want := `{ 866 "sha": "sha", 867 "filename": "fn", 868 "additions": 1, 869 "deletions": 1, 870 "changes": 1, 871 "status": "status", 872 "patch": "patch", 873 "blob_url": "burl", 874 "raw_url": "rurl", 875 "contents_url": "curl", 876 "previous_filename": "pf" 877 }` 878 879 testJSONMarshal(t, r, want) 880 } 881 882 func TestCommitStats_Marshal(t *testing.T) { 883 t.Parallel() 884 testJSONMarshal(t, &CommitStats{}, "{}") 885 886 r := &CommitStats{ 887 Additions: Ptr(1), 888 Deletions: Ptr(1), 889 Total: Ptr(1), 890 } 891 892 want := `{ 893 "additions": 1, 894 "deletions": 1, 895 "total": 1 896 }` 897 898 testJSONMarshal(t, r, want) 899 } 900 901 func TestRepositoryCommit_Marshal(t *testing.T) { 902 t.Parallel() 903 testJSONMarshal(t, &RepositoryCommit{}, "{}") 904 905 r := &RepositoryCommit{ 906 NodeID: Ptr("nid"), 907 SHA: Ptr("sha"), 908 Commit: &Commit{ 909 Message: Ptr("m"), 910 }, 911 Author: &User{ 912 Login: Ptr("l"), 913 }, 914 Committer: &User{ 915 Login: Ptr("l"), 916 }, 917 Parents: []*Commit{ 918 { 919 SHA: Ptr("s"), 920 }, 921 }, 922 HTMLURL: Ptr("hurl"), 923 URL: Ptr("url"), 924 CommentsURL: Ptr("curl"), 925 Stats: &CommitStats{ 926 Additions: Ptr(104), 927 Deletions: Ptr(4), 928 Total: Ptr(108), 929 }, 930 Files: []*CommitFile{ 931 { 932 Filename: Ptr("f"), 933 Additions: Ptr(10), 934 Deletions: Ptr(2), 935 Changes: Ptr(12), 936 Status: Ptr("s"), 937 Patch: Ptr("p"), 938 BlobURL: Ptr("b"), 939 RawURL: Ptr("r"), 940 ContentsURL: Ptr("c"), 941 }, 942 }, 943 } 944 945 want := `{ 946 "node_id": "nid", 947 "sha": "sha", 948 "commit": { 949 "message": "m" 950 }, 951 "author": { 952 "login": "l" 953 }, 954 "committer": { 955 "login": "l" 956 }, 957 "parents": [ 958 { 959 "sha": "s" 960 } 961 ], 962 "html_url": "hurl", 963 "url": "url", 964 "comments_url": "curl", 965 "stats": { 966 "additions": 104, 967 "deletions": 4, 968 "total": 108 969 }, 970 "files": [ 971 { 972 "filename": "f", 973 "additions": 10, 974 "deletions": 2, 975 "changes": 12, 976 "status": "s", 977 "patch": "p", 978 "blob_url": "b", 979 "raw_url": "r", 980 "contents_url": "c" 981 } 982 ] 983 }` 984 985 testJSONMarshal(t, r, want) 986 }