Skip to content

Commit 7fa5b0f

Browse files
BREAKING CHANGE: Use long type for reading PunchCard statistics, just in case (#2949)
* Use long type for PunchCard statistics in case just in case there are some really big counts * Fixes for public API surface and unit tests --------- Co-authored-by: Nick Floyd <[email protected]>
1 parent ffd1b40 commit 7fa5b0f

5 files changed

Lines changed: 58 additions & 20 deletions

File tree

Octokit.Tests/Clients/StatisticsClientTests.cs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,8 @@ public async Task RequestsCorrectUrl()
417417
var expectedEndPoint = new Uri("repos/owner/name/stats/punch_card", UriKind.Relative);
418418

419419
var client = Substitute.For<IApiConnection>();
420-
IReadOnlyList<int[]> data = new ReadOnlyCollection<int[]>(new[] { new[] { 2, 8, 42 } });
421-
client.GetQueuedOperation<int[]>(expectedEndPoint, Args.CancellationToken)
420+
IReadOnlyList<long[]> data = new ReadOnlyCollection<long[]>(new[] { new[] { 2L, 8, 42 } });
421+
client.GetQueuedOperation<long[]>(expectedEndPoint, Args.CancellationToken)
422422
.Returns(Task.FromResult(data));
423423
var statisticsClient = new StatisticsClient(client);
424424

@@ -436,8 +436,8 @@ public async Task RequestsCorrectUrlWithRepositoryId()
436436
var expectedEndPoint = new Uri("repositories/1/stats/punch_card", UriKind.Relative);
437437

438438
var client = Substitute.For<IApiConnection>();
439-
IReadOnlyList<int[]> data = new ReadOnlyCollection<int[]>(new[] { new[] { 2, 8, 42 } });
440-
client.GetQueuedOperation<int[]>(expectedEndPoint, Args.CancellationToken)
439+
IReadOnlyList<long[]> data = new ReadOnlyCollection<long[]>(new[] { new[] { 2L, 8, 42 } });
440+
client.GetQueuedOperation<long[]>(expectedEndPoint, Args.CancellationToken)
441441
.Returns(Task.FromResult(data));
442442
var statisticsClient = new StatisticsClient(client);
443443

@@ -456,9 +456,9 @@ public async Task RequestsCorrectUrlWithCancellationToken()
456456
var cancellationToken = new CancellationToken();
457457

458458
var connection = Substitute.For<IApiConnection>();
459-
IReadOnlyList<int[]> data = new ReadOnlyCollection<int[]>(new[] { new[] { 2, 8, 42 } });
459+
IReadOnlyList<long[]> data = new ReadOnlyCollection<long[]>(new[] { new[] { 2L, 8, 42 } });
460460

461-
connection.GetQueuedOperation<int[]>(expectedEndPoint, cancellationToken)
461+
connection.GetQueuedOperation<long[]>(expectedEndPoint, cancellationToken)
462462
.Returns(Task.FromResult(data));
463463
var client = new StatisticsClient(connection);
464464

@@ -477,9 +477,9 @@ public async Task RequestsCorrectUrlWithRepositoryIdWithCancellationToken()
477477
var cancellationToken = new CancellationToken();
478478

479479
var connection = Substitute.For<IApiConnection>();
480-
IReadOnlyList<int[]> data = new ReadOnlyCollection<int[]>(new[] { new[] { 2, 8, 42 } });
480+
IReadOnlyList<long[]> data = new ReadOnlyCollection<long[]>(new[] { new[] { 2L, 8, 42 } });
481481

482-
connection.GetQueuedOperation<int[]>(expectedEndPoint, cancellationToken)
482+
connection.GetQueuedOperation<long[]>(expectedEndPoint, cancellationToken)
483483
.Returns(Task.FromResult(data));
484484
var client = new StatisticsClient(connection);
485485

@@ -503,5 +503,24 @@ public async Task EnsureNonNullArguments()
503503
await Assert.ThrowsAsync<ArgumentException>(() => client.GetPunchCard("owner", ""));
504504
}
505505
}
506+
507+
[Fact]
508+
public async Task HandlesGreatBigCountsIfGetQueuedOperationTemplateParameterIsLong()
509+
{
510+
var expectedEndPoint = new Uri("repos/owner/name/stats/punch_card", UriKind.Relative);
511+
512+
var client = Substitute.For<IApiConnection>();
513+
IReadOnlyList<long[]> data = new ReadOnlyCollection<long[]>(new [] { new [] { 2L, 8L, 42424242424242L } });
514+
client.GetQueuedOperation<long[]>(expectedEndPoint, Args.CancellationToken)
515+
.Returns(Task.FromResult(data));
516+
var statisticsClient = new StatisticsClient(client);
517+
518+
var result = await statisticsClient.GetPunchCard("owner", "name");
519+
520+
Assert.Single(result.PunchPoints);
521+
Assert.Equal(DayOfWeek.Tuesday, result.PunchPoints[0].DayOfWeek);
522+
Assert.Equal(8, result.PunchPoints[0].HourOfTheDay);
523+
Assert.Equal(42424242424242L, result.PunchPoints[0].CommitCount);
524+
}
506525
}
507526
}

