github.com/google/go-github/v74@v74.0.0/github/repos_stats_test.go (about)

     1  // Copyright 2014 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  	"testing"
    13  	"time"
    14  
    15  	"github.com/google/go-cmp/cmp"
    16  )
    17  
    18  func TestRepositoriesService_ListContributorsStats(t *testing.T) {
    19  	t.Parallel()
    20  	client, mux, _ := setup(t)
    21  
    22  	mux.HandleFunc("/repos/o/r/stats/contributors", func(w http.ResponseWriter, r *http.Request) {
    23  		testMethod(t, r, "GET")
    24  
    25  		fmt.Fprint(w, `
    26  [
    27    {
    28      "author": {
    29  			"id": 1,
    30  			"node_id": "nodeid-1"
    31      },
    32      "total": 135,
    33      "weeks": [
    34        {
    35          "w": 1367712000,
    36          "a": 6898,
    37          "d": 77,
    38          "c": 10
    39        }
    40      ]
    41    }
    42  ]
    43  `)
    44  	})
    45  
    46  	ctx := context.Background()
    47  	stats, _, err := client.Repositories.ListContributorsStats(ctx, "o", "r")
    48  	if err != nil {
    49  		t.Errorf("RepositoriesService.ListContributorsStats returned error: %v", err)
    50  	}
    51  
    52  	want := []*ContributorStats{
    53  		{
    54  			Author: &Contributor{
    55  				ID:     Ptr(int64(1)),
    56  				NodeID: Ptr("nodeid-1"),
    57  			},
    58  			Total: Ptr(135),
    59  			Weeks: []*WeeklyStats{
    60  				{
    61  					Week:      &Timestamp{time.Date(2013, time.May, 05, 00, 00, 00, 0, time.UTC).Local()},
    62  					Additions: Ptr(6898),
    63  					Deletions: Ptr(77),
    64  					Commits:   Ptr(10),
    65  				},
    66  			},
    67  		},
    68  	}
    69  
    70  	if !cmp.Equal(stats, want) {
    71  		t.Errorf("RepositoriesService.ListContributorsStats returned %+v, want %+v", stats, want)
    72  	}
    73  
    74  	const methodName = "ListContributorsStats"
    75  	testBadOptions(t, methodName, func() (err error) {
    76  		_, _, err = client.Repositories.ListContributorsStats(ctx, "\n", "\n")
    77  		return err
    78  	})
    79  
    80  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    81  		got, resp, err := client.Repositories.ListContributorsStats(ctx, "o", "r")
    82  		if got != nil {
    83  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    84  		}
    85  		return resp, err
    86  	})
    87  }
    88  
    89  func TestRepositoriesService_ListCommitActivity(t *testing.T) {
    90  	t.Parallel()
    91  	client, mux, _ := setup(t)
    92  
    93  	mux.HandleFunc("/repos/o/r/stats/commit_activity", func(w http.ResponseWriter, r *http.Request) {
    94  		testMethod(t, r, "GET")
    95  
    96  		fmt.Fprint(w, `
    97  [
    98    {
    99      "days": [0, 3, 26, 20, 39, 1, 0],
   100      "total": 89,
   101      "week": 1336280400
   102    }
   103  ]
   104  `)
   105  	})
   106  
   107  	ctx := context.Background()
   108  	activity, _, err := client.Repositories.ListCommitActivity(ctx, "o", "r")
   109  	if err != nil {
   110  		t.Errorf("RepositoriesService.ListCommitActivity returned error: %v", err)
   111  	}
   112  
   113  	want := []*WeeklyCommitActivity{
   114  		{
   115  			Days:  []int{0, 3, 26, 20, 39, 1, 0},
   116  			Total: Ptr(89),
   117  			Week:  &Timestamp{time.Date(2012, time.May, 06, 05, 00, 00, 0, time.UTC).Local()},
   118  		},
   119  	}
   120  
   121  	if !cmp.Equal(activity, want) {
   122  		t.Errorf("RepositoriesService.ListCommitActivity returned %+v, want %+v", activity, want)
   123  	}
   124  
   125  	const methodName = "ListCommitActivity"
   126  	testBadOptions(t, methodName, func() (err error) {
   127  		_, _, err = client.Repositories.ListCommitActivity(ctx, "\n", "\n")
   128  		return err
   129  	})
   130  
   131  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   132  		got, resp, err := client.Repositories.ListCommitActivity(ctx, "o", "r")
   133  		if got != nil {
   134  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   135  		}
   136  		return resp, err
   137  	})
   138  }
   139  
   140  func TestRepositoriesService_ListCodeFrequency(t *testing.T) {
   141  	t.Parallel()
   142  	client, mux, _ := setup(t)
   143  
   144  	mux.HandleFunc("/repos/o/r/stats/code_frequency", func(w http.ResponseWriter, r *http.Request) {
   145  		testMethod(t, r, "GET")
   146  
   147  		fmt.Fprint(w, `[[1302998400, 1124, -435]]`)
   148  	})
   149  
   150  	ctx := context.Background()
   151  	code, _, err := client.Repositories.ListCodeFrequency(ctx, "o", "r")
   152  	if err != nil {
   153  		t.Errorf("RepositoriesService.ListCodeFrequency returned error: %v", err)
   154  	}
   155  
   156  	want := []*WeeklyStats{{
   157  		Week:      &Timestamp{time.Date(2011, time.April, 17, 00, 00, 00, 0, time.UTC).Local()},
   158  		Additions: Ptr(1124),
   159  		Deletions: Ptr(-435),
   160  	}}
   161  
   162  	if !cmp.Equal(code, want) {
   163  		t.Errorf("RepositoriesService.ListCodeFrequency returned %+v, want %+v", code, want)
   164  	}
   165  
   166  	const methodName = "ListCodeFrequency"
   167  	testBadOptions(t, methodName, func() (err error) {
   168  		_, _, err = client.Repositories.ListCodeFrequency(ctx, "\n", "\n")
   169  		return err
   170  	})
   171  
   172  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   173  		got, resp, err := client.Repositories.ListCodeFrequency(ctx, "o", "r")
   174  		if got != nil {
   175  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   176  		}
   177  		return resp, err
   178  	})
   179  }
   180  
   181  func TestRepositoriesService_Participation(t *testing.T) {
   182  	t.Parallel()
   183  	client, mux, _ := setup(t)
   184  
   185  	mux.HandleFunc("/repos/o/r/stats/participation", func(w http.ResponseWriter, r *http.Request) {
   186  		testMethod(t, r, "GET")
   187  
   188  		fmt.Fprint(w, `
   189  {
   190    "all": [
   191      11,21,15,2,8,1,8,23,17,21,11,10,33,
   192      91,38,34,22,23,32,3,43,87,71,18,13,5,
   193      13,16,66,27,12,45,110,117,13,8,18,9,19,
   194      26,39,12,20,31,46,91,45,10,24,9,29,7
   195    ],
   196    "owner": [
   197      3,2,3,0,2,0,5,14,7,9,1,5,0,
   198      48,19,2,0,1,10,2,23,40,35,8,8,2,
   199      10,6,30,0,2,9,53,104,3,3,10,4,7,
   200      11,21,4,4,22,26,63,11,2,14,1,10,3
   201    ]
   202  }
   203  `)
   204  	})
   205  
   206  	ctx := context.Background()
   207  	participation, _, err := client.Repositories.ListParticipation(ctx, "o", "r")
   208  	if err != nil {
   209  		t.Errorf("RepositoriesService.ListParticipation returned error: %v", err)
   210  	}
   211  
   212  	want := &RepositoryParticipation{
   213  		All: []int{
   214  			11, 21, 15, 2, 8, 1, 8, 23, 17, 21, 11, 10, 33,
   215  			91, 38, 34, 22, 23, 32, 3, 43, 87, 71, 18, 13, 5,
   216  			13, 16, 66, 27, 12, 45, 110, 117, 13, 8, 18, 9, 19,
   217  			26, 39, 12, 20, 31, 46, 91, 45, 10, 24, 9, 29, 7,
   218  		},
   219  		Owner: []int{
   220  			3, 2, 3, 0, 2, 0, 5, 14, 7, 9, 1, 5, 0,
   221  			48, 19, 2, 0, 1, 10, 2, 23, 40, 35, 8, 8, 2,
   222  			10, 6, 30, 0, 2, 9, 53, 104, 3, 3, 10, 4, 7,
   223  			11, 21, 4, 4, 22, 26, 63, 11, 2, 14, 1, 10, 3,
   224  		},
   225  	}
   226  
   227  	if !cmp.Equal(participation, want) {
   228  		t.Errorf("RepositoriesService.ListParticipation returned %+v, want %+v", participation, want)
   229  	}
   230  
   231  	const methodName = "ListParticipation"
   232  	testBadOptions(t, methodName, func() (err error) {
   233  		_, _, err = client.Repositories.ListParticipation(ctx, "\n", "\n")
   234  		return err
   235  	})
   236  
   237  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   238  		got, resp, err := client.Repositories.ListParticipation(ctx, "o", "r")
   239  		if got != nil {
   240  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   241  		}
   242  		return resp, err
   243  	})
   244  }
   245  
   246  func TestRepositoriesService_ListPunchCard(t *testing.T) {
   247  	t.Parallel()
   248  	client, mux, _ := setup(t)
   249  
   250  	mux.HandleFunc("/repos/o/r/stats/punch_card", func(w http.ResponseWriter, r *http.Request) {
   251  		testMethod(t, r, "GET")
   252  
   253  		fmt.Fprint(w, `[
   254  		  [0, 0, 5],
   255  		  [0, 1, 43],
   256  		  [0, 2, 21]
   257  		]`)
   258  	})
   259  
   260  	ctx := context.Background()
   261  	card, _, err := client.Repositories.ListPunchCard(ctx, "o", "r")
   262  	if err != nil {
   263  		t.Errorf("RepositoriesService.ListPunchCard returned error: %v", err)
   264  	}
   265  
   266  	want := []*PunchCard{
   267  		{Day: Ptr(0), Hour: Ptr(0), Commits: Ptr(5)},
   268  		{Day: Ptr(0), Hour: Ptr(1), Commits: Ptr(43)},
   269  		{Day: Ptr(0), Hour: Ptr(2), Commits: Ptr(21)},
   270  	}
   271  
   272  	if !cmp.Equal(card, want) {
   273  		t.Errorf("RepositoriesService.ListPunchCard returned %+v, want %+v", card, want)
   274  	}
   275  
   276  	const methodName = "ListPunchCard"
   277  	testBadOptions(t, methodName, func() (err error) {
   278  		_, _, err = client.Repositories.ListPunchCard(ctx, "\n", "\n")
   279  		return err
   280  	})
   281  
   282  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   283  		got, resp, err := client.Repositories.ListPunchCard(ctx, "o", "r")
   284  		if got != nil {
   285  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   286  		}
   287  		return resp, err
   288  	})
   289  }
   290  
   291  func TestRepositoriesService_AcceptedError(t *testing.T) {
   292  	t.Parallel()
   293  	client, mux, _ := setup(t)
   294  
   295  	mux.HandleFunc("/repos/o/r/stats/contributors", func(w http.ResponseWriter, r *http.Request) {
   296  		testMethod(t, r, "GET")
   297  		// This response indicates the fork will happen asynchronously.
   298  		w.WriteHeader(http.StatusAccepted)
   299  		fmt.Fprint(w, `{"id":1}`)
   300  	})
   301  
   302  	ctx := context.Background()
   303  	stats, _, err := client.Repositories.ListContributorsStats(ctx, "o", "r")
   304  	if err == nil {
   305  		t.Error("RepositoriesService.AcceptedError should have returned an error")
   306  	}
   307  
   308  	if _, ok := err.(*AcceptedError); !ok {
   309  		t.Errorf("RepositoriesService.AcceptedError returned an AcceptedError: %v", err)
   310  	}
   311  
   312  	if stats != nil {
   313  		t.Errorf("RepositoriesService.AcceptedError expected stats to be nil: %v", stats)
   314  	}
   315  
   316  	const methodName = "ListContributorsStats"
   317  	testBadOptions(t, methodName, func() (err error) {
   318  		_, _, err = client.Repositories.ListContributorsStats(ctx, "o", "r")
   319  		return err
   320  	})
   321  
   322  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   323  		got, resp, err := client.Repositories.ListContributorsStats(ctx, "o", "r")
   324  		if got != nil {
   325  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   326  		}
   327  		return resp, err
   328  	})
   329  }
   330  
   331  func TestRepositoryParticipation_Marshal(t *testing.T) {
   332  	t.Parallel()
   333  	testJSONMarshal(t, &RepositoryParticipation{}, "{}")
   334  
   335  	u := &RepositoryParticipation{
   336  		All:   []int{1},
   337  		Owner: []int{1},
   338  	}
   339  
   340  	want := `{
   341  		"all": [1],
   342  		"owner": [1]
   343  	}`
   344  
   345  	testJSONMarshal(t, u, want)
   346  }
   347  
   348  func TestWeeklyCommitActivity_Marshal(t *testing.T) {
   349  	t.Parallel()
   350  	testJSONMarshal(t, &WeeklyCommitActivity{}, "{}")
   351  
   352  	u := &WeeklyCommitActivity{
   353  		Days:  []int{1},
   354  		Total: Ptr(1),
   355  		Week:  &Timestamp{referenceTime},
   356  	}
   357  
   358  	want := `{
   359  		"days": [
   360  			1
   361  		],
   362  		"total": 1,
   363  		"week": ` + referenceTimeStr + `
   364  	}`
   365  
   366  	testJSONMarshal(t, u, want)
   367  }
   368  
   369  func TestWeeklyStats_Marshal(t *testing.T) {
   370  	t.Parallel()
   371  	testJSONMarshal(t, &WeeklyStats{}, "{}")
   372  
   373  	u := &WeeklyStats{
   374  		Week:      &Timestamp{referenceTime},
   375  		Additions: Ptr(1),
   376  		Deletions: Ptr(1),
   377  		Commits:   Ptr(1),
   378  	}
   379  
   380  	want := `{
   381  		"w": ` + referenceTimeStr + `,
   382  		"a": 1,
   383  		"d": 1,
   384  		"c": 1
   385  	}`
   386  
   387  	testJSONMarshal(t, u, want)
   388  }
   389  
   390  func TestContributorStats_Marshal(t *testing.T) {
   391  	t.Parallel()
   392  	testJSONMarshal(t, &ContributorStats{}, "{}")
   393  
   394  	u := &ContributorStats{
   395  		Author: &Contributor{ID: Ptr(int64(1))},
   396  		Total:  Ptr(1),
   397  		Weeks: []*WeeklyStats{
   398  			{
   399  				Week:      &Timestamp{referenceTime},
   400  				Additions: Ptr(1),
   401  				Deletions: Ptr(1),
   402  				Commits:   Ptr(1),
   403  			},
   404  		},
   405  	}
   406  
   407  	want := `{
   408  		"author": {
   409  			"id": 1
   410  		},
   411  		"total": 1,
   412  		"weeks": [
   413  			{
   414  				"w": ` + referenceTimeStr + `,
   415  				"a": 1,
   416  				"d": 1,
   417  				"c": 1
   418  			}
   419  		]
   420  	}`
   421  
   422  	testJSONMarshal(t, u, want)
   423  }