From 73c0a524858f858280089e60e67829d127074563 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 5 Oct 2018 22:38:06 +0200 Subject: [PATCH 01/36] Build with Cake 0.30.0 --- tools/packages.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/packages.config b/tools/packages.config index 3dec7f976..84d0eb467 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,4 +1,4 @@ - - \ No newline at end of file + + From 0af705f4f5f3f092fe8034a857fa9af2c82d3965 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 22 Oct 2018 00:25:44 +0200 Subject: [PATCH 02/36] Use jsDelivr for icon url --- nuspec/nuget/Cake.Issues.Testing.nuspec | 2 +- nuspec/nuget/Cake.Issues.nuspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nuspec/nuget/Cake.Issues.Testing.nuspec b/nuspec/nuget/Cake.Issues.Testing.nuspec index 99685b5ce..983c3714e 100644 --- a/nuspec/nuget/Cake.Issues.Testing.nuspec +++ b/nuspec/nuget/Cake.Issues.Testing.nuspec @@ -12,7 +12,7 @@ Common helpers for testing add-ins based on Cake.Issues https://github.com/cake-contrib/Cake.Issues.Testing/blob/develop/LICENSE http://cake-contrib.github.io/Cake.Issues.Website/ - https://cdn.rawgit.com/cake-contrib/graphics/a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png + https://cdn.jsdelivr.net/gh/cake-contrib/graphics@a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png false Copyright © BBT Software AG and contributors diff --git a/nuspec/nuget/Cake.Issues.nuspec b/nuspec/nuget/Cake.Issues.nuspec index a4f6c93a1..0aaff4e15 100644 --- a/nuspec/nuget/Cake.Issues.nuspec +++ b/nuspec/nuget/Cake.Issues.nuspec @@ -19,7 +19,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin https://github.com/cake-contrib/Cake.Issues/blob/develop/LICENSE http://cake-contrib.github.io/Cake.Issues.Website/ - https://cdn.rawgit.com/cake-contrib/graphics/a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png + https://cdn.jsdelivr.net/gh/cake-contrib/graphics@a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png false Copyright © BBT Software AG and contributors From c48b66db2a8f58c327f0e43d7d5950051e4433b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 2 Nov 2018 19:39:31 +0000 Subject: [PATCH 03/36] Bump Microsoft.NET.Test.Sdk from 15.8.0 to 15.9.0 in /src Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 15.8.0 to 15.9.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v15.8.0...v15.9.0) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 53c3f92ad..44580bf5d 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -25,7 +25,7 @@ - + From 7f557c67e9d95e08316feec46c112aef79b75637 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 2 Nov 2018 20:09:28 +0000 Subject: [PATCH 04/36] Bump Shouldly from 3.0.0 to 3.0.1 in /src Bumps [Shouldly](https://github.com/shouldly/shouldly) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/shouldly/shouldly/releases) - [Changelog](https://github.com/shouldly/shouldly/blob/master/BREAKING%20CHANGES.txt) - [Commits](https://github.com/shouldly/shouldly/compare/v3.0.0...v3.0.1) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 44580bf5d..2105438fd 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -28,7 +28,7 @@ - + From 813270c80b7b1e3923262e22e5915537879c9c0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 2 Nov 2018 20:54:47 +0000 Subject: [PATCH 05/36] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.6.1 to 2.6.2 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.6.1 to 2.6.2. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v2.6.1...v2.6.2) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 2 +- src/Cake.Issues/Cake.Issues.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 75bfb9a15..e55b345e7 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index 0df4b27e3..35b6a23cf 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -24,7 +24,7 @@ - + From 55c45e7c8c89cbb82e5a51c56037965429ba226f Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 3 Nov 2018 14:37:25 +0100 Subject: [PATCH 06/36] Update XUnit to 2.4.1 --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 2 +- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index e55b345e7..3d6625cba 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 2105438fd..e99248a0f 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -30,13 +30,8 @@ - - - - - - - + + From 9bbc5a896385f93ca18caeb717ad1100c5a0c59a Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sat, 3 Nov 2018 16:59:32 +0100 Subject: [PATCH 07/36] Add build definition for Azure Pipelines --- azure-pipelines.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..70c37806b --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,10 @@ +queue: + name: Hosted VS2017 + +trigger: +- develop +- master + +steps: +- powershell: ./build.ps1 + displayName: 'Cake Build' \ No newline at end of file From 454b0bfb03bd4bfc56bbbcb60bfbaceed23a3194 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 7 Nov 2018 04:43:49 +0000 Subject: [PATCH 08/36] Bump Shouldly from 3.0.1 to 3.0.2 in /src Bumps [Shouldly](https://github.com/shouldly/shouldly) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/shouldly/shouldly/releases) - [Changelog](https://github.com/shouldly/shouldly/blob/master/BREAKING%20CHANGES.txt) - [Commits](https://github.com/shouldly/shouldly/compare/v3.0.1...v3.0.2) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index e99248a0f..0a467624e 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -28,7 +28,7 @@ - + From c75b3cbcd9c658abf870aecde50a977c56e316b3 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Wed, 14 Nov 2018 17:57:44 +0000 Subject: [PATCH 09/36] Fix name of test case --- src/Cake.Issues.Tests/StringPathExtensionsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.Tests/StringPathExtensionsTests.cs b/src/Cake.Issues.Tests/StringPathExtensionsTests.cs index d1285a9fc..d6e6aeb43 100644 --- a/src/Cake.Issues.Tests/StringPathExtensionsTests.cs +++ b/src/Cake.Issues.Tests/StringPathExtensionsTests.cs @@ -62,7 +62,7 @@ public void Should_Return_True_If_Valid_Path(string path) [Theory] [InlineData("foo\tbar")] - public void Should_Return_False_If_Valid_Path(string path) + public void Should_Return_False_If_Invalid_Path(string path) { // Given / When var result = path.IsValidPath(); From 40c4380dac7abc6599f1738d7c1a7afc958131e1 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Tue, 8 Jan 2019 20:58:31 +0100 Subject: [PATCH 10/36] Build using Cake 0.32.0 --- tools/packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/packages.config b/tools/packages.config index 84d0eb467..2e475d63f 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,4 +1,4 @@ - + From c59bc7d6c0b0f01dd3e5f89fab079554bb17d001 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 11 Jan 2019 04:49:09 +0000 Subject: [PATCH 11/36] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.6.2 to 2.6.3 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.6.2 to 2.6.3. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v2.6.2...v2.6.3) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 2 +- src/Cake.Issues/Cake.Issues.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 3d6625cba..6676fafee 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index 35b6a23cf..bea7272f4 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -24,7 +24,7 @@ - + From 6441524eac2d61d7f00230942074b0b99ee8bcf4 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Sun, 16 Dec 2018 11:24:45 +0100 Subject: [PATCH 12/36] Add badges for Azure DevOps build status --- README.md | 7 ++++--- azure-pipelines.yml | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 28c5d53b2..9d3942cd5 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,10 @@ and for general information about the Cake build automation system see the [Cake ## Build Status -|Develop|Master| -|:--:|:--:| -|[![Build status](https://ci.appveyor.com/api/projects/status/sde2oe3lu4kpmw0r/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/sde2oe3lu4kpmw0r/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues/branch/master)| +| | Develop | Master | +|:--:|:--:|:--:| +|AppVeyor Windows|[![Build status](https://ci.appveyor.com/api/projects/status/sde2oe3lu4kpmw0r/branch/develop?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues/branch/develop)|[![Build status](https://ci.appveyor.com/api/projects/status/sde2oe3lu4kpmw0r/branch/master?svg=true)](https://ci.appveyor.com/project/cakecontrib/cake-issues/branch/master)| +|Azure DevOps Windows|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues/_apis/build/status/cake-contrib.Cake.Issues?branchName=develop&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues/_build/latest?definitionId=2?branchName=develop)|[![Build Status](https://dev.azure.com/cake-contrib/Cake.Issues/_apis/build/status/cake-contrib.Cake.Issues?branchName=master&jobName=Windows)](https://dev.azure.com/cake-contrib/Cake.Issues/_build/latest?definitionId=2?branchName=master)| ## Code Coverage diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 70c37806b..8f395df29 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,10 +1,16 @@ -queue: - name: Hosted VS2017 - trigger: - develop - master +- release/* +- hotfix/* + +pr: +- develop -steps: -- powershell: ./build.ps1 - displayName: 'Cake Build' \ No newline at end of file +jobs: +- job: Windows + pool: + vmImage: 'vs2017-win2016' + steps: + - powershell: ./build.ps1 + displayName: 'Cake Build' \ No newline at end of file From 6b43126cc69f7ba3c80d4c4a7ae722802e0aad0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 1 Mar 2019 05:01:51 +0000 Subject: [PATCH 13/36] Bump Microsoft.NET.Test.Sdk from 15.9.0 to 16.0.0 in /src Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 15.9.0 to 16.0.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/commits) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 0a467624e..0a182853d 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -25,7 +25,7 @@ - + From 68262d0659ae17a92f2da9cd99867c8914cc79ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 4 Mar 2019 17:43:00 +0000 Subject: [PATCH 14/36] Bump Microsoft.NET.Test.Sdk from 16.0.0 to 16.0.1 in /src Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.0.0 to 16.0.1. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/commits) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 0a182853d..90f56bea4 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -25,7 +25,7 @@ - + From 94eb50d0606a5922cb206362572244bddf813ae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Wed, 27 Mar 2019 04:35:12 +0000 Subject: [PATCH 15/36] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.6.3 to 2.9.0 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.6.3 to 2.9.0. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Commits](https://github.com/dotnet/roslyn-analyzers/commits) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 2 +- src/Cake.Issues/Cake.Issues.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 6676fafee..f608dd433 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index bea7272f4..9642ed25f 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -24,7 +24,7 @@ - + From da32d2d6cfaf27988448ad1249ede4cefd9f31cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 29 Mar 2019 04:41:20 +0000 Subject: [PATCH 16/36] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.9.0 to 2.9.1 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.9.0 to 2.9.1. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v2.9.0...v2.9.1) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 2 +- src/Cake.Issues/Cake.Issues.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index f608dd433..6c78fb4da 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index 9642ed25f..7e9fe47f2 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -24,7 +24,7 @@ - + From e97402236277eba56b10a88860633bddff07f851 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 8 Apr 2019 19:27:57 +0200 Subject: [PATCH 17/36] (GH-92) Build against Cake 0.33 --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 4 ++-- src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 4 ++-- src/Cake.Issues/Cake.Issues.csproj | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 6c78fb4da..9e08f5e6b 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -24,8 +24,8 @@ - - + + diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 90f56bea4..6ccee2e65 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -26,8 +26,8 @@ - - + + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index 7e9fe47f2..54b6d7357 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -23,7 +23,7 @@ - + From 716f51fa8e0dee9dc134075b7866266b4c4c8a54 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 8 Apr 2019 19:39:33 +0200 Subject: [PATCH 18/36] (GH-84) Allow to clear priority through issue builder --- src/Cake.Issues.Tests/IssueBuilderTests.cs | 14 ++++++++++++++ src/Cake.Issues/IssueBuilder.cs | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.Tests/IssueBuilderTests.cs b/src/Cake.Issues.Tests/IssueBuilderTests.cs index 52672ce95..d73fb1bf5 100644 --- a/src/Cake.Issues.Tests/IssueBuilderTests.cs +++ b/src/Cake.Issues.Tests/IssueBuilderTests.cs @@ -647,6 +647,20 @@ public void Should_Set_Line(int line) public sealed class TheWithPriorityMethod { + [Fact] + public void Should_Handle_Priority_Which_Is_Null() + { + // Given + var fixture = new IssueBuilderFixture(); + int? priority = null; + + // When + var issue = fixture.IssueBuilder.WithPriority(priority, "Foo").Create(); + + // Then + issue.Priority.ShouldBe(priority); + } + [Fact] public void Should_Handle_PriorityNames_Which_Are_Null() { diff --git a/src/Cake.Issues/IssueBuilder.cs b/src/Cake.Issues/IssueBuilder.cs index 731bf644a..0be1bf428 100644 --- a/src/Cake.Issues/IssueBuilder.cs +++ b/src/Cake.Issues/IssueBuilder.cs @@ -14,7 +14,7 @@ public class IssueBuilder private string projectName; private string filePath; private int? line; - private int priority; + private int? priority; private string priorityName; private string rule; private Uri ruleUrl; @@ -175,7 +175,7 @@ public IssueBuilder WithPriority(IssuePriority priority) /// The human friendly name of the priority. /// null or if no priority should be assigned. /// Issue Builder instance. - public IssueBuilder WithPriority(int value, string name) + public IssueBuilder WithPriority(int? value, string name) { this.priority = value; this.priorityName = name; From 4334519f3cfa4ff3adf31d75671d81cc6445fc9d Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 12 Apr 2019 08:55:52 +0200 Subject: [PATCH 19/36] Fix comment for IIssue.ProjectFileRelativePath --- src/Cake.Issues/IIssue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues/IIssue.cs b/src/Cake.Issues/IIssue.cs index 9ae0b753b..2394f725b 100644 --- a/src/Cake.Issues/IIssue.cs +++ b/src/Cake.Issues/IIssue.cs @@ -11,7 +11,7 @@ public interface IIssue /// /// Gets the path to the project to which the file affected by the issue belongs. /// The path is relative to the repository root. - /// Can be null or if issue is not related to a project. + /// Can be null if issue is not related to a project. /// FilePath ProjectFileRelativePath { get; } From dcee3ad528555a1b2a04401d1981a79ea120808a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 18 Apr 2019 04:24:27 +0000 Subject: [PATCH 20/36] Bump Microsoft.CodeAnalysis.FxCopAnalyzers from 2.9.1 to 2.9.2 in /src Bumps [Microsoft.CodeAnalysis.FxCopAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 2.9.1 to 2.9.2. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Commits](https://github.com/dotnet/roslyn-analyzers/compare/v2.9.1...v2.9.2) Signed-off-by: dependabot[bot] --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 2 +- src/Cake.Issues/Cake.Issues.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 9e08f5e6b..15d4e8872 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index 54b6d7357..ddf3dbdd5 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -24,7 +24,7 @@ - + From 83654ed78a1c1a7f0deedf599a008e6d6a886f2c Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 8 Apr 2019 20:32:44 +0200 Subject: [PATCH 21/36] (GH-65) Add extension to skip BOM in byte array stream --- .../ByteArrayExtensionsTests.cs | 119 ++++++++++++++++++ src/Cake.Issues/ByteArrayExtensions.cs | 41 ++++-- 2 files changed, 153 insertions(+), 7 deletions(-) diff --git a/src/Cake.Issues.Tests/ByteArrayExtensionsTests.cs b/src/Cake.Issues.Tests/ByteArrayExtensionsTests.cs index a072f3a78..8193deede 100644 --- a/src/Cake.Issues.Tests/ByteArrayExtensionsTests.cs +++ b/src/Cake.Issues.Tests/ByteArrayExtensionsTests.cs @@ -9,6 +9,125 @@ public sealed class ByteArrayExtensionsTests { + public sealed class TheRemovePreambleExtension + { + [Fact] + public void Should_Throw_If_Value_Is_Null() + { + // Given + byte[] value = null; + + // When + var result = Record.Exception(() => value.RemovePreamble()); + + // Then + result.IsArgumentNullException("value"); + } + + [Theory] + [InlineData("foo🐱bar")] + [InlineData("")] + public void Should_Remove_Preamble(string value) + { + // Given + var encoding = Encoding.UTF8; + var preamble = encoding.GetPreamble(); + var valueWithoutPreamble = value.ToByteArray(encoding); + var valueWithPreamble = preamble.Concat(valueWithoutPreamble).ToArray(); + + // When + var result = valueWithPreamble.RemovePreamble(); + + // Then + result.ShouldBe(valueWithoutPreamble); + } + } + + public sealed class TheRemovePreambleWithEncodingExtension + { + [Fact] + public void Should_Throw_If_Value_Is_Null() + { + // Given + byte[] value = null; + var encoding = Encoding.UTF32; + + // When + var result = Record.Exception(() => value.RemovePreamble(encoding)); + + // Then + result.IsArgumentNullException("value"); + } + + [Fact] + public void Should_Throw_If_Encoding_Is_Null() + { + // Given + var encoding = Encoding.UTF32; + var stringValue = "foo🐱bar"; + var byteArrayValue = stringValue.ToByteArray(encoding); + + // When + var result = Record.Exception(() => byteArrayValue.RemovePreamble(null)); + + // Then + result.IsArgumentNullException("encoding"); + } + + [Theory] + [InlineData("foo🐱bar")] + [InlineData("")] + public void Should_Remove_Preamble(string value) + { + // Given + var encoding = Encoding.UTF32; + var preamble = encoding.GetPreamble(); + var valueWithoutPreamble = value.ToByteArray(encoding); + var valueWithPreamble = preamble.Concat(valueWithoutPreamble).ToArray(); + + // When + var result = valueWithPreamble.RemovePreamble(encoding); + + // Then + result.ShouldBe(valueWithoutPreamble); + } + + [Theory] + [InlineData("foo🐱bar")] + [InlineData("")] + public void Should_Return_Correct_Value_If_Enconding_Has_Preamble_But_Value_Not(string value) + { + // Given + var encoding = Encoding.UTF32; + var preamble = encoding.GetPreamble(); + var valueWithoutPreamble = value.ToByteArray(encoding); + + // When + var result = valueWithoutPreamble.RemovePreamble(encoding); + + // Then + result.ShouldBe(valueWithoutPreamble); + } + + [Theory] + [InlineData("foo")] + [InlineData("")] + public void Should_Return_Correct_Value_If_Encoding_Does_Not_Have_Preamble(string value) + { + // Given + var encoding = Encoding.ASCII; + var preamble = encoding.GetPreamble(); + var valueWithoutPreamble = value.ToByteArray(encoding); + var valueWithPreamble = preamble.Concat(valueWithoutPreamble).ToArray(); + + // When + var result = valueWithPreamble.RemovePreamble(encoding); + + // Then + result.ShouldBe(valueWithoutPreamble); + } + } + public sealed class TheToStringUsingEncodingExtension { [Fact] diff --git a/src/Cake.Issues/ByteArrayExtensions.cs b/src/Cake.Issues/ByteArrayExtensions.cs index 946c31e67..7e64fb239 100644 --- a/src/Cake.Issues/ByteArrayExtensions.cs +++ b/src/Cake.Issues/ByteArrayExtensions.cs @@ -1,6 +1,5 @@ namespace Cake.Issues { - using System; using System.Linq; using System.Text; @@ -9,6 +8,39 @@ /// public static class ByteArrayExtensions { + /// + /// Removes the BOM of an UTF-8 encoded byte array. + /// + /// UTF-8 encoded byte array. + /// UTF-8 encoded byte array without BOM. + public static byte[] RemovePreamble(this byte[] value) + { + value.NotNull(nameof(value)); + + return value.RemovePreamble(Encoding.UTF8); + } + + /// + /// Removes the preamble from an byte array. + /// + /// Byte array. + /// Encoding of the byte array. + /// Byte array without preamble. + public static byte[] RemovePreamble(this byte[] value, Encoding encoding) + { + value.NotNull(nameof(value)); + encoding.NotNull(nameof(encoding)); + + var preamble = encoding.GetPreamble(); + + if (value.Zip(preamble, (x, y) => x == y).All(x => x)) + { + return value.Skip(preamble.Length).ToArray(); + } + + return value; + } + /// /// Converts a byte array of an UTF-8 encoded string to a string. /// @@ -47,12 +79,7 @@ public static string ToStringUsingEncoding(this byte[] value, Encoding encoding, if (value.Any() && skipPreamble) { - var preamble = encoding.GetPreamble(); - - if (value.Zip(preamble, (x, y) => x == y).All(x => x)) - { - value = value.Skip(preamble.Length).ToArray(); - } + value = value.RemovePreamble(encoding); } return encoding.GetString(value); From b3c66f690bae4ce27984a69ae15a4b9987968080 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 15 Apr 2019 15:31:56 +0200 Subject: [PATCH 22/36] Remove dependency on XUnit.Assert --- .../Cake.Issues.Testing.csproj | 1 - .../ExceptionAssertExtensions.cs | 45 +++- .../Testing/ExceptionAssertExtensionsTests.cs | 252 ++++++++++++++++++ 3 files changed, 288 insertions(+), 10 deletions(-) create mode 100644 src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 15d4e8872..7d4c706d3 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -28,7 +28,6 @@ - diff --git a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs index 0efade953..055af0a8c 100644 --- a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs +++ b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs @@ -1,7 +1,6 @@ namespace Cake.Issues.Testing { using System; - using Xunit; /// /// Extensions for asserting exceptions. @@ -15,8 +14,15 @@ public static class ExceptionAssertExtensions /// Expected name of the parameter which has caused the exception. public static void IsArgumentException(this Exception exception, string parameterName) { - Assert.IsType(exception); - Assert.Equal(parameterName, ((ArgumentException)exception).ParamName); + if (!(exception is ArgumentException argumentException)) + { + throw new Exception($"Expected exception of type '{typeof(ArgumentException)}' but was '{exception.GetType()}'"); + } + + if (argumentException.ParamName != parameterName) + { + throw new Exception($"Expected parameter name to be '{parameterName}' but was '{argumentException.ParamName}'."); + } } /// @@ -26,8 +32,15 @@ public static void IsArgumentException(this Exception exception, string paramete /// Expected name of the parameter which has caused the exception. public static void IsArgumentNullException(this Exception exception, string parameterName) { - Assert.IsType(exception); - Assert.Equal(parameterName, ((ArgumentNullException)exception).ParamName); + if (!(exception is ArgumentNullException argumentNullException)) + { + throw new Exception($"Expected exception of type '{typeof(ArgumentNullException)}' but was '{exception.GetType()}'"); + } + + if (argumentNullException.ParamName != parameterName) + { + throw new Exception($"Expected parameter name to be '{parameterName}' but was '{argumentNullException.ParamName}'."); + } } /// @@ -37,8 +50,15 @@ public static void IsArgumentNullException(this Exception exception, string para /// Expected name of the parameter which has caused the exception. public static void IsArgumentOutOfRangeException(this Exception exception, string parameterName) { - Assert.IsType(exception); - Assert.Equal(parameterName, ((ArgumentOutOfRangeException)exception).ParamName); + if (!(exception is ArgumentOutOfRangeException argumentOutOfRangeException)) + { + throw new Exception($"Expected exception of type '{typeof(ArgumentOutOfRangeException)}' but was '{exception.GetType()}'"); + } + + if (argumentOutOfRangeException.ParamName != parameterName) + { + throw new Exception($"Expected parameter name to be '{parameterName}' but was '{argumentOutOfRangeException.ParamName}'."); + } } /// @@ -48,8 +68,15 @@ public static void IsArgumentOutOfRangeException(this Exception exception, strin /// Expected exception message. public static void IsInvalidOperationException(this Exception exception, string message) { - Assert.IsType(exception); - Assert.Equal(message, exception.Message); + if (!(exception is InvalidOperationException invalidOperationException)) + { + throw new Exception($"Expected exception of type '{typeof(InvalidOperationException)}' but was '{exception.GetType()}'"); + } + + if (invalidOperationException.Message != message) + { + throw new Exception($"Expected exception message to be '{message}' but was '{invalidOperationException.Message}'."); + } } } } diff --git a/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs b/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs new file mode 100644 index 000000000..390cb0e09 --- /dev/null +++ b/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs @@ -0,0 +1,252 @@ +namespace Cake.Issues.Tests.Testing +{ + using System; + using Cake.Issues.Testing; + using Shouldly; + using Xunit; + + public sealed class ExceptionAssertExtensionsTests + { + public sealed class TheIsArgumentExceptionMethod + { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Not_ArgumentException() + { + // Given + var exception = new Exception("Foo"); + + // When + var result = Record.Exception(() => exception.IsArgumentException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentException' but was 'System.Exception'"); + } + + [Fact] + public void Should_Not_Throw_If_Exception_Type_Is_ArgumentException() + { + // Given + var exception = new ArgumentException("Message", "Foo"); + + // When + exception.IsArgumentException("Foo"); + + // Then + } + + [Theory] + [InlineData("Foo", "Bar")] + [InlineData(null, "Foo")] + [InlineData("Foo", null)] + public void Should_Throw_If_ParamName_Is_Different(string actualParamName, string expectedParamName) + { + // Given + var exception = new ArgumentException("Foo", actualParamName); + + // When + var result = Record.Exception(() => exception.IsArgumentException(expectedParamName)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected parameter name to be '{expectedParamName}' but was '{actualParamName}'."); + } + + [Theory] + [InlineData("Foo", "Foo")] + [InlineData(null, null)] + [InlineData("", "")] + public void Should_Not_Throw_If_ParamName_Is_The_Same(string actualParamName, string expectedParamName) + { + // Given + var exception = new ArgumentException("Foo", actualParamName); + + // When + exception.IsArgumentException(expectedParamName); + + // Then + } + } + + public sealed class TheIsArgumentNullExceptionMethod + { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Not_ArgumentNullException() + { + // Given + var exception = new Exception("Foo"); + + // When + var result = Record.Exception(() => exception.IsArgumentNullException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentNullException' but was 'System.Exception'"); + } + + [Fact] + public void Should_Not_Throw_If_Exception_Type_Is_ArgumentNullException() + { + // Given + var exception = new ArgumentNullException("Foo"); + + // When + exception.IsArgumentNullException("Foo"); + + // Then + } + + [Theory] + [InlineData("Foo", "Bar")] + [InlineData(null, "Foo")] + [InlineData("Foo", null)] + public void Should_Throw_If_ParamName_Is_Different(string actualParamName, string expectedParamName) + { + // Given + var exception = new ArgumentNullException(actualParamName); + + // When + var result = Record.Exception(() => exception.IsArgumentNullException(expectedParamName)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected parameter name to be '{expectedParamName}' but was '{actualParamName}'."); + } + + [Theory] + [InlineData("Foo", "Foo")] + [InlineData(null, null)] + [InlineData("", "")] + public void Should_Not_Throw_If_ParamName_Is_The_Same(string actualParamName, string expectedParamName) + { + // Given + var exception = new ArgumentNullException(actualParamName); + + // When + exception.IsArgumentNullException(expectedParamName); + + // Then + } + } + + public sealed class TheIsArgumentOutOfRangeExceptionMethod + { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Not_ArgumentOutOfRangeException() + { + // Given + var exception = new Exception("Foo"); + + // When + var result = Record.Exception(() => exception.IsArgumentOutOfRangeException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentOutOfRangeException' but was 'System.Exception'"); + } + + [Fact] + public void Should_Not_Throw_If_Exception_Type_Is_ArgumentOutOfRangeException() + { + // Given + var exception = new ArgumentOutOfRangeException("Foo"); + + // When + exception.IsArgumentOutOfRangeException("Foo"); + + // Then + } + + [Theory] + [InlineData("Foo", "Bar")] + [InlineData(null, "Foo")] + [InlineData("Foo", null)] + public void Should_Throw_If_ParamName_Is_Different(string actualParamName, string expectedParamName) + { + // Given + var exception = new ArgumentOutOfRangeException(actualParamName); + + // When + var result = Record.Exception(() => exception.IsArgumentOutOfRangeException(expectedParamName)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected parameter name to be '{expectedParamName}' but was '{actualParamName}'."); + } + + [Theory] + [InlineData("Foo", "Foo")] + [InlineData(null, null)] + [InlineData("", "")] + public void Should_Not_Throw_If_ParamName_Is_The_Same(string actualParamName, string expectedParamName) + { + // Given + var exception = new ArgumentOutOfRangeException(actualParamName); + + // When + exception.IsArgumentOutOfRangeException(expectedParamName); + + // Then + } + } + + public sealed class TheIsInvalidOperationExceptionMethod + { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Not_InvalidOperationException() + { + // Given + var exception = new Exception("Foo"); + + // When + var result = Record.Exception(() => exception.IsInvalidOperationException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.InvalidOperationException' but was 'System.Exception'"); + } + + [Fact] + public void Should_Not_Throw_If_Exception_Type_Is_InvalidOperationException() + { + // Given + var exception = new InvalidOperationException("Foo"); + + // When + exception.IsInvalidOperationException("Foo"); + + // Then + } + + [Theory] + [InlineData("Foo", "Bar")] + [InlineData("Foo", null)] + public void Should_Throw_If_Message_Is_Different(string actualMessage, string expectedMessage) + { + // Given + var exception = new InvalidOperationException(actualMessage); + + // When + var result = Record.Exception(() => exception.IsInvalidOperationException(expectedMessage)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception message to be '{expectedMessage}' but was '{actualMessage}'."); + } + + [Theory] + [InlineData("Foo", "Foo")] + [InlineData("", "")] + public void Should_Not_Throw_If_Message_Is_The_Same(string actualMessage, string expectedMessage) + { + // Given + var exception = new InvalidOperationException(actualMessage); + + // When + exception.IsInvalidOperationException(expectedMessage); + + // Then + } + } + } +} \ No newline at end of file From 8ceb47b2e715ac8e2d60214786bb0cee8825e00f Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 14:59:46 +0200 Subject: [PATCH 23/36] Update to StyleCop.Analyzers 1.1.1-rc.114 to support newer C# language features --- src/Cake.Issues.Testing/Cake.Issues.Testing.csproj | 5 ++++- src/Cake.Issues.Tests.ruleset | 2 ++ src/Cake.Issues.Tests/Cake.Issues.Tests.csproj | 5 ++++- src/Cake.Issues/Cake.Issues.csproj | 5 ++++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj index 7d4c706d3..9e1b78668 100644 --- a/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj +++ b/src/Cake.Issues.Testing/Cake.Issues.Testing.csproj @@ -27,7 +27,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Cake.Issues.Tests.ruleset b/src/Cake.Issues.Tests.ruleset index 71b6b949d..b470ca605 100644 --- a/src/Cake.Issues.Tests.ruleset +++ b/src/Cake.Issues.Tests.ruleset @@ -2,7 +2,9 @@ + + \ No newline at end of file diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index 6ccee2e65..f279bc345 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -29,7 +29,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Cake.Issues/Cake.Issues.csproj b/src/Cake.Issues/Cake.Issues.csproj index ddf3dbdd5..f08e102dd 100644 --- a/src/Cake.Issues/Cake.Issues.csproj +++ b/src/Cake.Issues/Cake.Issues.csproj @@ -25,7 +25,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From a050b243d90afdf9cee2746efb61ae4459880e47 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 12 Apr 2019 08:35:23 +0200 Subject: [PATCH 24/36] (GH-41) Add helper for checking issues in tests --- .../ExceptionAssertExtensions.cs | 18 + src/Cake.Issues.Testing/IssueChecker.cs | 178 +++++++ src/Cake.Issues.Tests/IssueBuilderFixture.cs | 10 +- .../Testing/IssueCheckerFixture.cs | 61 +++ .../Testing/IssueCheckerTests.cs | 485 ++++++++++++++++++ 5 files changed, 750 insertions(+), 2 deletions(-) create mode 100644 src/Cake.Issues.Testing/IssueChecker.cs create mode 100644 src/Cake.Issues.Tests/Testing/IssueCheckerFixture.cs create mode 100644 src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs diff --git a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs index 055af0a8c..45ac86cb2 100644 --- a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs +++ b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs @@ -78,5 +78,23 @@ public static void IsInvalidOperationException(this Exception exception, string throw new Exception($"Expected exception message to be '{message}' but was '{invalidOperationException.Message}'."); } } + + ///// + ///// Checks if an execption is of type . + ///// + ///// Exception to check. + ///// Expected exception message. + //public static void IsXUnitException(this Exception exception, string message) + //{ + // if (!(exception is XunitException xunitException)) + // { + // throw new Exception($"Expected exception of type '{typeof(XunitException)}' but was '{exception.GetType()}'"); + // } + + // if (xunitException.Message.StartsWith(message)) + // { + // throw new Exception($"Expected exception message to be '{message}' but was '{xunitException.Message}'."); + // } + //} } } diff --git a/src/Cake.Issues.Testing/IssueChecker.cs b/src/Cake.Issues.Testing/IssueChecker.cs new file mode 100644 index 000000000..1c036fa3c --- /dev/null +++ b/src/Cake.Issues.Testing/IssueChecker.cs @@ -0,0 +1,178 @@ +namespace Cake.Issues.Testing +{ + using System; + using Cake.Core.IO; + + /// + /// Class for checking issues. + /// + public static class IssueChecker + { + /// + /// Checks values of an issue. + /// + /// Issue which should be checked. + /// Description of the expected issue. + public static void Check( + IIssue issueToCheck, + IIssue expectedIssue) + { + issueToCheck.NotNull(nameof(issueToCheck)); + expectedIssue.NotNull(nameof(expectedIssue)); + + Check( + issueToCheck, + expectedIssue.ProviderType, + expectedIssue.ProviderName, + expectedIssue.ProjectFileRelativePath?.ToString(), + expectedIssue.ProjectName, + expectedIssue.AffectedFileRelativePath?.ToString(), + expectedIssue.Line, + expectedIssue.Message, + expectedIssue.Priority, + expectedIssue.PriorityName, + expectedIssue.Rule, + expectedIssue.RuleUrl); + } + + /// + /// Checks values of an issue. + /// + /// Issue which should be checked. + /// Expected type of the issue provider. + /// Expected human friendly name of the issue provider. + /// Expected relative path of the project file. + /// null if the issue is not expected to be related to a project. + /// Expected project name. + /// null or if the issue is not expected to be related to a project. + /// Expected relative path of the affected file. + /// null if the issue is not expected to be related to a change in a file. + /// Expected line number. + /// null if the issue is not expected to be related to a file or specific line. + /// Expected message. + /// Expected priority. + /// null if no priority is expected. + /// Expected priority name. + /// null or if no priority is expected. + /// Expected rule identifier. + /// null or if no rule identifier is expected. + /// Expected URL containing information about the failing rule. + /// null if no rule Url is expected. + public static void Check( + IIssue issue, + string providerType, + string providerName, + string projectFileRelativePath, + string projectName, + string affectedFileRelativePath, + int? line, + string message, + int? priority, + string priorityName, + string rule, + Uri ruleUrl) + { + issue.NotNull(nameof(issue)); + + if (issue.ProviderType != providerType) + { + throw new Exception( + $"Expected issue.ProviderType to be {providerType}"); + } + + if (issue.ProviderName != providerName) + { + throw new Exception( + $"Expected issue.ProviderName to be {providerName}"); + } + + if (issue.ProjectFileRelativePath == null) + { + if (projectFileRelativePath != null) + { + throw new Exception( + $"Expected issue.ProjectFileRelativePath to be {projectFileRelativePath}"); + } + } + else + { + if (issue.ProjectFileRelativePath.ToString() != new FilePath(projectFileRelativePath).ToString()) + { + throw new Exception( + $"Expected issue.ProjectFileRelativePath to be {projectFileRelativePath}"); + } + + if (!issue.ProjectFileRelativePath.IsRelative) + { + throw new Exception( + $"Expected issue.ProjectFileRelativePath to be a relative path"); + } + } + + if (issue.ProjectName != projectName) + { + throw new Exception( + $"Expected issue.ProjectName to be {projectName}"); + } + + if (issue.AffectedFileRelativePath == null) + { + if (affectedFileRelativePath != null) + { + throw new Exception( + $"Expected issue.AffectedFileRelativePath to be {affectedFileRelativePath}"); + } + } + else + { + if (issue.AffectedFileRelativePath.ToString() != new FilePath(affectedFileRelativePath).ToString()) + { + throw new Exception( + $"Expected issue.AffectedFileRelativePath to be {affectedFileRelativePath}"); + } + + if (!issue.AffectedFileRelativePath.IsRelative) + { + throw new Exception( + $"Expected issue.AffectedFileRelativePath to be a relative path"); + } + } + + if (issue.Line != line) + { + throw new Exception( + $"Expected issue.Line to be {line}"); + } + + if (issue.Message != message) + { + throw new Exception( + $"Expected issue.Message to be {message}"); + } + + if (issue.Priority != priority) + { + throw new Exception( + $"Expected issue.Priority to be {priority}"); + } + + if (issue.PriorityName != priorityName) + { + throw new Exception( + $"Expected issue.PriorityName to be {priorityName}"); + } + + if (issue.Rule != rule) + { + throw new Exception( + $"Expected issue.Rule to be {rule}"); + } + + if (issue.RuleUrl?.ToString() != ruleUrl?.ToString()) + { + throw new Exception( + $"Expected issue.RuleUrl to be {ruleUrl?.ToString()}"); + } + } + } +} diff --git a/src/Cake.Issues.Tests/IssueBuilderFixture.cs b/src/Cake.Issues.Tests/IssueBuilderFixture.cs index 3b168ca30..d734d2da9 100644 --- a/src/Cake.Issues.Tests/IssueBuilderFixture.cs +++ b/src/Cake.Issues.Tests/IssueBuilderFixture.cs @@ -1,10 +1,16 @@ namespace Cake.Issues.Tests { - public class IssueBuilderFixture + internal class IssueBuilderFixture { public IssueBuilderFixture() + : this("Message", "ProviderType", "ProviderName") { - this.IssueBuilder = IssueBuilder.NewIssue("Message", "ProviderType", "ProviderName"); + } + + public IssueBuilderFixture(string message, string providerType, string providerName) + { + this.IssueBuilder = + IssueBuilder.NewIssue(message, providerType, providerName); } public IssueBuilder IssueBuilder { get; private set; } diff --git a/src/Cake.Issues.Tests/Testing/IssueCheckerFixture.cs b/src/Cake.Issues.Tests/Testing/IssueCheckerFixture.cs new file mode 100644 index 000000000..e6102eeb4 --- /dev/null +++ b/src/Cake.Issues.Tests/Testing/IssueCheckerFixture.cs @@ -0,0 +1,61 @@ +namespace Cake.Issues.Tests +{ + using System; + + internal class IssueCheckerFixture : IssueBuilderFixture + { + public IssueCheckerFixture() + : this("Message", "ProviderType", "ProviderName") + { + } + + public IssueCheckerFixture(string message, string providerType, string providerName) + : base(message, providerType, providerName) + { + this.ProviderType = providerType; + this.ProviderName = providerName; + this.ProjectFileRelativePath = @"src\project.file"; + this.ProjectName = "ProjectName"; + this.AffectedFileRelativePath = @"src\source.file"; + this.Line = 42; + this.Message = message; + this.Priority = 100; + this.PriorityName = "PriorityName"; + this.Rule = "Rule"; + this.RuleUrl = new Uri("https://google.com"); + + this.IssueBuilder + .InProject(this.ProjectFileRelativePath, this.ProjectName) + .InFile(this.AffectedFileRelativePath, this.Line) + .OfRule(this.Rule, this.RuleUrl) + .WithPriority(this.Priority, this.PriorityName); + + this.Issue = + this.IssueBuilder.Create(); + } + + public IIssue Issue { get; private set; } + + public string ProviderType { get; private set; } + + public string ProviderName { get; private set; } + + public string ProjectFileRelativePath { get; private set; } + + public string ProjectName { get; private set; } + + public string AffectedFileRelativePath { get; private set; } + + public int Line { get; private set; } + + public string Message { get; private set; } + + public int Priority { get; private set; } + + public string PriorityName { get; private set; } + + public string Rule { get; private set; } + + public Uri RuleUrl { get; private set; } + } +} diff --git a/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs b/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs new file mode 100644 index 000000000..e3b8f54e5 --- /dev/null +++ b/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs @@ -0,0 +1,485 @@ +namespace Cake.Issues.Tests.Testing +{ + using System; + using Cake.Issues.Testing; + using Shouldly; + using Xunit; + + public sealed class IssueCheckerTests + { + public sealed class TheCheckMethodComparingTwoIssues + { + [Fact] + public void Should_Throw_If_IssueToCheck_Is_Null() + { +#pragma warning disable SA1123 // Do not place regions within elements + #region DupFinder Exclusion +#pragma warning restore SA1123 // Do not place regions within elements + + // Given + var fixture = new IssueBuilderFixture(); + IIssue issueToCheck = null; + var expectedIssue = fixture.IssueBuilder.Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check(issueToCheck, expectedIssue)); + + // Then + result.IsArgumentNullException("issueToCheck"); + + #endregion + } + + [Fact] + public void Should_Throw_If_ExpectedIssue_Is_Null() + { +#pragma warning disable SA1123 // Do not place regions within elements + #region DupFinder Exclusion +#pragma warning restore SA1123 // Do not place regions within elements + + // Given + var fixture = new IssueBuilderFixture(); + var issueToCheck = fixture.IssueBuilder.Create(); + IIssue expectedIssue = null; + + // When + var result = Record.Exception(() => + IssueChecker.Check(issueToCheck, expectedIssue)); + + // Then + result.IsArgumentNullException("expectedIssue"); + + #endregion + } + + [Fact] + public void Should_Not_Throw_If_Issues_Are_Identical() + { + // Given + var fixture = new IssueCheckerFixture(); + var issueToCheck = fixture.IssueBuilder.Create(); + var expectedIssue = fixture.IssueBuilder.Create(); + + // When + IssueChecker.Check(issueToCheck, expectedIssue); + + // Then + } + } + + public sealed class TheCheckMethodWithIndividualValues + { + [Fact] + public void Should_Throw_If_Issue_Is_Null() + { + // Given + var fixture = new IssueCheckerFixture(); + IIssue issue = null; + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.IsArgumentNullException("issue"); + } + + [Fact] + public void Should_Not_Throw_If_All_Values_Are_The_Same() + { + // Given + var fixture = new IssueCheckerFixture(); + + // When + IssueChecker.Check( + fixture.Issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl); + + // Then + } + + [Theory] + [InlineData("ProviderType", "Foo")] + [InlineData(null, "Foo")] + [InlineData("", "Foo")] + [InlineData(" ", "Foo")] + public void Should_Throw_If_ProviderType_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture("Message", actualValue, "ProviderName"); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + fixture.Issue, + expectedValue, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.ProviderType"); + } + + [Theory] + [InlineData("ProviderName", "Foo")] + [InlineData(null, "Foo")] + [InlineData("", "Foo")] + [InlineData(" ", "Foo")] + public void Should_Throw_If_ProviderName_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture("Message", "ProviderType", actualValue); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + fixture.Issue, + fixture.ProviderType, + expectedValue, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.ProviderName"); + } + + [Theory] + [InlineData(@"src\project.file", @"src\foo")] + public void Should_Throw_If_ProjectFileRelativePath_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .InProjectFile(actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + expectedValue, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.ProjectFileRelativePath"); + } + + [Theory] + [InlineData("ProjectName", "Foo")] + [InlineData(null, "Foo")] + [InlineData("", "Foo")] + [InlineData(" ", "Foo")] + public void Should_Throw_If_ProjectName_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .InProject(fixture.ProjectFileRelativePath, actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + expectedValue, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.ProjectName"); + } + + [Theory] + [InlineData(@"src\source.file", @"src\foo")] + public void Should_Throw_If_AffectedFileRelativePath_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .InFile(actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + expectedValue, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.AffectedFileRelativePath"); + } + + [Theory] + [InlineData(42, 23)] + [InlineData(null, 42)] + [InlineData(42, null)] + public void Should_Throw_If_Line_Is_Different(int? expectedValue, int? actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .InFile(fixture.AffectedFileRelativePath, actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + expectedValue, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.Line"); + } + + [Theory] + [InlineData("Message", "Foo")] + [InlineData(null, "Foo")] + [InlineData("", "Foo")] + [InlineData(" ", "Foo")] + public void Should_Throw_If_Message_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(actualValue, "ProviderType", "ProviderName"); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + fixture.Issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + expectedValue, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.Message"); + } + + [Theory] + [InlineData(IssuePriority.Error, IssuePriority.Warning)] + public void Should_Throw_If_Priority_Is_Different(IssuePriority expectedValue, IssuePriority actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .WithPriority(actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + (int)expectedValue, + fixture.PriorityName, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.Priority"); + } + + [Theory] + [InlineData("PriorityName", "Foo")] + [InlineData(null, "Foo")] + [InlineData("", "Foo")] + [InlineData(" ", "Foo")] + public void Should_Throw_If_PriorityName_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .WithPriority(fixture.Priority, actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + expectedValue, + fixture.Rule, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.PriorityName"); + } + + [Theory] + [InlineData("Rule", "Foo")] + [InlineData(null, "Foo")] + [InlineData("", "Foo")] + [InlineData(" ", "Foo")] + public void Should_Throw_If_Rule_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .OfRule(actualValue) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + expectedValue, + fixture.RuleUrl)); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.Rule"); + } + + [Theory] + [InlineData("https://google.com", "https://foo.bar")] + public void Should_Throw_If_RuleUrl_Is_Different(string expectedValue, string actualValue) + { + // Given + var fixture = new IssueCheckerFixture(); + var issue = + fixture.IssueBuilder + .OfRule(fixture.Rule, new Uri(actualValue)) + .Create(); + + // When + var result = Record.Exception(() => + IssueChecker.Check( + issue, + fixture.ProviderType, + fixture.ProviderName, + fixture.ProjectFileRelativePath, + fixture.ProjectName, + fixture.AffectedFileRelativePath, + fixture.Line, + fixture.Message, + fixture.Priority, + fixture.PriorityName, + fixture.Rule, + new Uri(expectedValue))); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldStartWith("Expected issue.RuleUrl"); + } + } + } +} \ No newline at end of file From 676293f0cd0a26162587b8fe5c0e986720a269ed Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 15:49:43 +0200 Subject: [PATCH 25/36] Update release notes links --- nuspec/nuget/Cake.Issues.Testing.nuspec | 2 +- nuspec/nuget/Cake.Issues.nuspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nuspec/nuget/Cake.Issues.Testing.nuspec b/nuspec/nuget/Cake.Issues.Testing.nuspec index 983c3714e..46ce3fe13 100644 --- a/nuspec/nuget/Cake.Issues.Testing.nuspec +++ b/nuspec/nuget/Cake.Issues.Testing.nuspec @@ -17,7 +17,7 @@ Common helpers for testing add-ins based on Cake.Issues Copyright © BBT Software AG and contributors Cake Script Cake-Issues Issues Testing - https://github.com/cake-contrib/Cake.Issues/releases/tag/0.6.2 + https://github.com/cake-contrib/Cake.Issues/releases/tag/0.7.0 diff --git a/nuspec/nuget/Cake.Issues.nuspec b/nuspec/nuget/Cake.Issues.nuspec index 0aaff4e15..c36075fea 100644 --- a/nuspec/nuget/Cake.Issues.nuspec +++ b/nuspec/nuget/Cake.Issues.nuspec @@ -24,7 +24,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin Copyright © BBT Software AG and contributors Cake Script Cake-Issues CodeAnalysis Linting Issues - https://github.com/cake-contrib/Cake.Issues/releases/tag/0.6.2 + https://github.com/cake-contrib/Cake.Issues/releases/tag/0.7.0 From ac862ab5da365335cf5e90f36ada7900ba060b3c Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 15:57:36 +0200 Subject: [PATCH 26/36] Fix StyleCop warnings --- .../ExceptionAssertExtensions.cs | 18 ------------------ .../FakeConfigurableIssueProvider.cs | 2 +- src/Cake.Issues.Testing/FakeIssueComponent.cs | 2 +- src/Cake.Issues.Testing/FakeIssueProvider.cs | 4 ++-- src/Cake.Issues.Tests/IssueReaderTests.cs | 18 +++++++++--------- src/Cake.Issues.Tests/IssuesFixture.cs | 2 +- ...aseConfigurableIssueProviderFixtureTests.cs | 4 ++-- .../Testing/BaseIssueProviderFixtureTests.cs | 4 ++-- ...BaseMultiFormatIssueProviderFixtureTests.cs | 4 ++-- src/Cake.Issues/BaseIssueProvider.cs | 2 +- src/Cake.Issues/BaseRuleUrlResolver.cs | 4 ++-- 11 files changed, 23 insertions(+), 41 deletions(-) diff --git a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs index 45ac86cb2..055af0a8c 100644 --- a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs +++ b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs @@ -78,23 +78,5 @@ public static void IsInvalidOperationException(this Exception exception, string throw new Exception($"Expected exception message to be '{message}' but was '{invalidOperationException.Message}'."); } } - - ///// - ///// Checks if an execption is of type . - ///// - ///// Exception to check. - ///// Expected exception message. - //public static void IsXUnitException(this Exception exception, string message) - //{ - // if (!(exception is XunitException xunitException)) - // { - // throw new Exception($"Expected exception of type '{typeof(XunitException)}' but was '{exception.GetType()}'"); - // } - - // if (xunitException.Message.StartsWith(message)) - // { - // throw new Exception($"Expected exception message to be '{message}' but was '{xunitException.Message}'."); - // } - //} } } diff --git a/src/Cake.Issues.Testing/FakeConfigurableIssueProvider.cs b/src/Cake.Issues.Testing/FakeConfigurableIssueProvider.cs index 7706c1741..3bff27240 100644 --- a/src/Cake.Issues.Testing/FakeConfigurableIssueProvider.cs +++ b/src/Cake.Issues.Testing/FakeConfigurableIssueProvider.cs @@ -24,7 +24,7 @@ public FakeConfigurableIssueProvider(ICakeLog log, IssueProviderSettings setting /// /// Initializes a new instance of the class. /// - /// The Cake log instance + /// The Cake log instance. /// The issue provider settings. /// Issues which should be returned by the issue provider. public FakeConfigurableIssueProvider( diff --git a/src/Cake.Issues.Testing/FakeIssueComponent.cs b/src/Cake.Issues.Testing/FakeIssueComponent.cs index 3b005bf27..3b5d456d6 100644 --- a/src/Cake.Issues.Testing/FakeIssueComponent.cs +++ b/src/Cake.Issues.Testing/FakeIssueComponent.cs @@ -10,7 +10,7 @@ public class FakeIssueComponent : BaseIssueComponent /// /// Initializes a new instance of the class. /// - /// The Cake log instance + /// The Cake log instance. public FakeIssueComponent(ICakeLog log) : base(log) { diff --git a/src/Cake.Issues.Testing/FakeIssueProvider.cs b/src/Cake.Issues.Testing/FakeIssueProvider.cs index 8a20dfd22..7d84a558f 100644 --- a/src/Cake.Issues.Testing/FakeIssueProvider.cs +++ b/src/Cake.Issues.Testing/FakeIssueProvider.cs @@ -13,7 +13,7 @@ public class FakeIssueProvider : BaseIssueProvider /// /// Initializes a new instance of the class. /// - /// The Cake log instance + /// The Cake log instance. public FakeIssueProvider(ICakeLog log) : base(log) { @@ -22,7 +22,7 @@ public FakeIssueProvider(ICakeLog log) /// /// Initializes a new instance of the class. /// - /// The Cake log instance + /// The Cake log instance. /// Issues which should be returned by the issue provider. public FakeIssueProvider(ICakeLog log, IEnumerable issues) : base(log) diff --git a/src/Cake.Issues.Tests/IssueReaderTests.cs b/src/Cake.Issues.Tests/IssueReaderTests.cs index 016c5b58e..61efe99b5 100644 --- a/src/Cake.Issues.Tests/IssueReaderTests.cs +++ b/src/Cake.Issues.Tests/IssueReaderTests.cs @@ -16,7 +16,7 @@ public void Should_Throw_If_Log_Is_Null() // Given var fixture = new IssuesFixture { - Log = null + Log = null, }; // When @@ -32,7 +32,7 @@ public void Should_Throw_If_Issue_Provider_List_Is_Null() // Given var fixture = new IssuesFixture { - IssueProviders = null + IssueProviders = null, }; // When @@ -77,7 +77,7 @@ public void Should_Throw_If_Settings_Are_Null() // Given var fixture = new IssuesFixture { - Settings = null + Settings = null, }; // When @@ -125,7 +125,7 @@ public void Should_Initialize_All_Issue_Provider() .InFile(@"src\Cake.Issues.Tests\FakeIssueProvider.cs", 12) .OfRule("Bar") .WithPriority(IssuePriority.Warning) - .Create() + .Create(), })); fixture.IssueProviders.Add( new FakeIssueProvider( @@ -143,7 +143,7 @@ public void Should_Initialize_All_Issue_Provider() .InFile(@"src\Cake.Issues.Tests\Bar.cs", 7) .OfRule("Bar") .WithPriority(IssuePriority.Warning) - .Create() + .Create(), })); // When @@ -179,7 +179,7 @@ public void Should_Read_Correct_Number_Of_Issues() new List { issue1, - issue2 + issue2, })); // When @@ -215,7 +215,7 @@ public void Should_Read_Correct_Number_Of_Issues_Not_Related_To_A_File() new List { issue1, - issue2 + issue2, })); // When @@ -267,7 +267,7 @@ public void Should_Read_Correct_Number_Of_Issues_From_Multiple_Providers() new List { issue1, - issue2 + issue2, })); fixture.IssueProviders.Add( new FakeIssueProvider( @@ -275,7 +275,7 @@ public void Should_Read_Correct_Number_Of_Issues_From_Multiple_Providers() new List { issue3, - issue4 + issue4, })); // When diff --git a/src/Cake.Issues.Tests/IssuesFixture.cs b/src/Cake.Issues.Tests/IssuesFixture.cs index 96011a5e9..9c6baf706 100644 --- a/src/Cake.Issues.Tests/IssuesFixture.cs +++ b/src/Cake.Issues.Tests/IssuesFixture.cs @@ -1,9 +1,9 @@ namespace Cake.Issues.Tests { using System.Collections.Generic; + using Cake.Core.Diagnostics; using Cake.Issues.Testing; using Cake.Testing; - using Core.Diagnostics; public class IssuesFixture { diff --git a/src/Cake.Issues.Tests/Testing/BaseConfigurableIssueProviderFixtureTests.cs b/src/Cake.Issues.Tests/Testing/BaseConfigurableIssueProviderFixtureTests.cs index 119d339fc..4d267d669 100644 --- a/src/Cake.Issues.Tests/Testing/BaseConfigurableIssueProviderFixtureTests.cs +++ b/src/Cake.Issues.Tests/Testing/BaseConfigurableIssueProviderFixtureTests.cs @@ -120,7 +120,7 @@ public void Should_Throw_If_Log_Is_Null() // Given var fixture = new FakeConfigurableIssueProviderFixture("Build.log") { - Log = null + Log = null, }; // When @@ -136,7 +136,7 @@ public void Should_Throw_If_RepositorySettings_Are_Null() // Given var fixture = new FakeConfigurableIssueProviderFixture("Build.log") { - RepositorySettings = null + RepositorySettings = null, }; // When diff --git a/src/Cake.Issues.Tests/Testing/BaseIssueProviderFixtureTests.cs b/src/Cake.Issues.Tests/Testing/BaseIssueProviderFixtureTests.cs index 82098d7cd..5cb0d3268 100644 --- a/src/Cake.Issues.Tests/Testing/BaseIssueProviderFixtureTests.cs +++ b/src/Cake.Issues.Tests/Testing/BaseIssueProviderFixtureTests.cs @@ -43,7 +43,7 @@ public void Should_Throw_If_Log_Is_Null() // Given var fixture = new FakeIssueProviderFixture { - Log = null + Log = null, }; // When @@ -59,7 +59,7 @@ public void Should_Throw_If_RepositorySettings_Are_Null() // Given var fixture = new FakeIssueProviderFixture { - RepositorySettings = null + RepositorySettings = null, }; // When diff --git a/src/Cake.Issues.Tests/Testing/BaseMultiFormatIssueProviderFixtureTests.cs b/src/Cake.Issues.Tests/Testing/BaseMultiFormatIssueProviderFixtureTests.cs index e7d2dfc8f..540dcf176 100644 --- a/src/Cake.Issues.Tests/Testing/BaseMultiFormatIssueProviderFixtureTests.cs +++ b/src/Cake.Issues.Tests/Testing/BaseMultiFormatIssueProviderFixtureTests.cs @@ -120,7 +120,7 @@ public void Should_Throw_If_Log_Is_Null() // Given var fixture = new FakeMultiFormatIssueProviderFixture("Build.log") { - Log = null + Log = null, }; // When @@ -136,7 +136,7 @@ public void Should_Throw_If_RepositorySettings_Are_Null() // Given var fixture = new FakeMultiFormatIssueProviderFixture("Build.log") { - RepositorySettings = null + RepositorySettings = null, }; // When diff --git a/src/Cake.Issues/BaseIssueProvider.cs b/src/Cake.Issues/BaseIssueProvider.cs index e102854e9..198821f40 100644 --- a/src/Cake.Issues/BaseIssueProvider.cs +++ b/src/Cake.Issues/BaseIssueProvider.cs @@ -33,7 +33,7 @@ public IEnumerable ReadIssues(IssueCommentFormat format) /// Compared to it is safe to access Settings from this method. /// /// Preferred format of the comments. - /// List of issues + /// List of issues. protected abstract IEnumerable InternalReadIssues(IssueCommentFormat format); } } diff --git a/src/Cake.Issues/BaseRuleUrlResolver.cs b/src/Cake.Issues/BaseRuleUrlResolver.cs index d76d76c11..859e7f802 100644 --- a/src/Cake.Issues/BaseRuleUrlResolver.cs +++ b/src/Cake.Issues/BaseRuleUrlResolver.cs @@ -7,14 +7,14 @@ /// /// Base class for retrieving an URL linking to a site containing help for a rule. /// - /// Type of the rule description + /// Type of the rule description. public abstract class BaseRuleUrlResolver where T : BaseRuleDescription, new() { private readonly List, int>> registeredUrlResolver = new List, int>>(); /// - /// Registers a new resolver with default priority of 0. + /// Registers a new resolver with default priority of 0. /// /// Resolver which returns an linking to a site /// containing help for a specific . From ca6dffb7873b2ea6a085b3381f8aecd9ad12a525 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 16:22:40 +0200 Subject: [PATCH 27/36] Use embedded license --- nuspec/nuget/Cake.Issues.Testing.nuspec | 2 +- nuspec/nuget/Cake.Issues.nuspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nuspec/nuget/Cake.Issues.Testing.nuspec b/nuspec/nuget/Cake.Issues.Testing.nuspec index 46ce3fe13..ba45d0df9 100644 --- a/nuspec/nuget/Cake.Issues.Testing.nuspec +++ b/nuspec/nuget/Cake.Issues.Testing.nuspec @@ -10,7 +10,7 @@ Common helpers for testing add-ins based on Cake.Issues - https://github.com/cake-contrib/Cake.Issues.Testing/blob/develop/LICENSE + MIT http://cake-contrib.github.io/Cake.Issues.Website/ https://cdn.jsdelivr.net/gh/cake-contrib/graphics@a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png false diff --git a/nuspec/nuget/Cake.Issues.nuspec b/nuspec/nuget/Cake.Issues.nuspec index c36075fea..02bc2ee3e 100644 --- a/nuspec/nuget/Cake.Issues.nuspec +++ b/nuspec/nuget/Cake.Issues.nuspec @@ -17,7 +17,7 @@ There are also additional addins for generating reports or posting issues to pul See the Project Site for an overview of the whole ecosystem of addins for working with issues in Cake scripts. - https://github.com/cake-contrib/Cake.Issues/blob/develop/LICENSE + MIT http://cake-contrib.github.io/Cake.Issues.Website/ https://cdn.jsdelivr.net/gh/cake-contrib/graphics@a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png false From 5e2cdc0f8051fb08c24e43f3ca8641717e922e31 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 16:51:31 +0200 Subject: [PATCH 28/36] Fix handling of null in ExceptionAssertExtensions --- .../ExceptionAssertExtensions.cs | 42 +++++++----- .../Testing/ExceptionAssertExtensionsTests.cs | 64 +++++++++++++++++-- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs index 055af0a8c..1b6a9c2e9 100644 --- a/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs +++ b/src/Cake.Issues.Testing/ExceptionAssertExtensions.cs @@ -14,10 +14,7 @@ public static class ExceptionAssertExtensions /// Expected name of the parameter which has caused the exception. public static void IsArgumentException(this Exception exception, string parameterName) { - if (!(exception is ArgumentException argumentException)) - { - throw new Exception($"Expected exception of type '{typeof(ArgumentException)}' but was '{exception.GetType()}'"); - } + var argumentException = exception.CheckExceptionType(); if (argumentException.ParamName != parameterName) { @@ -32,10 +29,7 @@ public static void IsArgumentException(this Exception exception, string paramete /// Expected name of the parameter which has caused the exception. public static void IsArgumentNullException(this Exception exception, string parameterName) { - if (!(exception is ArgumentNullException argumentNullException)) - { - throw new Exception($"Expected exception of type '{typeof(ArgumentNullException)}' but was '{exception.GetType()}'"); - } + var argumentNullException = exception.CheckExceptionType(); if (argumentNullException.ParamName != parameterName) { @@ -50,10 +44,7 @@ public static void IsArgumentNullException(this Exception exception, string para /// Expected name of the parameter which has caused the exception. public static void IsArgumentOutOfRangeException(this Exception exception, string parameterName) { - if (!(exception is ArgumentOutOfRangeException argumentOutOfRangeException)) - { - throw new Exception($"Expected exception of type '{typeof(ArgumentOutOfRangeException)}' but was '{exception.GetType()}'"); - } + var argumentOutOfRangeException = exception.CheckExceptionType(); if (argumentOutOfRangeException.ParamName != parameterName) { @@ -68,15 +59,34 @@ public static void IsArgumentOutOfRangeException(this Exception exception, strin /// Expected exception message. public static void IsInvalidOperationException(this Exception exception, string message) { - if (!(exception is InvalidOperationException invalidOperationException)) - { - throw new Exception($"Expected exception of type '{typeof(InvalidOperationException)}' but was '{exception.GetType()}'"); - } + var invalidOperationException = exception.CheckExceptionType(); if (invalidOperationException.Message != message) { throw new Exception($"Expected exception message to be '{message}' but was '{invalidOperationException.Message}'."); } } + + /// + /// Validates and converts an exception type. + /// + /// Type of expected exception. + /// Exception which should be checked. + /// Converted exception. + private static T CheckExceptionType(this Exception exception) + where T : Exception + { + if (exception == null) + { + throw new Exception($"Expected exception of type '{typeof(T)}' but no exception was thrown."); + } + + if (!(exception is T typedException)) + { + throw new Exception($"Expected exception of type '{typeof(T)}' but was '{exception.GetType()}'."); + } + + return typedException; + } } } diff --git a/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs b/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs index 390cb0e09..7e6474d93 100644 --- a/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs +++ b/src/Cake.Issues.Tests/Testing/ExceptionAssertExtensionsTests.cs @@ -9,6 +9,20 @@ public sealed class ExceptionAssertExtensionsTests { public sealed class TheIsArgumentExceptionMethod { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Null() + { + // Given + Exception exception = null; + + // When + var result = Record.Exception(() => exception.IsArgumentException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentException' but no exception was thrown."); + } + [Fact] public void Should_Throw_If_Exception_Type_Is_Not_ArgumentException() { @@ -20,7 +34,7 @@ public void Should_Throw_If_Exception_Type_Is_Not_ArgumentException() // Then result.ShouldBeOfType(); - result.Message.ShouldBe($"Expected exception of type 'System.ArgumentException' but was 'System.Exception'"); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentException' but was 'System.Exception'."); } [Fact] @@ -70,6 +84,20 @@ public void Should_Not_Throw_If_ParamName_Is_The_Same(string actualParamName, st public sealed class TheIsArgumentNullExceptionMethod { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Null() + { + // Given + Exception exception = null; + + // When + var result = Record.Exception(() => exception.IsArgumentNullException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentNullException' but no exception was thrown."); + } + [Fact] public void Should_Throw_If_Exception_Type_Is_Not_ArgumentNullException() { @@ -81,7 +109,7 @@ public void Should_Throw_If_Exception_Type_Is_Not_ArgumentNullException() // Then result.ShouldBeOfType(); - result.Message.ShouldBe($"Expected exception of type 'System.ArgumentNullException' but was 'System.Exception'"); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentNullException' but was 'System.Exception'."); } [Fact] @@ -131,6 +159,20 @@ public void Should_Not_Throw_If_ParamName_Is_The_Same(string actualParamName, st public sealed class TheIsArgumentOutOfRangeExceptionMethod { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Null() + { + // Given + Exception exception = null; + + // When + var result = Record.Exception(() => exception.IsArgumentOutOfRangeException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentOutOfRangeException' but no exception was thrown."); + } + [Fact] public void Should_Throw_If_Exception_Type_Is_Not_ArgumentOutOfRangeException() { @@ -142,7 +184,7 @@ public void Should_Throw_If_Exception_Type_Is_Not_ArgumentOutOfRangeException() // Then result.ShouldBeOfType(); - result.Message.ShouldBe($"Expected exception of type 'System.ArgumentOutOfRangeException' but was 'System.Exception'"); + result.Message.ShouldBe($"Expected exception of type 'System.ArgumentOutOfRangeException' but was 'System.Exception'."); } [Fact] @@ -192,6 +234,20 @@ public void Should_Not_Throw_If_ParamName_Is_The_Same(string actualParamName, st public sealed class TheIsInvalidOperationExceptionMethod { + [Fact] + public void Should_Throw_If_Exception_Type_Is_Null() + { + // Given + Exception exception = null; + + // When + var result = Record.Exception(() => exception.IsInvalidOperationException("Foo")); + + // Then + result.ShouldBeOfType(); + result.Message.ShouldBe($"Expected exception of type 'System.InvalidOperationException' but no exception was thrown."); + } + [Fact] public void Should_Throw_If_Exception_Type_Is_Not_InvalidOperationException() { @@ -203,7 +259,7 @@ public void Should_Throw_If_Exception_Type_Is_Not_InvalidOperationException() // Then result.ShouldBeOfType(); - result.Message.ShouldBe($"Expected exception of type 'System.InvalidOperationException' but was 'System.Exception'"); + result.Message.ShouldBe($"Expected exception of type 'System.InvalidOperationException' but was 'System.Exception'."); } [Fact] From 25c4ede2e9d0b7d4b2e2aba8c07754d05f512f3f Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 20:05:39 +0200 Subject: [PATCH 29/36] Improve exception message for IssueChecker --- src/Cake.Issues.Testing/IssueChecker.cs | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Cake.Issues.Testing/IssueChecker.cs b/src/Cake.Issues.Testing/IssueChecker.cs index 1c036fa3c..29bbb928c 100644 --- a/src/Cake.Issues.Testing/IssueChecker.cs +++ b/src/Cake.Issues.Testing/IssueChecker.cs @@ -77,13 +77,13 @@ public static void Check( if (issue.ProviderType != providerType) { throw new Exception( - $"Expected issue.ProviderType to be {providerType}"); + $"Expected issue.ProviderType to be '{providerType}' but was '{issue.ProviderType}'."); } if (issue.ProviderName != providerName) { throw new Exception( - $"Expected issue.ProviderName to be {providerName}"); + $"Expected issue.ProviderName to be '{providerName}' but was '{issue.ProviderName}'."); } if (issue.ProjectFileRelativePath == null) @@ -91,7 +91,7 @@ public static void Check( if (projectFileRelativePath != null) { throw new Exception( - $"Expected issue.ProjectFileRelativePath to be {projectFileRelativePath}"); + $"Expected issue.ProjectFileRelativePath to be '{projectFileRelativePath}' but was 'null'."); } } else @@ -99,7 +99,7 @@ public static void Check( if (issue.ProjectFileRelativePath.ToString() != new FilePath(projectFileRelativePath).ToString()) { throw new Exception( - $"Expected issue.ProjectFileRelativePath to be {projectFileRelativePath}"); + $"Expected issue.ProjectFileRelativePath to be '{projectFileRelativePath}' but was '{issue.ProjectFileRelativePath.ToString()}'."); } if (!issue.ProjectFileRelativePath.IsRelative) @@ -112,7 +112,7 @@ public static void Check( if (issue.ProjectName != projectName) { throw new Exception( - $"Expected issue.ProjectName to be {projectName}"); + $"Expected issue.ProjectName to be '{projectName}' but was '{issue.ProjectName}'."); } if (issue.AffectedFileRelativePath == null) @@ -120,7 +120,7 @@ public static void Check( if (affectedFileRelativePath != null) { throw new Exception( - $"Expected issue.AffectedFileRelativePath to be {affectedFileRelativePath}"); + $"Expected issue.AffectedFileRelativePath to be '{affectedFileRelativePath}' but was 'null'."); } } else @@ -128,7 +128,7 @@ public static void Check( if (issue.AffectedFileRelativePath.ToString() != new FilePath(affectedFileRelativePath).ToString()) { throw new Exception( - $"Expected issue.AffectedFileRelativePath to be {affectedFileRelativePath}"); + $"Expected issue.AffectedFileRelativePath to be '{affectedFileRelativePath}' but was '{issue.AffectedFileRelativePath.ToString()}'."); } if (!issue.AffectedFileRelativePath.IsRelative) @@ -141,37 +141,37 @@ public static void Check( if (issue.Line != line) { throw new Exception( - $"Expected issue.Line to be {line}"); + $"Expected issue.Line to be '{line}' but was '{issue.Line}'."); } if (issue.Message != message) { throw new Exception( - $"Expected issue.Message to be {message}"); + $"Expected issue.Message to be '{message}' but was '{issue.Message}'."); } if (issue.Priority != priority) { throw new Exception( - $"Expected issue.Priority to be {priority}"); + $"Expected issue.Priority to be '{priority}' but was '{issue.Priority}'."); } if (issue.PriorityName != priorityName) { throw new Exception( - $"Expected issue.PriorityName to be {priorityName}"); + $"Expected issue.PriorityName to be '{priorityName}' but was '{issue.PriorityName}'."); } if (issue.Rule != rule) { throw new Exception( - $"Expected issue.Rule to be {rule}"); + $"Expected issue.Rule to be '{rule}' but was '{issue.Rule}'."); } if (issue.RuleUrl?.ToString() != ruleUrl?.ToString()) { throw new Exception( - $"Expected issue.RuleUrl to be {ruleUrl?.ToString()}"); + $"Expected issue.RuleUrl to be '{ruleUrl?.ToString()}' but was '{issue.RuleUrl?.ToString()}'."); } } } From 8da63f6905dd3fa452bf491980fb30738c7251c3 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Fri, 19 Apr 2019 20:09:36 +0200 Subject: [PATCH 30/36] Allow to pass IssueBuilder to IssueChecker --- src/Cake.Issues.Testing/IssueChecker.cs | 17 ++++++ .../Testing/IssueCheckerTests.cs | 61 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/src/Cake.Issues.Testing/IssueChecker.cs b/src/Cake.Issues.Testing/IssueChecker.cs index 29bbb928c..a784d8970 100644 --- a/src/Cake.Issues.Testing/IssueChecker.cs +++ b/src/Cake.Issues.Testing/IssueChecker.cs @@ -8,6 +8,23 @@ /// public static class IssueChecker { + /// + /// Checks values of an issue. + /// + /// Issue which should be checked. + /// Description of the expected issue. + public static void Check( + IIssue issueToCheck, + IssueBuilder expectedIssue) + { + issueToCheck.NotNull(nameof(issueToCheck)); + expectedIssue.NotNull(nameof(expectedIssue)); + + Check( + issueToCheck, + expectedIssue.Create()); + } + /// /// Checks values of an issue. /// diff --git a/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs b/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs index e3b8f54e5..310fdd7ca 100644 --- a/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs +++ b/src/Cake.Issues.Tests/Testing/IssueCheckerTests.cs @@ -7,6 +7,67 @@ public sealed class IssueCheckerTests { + public sealed class TheCheckMethodWithIssueBuilder + { + [Fact] + public void Should_Throw_If_IssueToCheck_Is_Null() + { +#pragma warning disable SA1123 // Do not place regions within elements + #region DupFinder Exclusion +#pragma warning restore SA1123 // Do not place regions within elements + + // Given + var fixture = new IssueBuilderFixture(); + IIssue issueToCheck = null; + var expectedIssue = fixture.IssueBuilder; + + // When + var result = Record.Exception(() => + IssueChecker.Check(issueToCheck, expectedIssue)); + + // Then + result.IsArgumentNullException("issueToCheck"); + + #endregion + } + + [Fact] + public void Should_Throw_If_ExpectedIssue_Is_Null() + { +#pragma warning disable SA1123 // Do not place regions within elements + #region DupFinder Exclusion +#pragma warning restore SA1123 // Do not place regions within elements + + // Given + var fixture = new IssueBuilderFixture(); + var issueToCheck = fixture.IssueBuilder.Create(); + IssueBuilder expectedIssue = null; + + // When + var result = Record.Exception(() => + IssueChecker.Check(issueToCheck, expectedIssue)); + + // Then + result.IsArgumentNullException("expectedIssue"); + + #endregion + } + + [Fact] + public void Should_Not_Throw_If_Issues_Are_Identical() + { + // Given + var fixture = new IssueCheckerFixture(); + var issueToCheck = fixture.IssueBuilder.Create(); + var expectedIssue = fixture.IssueBuilder; + + // When + IssueChecker.Check(issueToCheck, expectedIssue); + + // Then + } + } + public sealed class TheCheckMethodComparingTwoIssues { [Fact] From 7de8388259052976cea15db2b97fd1d70096ec88 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 25 Apr 2019 23:27:11 +0200 Subject: [PATCH 31/36] Exclude Shouldly from code coverage --- setup.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cake b/setup.cake index 24d61f30f..bc8c59444 100644 --- a/setup.cake +++ b/setup.cake @@ -17,7 +17,7 @@ BuildParameters.PrintParameters(Context); ToolSettings.SetToolSettings( context: Context, dupFinderExcludePattern: new string[] { BuildParameters.RootDirectoryPath + "/src/Cake.Issues.Tests/*.cs", BuildParameters.RootDirectoryPath + "/src/Cake.Issues*/**/*.AssemblyInfo.cs" }, - testCoverageFilter: "+[*]* -[xunit.*]* -[Cake.Core]* -[Cake.Testing]* -[*.Tests]* ", + testCoverageFilter: "+[*]* -[xunit.*]* -[Cake.Core]* -[Cake.Testing]* -[*.Tests]* -[Shouldly]*", testCoverageExcludeByAttribute: "*.ExcludeFromCodeCoverage*", testCoverageExcludeByFile: "*/*Designer.cs;*/*.g.cs;*/*.g.i.cs"); From 91fd524b25fb22603b90a7c3ef87068e06b321ff Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 25 Apr 2019 23:43:13 +0200 Subject: [PATCH 32/36] Build with Cake.Recipe 1.0.0 --- setup.cake | 2 +- tools/packages.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cake b/setup.cake index bc8c59444..c22d5dd85 100644 --- a/setup.cake +++ b/setup.cake @@ -1,4 +1,4 @@ -#load nuget:https://www.myget.org/F/cake-contrib/api/v2?package=Cake.Recipe&prerelease +#load nuget:?package=Cake.Recipe&version=1.0.0 Environment.SetVariableNames(); diff --git a/tools/packages.config b/tools/packages.config index 2e475d63f..997c0e1b3 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,4 +1,4 @@ - + From f3670a4d52e9856669348fb6d29d7e19fda430b3 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 23 May 2019 23:52:36 +0200 Subject: [PATCH 33/36] Fix analyzer issues --- src/Cake.Issues/IBaseIssueComponent.cs | 2 +- src/Cake.Issues/ILogFileFormat.cs | 2 +- src/Cake.Issues/IssueCommentFormat.cs | 2 +- src/Cake.Issues/IssuePriority.cs | 2 +- src/Cake.Issues/IssuesArgumentChecks.cs | 12 ++++++------ src/Cake.Issues/StringPathExtensions.cs | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Cake.Issues/IBaseIssueComponent.cs b/src/Cake.Issues/IBaseIssueComponent.cs index dedb2d9d8..8d10ddc91 100644 --- a/src/Cake.Issues/IBaseIssueComponent.cs +++ b/src/Cake.Issues/IBaseIssueComponent.cs @@ -12,7 +12,7 @@ public interface IBaseIssueComponent /// /// Initializes the component. /// - /// The settings + /// The settings. /// true if the initialization was successful, false otherwise. bool Initialize(T settings); diff --git a/src/Cake.Issues/ILogFileFormat.cs b/src/Cake.Issues/ILogFileFormat.cs index 8d73a8355..ca62fdcdd 100644 --- a/src/Cake.Issues/ILogFileFormat.cs +++ b/src/Cake.Issues/ILogFileFormat.cs @@ -18,7 +18,7 @@ public interface ILogFileFormat /// Preferred format for comments. /// Repository settings to use. /// Settings for issue provider to use. - /// List of issues + /// List of issues. IEnumerable ReadIssues( TIssueProvider issueProvider, IssueCommentFormat format, diff --git a/src/Cake.Issues/IssueCommentFormat.cs b/src/Cake.Issues/IssueCommentFormat.cs index baf02d20a..6ca94d6de 100644 --- a/src/Cake.Issues/IssueCommentFormat.cs +++ b/src/Cake.Issues/IssueCommentFormat.cs @@ -23,6 +23,6 @@ public enum IssueCommentFormat /// /// Markdown syntax. /// - Markdown + Markdown, } } diff --git a/src/Cake.Issues/IssuePriority.cs b/src/Cake.Issues/IssuePriority.cs index 561b599d0..3c57b5aa5 100644 --- a/src/Cake.Issues/IssuePriority.cs +++ b/src/Cake.Issues/IssuePriority.cs @@ -28,6 +28,6 @@ public enum IssuePriority /// /// Issues that either prevent code from compiling or result in runtime errors. /// - Error = 400 + Error = 400, } } diff --git a/src/Cake.Issues/IssuesArgumentChecks.cs b/src/Cake.Issues/IssuesArgumentChecks.cs index 7efa4caac..678048352 100644 --- a/src/Cake.Issues/IssuesArgumentChecks.cs +++ b/src/Cake.Issues/IssuesArgumentChecks.cs @@ -16,7 +16,7 @@ public static class IssuesArgumentChecks /// The type of the parameter. /// The value of the argument. /// The name of the parameter to include in any thrown exception. - /// Thrown if is null + /// Thrown if is null. [DebuggerStepThrough] public static void NotNull([ValidatedNotNull]this T value, string parameterName) where T : class @@ -32,8 +32,8 @@ public static void NotNull([ValidatedNotNull]this T value, string parameterNa /// /// The value of the argument. /// The name of the parameter to include in any thrown exception. - /// Thrown if is null - /// Thrown if is empty or consists only of white-space characters + /// Thrown if is null. + /// Thrown if is empty or consists only of white-space characters. [DebuggerStepThrough] public static void NotNullOrWhiteSpace([ValidatedNotNull]this string value, string parameterName) { @@ -84,7 +84,7 @@ public static void NotNegativeOrZero(this int value, string parameterName) /// The type of the parameter. /// The value of the argument. /// The name of the parameter to include in any thrown exception. - /// Thrown if is null + /// Thrown if is null. /// Thrown if is empty. [DebuggerStepThrough] public static void NotNullOrEmpty(this IEnumerable value, string parameterName) @@ -105,7 +105,7 @@ public static void NotNullOrEmpty(this IEnumerable value, string parameter /// The type of the parameter. /// The value of the argument. /// The name of the parameter to include in any thrown exception. - /// Thrown if is null + /// Thrown if is null. /// Thrown if is empty. /// Thrown if contains an empty element. [DebuggerStepThrough] @@ -127,7 +127,7 @@ public static void NotNullOrEmptyElement(this IEnumerable value, string pa /// The type of the parameter. /// The value of the argument. /// The name of the parameter to include in any thrown exception. - /// Thrown if is null + /// Thrown if is null. /// Thrown if is empty. /// Thrown if contains an empty element. [DebuggerStepThrough] diff --git a/src/Cake.Issues/StringPathExtensions.cs b/src/Cake.Issues/StringPathExtensions.cs index 934420293..16a9bf48a 100644 --- a/src/Cake.Issues/StringPathExtensions.cs +++ b/src/Cake.Issues/StringPathExtensions.cs @@ -26,7 +26,7 @@ public static bool IsValidPath(this string path) /// /// Checks if a string containing a path is a full path. /// - /// Path which should be checked + /// Path which should be checked. /// True if full path. public static bool IsFullPath(this string path) { @@ -102,7 +102,7 @@ public static string NormalizePath(this string path) /// "hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo". /// String to which should be added. /// String which should be added to . - /// with the minimal concatenation of + /// with the minimal concatenation of . internal static string WithEnding(this string value, string ending) { if (value == null) From 4c21b9f97341d13c37921a4a35d6ce08b09a4c0b Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 23 May 2019 23:54:00 +0200 Subject: [PATCH 34/36] Fix parameter name --- src/Cake.Issues.Tests/IssueTests.cs | 6 +++--- src/Cake.Issues/Issue.cs | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Cake.Issues.Tests/IssueTests.cs b/src/Cake.Issues.Tests/IssueTests.cs index 643ab326e..3df1205d5 100644 --- a/src/Cake.Issues.Tests/IssueTests.cs +++ b/src/Cake.Issues.Tests/IssueTests.cs @@ -367,7 +367,7 @@ public void Should_Set_ProjectName(string projectName) } } - public sealed class TheFilePathArgument + public sealed class TheAffectedFileRelativePathArgument { [Theory] [InlineData("foo\tbar")] @@ -401,7 +401,7 @@ public void Should_Throw_If_File_Path_Is_Invalid(string filePath) providerName)); // Then - result.IsArgumentException("filePath"); + result.IsArgumentException("affectedFileRelativePath"); } [Theory] @@ -438,7 +438,7 @@ public void Should_Throw_If_File_Path_Is_Absolute(string filePath) providerName)); // Then - result.IsArgumentOutOfRangeException("filePath"); + result.IsArgumentOutOfRangeException("affectedFileRelativePath"); } [Fact] diff --git a/src/Cake.Issues/Issue.cs b/src/Cake.Issues/Issue.cs index e8714449a..d84186f90 100644 --- a/src/Cake.Issues/Issue.cs +++ b/src/Cake.Issues/Issue.cs @@ -16,7 +16,7 @@ public class Issue : IIssue /// Can be null or if issue is not related to a project. /// The name of the project to which the file affected by the issue belongs. /// Can be null or if issue is not related to a project. - /// The path to the file affacted by the issue. + /// The path to the file affacted by the issue. /// The path needs to be relative to the repository root. /// null or if issue is not related to a change in a file. /// The line in the file where the issues has occurred. @@ -35,7 +35,7 @@ public class Issue : IIssue public Issue( string projectFileRelativePath, string projectName, - string filePath, + string affectedFileRelativePath, int? line, string message, int? priority, @@ -67,18 +67,18 @@ public Issue( } // File path needs to be relative to the repository root. - if (!string.IsNullOrWhiteSpace(filePath)) + if (!string.IsNullOrWhiteSpace(affectedFileRelativePath)) { - if (!filePath.IsValidPath()) + if (!affectedFileRelativePath.IsValidPath()) { - throw new ArgumentException("Invalid path", nameof(filePath)); + throw new ArgumentException("Invalid path", nameof(affectedFileRelativePath)); } - this.AffectedFileRelativePath = filePath; + this.AffectedFileRelativePath = affectedFileRelativePath; if (!this.AffectedFileRelativePath.IsRelative) { - throw new ArgumentOutOfRangeException(nameof(filePath), "File path needs to be relative to the repository root."); + throw new ArgumentOutOfRangeException(nameof(affectedFileRelativePath), "File path needs to be relative to the repository root."); } } From 232c89bd2cb40a74fa6b5610f437d7254062f5c7 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Mon, 27 May 2019 15:21:04 +0200 Subject: [PATCH 35/36] (GH-106) Add aliases for serialization and deserialization of issues (#107) --- .../Cake.Issues.Tests.csproj | 12 + .../IssueSerializationExtensionsTests.cs | 827 ++++++++++++++++++ .../Testfiles/empty-array.json | 1 + src/Cake.Issues.Tests/Testfiles/issue.json | 13 + src/Cake.Issues.Tests/Testfiles/issues.json | 28 + src/Cake.Issues/Aliases.IssueSerialization.cs | 231 +++++ .../IssueSerializationExtensions.cs | 226 +++++ src/Cake.Issues/IssuesAliasConstants.cs | 5 + src/Cake.Issues/SerializableIssue.cs | 55 ++ 9 files changed, 1398 insertions(+) create mode 100644 src/Cake.Issues.Tests/IssueSerializationExtensionsTests.cs create mode 100644 src/Cake.Issues.Tests/Testfiles/empty-array.json create mode 100644 src/Cake.Issues.Tests/Testfiles/issue.json create mode 100644 src/Cake.Issues.Tests/Testfiles/issues.json create mode 100644 src/Cake.Issues/Aliases.IssueSerialization.cs create mode 100644 src/Cake.Issues/IssueSerializationExtensions.cs create mode 100644 src/Cake.Issues/SerializableIssue.cs diff --git a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj index f279bc345..3f73f8f4c 100644 --- a/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj +++ b/src/Cake.Issues.Tests/Cake.Issues.Tests.csproj @@ -42,4 +42,16 @@ + + + Always + + + Always + + + Always + + + diff --git a/src/Cake.Issues.Tests/IssueSerializationExtensionsTests.cs b/src/Cake.Issues.Tests/IssueSerializationExtensionsTests.cs new file mode 100644 index 000000000..dd18d166d --- /dev/null +++ b/src/Cake.Issues.Tests/IssueSerializationExtensionsTests.cs @@ -0,0 +1,827 @@ +namespace Cake.Issues.Tests +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Cake.Core.IO; + using Cake.Issues.Testing; + using Shouldly; + using Xunit; + + public sealed class IssueSerializationExtensionsTests + { + public sealed class TheSerializeToJsonStringExtensionForASingleIssue + { + [Fact] + public void Should_Throw_If_Issue_Is_Null() + { + // Given + IIssue issue = null; + + // When + var result = Record.Exception(() => issue.SerializeToJsonString()); + + // Then + result.IsArgumentNullException("issue"); + } + + [Fact] + public void Should_Give_Correct_Result_For_Message_After_Roundtrip() + { + // Given + var message = "message"; + var issue = + IssueBuilder + .NewIssue(message, "providerType", "providerName") + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.Message.ShouldBe(message); + } + + [Fact] + public void Should_Give_Correct_Result_For_ProviderType_After_Roundtrip() + { + // Given + var providerType = "providerType"; + var issue = + IssueBuilder + .NewIssue("message", providerType, "providerName") + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.ProviderType.ShouldBe(providerType); + } + + [Fact] + public void Should_Give_Correct_Result_For_ProviderName_After_Roundtrip() + { + // Given + var providerName = "providerName"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", providerName) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.ProviderName.ShouldBe(providerName); + } + + [Fact] + public void Should_Give_Correct_Result_For_ProjectFileRelativePath_After_Roundtrip() + { + // Given + var projectFileRelativePath = @"src/myproj.file"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InProjectFile(projectFileRelativePath) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.ProjectFileRelativePath.FullPath.ShouldBe(projectFileRelativePath); + } + + [Fact] + public void Should_Give_Correct_Result_For_ProjectName_After_Roundtrip() + { + // Given + var projectName = "projectName"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InProjectOfName(projectName) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.ProjectName.ShouldBe(projectName); + } + + [Fact] + public void Should_Give_Correct_Result_For_AffectedFileRelativePath_After_Roundtrip() + { + // Given + var affectedFileRelativePath = @"src/foo.bar"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InFile(affectedFileRelativePath) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.AffectedFileRelativePath.FullPath.ShouldBe(affectedFileRelativePath); + } + + [Fact] + public void Should_Give_Correct_Result_For_Line_After_Roundtrip() + { + // Given + var line = 42; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InFile(@"src/foo.bar", line) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.Line.ShouldBe(line); + } + + [Fact] + public void Should_Give_Correct_Result_For_Priority_After_Roundtrip() + { + // Given + var priority = 42; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .WithPriority(priority, "priorityName") + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.Priority.ShouldBe(priority); + } + + [Fact] + public void Should_Give_Correct_Result_For_PriorityName_After_Roundtrip() + { + // Given + var priorityName = "priorityName"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .WithPriority(42, priorityName) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.PriorityName.ShouldBe(priorityName); + } + + [Fact] + public void Should_Give_Correct_Result_For_Rule_After_Roundtrip() + { + // Given + var rule = "rule"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .OfRule(rule) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.Rule.ShouldBe(rule); + } + + [Fact] + public void Should_Give_Correct_Result_For_RuleUrl_After_Roundtrip() + { + // Given + var ruleUrl = new Uri("https://rule.url"); + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .OfRule("rule", ruleUrl) + .Create(); + + // When + var result = issue.SerializeToJsonString().DeserializeToIssue(); + + // Then + result.RuleUrl.ToString().ShouldBe(ruleUrl.ToString()); + } + } + + public sealed class TheSerializeToJsonStringExtensionForAnEnumerableOfIssues + { + [Fact] + public void Should_Throw_If_Issue_Is_Null() + { + // Given + IEnumerable issues = null; + + // When + var result = Record.Exception(() => issues.SerializeToJsonString()); + + // Then + result.IsArgumentNullException("issues"); + } + + [Fact] + public void Should_Serialize_Issues() + { + // Given + var issues = + new List + { + IssueBuilder + .NewIssue("message1", "providerType1", "providerName1") + .Create(), + IssueBuilder + .NewIssue("message2", "providerType2", "providerName2") + .Create(), + }; + + // When + var result = issues.SerializeToJsonString(); + + // Then + result.ShouldNotBeNull(); + } + } + + public sealed class TheSerializeToJsonFileExtensionForASingleIssue + { + [Fact] + public void Should_Throw_If_Issue_Is_Null() + { + // Given + IIssue issue = null; + var filePath = @"c:\issue.json"; + + // When + var result = Record.Exception(() => issue.SerializeToJsonFile(filePath)); + + // Then + result.IsArgumentNullException("issue"); + } + + [Fact] + public void Should_Throw_If_FilePath_Is_Null() + { + // Given + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .Create(); + FilePath filePath = null; + + // When + var result = Record.Exception(() => issue.SerializeToJsonFile(filePath)); + + // Then + result.IsArgumentNullException("filePath"); + } + + [Fact] + public void Should_Give_Correct_Result_For_Message_After_Roundtrip() + { + // Given + var message = "message"; + var issue = + IssueBuilder + .NewIssue(message, "providerType", "providerName") + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.Message.ShouldBe(message); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_ProviderType_After_Roundtrip() + { + // Given + var providerType = "providerType"; + var issue = + IssueBuilder + .NewIssue("message", providerType, "providerName") + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.ProviderType.ShouldBe(providerType); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_ProviderName_After_Roundtrip() + { + // Given + var providerName = "providerName"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", providerName) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.ProviderName.ShouldBe(providerName); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_ProjectFileRelativePath_After_Roundtrip() + { + // Given + var projectFileRelativePath = @"src/myproj.file"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InProjectFile(projectFileRelativePath) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.ProjectFileRelativePath.FullPath.ShouldBe(projectFileRelativePath); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_ProjectName_After_Roundtrip() + { + // Given + var projectName = "projectName"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InProjectOfName(projectName) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.ProjectName.ShouldBe(projectName); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_AffectedFileRelativePath_After_Roundtrip() + { + // Given + var affectedFileRelativePath = @"src/foo.bar"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InFile(affectedFileRelativePath) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.AffectedFileRelativePath.FullPath.ShouldBe(affectedFileRelativePath); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_Line_After_Roundtrip() + { + // Given + var line = 42; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .InFile(@"src/foo.bar", line) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.Line.ShouldBe(line); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_Priority_After_Roundtrip() + { + // Given + var priority = 42; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .WithPriority(priority, "priorityName") + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.Priority.ShouldBe(priority); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_PriorityName_After_Roundtrip() + { + // Given + var priorityName = "priorityName"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .WithPriority(42, priorityName) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.PriorityName.ShouldBe(priorityName); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_Rule_After_Roundtrip() + { + // Given + var rule = "rule"; + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .OfRule(rule) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.Rule.ShouldBe(rule); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + + [Fact] + public void Should_Give_Correct_Result_For_RuleUrl_After_Roundtrip() + { + // Given + var ruleUrl = new Uri("https://rule.url"); + var issue = + IssueBuilder + .NewIssue("message", "providerType", "providerName") + .OfRule("rule", ruleUrl) + .Create(); + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issue.SerializeToJsonFile(filePath); + var result = filePath.DeserializeToIssue(); + + // Then + result.RuleUrl.ToString().ShouldBe(ruleUrl.ToString()); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + } + + public sealed class TheSerializeToJsonFileExtensionForAnEnumerableOfIssues + { + [Fact] + public void Should_Throw_If_Issue_Is_Null() + { + // Given + IEnumerable issues = null; + var filePath = @"c:\issues.json"; + + // When + var result = Record.Exception(() => issues.SerializeToJsonFile(filePath)); + + // Then + result.IsArgumentNullException("issues"); + } + + [Fact] + public void Should_Throw_If_FilePath_Is_Null() + { + // Given + var issues = new List(); + FilePath filePath = null; + + // When + var result = Record.Exception(() => issues.SerializeToJsonFile(filePath)); + + // Then + result.IsArgumentNullException("filePath"); + } + + [Fact] + public void Should_Serialize_Issues() + { + // Given + var issues = + new List + { + IssueBuilder + .NewIssue("message1", "providerType1", "providerName1") + .Create(), + IssueBuilder + .NewIssue("message2", "providerType2", "providerName2") + .Create(), + }; + var filePath = new FilePath(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".json"); + + try + { + // When + issues.SerializeToJsonFile(filePath); + + // Then + System.IO.File.Exists(filePath.FullPath).ShouldBeTrue(); + } + finally + { + System.IO.File.Delete(filePath.FullPath); + } + } + } + + public sealed class TheDeserializeToIssueExtensionForAJsonString + { + [Fact] + public void Should_Throw_If_JsonString_Is_Null() + { + // Given + string jsonString = null; + + // When + var result = Record.Exception(() => jsonString.DeserializeToIssue()); + + // Then + result.IsArgumentNullException("jsonString"); + } + } + + public sealed class TheDeserializeToIssuesExtensionForAJsonString + { + [Fact] + public void Should_Throw_If_JsonString_Is_Null() + { + // Given + string jsonString = null; + + // When + var result = Record.Exception(() => jsonString.DeserializeToIssues()); + + // Then + result.IsArgumentNullException("jsonString"); + } + + [Fact] + public void Should_Return_An_Empty_List_For_An_Empty_Array() + { + // Given + string jsonString = "[]"; + + // When + var result = jsonString.DeserializeToIssues(); + + // Then + result.ShouldBeEmpty(); + } + } + + public sealed class TheDeserializeToIssueExtensionForAJsonFile + { + [Fact] + public void Should_Throw_If_FilePath_Is_Null() + { + // Given + FilePath filePath = null; + + // When + var result = Record.Exception(() => filePath.DeserializeToIssue()); + + // Then + result.IsArgumentNullException("filePath"); + } + + [Fact] + public void Should_Return_Issue() + { + // Given + var filePath = new FilePath("Testfiles/issue.json"); + + // When + var result = filePath.DeserializeToIssue(); + + // Then + IssueChecker.Check( + result, + IssueBuilder.NewIssue( + "Something went wrong.", + "TestProvider", + "Test Provider") + .InProject(@"src\Foo\Bar.csproj", "Bar") + .InFile(@"src\Foo\Bar.cs", 42) + .OfRule("Rule", new Uri("https://google.com")) + .WithPriority(IssuePriority.Warning)); + } + } + + public sealed class TheDeserializeToIssuesExtensionForAJsonFile + { + [Fact] + public void Should_Throw_If_FilePath_Is_Null() + { + // Given + FilePath filePath = null; + + // When + var result = Record.Exception(() => filePath.DeserializeToIssues()); + + // Then + result.IsArgumentNullException("filePath"); + } + + [Fact] + public void Should_Return_An_Empty_List_For_An_Empty_Array() + { + // Given + var filePath = new FilePath("Testfiles/empty-array.json"); + + // When + var result = filePath.DeserializeToIssues(); + + // Then + result.ShouldBeEmpty(); + } + + [Fact] + public void Should_Return_List_Of_Issues() + { + // Given + var filePath = new FilePath("Testfiles/issues.json"); + + // When + var result = filePath.DeserializeToIssues().ToList(); + + // Then + result.Count.ShouldBe(2); + IssueChecker.Check( + result[0], + IssueBuilder.NewIssue( + "Something went wrong.", + "TestProvider", + "Test Provider") + .InProject(@"src\Foo\Bar.csproj", "Bar") + .InFile(@"src\Foo\Bar.cs", 42) + .OfRule("Rule", new Uri("https://google.com")) + .WithPriority(IssuePriority.Warning)); + IssueChecker.Check( + result[1], + IssueBuilder.NewIssue( + "Something went wrong again.", + "TestProvider", + "Test Provider") + .InProject(@"src\Foo\Bar.csproj", "Bar") + .InFile(@"src\Foo\Bar2.cs") + .WithPriority(IssuePriority.Warning)); + } + } + + public sealed class TheToSerializableIssueExtension + { + [Fact] + public void Should_Throw_If_Issue_Is_Null() + { + // Given + IIssue issue = null; + + // When + var result = Record.Exception(() => issue.ToSerializableIssue()); + + // Then + result.IsArgumentNullException("issue"); + } + } + + public sealed class TheToIssueExtension + { + [Fact] + public void Should_Throw_If_SerializableIssue_Is_Null() + { + // Given + SerializableIssue serializableIssue = null; + + // When + var result = Record.Exception(() => serializableIssue.ToIssue()); + + // Then + result.IsArgumentNullException("serializableIssue"); + } + } + } +} \ No newline at end of file diff --git a/src/Cake.Issues.Tests/Testfiles/empty-array.json b/src/Cake.Issues.Tests/Testfiles/empty-array.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/src/Cake.Issues.Tests/Testfiles/empty-array.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/src/Cake.Issues.Tests/Testfiles/issue.json b/src/Cake.Issues.Tests/Testfiles/issue.json new file mode 100644 index 000000000..8818f72b1 --- /dev/null +++ b/src/Cake.Issues.Tests/Testfiles/issue.json @@ -0,0 +1,13 @@ +{ + "AffectedFileRelativePath": "src\/Foo\/Bar.cs", + "Line": 42, + "Message": "Something went wrong.", + "Priority": 300, + "PriorityName": "Warning", + "ProjectFileRelativePath": "src\/Foo\/Bar.csproj", + "ProjectName": "Bar", + "ProviderName": "Test Provider", + "ProviderType": "TestProvider", + "Rule": "Rule", + "RuleUrl": "https://google.com" +} \ No newline at end of file diff --git a/src/Cake.Issues.Tests/Testfiles/issues.json b/src/Cake.Issues.Tests/Testfiles/issues.json new file mode 100644 index 000000000..e9ff4e3ad --- /dev/null +++ b/src/Cake.Issues.Tests/Testfiles/issues.json @@ -0,0 +1,28 @@ +[ + { + "AffectedFileRelativePath": "src\/Foo\/Bar.cs", + "Line": 42, + "Message": "Something went wrong.", + "Priority": 300, + "PriorityName": "Warning", + "ProjectFileRelativePath": "src\/Foo\/Bar.csproj", + "ProjectName": "Bar", + "ProviderName": "Test Provider", + "ProviderType": "TestProvider", + "Rule": "Rule", + "RuleUrl": "https://google.com" + }, + { + "AffectedFileRelativePath": "src\/Foo\/Bar2.cs", + "Line": null, + "Message": "Something went wrong again.", + "Priority": 300, + "PriorityName": "Warning", + "ProjectFileRelativePath": "src\/Foo\/Bar.csproj", + "ProjectName": "Bar", + "ProviderName": "Test Provider", + "ProviderType": "TestProvider", + "Rule": null, + "RuleUrl": null + } +] \ No newline at end of file diff --git a/src/Cake.Issues/Aliases.IssueSerialization.cs b/src/Cake.Issues/Aliases.IssueSerialization.cs new file mode 100644 index 000000000..56959cff3 --- /dev/null +++ b/src/Cake.Issues/Aliases.IssueSerialization.cs @@ -0,0 +1,231 @@ +namespace Cake.Issues +{ + using System.Collections.Generic; + using Cake.Core; + using Cake.Core.Annotations; + using Cake.Core.IO; + + /// + /// Contains functionality related to serializing and deserializing issues. + /// + public static partial class Aliases + { + /// + /// Serializes an to a JSON string. + /// + /// The context. + /// Issue which should be serialized. + /// Serialized issue. + /// + /// Serializes an issue to a JSON string: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static string SerializeIssueToJsonString( + this ICakeContext context, + IIssue issue) + { + context.NotNull(nameof(context)); + issue.NotNull(nameof(issue)); + + return issue.SerializeToJsonString(); + } + + /// + /// Serializes an to a JSON string. + /// + /// The context. + /// Issues which should be serialized. + /// Serialized issues. + /// + /// Serializes a list of issues to a JSON string: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static string SerializeIssuesToJsonString( + this ICakeContext context, + IEnumerable issues) + { + context.NotNull(nameof(context)); + issues.NotNull(nameof(issues)); + + return issues.SerializeToJsonString(); + } + + /// + /// Serializes an to a JSON file. + /// + /// The context. + /// Issue which should be serialized. + /// Path to the file. + /// + /// Serializes an issue to a JSON file: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static void SerializeIssueToJsonFile( + this ICakeContext context, + IIssue issue, + FilePath filePath) + { + context.NotNull(nameof(context)); + issue.NotNull(nameof(issue)); + filePath.NotNull(nameof(filePath)); + + issue.SerializeToJsonFile(filePath); + } + + /// + /// Serializes an to a JSON file. + /// + /// The context. + /// Issues which should be serialized. + /// Path to the file. + /// + /// Serializes a list of issues to a JSON file: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static void SerializeIssuesToJsonFile( + this ICakeContext context, + IEnumerable issues, + FilePath filePath) + { + context.NotNull(nameof(context)); + issues.NotNull(nameof(issues)); + filePath.NotNull(nameof(filePath)); + + issues.SerializeToJsonFile(filePath); + } + + /// + /// Deserializes an from a JSON string. + /// + /// The context. + /// JSON representation of the issue. + /// Instance of the issue. + /// + /// Deserializes an issue from a JSON string: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static Issue DeserializeIssueFromJsonString( + this ICakeContext context, + string jsonString) + { + context.NotNull(nameof(context)); + jsonString.NotNullOrWhiteSpace(nameof(jsonString)); + + return jsonString.DeserializeToIssue(); + } + + /// + /// Deserializes an from a JSON string. + /// + /// The context. + /// JSON representation of the issues. + /// List of issues. + /// + /// Deserializes a list of issue from a JSON string: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static IEnumerable DeserializeIssuesFromJsonString( + this ICakeContext context, + string jsonString) + { + context.NotNull(nameof(context)); + jsonString.NotNullOrWhiteSpace(nameof(jsonString)); + + return jsonString.DeserializeToIssues(); + } + + /// + /// Deserializes an from a JSON file. + /// + /// The context. + /// Path to the JSON file. + /// Instance of the issue. + /// + /// Deserializes an issue from a JSON file: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static Issue DeserializeIssueFromJsonFile( + this ICakeContext context, + FilePath filePath) + { + context.NotNull(nameof(context)); + filePath.NotNull(nameof(filePath)); + + return filePath.DeserializeToIssue(); + } + + /// + /// Deserializes an from a JSON file. + /// + /// The context. + /// Path to the JSON file. + /// List of issues. + /// + /// Deserializes a list of issue from a JSON file: + /// + /// + /// + /// + [CakeMethodAlias] + [CakeAliasCategory(IssuesAliasConstants.SerializationCakeAliasCategory)] + public static IEnumerable DeserializeIssuesFromJsonFile( + this ICakeContext context, + FilePath filePath) + { + context.NotNull(nameof(context)); + filePath.NotNull(nameof(filePath)); + + return filePath.DeserializeToIssues(); + } + } +} diff --git a/src/Cake.Issues/IssueSerializationExtensions.cs b/src/Cake.Issues/IssueSerializationExtensions.cs new file mode 100644 index 000000000..3a6a9e6d5 --- /dev/null +++ b/src/Cake.Issues/IssueSerializationExtensions.cs @@ -0,0 +1,226 @@ +namespace Cake.Issues +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Runtime.Serialization.Json; + using System.Text; + using Cake.Core.IO; + + /// + /// Extensions for serializing and deserializing an . + /// + internal static class IssueSerializationExtensions + { + /// + /// Serializes an to a JSON string. + /// + /// Issue which should be serialized. + /// Serialized issue. + public static string SerializeToJsonString(this IIssue issue) + { + issue.NotNull(nameof(issue)); + + var serializer = new DataContractJsonSerializer(typeof(SerializableIssue)); + + using (var stream = new MemoryStream()) + { + serializer.WriteObject(stream, issue.ToSerializableIssue()); + return Encoding.UTF8.GetString(stream.ToArray()); + } + } + + /// + /// Serializes an to a JSON string. + /// + /// Issues which should be serialized. + /// Serialized issues. + public static string SerializeToJsonString(this IEnumerable issues) + { + issues.NotNull(nameof(issues)); + + var serializer = new DataContractJsonSerializer(typeof(IEnumerable)); + + using (var stream = new MemoryStream()) + { + serializer.WriteObject(stream, issues.Select(x => x.ToSerializableIssue())); + return Encoding.UTF8.GetString(stream.ToArray()); + } + } + + /// + /// Serializes an to a JSON file. + /// + /// Issue which should be serialized. + /// Path to the file. + public static void SerializeToJsonFile(this IIssue issue, FilePath filePath) + { + issue.NotNull(nameof(issue)); + filePath.NotNull(nameof(filePath)); + + var serializer = new DataContractJsonSerializer(typeof(SerializableIssue)); + + using (var stream = File.Open(filePath.FullPath, FileMode.Create)) + { + serializer.WriteObject(stream, issue.ToSerializableIssue()); + } + } + + /// + /// Serializes an to a JSON file. + /// + /// Issues which should be serialized. + /// Path to the file. + public static void SerializeToJsonFile(this IEnumerable issues, FilePath filePath) + { + issues.NotNull(nameof(issues)); + filePath.NotNull(nameof(filePath)); + + var serializer = new DataContractJsonSerializer(typeof(IEnumerable)); + + using (var stream = File.Open(filePath.FullPath, FileMode.Create)) + { + serializer.WriteObject(stream, issues.Select(x => x.ToSerializableIssue())); + } + } + + /// + /// Deserializes an from a JSON string. + /// + /// JSON representation of the issue. + /// Instance of the issue. + public static Issue DeserializeToIssue(this string jsonString) + { + jsonString.NotNullOrWhiteSpace(nameof(jsonString)); + + using (var stream = new MemoryStream(Encoding.Default.GetBytes(jsonString))) + { + return DeserializeStreamToIssue(stream); + } + } + + /// + /// Deserializes an from a JSON string. + /// + /// JSON representation of the issues. + /// List of issues. + public static IEnumerable DeserializeToIssues(this string jsonString) + { + jsonString.NotNullOrWhiteSpace(nameof(jsonString)); + + using (var stream = new MemoryStream(Encoding.Default.GetBytes(jsonString))) + { + return DeserializeStreamToIssues(stream); + } + } + + /// + /// Deserializes an from a JSON file. + /// + /// Path to the JSON file. + /// Instance of the issue. + public static Issue DeserializeToIssue(this FilePath filePath) + { + filePath.NotNull(nameof(filePath)); + + using (var stream = File.Open(filePath.FullPath, FileMode.Open)) + { + return DeserializeStreamToIssue(stream); + } + } + + /// + /// Deserializes an from a JSON file. + /// + /// Path to the JSON file. + /// List of issues. + public static IEnumerable DeserializeToIssues(this FilePath filePath) + { + filePath.NotNull(nameof(filePath)); + + using (var stream = File.Open(filePath.FullPath, FileMode.Open)) + { + return DeserializeStreamToIssues(stream); + } + } + + /// + /// Converts an to a . + /// + /// Issue which should be converted. + /// Converted issue. + internal static SerializableIssue ToSerializableIssue(this IIssue issue) + { + issue.NotNull(nameof(issue)); + + return new SerializableIssue + { + ProjectFileRelativePath = issue.ProjectFileRelativePath?.FullPath, + ProjectName = issue.ProjectName, + AffectedFileRelativePath = issue.AffectedFileRelativePath?.FullPath, + Line = issue.Line, + Message = issue.Message, + Priority = issue.Priority, + PriorityName = issue.PriorityName, + Rule = issue.Rule, + RuleUrl = issue.RuleUrl?.ToString(), + ProviderType = issue.ProviderType, + ProviderName = issue.ProviderName, + }; + } + + /// + /// Converts a to an . + /// + /// Issue which should be converted. + /// Converted issue. + internal static Issue ToIssue(this SerializableIssue serializableIssue) + { + serializableIssue.NotNull(nameof(serializableIssue)); + + Uri ruleUrl = null; + if (!string.IsNullOrWhiteSpace(serializableIssue.RuleUrl)) + { + ruleUrl = new Uri(serializableIssue.RuleUrl); + } + + return new Issue( + serializableIssue.ProjectFileRelativePath, + serializableIssue.ProjectName, + serializableIssue.AffectedFileRelativePath, + serializableIssue.Line, + serializableIssue.Message, + serializableIssue.Priority, + serializableIssue.PriorityName, + serializableIssue.Rule, + ruleUrl, + serializableIssue.ProviderType, + serializableIssue.ProviderName); + } + + private static Issue DeserializeStreamToIssue(Stream stream) + { + var serializer = new DataContractJsonSerializer(typeof(SerializableIssue)); + + if (!(serializer.ReadObject(stream) is SerializableIssue deserializedIssue)) + { + return null; + } + + return deserializedIssue.ToIssue(); + } + + private static IEnumerable DeserializeStreamToIssues(Stream stream) + { + var serializer = new DataContractJsonSerializer(typeof(IEnumerable)); + + if (!(serializer.ReadObject(stream) is IEnumerable deserializedIssues)) + { + return new List(); + } + + return deserializedIssues.Select(x => x.ToIssue()); + } + } +} diff --git a/src/Cake.Issues/IssuesAliasConstants.cs b/src/Cake.Issues/IssuesAliasConstants.cs index 94c45aa39..4ecf0d797 100644 --- a/src/Cake.Issues/IssuesAliasConstants.cs +++ b/src/Cake.Issues/IssuesAliasConstants.cs @@ -20,6 +20,11 @@ public static class IssuesAliasConstants /// public const string ReadCakeAliasCategory = "Reading Issues"; + /// + /// Category to use for all Cake aliases providing functionality for serializing and deserializing issues. + /// + public const string SerializationCakeAliasCategory = "Issue Serialization"; + /// /// Category to use for all Cake aliases creating issue providers. /// diff --git a/src/Cake.Issues/SerializableIssue.cs b/src/Cake.Issues/SerializableIssue.cs new file mode 100644 index 000000000..86c80e743 --- /dev/null +++ b/src/Cake.Issues/SerializableIssue.cs @@ -0,0 +1,55 @@ +namespace Cake.Issues +{ + using System.Runtime.Serialization; + + /// + /// Class for serializing and deserializing an instance. + /// + [DataContract] + internal class SerializableIssue + { + /// + [DataMember] + public string ProjectFileRelativePath { get; set; } + + /// + [DataMember] + public string ProjectName { get; set; } + + /// + [DataMember] + public string AffectedFileRelativePath { get; set; } + + /// + [DataMember] + public int? Line { get; set; } + + /// + [DataMember] + public string Message { get; set; } + + /// + [DataMember] + public int? Priority { get; set; } + + /// + [DataMember] + public string PriorityName { get; set; } + + /// + [DataMember] + public string Rule { get; set; } + + /// + [DataMember] + public string RuleUrl { get; set; } + + /// + [DataMember] + public string ProviderType { get; set; } + + /// + [DataMember] + public string ProviderName { get; set; } + } +} From 4b8ea0f46628f45bf7edc912075136d3e9e9016d Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Tue, 28 May 2019 22:11:25 +0200 Subject: [PATCH 36/36] Update repository URL --- nuspec/nuget/Cake.Issues.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nuspec/nuget/Cake.Issues.nuspec b/nuspec/nuget/Cake.Issues.nuspec index 02bc2ee3e..d0d6a2c74 100644 --- a/nuspec/nuget/Cake.Issues.nuspec +++ b/nuspec/nuget/Cake.Issues.nuspec @@ -21,7 +21,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin http://cake-contrib.github.io/Cake.Issues.Website/ https://cdn.jsdelivr.net/gh/cake-contrib/graphics@a5cf0f881c390650144b2243ae551d5b9f836196/png/cake-contrib-medium.png false - + Copyright © BBT Software AG and contributors Cake Script Cake-Issues CodeAnalysis Linting Issues https://github.com/cake-contrib/Cake.Issues/releases/tag/0.7.0