Octokit.Tests/Models/PunchCardTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ public void DoesNotThrowExceptionWhenPunchPointsHaveCorrectFormat()
3333
[Fact]
3434
public void CanQueryCommitsForDayAndHour()
3535
{
36-
IList<int> point1 = new[] { 1, 0, 3 };
37-
IList<int> point2 = new[] { 1, 1, 4 };
38-
IList<int> point3 = new[] { 1, 2, 0 };
39-
IEnumerable<IList<int>> points = new List<IList<int>> { point1, point2, point3 };
36+
IList<long> point1 = new long[] { 1, 0, 3 };
37+
IList<long> point2 = new long[] { 1, 1, 4 };
38+
IList<long> point3 = new long[] { 1, 2, 0 };
39+
IEnumerable<IList<long>> points = new List<IList<long>> { point1, point2, point3 };
4040

4141
var punchCard = new PunchCard(points);
4242

@@ -54,10 +54,10 @@ public void CanQueryCommitsForDayAndHour()
5454
[Fact]
5555
public void SetsPunchPointsAsReadOnlyDictionary()
5656
{
57-
IList<int> point1 = new[] { 1, 0, 3 };
58-
IList<int> point2 = new[] { 1, 1, 4 };
59-
IList<int> point3 = new[] { 1, 2, 0 };
60-
IEnumerable<IList<int>> points = new List<IList<int>> { point1, point2, point3 };
57+
IList<long> point1 = new long[] { 1, 0, 3 };
58+
IList<long> point2 = new long[] { 1, 1, 4 };
59+
IList<long> point3 = new long[] { 1, 2, 0 };
60+
IEnumerable<IList<long>> points = new List<IList<long>> { point1, point2, point3 };
6161

6262
var punchCard = new PunchCard(points);
6363

Octokit/Clients/StatisticsClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public async Task<PunchCard> GetPunchCard(string owner, string name, Cancellatio
265265
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
266266
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
267267

268-
var punchCardData = await ApiConnection.GetQueuedOperation<int[]>(ApiUrls.StatsPunchCard(owner, name), cancellationToken).ConfigureAwait(false);
268+
var punchCardData = await ApiConnection.GetQueuedOperation<long[]>(ApiUrls.StatsPunchCard(owner, name), cancellationToken).ConfigureAwait(false);
269269
return new PunchCard(punchCardData);
270270
}
271271

@@ -277,7 +277,7 @@ public async Task<PunchCard> GetPunchCard(string owner, string name, Cancellatio
277277
[ManualRoute("GET", "/repositories/{id}/stats/punch_card")]
278278
public async Task<PunchCard> GetPunchCard(long repositoryId, CancellationToken cancellationToken)
279279
{
280-
var punchCardData = await ApiConnection.GetQueuedOperation<int[]>(ApiUrls.StatsPunchCard(repositoryId), cancellationToken).ConfigureAwait(false);
280+
var punchCardData = await ApiConnection.GetQueuedOperation<long[]>(ApiUrls.StatsPunchCard(repositoryId), cancellationToken).ConfigureAwait(false);
281281
return new PunchCard(punchCardData);
282282
}
283283
}

Octokit/Models/Response/PunchCard.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ public PunchCard(IEnumerable<IList<int>> punchCardData)
1919
punchCardData.Select(point => new PunchCardPoint(point)).ToList());
2020
}
2121

22+
public PunchCard(IEnumerable<IList<long>> punchCardData)
23+
{
24+
Ensure.ArgumentNotNull(punchCardData, nameof(punchCardData));
25+
PunchPoints = new ReadOnlyCollection<PunchCardPoint>(
26+
punchCardData.Select(point => new PunchCardPoint(point)).ToList());
27+
}
28+
2229
public PunchCard(IEnumerable<PunchCardPoint> punchPoints)
2330
{
2431
PunchPoints = punchPoints?.ToList();
@@ -36,7 +43,7 @@ public PunchCard(IEnumerable<PunchCardPoint> punchPoints)
3643
/// <param name="dayOfWeek">The day of the week to query</param>
3744
/// <param name="hourOfDay">The hour in 24 hour time. 0-23.</param>
3845
/// <returns>The total number of commits made.</returns>
39-
public int GetCommitCountFor(DayOfWeek dayOfWeek, int hourOfDay)
46+
public long GetCommitCountFor(DayOfWeek dayOfWeek, int hourOfDay)
4047
{
4148
var punchPoint = PunchPoints.SingleOrDefault(point => point.DayOfWeek == dayOfWeek && point.HourOfTheDay == hourOfDay);
4249
return punchPoint == null ? 0 : punchPoint.CommitCount;

Octokit/Models/Response/PunchCardPoint.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ public PunchCardPoint(IList<int> punchPoint)
2222
CommitCount = punchPoint[2];
2323
}
2424

25+
public PunchCardPoint(IList<long> punchPoint)
26+
{
27+
Ensure.ArgumentNotNull(punchPoint, nameof(punchPoint));
28+
if (punchPoint.Count != 3)
29+
{
30+
throw new ArgumentException("Daily punch card must only contain three data points.");
31+
}
32+
DayOfWeek = (DayOfWeek)punchPoint[0];
33+
HourOfTheDay = (int)punchPoint[1];
34+
CommitCount = punchPoint[2];
35+
}
36+
2537
public PunchCardPoint(DayOfWeek dayOfWeek, int hourOfTheDay, int commitCount)
2638
{
2739
DayOfWeek = dayOfWeek;
@@ -31,7 +43,7 @@ public PunchCardPoint(DayOfWeek dayOfWeek, int hourOfTheDay, int commitCount)
3143

3244
public StringEnum<DayOfWeek> DayOfWeek { get; private set; }
3345
public int HourOfTheDay { get; private set; }
34-
public int CommitCount { get; private set; }
46+
public long CommitCount { get; private set; }
3547

3648
internal string DebuggerDisplay
3749
{

0 commit comments

Comments
 (0)