From a06d436da703a58b575372901984e919c7e69166 Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 4 Apr 2025 14:06:55 +0200 Subject: [PATCH 01/11] set exit code according ExitCodes.cs --- Directory.Packages.props | 8 +++--- Documentation/GlobalTool.md | 1 - .../coverlet.collector.csproj | 1 - src/coverlet.console/ExitCodes.cs | 5 ---- src/coverlet.console/Program.cs | 23 +++++++++-------- src/coverlet.console/coverlet.console.csproj | 1 - .../coverlet.msbuild.tasks.csproj | 1 - .../DeepThought.cs | 23 ++++++++++++----- test/coverlet.integration.tests/DotnetTool.cs | 25 ++++++++++--------- test/coverlet.integration.tests/Msbuild.cs | 24 +++++++++--------- .../coverlet.integration.tests.csproj | 1 + 11 files changed, 59 insertions(+), 54 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index eba94e254..995b8e1fc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -54,18 +54,18 @@ - + - + - + - + diff --git a/Documentation/GlobalTool.md b/Documentation/GlobalTool.md index e91f67c9d..6b9161b4f 100644 --- a/Documentation/GlobalTool.md +++ b/Documentation/GlobalTool.md @@ -275,5 +275,4 @@ Coverlet outputs specific exit codes to better support build automation systems 2 - Coverage percentage is below threshold. 3 - Test fails and also coverage percentage is below threshold. 101 - General exception occurred during coverlet process. -102 - Missing options or invalid arguments for coverlet process. ``` diff --git a/src/coverlet.collector/coverlet.collector.csproj b/src/coverlet.collector/coverlet.collector.csproj index 7630bb845..fa18b7b3c 100644 --- a/src/coverlet.collector/coverlet.collector.csproj +++ b/src/coverlet.collector/coverlet.collector.csproj @@ -27,7 +27,6 @@ tonerdo MIT https://github.com/coverlet-coverage/coverlet - https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true coverlet-icon.png false Coverlet is a cross platform code coverage library for .NET, with support for line, branch and method coverage. diff --git a/src/coverlet.console/ExitCodes.cs b/src/coverlet.console/ExitCodes.cs index 93a7d395f..616bf8b10 100644 --- a/src/coverlet.console/ExitCodes.cs +++ b/src/coverlet.console/ExitCodes.cs @@ -28,10 +28,5 @@ internal enum CommandExitCodes /// Indicates exception occurred during Coverlet process. /// Exception = 101, - - /// - /// Indicates missing options or empty arguments for Coverlet process. - /// - CommandParsingException = 102 } diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index ec763612d..f591095b0 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -25,6 +25,7 @@ namespace Coverlet.Console { public static class Program { + static int s_exitCode; static int Main(string[] args) { var moduleOrAppDirectory = new Argument("path", "Path to the test assembly or application directory."); @@ -175,7 +176,7 @@ string sourceMappingFile // Adjust log level based on user input. logger.Level = verbosity; - int exitCode = (int)CommandExitCodes.Success; + s_exitCode = (int)CommandExitCodes.Success; try { @@ -357,44 +358,44 @@ string sourceMappingFile logger.LogInformation(coverageTable.ToStringAlternative()); if (process.ExitCode > 0) { - exitCode += (int)CommandExitCodes.TestFailed; + s_exitCode = (int)CommandExitCodes.TestFailed; } ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStat); if (thresholdTypeFlags != ThresholdTypeFlags.None) { - exitCode += (int)CommandExitCodes.CoverageBelowThreshold; - var exceptionMessageBuilder = new StringBuilder(); + s_exitCode = (int)CommandExitCodes.CoverageBelowThreshold; + var errorMessageBuilder = new StringBuilder(); if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None) { - exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Line]}"); + errorMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Line]}"); } if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None) { - exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Branch]}"); + errorMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Branch]}"); } if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None) { - exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Method]}"); + errorMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {thresholdTypeFlagValues[ThresholdTypeFlags.Method]}"); } - throw new InvalidOperationException(exceptionMessageBuilder.ToString()); + logger.LogError(errorMessageBuilder.ToString()); } - return Task.FromResult(exitCode); + return Task.FromResult(s_exitCode); } catch (Win32Exception we) when (we.Source == "System.Diagnostics.Process") { logger.LogError($"Start process '{target}' failed with '{we.Message}'"); - return Task.FromResult(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception); + return Task.FromResult(s_exitCode > 0 ? s_exitCode : (int)CommandExitCodes.Exception); } catch (Exception ex) { logger.LogError(ex.Message); - return Task.FromResult(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception); + return Task.FromResult(s_exitCode > 0 ? s_exitCode : (int)CommandExitCodes.Exception); } } diff --git a/src/coverlet.console/coverlet.console.csproj b/src/coverlet.console/coverlet.console.csproj index 2a7181b18..c2798a2a1 100644 --- a/src/coverlet.console/coverlet.console.csproj +++ b/src/coverlet.console/coverlet.console.csproj @@ -16,7 +16,6 @@ coverage;testing;unit-test;lcov;opencover;quality GlobalTool.md https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/Changelog.md - https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true coverlet-icon.png https://github.com/coverlet-coverage/coverlet MIT diff --git a/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj b/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj index c04e823b0..08e532b4f 100644 --- a/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj +++ b/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj @@ -28,7 +28,6 @@ tonerdo MIT https://github.com/coverlet-coverage/coverlet - https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true coverlet-icon.png false true diff --git a/test/coverlet.integration.template/DeepThought.cs b/test/coverlet.integration.template/DeepThought.cs index e2a3f4b9c..998a001a2 100644 --- a/test/coverlet.integration.template/DeepThought.cs +++ b/test/coverlet.integration.template/DeepThought.cs @@ -1,10 +1,21 @@ -namespace Coverlet.Integration.Template +namespace Coverlet.Integration.Template { - public class DeepThought + public class DeepThought + { + public int AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() { - public int AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() - { - return 42; - } + return 42; } + + // This method is not covered by any test + // It is here to demonstrate how Coverlet will report on untested code + // required for Coverlet.Integration.Tests.DotnetGlobalTools.StandAloneThreshold + // required for Coverlet.Integration.Tests.DotnetGlobalTools.DotnetToolThreshold + public void TheUntestedMethod() + { +#pragma warning disable CS0219 // Variable is assigned but its value is never used + string s = "this will never be covered by any test"; +#pragma warning restore CS0219 // Variable is assigned but its value is never used + } + } } diff --git a/test/coverlet.integration.tests/DotnetTool.cs b/test/coverlet.integration.tests/DotnetTool.cs index 91e989f02..918df68e2 100644 --- a/test/coverlet.integration.tests/DotnetTool.cs +++ b/test/coverlet.integration.tests/DotnetTool.cs @@ -35,13 +35,14 @@ public void DotnetTool() string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", out string buildOutput, out string buildError); string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll").Single(f => !f.Contains("obj") && !f.Contains("ref")); - RunCommand(coverletToolCommandPath, $"\"{publishedTestFile}\" --target \"dotnet\" --targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" --include-test-assembly --output \"{outputPath}\"", out string standardOutput, out string standardError); + int cmdExitCode = RunCommand(coverletToolCommandPath, $"\"{publishedTestFile}\" --target \"dotnet\" --targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" --include-test-assembly --output \"{outputPath}\"", out string standardOutput, out string standardError); if (!string.IsNullOrEmpty(standardError)) { _output.WriteLine(standardError); } Assert.Contains("Passed!", standardOutput); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); + Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); } [Fact] @@ -53,7 +54,7 @@ public void StandAlone() string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", out string buildOutput, out string buildError); string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll").Single(f => !f.Contains("obj") && !f.Contains("ref")); - RunCommand(coverletToolCommandPath, $"\"{Path.GetDirectoryName(publishedTestFile)}\" --target \"dotnet\" --targetargs \"{publishedTestFile}\" --output \"{outputPath}\"", out string standardOutput, out string standardError); + int cmdExitCode = RunCommand(coverletToolCommandPath, $"\"{Path.GetDirectoryName(publishedTestFile)}\" --target \"dotnet\" --targetargs \"{publishedTestFile}\" --output \"{outputPath}\"", out string standardOutput, out string standardError); if (!string.IsNullOrEmpty(standardError)) { _output.WriteLine(standardError); @@ -61,6 +62,7 @@ public void StandAlone() //Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); + Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); } [Fact] @@ -85,10 +87,9 @@ public void StandAloneThreshold() //Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); - //Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); - // this messages are now in stderr available but standardError stream is empty in test environment - //Assert.Contains("The minimum line coverage is below the specified 80", standardError); - //Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); + Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); + Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); + Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); } [Fact] @@ -113,9 +114,9 @@ public void StandAloneThresholdLine() // Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); - //Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); - //Assert.Contains("The minimum line coverage is below the specified 80", standardError); - //Assert.DoesNotContain("The minimum method coverage is below the specified 80", standardOutput); + Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); + Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); + Assert.DoesNotContain("The minimum method coverage is below the specified 80", standardOutput); } [Fact] @@ -140,9 +141,9 @@ public void StandAloneThresholdLineAndMethod() // Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); - //Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); - //Assert.Contains("The minimum line coverage is below the specified 80", standardError); - //Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); + Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); + Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); + Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); } } } diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index abb784d10..7e4c8656f 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -45,7 +45,7 @@ public void TestMsbuild() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -66,7 +66,7 @@ public void TestMsbuild_NoCoverletOutput() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -87,7 +87,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithoutExtension() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -99,7 +99,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension() using ClonedTemplateProject clonedTemplateProject = PrepareTemplateProject(); Assert.Equal(0, DotnetCli($"test -c {_buildConfiguration} -f {_buildTargetFramework} \"{clonedTemplateProject.ProjectRootPath}\" /p:CollectCoverage=true /p:Include=\"[{ClonedTemplateProject.AssemblyName}]*DeepThought\" /p:IncludeTestAssembly=true /p:CoverletOutput=\"{clonedTemplateProject.ProjectRootPath}\"\\file.ext", out string standardOutput, out string standardError)); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -123,7 +123,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension_SpecifyFramework _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, "file.ext"))); AssertCoverage(clonedTemplateProject, "file.ext"); } @@ -142,7 +142,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithDoubleExtension() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext1.ext2"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -164,7 +164,7 @@ public void Test_MultipleTargetFrameworkReport_NoCoverletOutput() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -191,7 +191,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -218,7 +218,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -248,7 +248,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -281,7 +281,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -307,7 +307,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 100% | 100% | 100% |", standardOutput, StringComparison.Ordinal); + Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { diff --git a/test/coverlet.integration.tests/coverlet.integration.tests.csproj b/test/coverlet.integration.tests/coverlet.integration.tests.csproj index 4c8cc9c50..fbb887bc2 100644 --- a/test/coverlet.integration.tests/coverlet.integration.tests.csproj +++ b/test/coverlet.integration.tests/coverlet.integration.tests.csproj @@ -29,6 +29,7 @@ + From 06732cf1d384a97003c4f02990575a1aa86373c8 Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 4 Apr 2025 14:27:25 +0200 Subject: [PATCH 02/11] remove comments --- test/coverlet.integration.tests/DotnetTool.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/coverlet.integration.tests/DotnetTool.cs b/test/coverlet.integration.tests/DotnetTool.cs index 918df68e2..cadec6207 100644 --- a/test/coverlet.integration.tests/DotnetTool.cs +++ b/test/coverlet.integration.tests/DotnetTool.cs @@ -59,7 +59,6 @@ public void StandAlone() { _output.WriteLine(standardError); } - //Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); @@ -84,7 +83,6 @@ public void StandAloneThreshold() // make standard output available in trx file _output.WriteLine(standardOutput); } - //Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); @@ -111,7 +109,6 @@ public void StandAloneThresholdLine() // make standard output available in trx file _output.WriteLine(standardOutput); } - // Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); @@ -138,7 +135,6 @@ public void StandAloneThresholdLineAndMethod() // make standard output available in trx file _output.WriteLine(standardOutput); } - // Assert.Contains("Hello World!", standardOutput); Assert.True(File.Exists(outputPath)); AssertCoverage(clonedTemplateProject, standardOutput: standardOutput); Assert.Equal((int)CommandExitCodes.CoverageBelowThreshold, cmdExitCode); From e41b132d28baa025030940a7e121862f7c59ec10 Mon Sep 17 00:00:00 2001 From: Bert Date: Mon, 7 Apr 2025 10:18:45 +0200 Subject: [PATCH 03/11] update xunit.v3 version (double-check trx functionality) --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 995b8e1fc..4bf6202f1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -13,7 +13,7 @@ 17.13.0 6.13.2 - 2.0.0 + 2.0.1 3.0.2 From 4b51722f78efac176914f540ff68e2a268ac1954 Mon Sep 17 00:00:00 2001 From: Bert Date: Mon, 7 Apr 2025 10:28:57 +0200 Subject: [PATCH 04/11] revert xunit.v3 version update --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 4bf6202f1..995b8e1fc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -13,7 +13,7 @@ 17.13.0 6.13.2 - 2.0.1 + 2.0.0 3.0.2 From 4c549f3ff59f27695e828b0b612f90006dc9d2fa Mon Sep 17 00:00:00 2001 From: Bert Date: Thu, 10 Apr 2025 14:20:14 +0200 Subject: [PATCH 05/11] update SDK version --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 6dfc6666e..0417b6523 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.407" + "version": "8.0.408" } } From 484d643401026aa75efdc5a6fedf96859ed546fd Mon Sep 17 00:00:00 2001 From: Bert Date: Sat, 17 May 2025 10:23:06 +0200 Subject: [PATCH 06/11] update nuget packages --- Directory.Packages.props | 8 ++++---- .../coverlet.core.tests.samples.netstandard.csproj | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 995b8e1fc..70fd039bb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,7 +12,7 @@ 4.12.0 17.13.0 - 6.13.2 + 6.14.0 2.0.0 3.0.2 @@ -58,14 +58,14 @@ - + - + - + diff --git a/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj b/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj index 36bc43a36..a7ce141f5 100644 --- a/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj +++ b/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj @@ -8,7 +8,7 @@ - + From 9a206625cf35e52029a802d4be7c693809823526 Mon Sep 17 00:00:00 2001 From: Bert Date: Tue, 27 May 2025 11:15:17 +0200 Subject: [PATCH 07/11] improve excludeAssembliesWithoutSources parameter validation --- global.json | 2 +- src/coverlet.console/Program.cs | 2 +- test/coverlet.integration.tests/DotnetTool.cs | 84 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 0417b6523..8b2877a60 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.408" + "version": "8.0.409" } } diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index f591095b0..acc1e9652 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -48,7 +48,7 @@ static int Main(string[] args) var mergeWith = new Option("--merge-with", "Path to existing coverage result to merge.") { Arity = ArgumentArity.ZeroOrOne }; var useSourceLink = new Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.") { Arity = ArgumentArity.Zero }; var doesNotReturnAttributes = new Option("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; - var excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", "Specifies behavior of heuristic to ignore assemblies with missing source documents.") { Arity = ArgumentArity.ZeroOrOne }; + Option excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", "Specifies behavior of heuristic to ignore assemblies with missing source documents.").FromAmong("MissingAll", "MissingAny", "None"); var sourceMappingFile = new Option("--source-mapping-file", "Specifies the path to a SourceRootsMappings file.") { Arity = ArgumentArity.ZeroOrOne }; RootCommand rootCommand = new() diff --git a/test/coverlet.integration.tests/DotnetTool.cs b/test/coverlet.integration.tests/DotnetTool.cs index cadec6207..19c45b305 100644 --- a/test/coverlet.integration.tests/DotnetTool.cs +++ b/test/coverlet.integration.tests/DotnetTool.cs @@ -141,5 +141,89 @@ public void StandAloneThresholdLineAndMethod() Assert.Contains("The minimum line coverage is below the specified 80", standardOutput); Assert.Contains("The minimum method coverage is below the specified 80", standardOutput); } + + [Fact] + public void ExcludeAssembliesWithoutSources_WrongValue() + { + using ClonedTemplateProject clonedTemplateProject = CloneTemplateProject(); + UpdateNugetConfigWithLocalPackageFolder(clonedTemplateProject.ProjectRootPath!); + string coverletToolCommandPath = InstallTool(clonedTemplateProject.ProjectRootPath!); + string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; + + // Build the test project + DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", + out string buildOutput, + out string buildError); + + string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll") + .Single(f => !f.Contains("obj") && !f.Contains("ref")); + + // Run coverage with exclude-assemblies-without-sources parameter + int cmdExitCode = RunCommand( + coverletToolCommandPath, + $"\"{publishedTestFile}\" --target \"dotnet\" " + + $"--targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" " + + $"--exclude-assemblies-without-sources nonsense " + + $"--output \"{outputPath}\"", + out string standardOutput, + out string standardError); + + if (!string.IsNullOrEmpty(standardError)) + { + _output.WriteLine(standardError); + } + else + { + _output.WriteLine(standardOutput); + } + + // Verify results + Assert.Contains("Argument 'nonsense' not recognized. Must be one of:\t'MissingAll'\t'MissingAny'\t'None'", standardError); + } + + [Theory] + [InlineData("MissingAll")] + [InlineData("MissingAny")] + [InlineData("None")] + public void ExcludeAssembliesWithoutSources_DifferentModes(string mode) + { + using ClonedTemplateProject clonedTemplateProject = CloneTemplateProject(); + UpdateNugetConfigWithLocalPackageFolder(clonedTemplateProject.ProjectRootPath!); + string coverletToolCommandPath = InstallTool(clonedTemplateProject.ProjectRootPath!); + string outputPath = $"{clonedTemplateProject.ProjectRootPath}{Path.DirectorySeparatorChar}coverage.json"; + + // Build the test project + DotnetCli($"build -f {_buildTargetFramework} {clonedTemplateProject.ProjectRootPath}", + out string buildOutput, + out string buildError); + + string publishedTestFile = clonedTemplateProject.GetFiles("*" + ClonedTemplateProject.AssemblyName + ".dll") + .Single(f => !f.Contains("obj") && !f.Contains("ref")); + + // Run coverage with different exclude-assemblies-without-sources modes + int cmdExitCode = RunCommand( + coverletToolCommandPath, + $"\"{publishedTestFile}\" --target \"dotnet\" " + + $"--targetargs \"test {Path.Combine(clonedTemplateProject.ProjectRootPath, ClonedTemplateProject.ProjectFileName)} --no-build\" " + + $"--exclude-assemblies-without-sources {mode} " + + $"--output \"{outputPath}\"", + out string standardOutput, + out string standardError); + + if (!string.IsNullOrEmpty(standardError)) + { + _output.WriteLine(standardError); + } + else + { + _output.WriteLine(standardOutput); + } + + // Verify basic execution + Assert.Empty(standardError); + Assert.True(File.Exists(outputPath), "Coverage output file should exist"); + Assert.Equal((int)CommandExitCodes.Success, cmdExitCode); + Assert.Contains("Passed!", standardOutput); + } } } From ee97f189b7a6536dd7dda3ce6d0cd0ce247337ec Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 6 Jun 2025 08:44:12 +0200 Subject: [PATCH 08/11] Refactor assertions to use expected result variable Added a static readonly string `_expectedResult` in the `Msbuild` class to hold the expected output format. Updated multiple assertions to use this variable instead of hardcoded strings, enhancing maintainability and readability of the test code. --- test/coverlet.integration.tests/Msbuild.cs | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index 7e4c8656f..65e878575 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -14,6 +14,7 @@ public class Msbuild : BaseTest private readonly string _buildConfiguration; private readonly string _buildTargetFramework; private readonly ITestOutputHelper _output; + private static readonly string _expectedResult = "| coverletsamplelib.integration.template | 50 % | 100 % | 50 % |"; public Msbuild(ITestOutputHelper output) { @@ -45,7 +46,7 @@ public void TestMsbuild() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -66,7 +67,7 @@ public void TestMsbuild_NoCoverletOutput() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -87,7 +88,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithoutExtension() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -99,7 +100,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension() using ClonedTemplateProject clonedTemplateProject = PrepareTemplateProject(); Assert.Equal(0, DotnetCli($"test -c {_buildConfiguration} -f {_buildTargetFramework} \"{clonedTemplateProject.ProjectRootPath}\" /p:CollectCoverage=true /p:Include=\"[{ClonedTemplateProject.AssemblyName}]*DeepThought\" /p:IncludeTestAssembly=true /p:CoverletOutput=\"{clonedTemplateProject.ProjectRootPath}\"\\file.ext", out string standardOutput, out string standardError)); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -123,7 +124,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension_SpecifyFramework _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, "file.ext"))); AssertCoverage(clonedTemplateProject, "file.ext"); } @@ -142,7 +143,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithDoubleExtension() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext1.ext2"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -164,7 +165,7 @@ public void Test_MultipleTargetFrameworkReport_NoCoverletOutput() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -191,7 +192,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -218,7 +219,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -248,7 +249,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -281,7 +282,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -307,7 +308,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains("| coverletsamplelib.integration.template | 50% | 100% | 50% |", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { From 9c341dc0aadedca42f1584bb1423a4f9fe71e457 Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 6 Jun 2025 09:28:49 +0200 Subject: [PATCH 09/11] Update Msbuild.cs fix name --- test/coverlet.integration.tests/Msbuild.cs | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index 65e878575..9281fd0d7 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -14,7 +14,7 @@ public class Msbuild : BaseTest private readonly string _buildConfiguration; private readonly string _buildTargetFramework; private readonly ITestOutputHelper _output; - private static readonly string _expectedResult = "| coverletsamplelib.integration.template | 50 % | 100 % | 50 % |"; + private static readonly string s_expectedResult = "| coverletsamplelib.integration.template | 50 % | 100 % | 50 % |"; public Msbuild(ITestOutputHelper output) { @@ -46,7 +46,7 @@ public void TestMsbuild() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -67,7 +67,7 @@ public void TestMsbuild_NoCoverletOutput() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"coverage.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -88,7 +88,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithoutExtension() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.json"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -100,7 +100,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension() using ClonedTemplateProject clonedTemplateProject = PrepareTemplateProject(); Assert.Equal(0, DotnetCli($"test -c {_buildConfiguration} -f {_buildTargetFramework} \"{clonedTemplateProject.ProjectRootPath}\" /p:CollectCoverage=true /p:Include=\"[{ClonedTemplateProject.AssemblyName}]*DeepThought\" /p:IncludeTestAssembly=true /p:CoverletOutput=\"{clonedTemplateProject.ProjectRootPath}\"\\file.ext", out string standardOutput, out string standardError)); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -124,7 +124,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameExtension_SpecifyFramework _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, "file.ext"))); AssertCoverage(clonedTemplateProject, "file.ext"); } @@ -143,7 +143,7 @@ public void TestMsbuild_CoverletOutput_Folder_FileNameWithDoubleExtension() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); string coverageFileName = $"file.ext1.ext2"; Assert.True(File.Exists(Path.Combine(clonedTemplateProject.ProjectRootPath, coverageFileName))); AssertCoverage(clonedTemplateProject, coverageFileName); @@ -165,7 +165,7 @@ public void Test_MultipleTargetFrameworkReport_NoCoverletOutput() _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -192,7 +192,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder() } Assert.Equal(0, result); Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -219,7 +219,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -249,7 +249,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -282,7 +282,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { @@ -308,7 +308,7 @@ public void Test_MultipleTargetFrameworkReport_CoverletOutput_Folder_FileNameWit _output.WriteLine(standardOutput); } Assert.Contains("Passed!", standardOutput, StringComparison.Ordinal); - Assert.Contains($"{_expectedResult}", standardOutput, StringComparison.Ordinal); + Assert.Contains($"{s_expectedResult}", standardOutput, StringComparison.Ordinal); foreach (string targetFramework in targetFrameworks) { From 8c2bdc6179c28a9f69a8b17a845494202c4487f4 Mon Sep 17 00:00:00 2001 From: Bert Date: Fri, 6 Jun 2025 10:09:31 +0200 Subject: [PATCH 10/11] apply copilot comments --- test/coverlet.integration.tests/Msbuild.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index 9281fd0d7..53afa3fc5 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -14,7 +14,7 @@ public class Msbuild : BaseTest private readonly string _buildConfiguration; private readonly string _buildTargetFramework; private readonly ITestOutputHelper _output; - private static readonly string s_expectedResult = "| coverletsamplelib.integration.template | 50 % | 100 % | 50 % |"; + private static readonly string s_expectedResult = "| coverletsamplelib.integration.template | 50% | 100% | 50% |"; public Msbuild(ITestOutputHelper output) { From 61b14afc0e78f3396bb169832eabb8f962d02166 Mon Sep 17 00:00:00 2001 From: Bert Date: Sat, 7 Jun 2025 11:36:54 +0200 Subject: [PATCH 11/11] set default and specify formats --- src/coverlet.console/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index acc1e9652..93e595683 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -33,9 +33,9 @@ static int Main(string[] args) var targs = new Option(["--targetargs", "-a"], "Arguments to be passed to the test runner.") { Arity = ArgumentArity.ZeroOrOne }; var output = new Option(["--output", "-o"], "Output of the generated coverage report") { Arity = ArgumentArity.ZeroOrOne }; var verbosity = new Option(["--verbosity", "-v"], () => LogLevel.Normal, "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.") { Arity = ArgumentArity.ZeroOrOne }; - var formats = new Option(["--format", "-f"], () => ["json"], "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; + var formats = new Option(aliases: ["--format", "-f"], getDefaultValue: () => ["json"], description: "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }.FromAmong("json", "lcov", "opencover", "cobertura", "teamcity"); var threshold = new Option("--threshold", "Exits with error if the coverage % is below value.") { Arity = ArgumentArity.ZeroOrOne }; - Option> thresholdTypes = new Option>("--threshold-type", () => new List(new string[] { "line", "branch", "method" }), "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method"); + Option> thresholdTypes = new Option>("--threshold-type", () => ["line", "branch", "method"], "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method"); var thresholdStat = new Option("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrOne }; var excludeFilters = new Option("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var includeFilters = new Option("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; @@ -48,7 +48,7 @@ static int Main(string[] args) var mergeWith = new Option("--merge-with", "Path to existing coverage result to merge.") { Arity = ArgumentArity.ZeroOrOne }; var useSourceLink = new Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.") { Arity = ArgumentArity.Zero }; var doesNotReturnAttributes = new Option("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; - Option excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", "Specifies behavior of heuristic to ignore assemblies with missing source documents.").FromAmong("MissingAll", "MissingAny", "None"); + Option excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", () => "MissingAll", "Specifies behavior of heuristic to ignore assemblies with missing source documents.").FromAmong("MissingAll", "MissingAny", "None"); var sourceMappingFile = new Option("--source-mapping-file", "Specifies the path to a SourceRootsMappings file.") { Arity = ArgumentArity.ZeroOrOne }; RootCommand rootCommand = new()