diff --git a/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs b/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs index 4b1f7357..523d9f72 100644 --- a/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs +++ b/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs @@ -73,12 +73,13 @@ namespace Octokit.Tests.Integration.Clients } [IntegrationTest] - public async Task CanGetCommitPerHourPerDay() + public async Task CanGetPunchCardForRepository() { var repository = await CreateRepository(); await CommitToRepository(repository); - var hourlyCommits = await _client.Statistics.GetCommitPerHour(repository.Owner, repository.Name); - Assert.NotNull(hourlyCommits); + var punchCard = await _client.Statistics.GetPunchCard(repository.Owner, repository.Name); + Assert.NotNull(punchCard); + Assert.NotNull(punchCard.PunchPoints); } async Task CreateRepository() diff --git a/Octokit.Tests/Clients/StatisticsClientTests.cs b/Octokit.Tests/Clients/StatisticsClientTests.cs index 2f80fbcf..388ae75b 100644 --- a/Octokit.Tests/Clients/StatisticsClientTests.cs +++ b/Octokit.Tests/Clients/StatisticsClientTests.cs @@ -148,7 +148,7 @@ namespace Octokit.Tests.Clients var client = Substitute.For(); var statisticsClient = new StatisticsClient(client); - statisticsClient.GetCommitPerHour("username", "repositoryName"); + statisticsClient.GetPunchCard("username", "repositoryName"); client.Received().GetQueuedOperation>(expectedEndPoint, Args.CancellationToken); } @@ -157,14 +157,14 @@ namespace Octokit.Tests.Clients public async Task ThrowsIfGivenNullOwner() { var statisticsClient = new StatisticsClient(Substitute.For()); - await AssertEx.Throws(() => statisticsClient.GetCommitPerHour(null, "repositoryName")); + await AssertEx.Throws(() => statisticsClient.GetPunchCard(null, "repositoryName")); } [Fact] public async Task ThrowsIfGivenNullRepositoryName() { var statisticsClient = new StatisticsClient(Substitute.For()); - await AssertEx.Throws(() => statisticsClient.GetCommitPerHour("owner", null)); + await AssertEx.Throws(() => statisticsClient.GetPunchCard("owner", null)); } } } diff --git a/Octokit.Tests/Models/PunchCardTests.cs b/Octokit.Tests/Models/PunchCardTests.cs new file mode 100644 index 00000000..c46baf0e --- /dev/null +++ b/Octokit.Tests/Models/PunchCardTests.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Octokit.Response; +using Xunit; + +namespace Octokit.Tests.Models +{ + public class PunchCardTests + { + [Fact] + public void ThrowsExceptionWithNullPunchCardPoints() + { + Assert.Throws(()=>new PunchCard(null)); + } + + [Fact] + public void ThrowsExceptionWhenPunchCardPointsHaveIncorrectFormat() + { + IList point1 = new []{1,2,3,4,5,6}; + IEnumerable> points = new List>{point1}; + Assert.Throws(() => new PunchCard(points)); + } + + [Fact] + public void DoesNotThrowExceptionWhenPunchPointsHaveCorrectFormat() + { + IList point1 = new[] { 1, 2, 3}; + IEnumerable> points = new List> { point1 }; + Assert.DoesNotThrow(() => new PunchCard(points)); + } + + [Fact] + public void CanQueryCommitsForDayAndHour() + { + IList point1 = new[] { 1, 0, 3 }; + IList point2 = new[] { 1, 1, 4 }; + IList point3 = new[] { 1, 2, 0 }; + IEnumerable> points = new List> { point1,point2,point3 }; + + var punchCard = new PunchCard(points); + + var commitsAtMondayAt12Am = punchCard.GetCommitCountFor(DayOfWeek.Monday, 0); + var commitsAtMondayAt1Am = punchCard.GetCommitCountFor(DayOfWeek.Monday, 1); + var commitsAtMondayAt2Am = punchCard.GetCommitCountFor(DayOfWeek.Monday, 2); + var commitsAtTuesdayAt2Am = punchCard.GetCommitCountFor(DayOfWeek.Tuesday, 2); + + Assert.Equal(3,commitsAtMondayAt12Am); + Assert.Equal(4, commitsAtMondayAt1Am); + Assert.Equal(0, commitsAtMondayAt2Am); + Assert.Equal(0, commitsAtTuesdayAt2Am); + } + } +} diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index e93b79b9..e6c24604 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -127,6 +127,7 @@ + diff --git a/Octokit/Clients/IStatisticsClient.cs b/Octokit/Clients/IStatisticsClient.cs index 41de2ff4..5534f837 100644 --- a/Octokit/Clients/IStatisticsClient.cs +++ b/Octokit/Clients/IStatisticsClient.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Octokit.Response; namespace Octokit { @@ -80,7 +81,7 @@ namespace Octokit /// The owner of the repository /// The name of the repository /// Returns commit counts per hour in each day - Task> GetCommitPerHour(string owner, string repositoryName); + Task GetPunchCard(string owner, string repositoryName); /// /// Returns a list of the number of commits per hour in each day @@ -89,6 +90,6 @@ namespace Octokit /// The name of the repository /// A token used to cancel this potentially long running request /// Returns commit counts per hour in each day - Task> GetCommitPerHour(string owner, string repositoryName, CancellationToken cancellationToken); + Task GetPunchCard(string owner, string repositoryName, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/Octokit/Clients/StatisticsClient.cs b/Octokit/Clients/StatisticsClient.cs index 7ea3b978..49651ca2 100644 --- a/Octokit/Clients/StatisticsClient.cs +++ b/Octokit/Clients/StatisticsClient.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Octokit.Response; namespace Octokit { @@ -128,9 +129,9 @@ namespace Octokit /// The owner of the repository /// The name of the repository /// Returns commit counts per hour in each day - public Task> GetCommitPerHour(string owner, string repositoryName) + public Task GetPunchCard(string owner, string repositoryName) { - return GetCommitPerHour(owner, repositoryName,CancellationToken.None); + return GetPunchCard(owner, repositoryName,CancellationToken.None); } /// @@ -140,13 +141,14 @@ namespace Octokit /// The name of the repository /// A token used to cancel this potentially long running request /// Returns commit counts per hour in each day - public async Task> GetCommitPerHour(string owner, string repositoryName, CancellationToken cancellationToken) + public async Task GetPunchCard(string owner, string repositoryName, CancellationToken cancellationToken) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(repositoryName, "repositoryName"); var endpoint = "/repos/{0}/{1}/stats/punch_card".FormatUri(owner, repositoryName); - return await ApiConnection.GetQueuedOperation>(endpoint, cancellationToken); + var punchCardData = await ApiConnection.GetQueuedOperation>(endpoint, cancellationToken); + return new PunchCard(punchCardData); } } } \ No newline at end of file diff --git a/Octokit/Models/Response/PunchCard.cs b/Octokit/Models/Response/PunchCard.cs new file mode 100644 index 00000000..f48a7e27 --- /dev/null +++ b/Octokit/Models/Response/PunchCard.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Octokit.Response +{ + public class PunchCard + { + public PunchCard(IEnumerable> punchCardData) + { + Ensure.ArgumentNotNull(punchCardData, "punchCardData"); + PunchPoints = punchCardData.Select(point => new PunchCardPoint(point)).ToList(); + } + + /// + /// The raw punch card points + /// + public IReadOnlyCollection PunchPoints { get; private set; } + + /// + /// Gets the number of commits made on the specified day of the week + /// at the hour of the day, over the lifetime of this repository + /// + /// The day of the week to query + /// The hour in 24 hour time. 0-23. + /// The total number of commits made. + public int GetCommitCountFor(DayOfWeek dayOfWeek, int hourOfDay) + { + var punchPoint = PunchPoints.SingleOrDefault(point => point.DayOfWeek == dayOfWeek && point.HourOfTheDay == hourOfDay); + return punchPoint == null ? 0 : punchPoint.CommitCount; + } + } +} \ No newline at end of file diff --git a/Octokit/Models/Response/PunchCardPoint.cs b/Octokit/Models/Response/PunchCardPoint.cs new file mode 100644 index 00000000..9668db96 --- /dev/null +++ b/Octokit/Models/Response/PunchCardPoint.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace Octokit.Response +{ + public class PunchCardPoint + { + public PunchCardPoint(IList punchPoint) + { + Ensure.ArgumentNotNull(punchPoint, "punchPoint"); + if (punchPoint.Count != 3) + { + throw new ArgumentException("Daily punch card must only contain three data points."); + } + DayOfWeek = (DayOfWeek)punchPoint[0]; + HourOfTheDay = punchPoint[1]; + CommitCount = punchPoint[2]; + } + + public DayOfWeek DayOfWeek { get; private set; } + public int HourOfTheDay { get; private set; } + public int CommitCount { get; private set; } + } +} \ No newline at end of file diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index 5f91ce4b..e5a2b777 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -273,6 +273,8 @@ + + \ No newline at end of file diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index 124baf6b..eaf3fad6 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -283,6 +283,8 @@ + + \ No newline at end of file diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index d4bda2a6..2dc53bcb 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -278,6 +278,8 @@ + + \ No newline at end of file diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 87c2b277..246c419f 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -271,6 +271,8 @@ + + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index cddd0e09..edb86ebb 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -126,6 +126,8 @@ + +