├── .gitattributes
├── test
├── .gitignore
├── coverlet.core.tests
│ ├── .gitignore
│ ├── coverlet.core.tests.snk
│ ├── TestAssets
│ │ ├── System.Private.CoreLib.dll
│ │ ├── System.Private.CoreLib.pdb
│ │ ├── CoverletSourceRootsMappingTest
│ │ ├── 75d9f96508d74def860a568f426ea4a4.dll
│ │ └── 75d9f96508d74def860a568f426ea4a4.pdb
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Samples
│ │ ├── .editorconfig
│ │ ├── Instrumentation.ExcludeFromCoverage.Issue1302.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.NestedStateMachines.cs
│ │ ├── Instrumentation.AsyncIterator.cs
│ │ ├── Instrumentation.AutoProps.cs
│ │ ├── Instrumentation.SelectionStatements.cs
│ │ ├── Instrumentation.AwaitUsing.cs
│ │ ├── Instrumentation.AsyncForeach.cs
│ │ ├── Instrumentation.Yield.cs
│ │ ├── Instrumentation.ExcludeFromCoverage.Issue670.cs
│ │ ├── Instrumentation.ExcludeFilter.cs
│ │ └── Instrumentation.AsyncAwaitValueTask.cs
│ ├── Helpers
│ │ ├── FileSystemTests.cs
│ │ └── RetryHelperTests.cs
│ ├── Reporters
│ │ ├── ReporterFactoryTests.cs
│ │ ├── JsonReporterTests.cs
│ │ ├── LcovReporterTests.cs
│ │ └── Reporters.cs
│ └── Coverage
│ │ ├── CoverageTests.AsyncIterator.cs
│ │ ├── CoverageTests.AwaitUsing.cs
│ │ ├── CoverageTests.IntegerOverflow.cs
│ │ └── CoverageTests.AsyncAwaitValueTask.cs
├── coverlet.tests.remoteexecutor
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── coverlet.tests.remoteexecutor.snk
│ ├── coverlet.tests.remoteexecutor.csproj
│ └── Program.cs
├── coverlet.collector.tests
│ ├── coverlet.collector.tests.snk
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── coverlet.collector.tests.csproj
├── coverlet.integration.tests
│ ├── coverlet.integration.tests.snk
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── coverlet.integration.tests.csproj
│ ├── DotnetTool.cs
│ └── AssertHelper.cs
├── coverlet.core.tests.samples.netstandard
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── coverlet.core.tests.samples.netstandard.snk
│ ├── .editorconfig
│ ├── coverlet.core.tests.samples.netstandard.csproj
│ └── Instrumentation.AsyncAwait.cs
├── coverlet.tests.projectsample.fsharp
│ ├── Library.fs
│ └── coverlet.tests.projectsample.fsharp.fsproj
├── coverlet.tests.xunit.extensions
│ ├── coverlet.tests.xunit.extensions.snk
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── ITestCondition.cs
│ ├── coverlet.tests.xunit.extensions.csproj
│ ├── SkipOnOS.cs
│ ├── Extensions.cs
│ └── ConditionalFact.cs
├── coverlet.tests.projectsample.empty
│ ├── Class1.cs
│ ├── coverlet.tests.projectsample.empty.csproj
│ └── .editorconfig
├── coverlet.integration.template
│ ├── nuget.config
│ ├── DeepThought.cs
│ ├── .editorconfig
│ ├── TemplateTest.cs
│ ├── Program.cs
│ └── coverlet.integration.template.csproj
├── Directory.Build.props
├── coverlet.testsubject
│ ├── coverlet.testsubject.csproj
│ └── .editorconfig
├── coverlet.integration.determisticbuild
│ ├── DeepThought.cs
│ ├── .editorconfig
│ ├── TemplateTest.cs
│ └── coverlet.integration.determisticbuild.csproj
├── coverlet.core.performancetest
│ ├── .editorconfig
│ ├── coverlet.core.performancetest.csproj
│ └── PerformanceTest.cs
├── coverlet.tests.projectsample.netframework
│ ├── .editorconfig
│ ├── AsyncAwaitStateMachineNetFramework.cs
│ └── coverlet.tests.projectsample.netframework.csproj
├── coverlet.tests.projectsample.excludedbyattribute
│ ├── coverlet.tests.projectsample.excludedbyattribute.csproj
│ ├── .editorconfig
│ └── SampleClass.cs
└── Directory.Build.targets
├── _assets
├── coverlet.png
├── coverlet@2x.png
├── coverlet@3x.png
├── coverlet@4x.png
├── coverlet-icon.png
├── coverlet@0.5x.png
├── coverlet@1.5x.png
├── coverlet@0.75x.png
└── coverlet-icon.svg
├── src
├── coverlet.console
│ ├── runtimeconfig.template.json
│ ├── coverlet.console.snk
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── ConsoleTables
│ │ └── .editorconfig
│ ├── ExitCodes.cs
│ ├── Logging
│ │ ├── LogLevel.cs
│ │ └── ConsoleLogger.cs
│ └── coverlet.console.csproj
├── coverlet.core
│ ├── coverlet.core.snk
│ ├── Abstractions
│ │ ├── IConsole.cs
│ │ ├── IProcessExitHandler.cs
│ │ ├── IRetryHelper.cs
│ │ ├── ILogger.cs
│ │ ├── ISourceRootTranslator.cs
│ │ ├── IReporter.cs
│ │ ├── ICecilSymbolHelper.cs
│ │ ├── IFileSystem.cs
│ │ └── IInstrumentationHelper.cs
│ ├── Enums
│ │ ├── ThresholdStatistic.cs
│ │ └── ThresholdTypeFlags.cs
│ ├── Attributes
│ │ ├── DoesNotReturnAttribute.cs
│ │ └── ExcludeFromCoverage.cs
│ ├── Helpers
│ │ ├── Console.cs
│ │ ├── ProcessExitHandler.cs
│ │ ├── FileSystem.cs
│ │ └── RetryHelper.cs
│ ├── Extensions
│ │ └── HelperExtensions.cs
│ ├── Reporters
│ │ ├── JsonReporter.cs
│ │ ├── ReporterFactory.cs
│ │ ├── LcovReporter.cs
│ │ └── TeamCityReporter.cs
│ ├── coverlet.core.csproj
│ ├── CoverageDetails.cs
│ ├── Exceptions.cs
│ ├── Symbols
│ │ └── BranchPoint.cs
│ ├── CoveragePrepareResult.cs
│ └── Properties
│ │ └── AssemblyInfo.cs
├── coverlet.collector
│ ├── coverlet.collector.snk
│ ├── Utilities
│ │ ├── CoverletDataCollectorException.cs
│ │ ├── FileHelper.cs
│ │ ├── DirectoryHelper.cs
│ │ ├── TestPlatformLogger.cs
│ │ ├── Interfaces
│ │ │ ├── ICountDown.cs
│ │ │ ├── IFileHelper.cs
│ │ │ ├── IDirectoryHelper.cs
│ │ │ └── ICoverageWrapper.cs
│ │ ├── CountDownEvent.cs
│ │ ├── CoverletConstants.cs
│ │ └── TestPlatformEqtTrace.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── DataCollection
│ │ ├── CoverletLogger.cs
│ │ └── CoverageWrapper.cs
│ └── build
│ │ └── netstandard1.0
│ │ └── coverlet.collector.targets
└── coverlet.msbuild.tasks
│ ├── coverlet.msbuild.tasks.snk
│ ├── BaseTask.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── MSBuildLogger.cs
│ ├── coverlet.msbuild.props
│ ├── ReportWriter.cs
│ └── coverlet.msbuild.tasks.csproj
├── Documentation
├── images
│ ├── file.png
│ ├── nightly.PNG
│ └── nightlyExample.PNG
├── Examples
│ ├── VSTest
│ │ ├── DeterministicBuild
│ │ │ ├── Directory.Build.targets
│ │ │ ├── ClassLibrary1
│ │ │ │ ├── ClassLibrary1.csproj
│ │ │ │ └── Class1.cs
│ │ │ ├── XUnitTestProject1
│ │ │ │ ├── UnitTest1.cs
│ │ │ │ └── XUnitTestProject1.csproj
│ │ │ ├── Directory.Build.props
│ │ │ ├── DeterministicBuild.targets
│ │ │ └── DeterministicBuild.sln
│ │ └── HelloWorld
│ │ │ ├── ClassLibrary1
│ │ │ ├── ClassLibrary1.csproj
│ │ │ └── Class1.cs
│ │ │ ├── HowTo.md
│ │ │ ├── XUnitTestProject1
│ │ │ ├── UnitTest1.cs
│ │ │ ├── runsettings.xml
│ │ │ └── XUnitTestProject1.csproj
│ │ │ └── HelloWorld.sln
│ └── MSBuild
│ │ ├── DeterministicBuild
│ │ ├── Directory.Build.targets
│ │ ├── ClassLibrary1
│ │ │ ├── ClassLibrary1.csproj
│ │ │ └── Class1.cs
│ │ ├── XUnitTestProject1
│ │ │ ├── UnitTest1.cs
│ │ │ └── XUnitTestProject1.csproj
│ │ ├── Directory.Build.props
│ │ ├── DeterministicBuild.targets
│ │ └── DeterministicBuild.sln
│ │ └── MergeWith
│ │ ├── ClassLibrary1
│ │ ├── ClassLibrary1.csproj
│ │ └── Class1.cs
│ │ ├── ClassLibrary2
│ │ ├── ClassLibrary2.csproj
│ │ └── Class2.cs
│ │ ├── ClassLibrary3
│ │ ├── ClassLibrary3.csproj
│ │ └── Class3.cs
│ │ ├── XUnitTestProject1
│ │ ├── UnitTest1.cs
│ │ └── XUnitTestProject1.csproj
│ │ ├── XUnitTestProject2
│ │ ├── UnitTest2.cs
│ │ └── XUnitTestProject2.csproj
│ │ ├── XUnitTestProject3
│ │ ├── UnitTest3.cs
│ │ └── XUnitTestProject3.csproj
│ │ └── HowTo.md
├── Examples.md
├── DriversFeatures.md
├── ConsumeNightlyBuild.md
└── Roadmap.md
├── global.json
├── CODE_OF_CONDUCT.md
├── version.json
├── eng
├── signclient.json
├── build.yml
├── azure-pipelines-nightly.yml
└── azure-pipelines.yml
├── DeterministicBuild.targets
├── LICENSE
├── Directory.Build.props
├── THIRD-PARTY-NOTICES.txt
├── Directory.Build.targets
└── CONTRIBUTING.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | coverage.json
2 | coverage.opencover.xml
3 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/.gitignore:
--------------------------------------------------------------------------------
1 | coverage.*
2 | !75d9f96508d74def860a568f426ea4a4.*
--------------------------------------------------------------------------------
/_assets/coverlet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet.png
--------------------------------------------------------------------------------
/_assets/coverlet@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet@2x.png
--------------------------------------------------------------------------------
/_assets/coverlet@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet@3x.png
--------------------------------------------------------------------------------
/_assets/coverlet@4x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet@4x.png
--------------------------------------------------------------------------------
/src/coverlet.console/runtimeconfig.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "rollForwardOnNoCandidateFx": 2
3 | }
4 |
--------------------------------------------------------------------------------
/_assets/coverlet-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet-icon.png
--------------------------------------------------------------------------------
/_assets/coverlet@0.5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet@0.5x.png
--------------------------------------------------------------------------------
/_assets/coverlet@1.5x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet@1.5x.png
--------------------------------------------------------------------------------
/_assets/coverlet@0.75x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/_assets/coverlet@0.75x.png
--------------------------------------------------------------------------------
/Documentation/images/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/Documentation/images/file.png
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "5.0.401",
4 | "rollForward": "latestMajor"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Documentation/images/nightly.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/Documentation/images/nightly.PNG
--------------------------------------------------------------------------------
/src/coverlet.core/coverlet.core.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/src/coverlet.core/coverlet.core.snk
--------------------------------------------------------------------------------
/Documentation/images/nightlyExample.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/Documentation/images/nightlyExample.PNG
--------------------------------------------------------------------------------
/src/coverlet.console/coverlet.console.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/src/coverlet.console/coverlet.console.snk
--------------------------------------------------------------------------------
/src/coverlet.collector/coverlet.collector.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/src/coverlet.collector/coverlet.collector.snk
--------------------------------------------------------------------------------
/test/coverlet.core.tests/coverlet.core.tests.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests/coverlet.core.tests.snk
--------------------------------------------------------------------------------
/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.snk
--------------------------------------------------------------------------------
/test/coverlet.tests.remoteexecutor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | [assembly: AssemblyKeyFile("coverlet.tests.remoteexecutor.snk")]
--------------------------------------------------------------------------------
/test/coverlet.collector.tests/coverlet.collector.tests.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.collector.tests/coverlet.collector.tests.snk
--------------------------------------------------------------------------------
/test/coverlet.core.tests/TestAssets/System.Private.CoreLib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests/TestAssets/System.Private.CoreLib.dll
--------------------------------------------------------------------------------
/test/coverlet.core.tests/TestAssets/System.Private.CoreLib.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests/TestAssets/System.Private.CoreLib.pdb
--------------------------------------------------------------------------------
/test/coverlet.integration.tests/coverlet.integration.tests.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.integration.tests/coverlet.integration.tests.snk
--------------------------------------------------------------------------------
/test/coverlet.core.tests.samples.netstandard/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | [assembly: AssemblyKeyFile("coverlet.core.tests.samples.netstandard.snk")]
--------------------------------------------------------------------------------
/test/coverlet.core.tests/TestAssets/CoverletSourceRootsMappingTest:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests/TestAssets/CoverletSourceRootsMappingTest
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.fsharp/Library.fs:
--------------------------------------------------------------------------------
1 | namespace coverlet.tests.projectsample.fsharp
2 |
3 | module TestModule =
4 | type Type1 = Option1 | Option2 of {| x: string |}
5 |
--------------------------------------------------------------------------------
/test/coverlet.tests.remoteexecutor/coverlet.tests.remoteexecutor.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.tests.remoteexecutor/coverlet.tests.remoteexecutor.snk
--------------------------------------------------------------------------------
/test/coverlet.core.tests/TestAssets/75d9f96508d74def860a568f426ea4a4.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests/TestAssets/75d9f96508d74def860a568f426ea4a4.dll
--------------------------------------------------------------------------------
/test/coverlet.core.tests/TestAssets/75d9f96508d74def860a568f426ea4a4.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests/TestAssets/75d9f96508d74def860a568f426ea4a4.pdb
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/coverlet.tests.xunit.extensions.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.tests.xunit.extensions/coverlet.tests.xunit.extensions.snk
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mdsol/coverlet/master/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.snk
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary2/ClassLibrary2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary3/ClassLibrary3.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.empty/Class1.cs:
--------------------------------------------------------------------------------
1 | namespace Coverlet.Tests.ProjectSample.Empty
2 | {
3 | public class Class1
4 | {
5 | public int Method()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/coverlet.integration.template/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary1
4 | {
5 | public class Class1
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary2/Class2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary2
4 | {
5 | public class Class2
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/ClassLibrary3/Class3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary3
4 | {
5 | public class Class3
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary1
4 | {
5 | public class Class1
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/coverlet.console/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | [assembly: System.Reflection.AssemblyKeyFileAttribute("coverlet.console.snk")]
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary1
4 | {
5 | public class Class1
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/ClassLibrary1/Class1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary1
4 | {
5 | public class Class1
6 | {
7 | public int Method()
8 | {
9 | return 42;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 |
6 | [assembly: AssemblyKeyFile("coverlet.core.tests.snk")]
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 |
3 | This project has adopted the code of conduct defined by the Contributor Covenant
4 | to clarify expected behavior in our community.
5 |
6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/HowTo.md:
--------------------------------------------------------------------------------
1 | **Run from XUnitTestProject1 folder**
2 |
3 | ```
4 | dotnet test --collect:"XPlat Code Coverage"
5 | ```
6 |
7 | With custom runsettings file
8 |
9 | ```
10 | dotnet test --collect:"XPlat Code Coverage" --settings runsettings.xml
11 | ```
--------------------------------------------------------------------------------
/test/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 |
7 |
--------------------------------------------------------------------------------
/test/coverlet.collector.tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 |
6 | [assembly: AssemblyKeyFile("coverlet.collector.tests.snk")]
7 |
--------------------------------------------------------------------------------
/test/coverlet.integration.template/DeepThought.cs:
--------------------------------------------------------------------------------
1 | namespace Coverlet.Integration.Template
2 | {
3 | public class DeepThought
4 | {
5 | public int AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/coverlet.testsubject/coverlet.testsubject.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | false
6 | false
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/coverlet.integration.tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 |
6 | [assembly: AssemblyKeyFile("coverlet.integration.tests.snk")]
7 |
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 |
6 | [assembly: AssemblyKeyFile("coverlet.tests.xunit.extensions.snk")]
7 |
--------------------------------------------------------------------------------
/test/coverlet.integration.determisticbuild/DeepThought.cs:
--------------------------------------------------------------------------------
1 | namespace Coverlet.Integration.DeterministicBuild
2 | {
3 | public class DeepThought
4 | {
5 | public int AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything()
6 | {
7 | return 42;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/coverlet.testsubject/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.empty/coverlet.tests.projectsample.empty.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 | false
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/coverlet.console/ConsoleTables/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.core.performancetest/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.integration.template/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3 | "version": "3.1.3-preview.{height}",
4 | "publicReleaseRefSpec": [
5 | "^refs/heads/master$"
6 | ],
7 | "nugetPackageVersion":{
8 | "semVer": 2
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject1
5 | {
6 | public class UnitTest1
7 | {
8 | [Fact]
9 | public void Test1()
10 | {
11 | new ClassLibrary1.Class1().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject2/UnitTest2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject2
5 | {
6 | public class UnitTest2
7 | {
8 | [Fact]
9 | public void Test2()
10 | {
11 | new ClassLibrary2.Class2().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject3/UnitTest3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject3
5 | {
6 | public class UnitTest3
7 | {
8 | [Fact]
9 | public void Test3()
10 | {
11 | new ClassLibrary3.Class3().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject1
5 | {
6 | public class UnitTest1
7 | {
8 | [Fact]
9 | public void Test1()
10 | {
11 | new ClassLibrary1.Class1().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.empty/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests.samples.netstandard/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.integration.determisticbuild/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.netframework/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject1
5 | {
6 | public class UnitTest1
7 | {
8 | [Fact]
9 | public void Test1()
10 | {
11 | new ClassLibrary1.Class1().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/XUnitTestProject1/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace XUnitTestProject1
5 | {
6 | public class UnitTest1
7 | {
8 | [Fact]
9 | public void Test1()
10 | {
11 | new ClassLibrary1.Class1().Method();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IConsole.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Abstractions
5 | {
6 | internal interface IConsole
7 | {
8 | public void WriteLine(string value);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.excludedbyattribute/coverlet.tests.projectsample.excludedbyattribute.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | false
6 | false
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.excludedbyattribute/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | # We don't want to import other EditorConfig files and we want
3 | # to ensure no rules are enabled for these asset source files.
4 | root = true
5 |
6 | [*.cs]
7 | # Default severity for all analyzer diagnostics
8 | dotnet_analyzer_diagnostic.severity = none
9 |
--------------------------------------------------------------------------------
/src/coverlet.core/Enums/ThresholdStatistic.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Enums
5 | {
6 | internal enum ThresholdStatistic
7 | {
8 | Minimum,
9 | Average,
10 | Total
11 | }
12 | }
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.netframework/AsyncAwaitStateMachineNetFramework.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace coverlet.tests.projectsample.netframework
4 | {
5 | public class AsyncAwaitStateMachineNetFramework
6 | {
7 | public async Task AsyncAwait()
8 | {
9 | await Task.CompletedTask;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IProcessExitHandler.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface IProcessExitHandler
9 | {
10 | void Add(EventHandler handler);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/ITestCondition.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Tests.Xunit.Extensions
5 | {
6 | public interface ITestCondition
7 | {
8 | bool IsMet { get; }
9 | string SkipReason { get; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/coverlet.tests.xunit.extensions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/test/coverlet.integration.template/TemplateTest.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Coverlet.Integration.Template
4 | {
5 | public class TemplateTest
6 | {
7 | [Fact]
8 | public void Answer()
9 | {
10 | DeepThought dt = new DeepThought();
11 | Assert.Equal(42, dt.AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything());
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.excludedbyattribute/SampleClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 |
4 | [assembly: ExcludeFromCodeCoverage]
5 |
6 | namespace coverlet.tests.projectsample.excludedbyattribute
7 | {
8 | public class SampleClass
9 | {
10 | public int SampleMethod()
11 | {
12 | return new Random().Next();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/coverlet.core/Enums/ThresholdTypeFlags.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Enums
7 | {
8 | [Flags]
9 | internal enum ThresholdTypeFlags
10 | {
11 | None = 0,
12 | Line = 2,
13 | Branch = 4,
14 | Method = 8
15 | }
16 | }
--------------------------------------------------------------------------------
/test/coverlet.integration.determisticbuild/TemplateTest.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Coverlet.Integration.DeterministicBuild
4 | {
5 | public class TemplateTest
6 | {
7 | [Fact]
8 | public void Answer()
9 | {
10 | DeepThought dt = new DeepThought();
11 | Assert.Equal(42, dt.AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything());
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/coverlet.msbuild.tasks/BaseTask.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Microsoft.Build.Utilities;
6 |
7 | namespace Coverlet.MSbuild.Tasks
8 | {
9 | public abstract class BaseTask : Task
10 | {
11 | protected static IServiceProvider ServiceProvider { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/coverlet.integration.template/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Coverlet.Integration.Template;
4 |
5 | namespace HelloWorld
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | DeepThought dt = new DeepThought();
12 | dt.AnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything();
13 | Console.WriteLine("Hello World!");
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/XUnitTestProject1/runsettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | lcov,cobertura
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/eng/signclient.json:
--------------------------------------------------------------------------------
1 | {
2 | "SignClient": {
3 | "AzureAd": {
4 | "AADInstance": "https://login.microsoftonline.com/",
5 | "ClientId": "c248d68a-ba6f-4aa9-8a68-71fe872063f8",
6 | "TenantId": "16076fdc-fcc1-4a15-b1ca-32c9a255900e"
7 | },
8 | "Service": {
9 | "Url": "https://codesign.dotnetfoundation.org/",
10 | "ResourceId": "https://SignService/3c30251f-36f3-490b-a955-520addb85001"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/test/coverlet.core.tests.samples.netstandard/coverlet.core.tests.samples.netstandard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | false
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/coverlet.core/Attributes/DoesNotReturnAttribute.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Attributes
7 | {
8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class)]
9 | internal class DoesNotReturnAttribute : Attribute { }
10 | }
11 |
--------------------------------------------------------------------------------
/src/coverlet.core/Attributes/ExcludeFromCoverage.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Attributes
7 | {
8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class)]
9 | internal sealed class ExcludeFromCoverageAttribute : Attribute { }
10 | }
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.fsharp/coverlet.tests.projectsample.fsharp.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | true
6 | false
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/Console.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | public class SystemConsole : IConsole
10 | {
11 | public void WriteLine(string value)
12 | {
13 | Console.WriteLine(value);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | https://api.nuget.org/v3/index.json;
6 | ..\..\..\..\..\bin\$(Configuration)\Packages
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | https://api.nuget.org/v3/index.json;
6 | ..\..\..\..\..\bin\$(Configuration)\Packages
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Documentation/Examples.md:
--------------------------------------------------------------------------------
1 | # Examples
2 | ## MSBuild Integration
3 |
4 | * Using `/p:MergeWith` feature `Documentation/Examples/MSBuild/MergeWith/MergeWith.sln`
5 | * Deterministic build feature `Documentation/Examples/MSBuild/DeterministicBuild/DeterministicBuild.sln`
6 |
7 | ## VSTest Integration
8 |
9 | * HelloWorld sample `Documentation/Examples/VSTest/HelloWorld/HelloWorld.sln`
10 | * Deterministic build feature `Documentation/Examples/VSTest/DeterministicBuild/DeterministicBuild.sln`
11 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IRetryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface IRetryHelper
9 | {
10 | void Retry(Action action, Func backoffStrategy, int maxAttemptCount = 3);
11 | T Do(Func action, Func backoffStrategy, int maxAttemptCount = 3);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/ProcessExitHandler.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | internal class ProcessExitHandler : IProcessExitHandler
10 | {
11 | public void Add(EventHandler handler)
12 | {
13 | AppDomain.CurrentDomain.ProcessExit += handler;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/coverlet.tests.projectsample.netframework/coverlet.tests.projectsample.netframework.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net472
5 | false
6 | false
7 |
8 |
9 |
10 |
11 | all
12 |
13 |
14 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.ExcludeFromCoverage.Issue1302.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Coverlet.Core.Samples.Tests
4 | {
5 | public class Issue1302
6 | {
7 | public void Run()
8 | {
9 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
10 | static Func LocalFunction()
11 | {
12 | return myString => myString.Length == 10;
13 | }
14 |
15 | LocalFunction();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/ILogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface ILogger
9 | {
10 | void LogVerbose(string message);
11 | void LogInformation(string message, bool important = false);
12 | void LogWarning(string message);
13 | void LogError(string message);
14 | void LogError(Exception exception);
15 | }
16 | }
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/ISourceRootTranslator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using Coverlet.Core.Helpers;
6 |
7 | namespace Coverlet.Core.Abstractions
8 | {
9 | internal interface ISourceRootTranslator
10 | {
11 | string ResolveFilePath(string originalFileName);
12 | string ResolveDeterministicPath(string originalFileName);
13 | IReadOnlyList ResolvePathRoot(string pathRoot);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IReporter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Abstractions
5 | {
6 | internal interface IReporter
7 | {
8 | ReporterOutputType OutputType { get; }
9 | string Format { get; }
10 | string Extension { get; }
11 | string Report(CoverageResult result, ISourceRootTranslator sourceRootTranslator);
12 | }
13 |
14 | internal enum ReporterOutputType
15 | {
16 | File,
17 | Console,
18 | }
19 | }
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/CoverletDataCollectorException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Collector.Utilities
7 | {
8 | internal class CoverletDataCollectorException : Exception
9 | {
10 | public CoverletDataCollectorException(string message) : base(message)
11 | {
12 | }
13 |
14 | public CoverletDataCollectorException(string message, Exception innerException) : base(message, innerException)
15 | {
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/coverlet.core/Extensions/HelperExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Attributes;
6 |
7 | namespace Coverlet.Core.Extensions
8 | {
9 | internal static class HelperExtensions
10 | {
11 | [ExcludeFromCoverage]
12 | public static TRet Maybe(this T value, Func action, TRet defValue = default)
13 | where T : class
14 | {
15 | return (value != null) ? action(value) : defValue;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/coverlet.integration.template/coverlet.integration.template.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | false
6 | coverletsamplelib.integration.template
7 | false
8 | Exe
9 | false
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.ExcludeFromCoverage.NestedStateMachines.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | namespace Coverlet.Core.Samples.Tests
4 | {
5 | public class MethodsWithExcludeFromCodeCoverageAttr_NestedStateMachines
6 | {
7 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
8 | public async System.Threading.Tasks.Task NestedStateMachines()
9 | {
10 | await System.Threading.Tasks.Task.Run(async () => await System.Threading.Tasks.Task.Delay(50));
11 | }
12 |
13 | public int Test()
14 | {
15 | return 0;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/coverlet.msbuild.tasks/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 | using System.Runtime.CompilerServices;
6 |
7 | [assembly: AssemblyKeyFile("coverlet.msbuild.tasks.snk")]
8 | [assembly: InternalsVisibleTo("coverlet.core.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100757cf9291d78a82e5bb58a827a3c46c2f959318327ad30d1b52e918321ffbd847fb21565b8576d2a3a24562a93e86c77a298b564a0f1b98f63d7a1441a3a8bcc206da3ed09d5dacc76e122a109a9d3ac608e21a054d667a2bae98510a1f0f653c0e6f58f42b4b3934f6012f5ec4a09b3dfd3e14d437ede1424bdb722aead64ad")]
--------------------------------------------------------------------------------
/test/coverlet.core.performancetest/coverlet.core.performancetest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/FileHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Collector.Utilities.Interfaces;
6 |
7 | namespace Coverlet.Collector.Utilities
8 | {
9 | ///
10 | internal class FileHelper : IFileHelper
11 | {
12 | ///
13 | public bool Exists(string path)
14 | {
15 | return File.Exists(path);
16 | }
17 |
18 | ///
19 | public void WriteAllText(string path, string contents)
20 | {
21 | File.WriteAllText(path, contents);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/coverlet.core/Reporters/JsonReporter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Coverlet.Core.Abstractions;
5 | using Newtonsoft.Json;
6 |
7 | namespace Coverlet.Core.Reporters
8 | {
9 | internal class JsonReporter : IReporter
10 | {
11 | public ReporterOutputType OutputType => ReporterOutputType.File;
12 |
13 | public string Format => "json";
14 |
15 | public string Extension => "json";
16 |
17 | public string Report(CoverageResult result, ISourceRootTranslator _)
18 | {
19 | return JsonConvert.SerializeObject(result.Modules, Formatting.Indented);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/ICecilSymbolHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using Coverlet.Core.Symbols;
6 | using Mono.Cecil;
7 | using Mono.Cecil.Cil;
8 |
9 | namespace Coverlet.Core.Abstractions
10 | {
11 | internal interface ICecilSymbolHelper
12 | {
13 | IReadOnlyList GetBranchPoints(MethodDefinition methodDefinition);
14 | bool SkipNotCoverableInstruction(MethodDefinition methodDefinition, Instruction instruction);
15 | bool SkipInlineAssignedAutoProperty(bool skipAutoProps, MethodDefinition methodDefinition, Instruction instruction);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Helpers/FileSystemTests.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Xunit;
5 |
6 | namespace Coverlet.Core.Helpers.Tests
7 | {
8 | public class FileSystemTests
9 | {
10 | [Theory]
11 | [InlineData(null, null)]
12 | [InlineData("", "")]
13 | [InlineData("filename.cs", "filename.cs")]
14 | [InlineData("filename{T}.cs", "filename{{T}}.cs")]
15 | public void TestEscapeFileName(string fileName, string expected)
16 | {
17 | string actual = FileSystem.EscapeFileName(fileName);
18 |
19 | Assert.Equal(expected, actual);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/test/coverlet.core.tests.samples.netstandard/Instrumentation.AsyncAwait.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | namespace Coverlet.Core.Tests
4 | {
5 | public class Issue_669_2
6 | {
7 | private readonly System.Net.Http.HttpClient _httpClient = new System.Net.Http.HttpClient();
8 |
9 | async public System.Threading.Tasks.ValueTask SendRequest()
10 | {
11 | using (var requestMessage = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, "https://www.google.it"))
12 | {
13 | return await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/coverlet.core/coverlet.core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Library
5 | netstandard2.0
6 | 5.7.2
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IFileSystem.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 |
6 | namespace Coverlet.Core.Abstractions
7 | {
8 | internal interface IFileSystem
9 | {
10 | bool Exists(string path);
11 |
12 | void WriteAllText(string path, string contents);
13 |
14 | string ReadAllText(string path);
15 |
16 | Stream OpenRead(string path);
17 |
18 | void Copy(string sourceFileName, string destFileName, bool overwrite);
19 |
20 | void Delete(string path);
21 |
22 | Stream NewFileStream(string path, FileMode mode);
23 |
24 | Stream NewFileStream(string path, FileMode mode, FileAccess access);
25 |
26 | string[] ReadAllLines(string path);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/test/coverlet.tests.remoteexecutor/coverlet.tests.remoteexecutor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 | Coverlet.Tests.RemoteExecutor
7 | false
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 |
7 |
8 |
9 |
10 | all
11 | runtime; build; native; contentfiles; analyzers; buildtransitive
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject2/XUnitTestProject2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 |
7 |
8 |
9 |
10 | all
11 | runtime; build; native; contentfiles; analyzers; buildtransitive
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/XUnitTestProject3/XUnitTestProject3.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 |
7 |
8 |
9 |
10 | all
11 | runtime; build; native; contentfiles; analyzers; buildtransitive
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/HelloWorld/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | all
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/eng/build.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - task: UseDotNet@2
3 | inputs:
4 | version: 3.1.404
5 | displayName: Install .NET Core SDK 3.1.404
6 |
7 | - task: UseDotNet@2
8 | inputs:
9 | version: 5.0.401
10 | displayName: Install .NET Core SDK 5.0.401
11 |
12 | - script: dotnet restore
13 | displayName: Restore packages
14 |
15 | - script: dotnet build -c $(BuildConfiguration) --no-restore
16 | displayName: Build
17 |
18 | - script: dotnet pack -c $(BuildConfiguration) --no-restore
19 | displayName: Pack
20 |
21 | - task: DotNetCoreCLI@2
22 | displayName: Run tests
23 | inputs:
24 | command: test
25 | arguments: -c $(BuildConfiguration) --no-build /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Include="[coverlet.collector]*%2c[coverlet.core]*%2c[coverlet.msbuild.tasks]*" /p:Exclude="[coverlet.core.tests.samples.netstandard]*%2c[coverlet.tests.xunit.extensions]*"
26 | testRunTitle: $(Agent.JobName)
27 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/DirectoryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Collector.Utilities.Interfaces;
6 |
7 | namespace Coverlet.Collector.Utilities
8 | {
9 | ///
10 | internal class DirectoryHelper : IDirectoryHelper
11 | {
12 | ///
13 | public bool Exists(string path)
14 | {
15 | return Directory.Exists(path);
16 | }
17 |
18 | ///
19 | public void CreateDirectory(string path)
20 | {
21 | Directory.CreateDirectory(path);
22 | }
23 |
24 | ///
25 | public void Delete(string path, bool recursive)
26 | {
27 | Directory.Delete(path, recursive);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/coverlet.integration.tests/coverlet.integration.tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 | false
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.AsyncIterator.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace Coverlet.Core.Samples.Tests
10 | {
11 | public class AsyncIterator
12 | {
13 | async public Task Issue1104_Repro()
14 | {
15 | int sum = 0;
16 |
17 | await foreach (int result in CreateSequenceAsync())
18 | {
19 | sum += result;
20 | }
21 |
22 | return sum;
23 | }
24 |
25 | async private IAsyncEnumerable CreateSequenceAsync()
26 | {
27 | for (int i = 0; i < 100; ++i)
28 | {
29 | await Task.CompletedTask;
30 | yield return i;
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/coverlet.core/CoverageDetails.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core
7 | {
8 | internal class CoverageDetails
9 | {
10 | private double _averageModulePercent;
11 |
12 | public Modules Modules { get; internal set; }
13 | public double Covered { get; internal set; }
14 | public int Total { get; internal set; }
15 | public double Percent
16 | {
17 | get
18 | {
19 | if (Modules?.Count == 0) return 0;
20 | return Total == 0 ? 100D : Math.Floor((Covered / Total) * 10000) / 100;
21 | }
22 | }
23 |
24 | public double AverageModulePercent
25 | {
26 | get { return Math.Floor(_averageModulePercent * 100) / 100; }
27 | internal set { _averageModulePercent = value; }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/eng/azure-pipelines-nightly.yml:
--------------------------------------------------------------------------------
1 | pool:
2 | vmImage: 'windows-2019'
3 |
4 | steps:
5 | - task: UseDotNet@2
6 | inputs:
7 | version: 3.1.404
8 | displayName: Install .NET Core SDK 3.1.404
9 |
10 | - task: UseDotNet@2
11 | inputs:
12 | version: 5.0.401
13 | displayName: Install .NET Core SDK 5.0.401
14 |
15 | - task: NuGetAuthenticate@0
16 | displayName: Authenticate with NuGet feeds
17 |
18 | - script: dotnet pack -c Release /p:PublicRelease=false
19 | displayName: Create NuGet packages
20 |
21 | - task: NuGetCommand@2
22 | inputs:
23 | command: push
24 | packagesToPush: $(Build.SourcesDirectory)/bin/Release/Packages/*.nupkg
25 | nuGetFeedType: internal
26 | publishVstsFeed: coverlet/coverlet-nightly
27 | displayName: Publish NuGet packages
28 |
29 | - task: NuGetCommand@2
30 | inputs:
31 | command: push
32 | packagesToPush: $(Build.SourcesDirectory)/bin/Release/Packages/*.snupkg
33 | nuGetFeedType: internal
34 | publishVstsFeed: coverlet/coverlet-nightly
35 | displayName: Publish NuGet symbol packages
36 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Reporters/ReporterFactoryTests.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Xunit;
5 |
6 | namespace Coverlet.Core.Reporters.Tests
7 | {
8 | public class ReporterFactoryTests
9 | {
10 | [Fact]
11 | public void TestCreateReporter()
12 | {
13 | Assert.Equal(typeof(JsonReporter), new ReporterFactory("json").CreateReporter().GetType());
14 | Assert.Equal(typeof(LcovReporter), new ReporterFactory("lcov").CreateReporter().GetType());
15 | Assert.Equal(typeof(OpenCoverReporter), new ReporterFactory("opencover").CreateReporter().GetType());
16 | Assert.Equal(typeof(CoberturaReporter), new ReporterFactory("cobertura").CreateReporter().GetType());
17 | Assert.Equal(typeof(TeamCityReporter), new ReporterFactory("teamcity").CreateReporter().GetType());
18 | Assert.Null(new ReporterFactory("").CreateReporter());
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/XUnitTestProject1/XUnitTestProject1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/coverlet.collector.tests/coverlet.collector.tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net5.0
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/DeterministicBuild.targets:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
20 | <_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/coverlet.core.performancetest/PerformanceTest.cs:
--------------------------------------------------------------------------------
1 | using coverlet.testsubject;
2 | using System.Threading.Tasks;
3 | using System.Collections.Generic;
4 | using Xunit;
5 |
6 | namespace Coverlet.Core.PerformanceTest
7 | {
8 | ///
9 | /// Test the performance of coverlet by running a unit test that calls a reasonably big and complex test class.
10 | /// Enable the test, compile, then run the test in the command line:
11 | ///
12 | /// dotnet test /p:CollectCoverage=true test/Coverlet.Core.PerformanceTest/
13 | ///
14 | ///
15 | public class PerformanceTest
16 | {
17 | [Theory]
18 | [InlineData(20_000)]
19 | public void TestPerformance(int iterations)
20 | {
21 | var big = new BigClass();
22 |
23 | var tasks = new List();
24 |
25 | for (var i = 0; i < iterations; i++)
26 | {
27 | var j = i;
28 | tasks.Add(Task.Run(() => big.Do(j)));
29 | }
30 |
31 | Task.WaitAll(tasks.ToArray());
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/_assets/coverlet-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/coverlet.core/Reporters/ReporterFactory.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Linq;
6 | using Coverlet.Core.Abstractions;
7 |
8 | namespace Coverlet.Core.Reporters
9 | {
10 | internal class ReporterFactory
11 | {
12 | private readonly string _format;
13 | private readonly IReporter[] _reporters;
14 |
15 | public ReporterFactory(string format)
16 | {
17 | _format = format;
18 | _reporters = new IReporter[] {
19 | new JsonReporter(), new LcovReporter(),
20 | new OpenCoverReporter(), new CoberturaReporter(),
21 | new TeamCityReporter()
22 | };
23 | }
24 |
25 | public bool IsValidFormat()
26 | {
27 | return CreateReporter() != null;
28 | }
29 |
30 | public IReporter CreateReporter()
31 | => _reporters.FirstOrDefault(r => string.Equals(r.Format, _format, StringComparison.OrdinalIgnoreCase));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.AutoProps.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Coverlet.Core.Samples.Tests
4 | {
5 | public class AutoProps
6 | {
7 | private int _myVal = 0;
8 | public AutoProps()
9 | {
10 | _myVal = new Random().Next();
11 | }
12 | public int AutoPropsNonInit { get; set; }
13 | public int AutoPropsInit { get; set; } = 10;
14 | }
15 |
16 | public record RecordWithPropertyInit
17 | {
18 | private int _myRecordVal = 0;
19 | public RecordWithPropertyInit()
20 | {
21 | _myRecordVal = new Random().Next();
22 | }
23 | public string RecordAutoPropsNonInit { get; set; }
24 | public string RecordAutoPropsInit { get; set; } = string.Empty;
25 | }
26 |
27 | public class ClassWithAutoRecordProperties
28 | {
29 | record AutoRecordWithProperties(string Prop1, string Prop2);
30 |
31 | public ClassWithAutoRecordProperties()
32 | {
33 | var record = new AutoRecordWithProperties(string.Empty, string.Empty);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/DeterministicBuild/DeterministicBuild.targets:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
20 | <_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Documentation/Examples/VSTest/DeterministicBuild/DeterministicBuild.targets:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
19 |
20 | <_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Toni Solarin-Sodara
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/TestPlatformLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
5 |
6 | namespace Coverlet.Collector.Utilities
7 | {
8 | ///
9 | /// Test platform logger
10 | ///
11 | internal class TestPlatformLogger
12 | {
13 | private readonly DataCollectionLogger _logger;
14 | private readonly DataCollectionContext _dataCollectionContext;
15 |
16 | public TestPlatformLogger(DataCollectionLogger logger, DataCollectionContext dataCollectionContext)
17 | {
18 | _logger = logger;
19 | _dataCollectionContext = dataCollectionContext;
20 | }
21 |
22 | ///
23 | /// Log warning
24 | ///
25 | /// Warning message
26 | public void LogWarning(string warning)
27 | {
28 | _logger.LogWarning(_dataCollectionContext, $"[coverlet]{warning}");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | false
10 |
11 |
12 |
13 |
17 | $(RepoRoot)src\coverlet.msbuild.tasks\bin\$(Configuration)\netstandard2.0\
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/ICountDown.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Collector.Utilities.Interfaces
7 | {
8 |
9 | ///
10 | /// Factory for ICountDownEvent
11 | ///
12 | internal interface ICountDownEventFactory
13 | {
14 | ///
15 | /// Create ICountDownEvent instance
16 | ///
17 | /// count of CountDownEvent
18 | /// max wait
19 | ///
20 | ICountDownEvent Create(int count, TimeSpan waitTimeout);
21 | }
22 |
23 | ///
24 | /// Wrapper interface for CountDownEvent
25 | ///
26 | internal interface ICountDownEvent
27 | {
28 | ///
29 | /// Signal event
30 | ///
31 | void Signal();
32 |
33 | ///
34 | /// Wait for event
35 | ///
36 | void Wait();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/coverlet.console/ExitCodes.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | ///
7 | /// Exit Codes returned from Coverlet console process.
8 | ///
9 | [Flags]
10 | internal enum CommandExitCodes
11 | {
12 | ///
13 | /// Indicates successful run of dotnet test without any test failure and coverage percentage above threshold if provided.
14 | ///
15 | Success = 0,
16 |
17 | ///
18 | /// Indicates test failure by dotnet test.
19 | ///
20 | TestFailed = 1,
21 |
22 | ///
23 | /// Indicates coverage percentage is below given threshold for one or more threshold type.
24 | ///
25 | CoverageBelowThreshold = 2,
26 |
27 | ///
28 | /// Indicates exception occurred during Coverlet process.
29 | ///
30 | Exception = 101,
31 |
32 | ///
33 | /// Indicates missing options or empty arguments for Coverlet process.
34 | ///
35 | CommandParsingException = 102
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/src/coverlet.console/Logging/LogLevel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Console.Logging
5 | {
6 | ///
7 | /// Defines logging severity levels.
8 | ///
9 | enum LogLevel
10 | {
11 | ///
12 | /// Logs that track the general flow of the application. These logs should have long-term value.
13 | ///
14 | Detailed = 0,
15 |
16 | ///
17 | /// Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the
18 | /// application execution to stop.
19 | ///
20 | Normal = 1,
21 |
22 | ///
23 | /// Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a
24 | /// failure in the current activity, not an application-wide failure.
25 | ///
26 | Minimal = 2,
27 |
28 | ///
29 | /// Not used for writing log messages. Specifies that a logging category should not write any messages except warning and errors.
30 | ///
31 | Quiet = 3
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/coverlet.msbuild.tasks/MSBuildLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Microsoft.Build.Framework;
6 | using Microsoft.Build.Utilities;
7 | using ILogger = Coverlet.Core.Abstractions.ILogger;
8 |
9 | namespace Coverlet.MSbuild.Tasks
10 | {
11 | class MSBuildLogger : ILogger
12 | {
13 | private const string LogPrefix = "[coverlet] ";
14 |
15 | private readonly TaskLoggingHelper _log;
16 |
17 | public MSBuildLogger(TaskLoggingHelper log) => _log = log;
18 |
19 | public void LogVerbose(string message) => _log.LogMessage(MessageImportance.Low, $"{LogPrefix}{message}");
20 |
21 | // We use `MessageImportance.High` because with `MessageImportance.Normal` doesn't show anything
22 | public void LogInformation(string message, bool important = false) => _log.LogMessage(MessageImportance.High, $"{LogPrefix}{message}");
23 |
24 | public void LogWarning(string message) => _log.LogWarning($"{LogPrefix}{message}");
25 |
26 | public void LogError(string message) => _log.LogError($"{LogPrefix}{message}");
27 |
28 | public void LogError(Exception exception) => _log.LogErrorFromException(exception, true);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/coverlet.core/Abstractions/IInstrumentationHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Core.Abstractions
5 | {
6 | internal interface IInstrumentationHelper
7 | {
8 | void BackupOriginalModule(string module, string identifier);
9 | void DeleteHitsFile(string path);
10 | string[] GetCoverableModules(string module, string[] directories, bool includeTestAssembly);
11 | bool HasPdb(string module, out bool embedded);
12 | bool IsModuleExcluded(string module, string[] excludeFilters);
13 | bool IsModuleIncluded(string module, string[] includeFilters);
14 | bool IsValidFilterExpression(string filter);
15 | bool IsTypeExcluded(string module, string type, string[] excludeFilters);
16 | bool IsTypeIncluded(string module, string type, string[] includeFilters);
17 | void RestoreOriginalModule(string module, string identifier);
18 | bool EmbeddedPortablePdbHasLocalSource(string module, out string firstNotFoundDocument);
19 | bool PortablePdbHasLocalSource(string module, out string firstNotFoundDocument);
20 | bool IsLocalMethod(string method);
21 | void SetLogger(ILogger logger);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.SelectionStatements.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | namespace Coverlet.Core.Samples.Tests
4 | {
5 | public class SelectionStatements
6 | {
7 | public int If(bool condition)
8 | {
9 | if (condition)
10 | {
11 | return 1;
12 | }
13 | else
14 | {
15 | return 0;
16 | }
17 | }
18 |
19 | public int Switch(int caseSwitch)
20 | {
21 | switch (caseSwitch)
22 | {
23 | case 1:
24 | return 1;
25 | case 2:
26 | return 2;
27 | default:
28 | return 0;
29 | }
30 | }
31 |
32 | public string SwitchCsharp8(object value) =>
33 | value
34 | switch
35 | {
36 | int i => i.ToString(System.Globalization.CultureInfo.InvariantCulture),
37 | uint ui => ui.ToString(System.Globalization.CultureInfo.InvariantCulture),
38 | short s => s.ToString(System.Globalization.CultureInfo.InvariantCulture),
39 | _ => throw new System.NotSupportedException()
40 | };
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/SkipOnOS.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Runtime.InteropServices;
6 |
7 | namespace Coverlet.Tests.Xunit.Extensions
8 | {
9 | public enum OS
10 | {
11 | Linux,
12 | MacOS,
13 | Windows
14 | }
15 |
16 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
17 | public class SkipOnOSAttribute : Attribute, ITestCondition
18 | {
19 | private readonly OS _os;
20 | private readonly string _reason;
21 |
22 | public SkipOnOSAttribute(OS os, string reason = "") => (_os, _reason) = (os, reason);
23 |
24 | public bool IsMet => _os switch
25 | {
26 | OS.Linux => !RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
27 | OS.MacOS => !RuntimeInformation.IsOSPlatform(OSPlatform.OSX),
28 | OS.Windows => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows),
29 | _ => throw new NotSupportedException($"Not supported OS {_os}")
30 | };
31 |
32 | public string SkipReason => $"OS not supported{(string.IsNullOrEmpty(_reason) ? "" : $", {_reason}")}";
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.AwaitUsing.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | using System;
4 | using System.IO;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Coverlet.Core.Samples.Tests
9 | {
10 | public class AwaitUsing
11 | {
12 | async public ValueTask HasAwaitUsing()
13 | {
14 | await using (var ms = new MemoryStream(Encoding.ASCII.GetBytes("Boo")))
15 | {
16 | }
17 | }
18 |
19 |
20 | async public Task Issue914_Repro()
21 | {
22 | await Issue914_Repro_Example1();
23 | await Issue914_Repro_Example2();
24 | }
25 |
26 |
27 | async private Task Issue914_Repro_Example1()
28 | {
29 | await using var transaction = new MyTransaction();
30 | }
31 |
32 |
33 | async private Task Issue914_Repro_Example2()
34 | {
35 | var transaction = new MyTransaction();
36 | await transaction.DisposeAsync();
37 | }
38 |
39 |
40 | private class MyTransaction : IAsyncDisposable
41 | {
42 | public async ValueTask DisposeAsync()
43 | {
44 | await default(ValueTask);
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/test/coverlet.integration.determisticbuild/coverlet.integration.determisticbuild.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | net5.0
7 | false
8 | coverletsample.integration.determisticbuild
9 |
10 | https://api.nuget.org/v3/index.json;
11 | $(RepoRoot)bin\$(Configuration)\Packages
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 | all
22 | runtime; build; native; contentfiles; analyzers; buildtransitive
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/coverlet.core/Exceptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Coverlet.Core.Exceptions
7 | {
8 | [Serializable]
9 | internal class CoverletException : Exception
10 | {
11 | public CoverletException() { }
12 | public CoverletException(string message) : base(message) { }
13 | public CoverletException(string message, System.Exception inner) : base(message, inner) { }
14 | protected CoverletException(
15 | System.Runtime.Serialization.SerializationInfo info,
16 | System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
17 | }
18 |
19 | [Serializable]
20 | internal class CecilAssemblyResolutionException : CoverletException
21 | {
22 | public CecilAssemblyResolutionException() { }
23 | public CecilAssemblyResolutionException(string message) : base(message) { }
24 | public CecilAssemblyResolutionException(string message, System.Exception inner) : base(message, inner) { }
25 | protected CecilAssemblyResolutionException(
26 | System.Runtime.Serialization.SerializationInfo info,
27 | System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/CountDownEvent.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Threading;
6 | using Coverlet.Collector.Utilities.Interfaces;
7 |
8 | namespace Coverlet.Collector.Utilities
9 | {
10 | internal class CollectorCountdownEventFactory : ICountDownEventFactory
11 | {
12 | public ICountDownEvent Create(int count, TimeSpan waitTimeout)
13 | {
14 | return new CollectorCountdownEvent(count, waitTimeout);
15 | }
16 | }
17 |
18 | internal class CollectorCountdownEvent : ICountDownEvent
19 | {
20 | private readonly CountdownEvent _countDownEvent;
21 | private readonly TimeSpan _waitTimeout;
22 |
23 | public CollectorCountdownEvent(int count, TimeSpan waitTimeout)
24 | {
25 | _countDownEvent = new CountdownEvent(count);
26 | _waitTimeout = waitTimeout;
27 | }
28 |
29 | public void Signal()
30 | {
31 | _countDownEvent.Signal();
32 | }
33 |
34 | public void Wait()
35 | {
36 | if (!_countDownEvent.Wait(_waitTimeout))
37 | {
38 | throw new TimeoutException($"CollectorCountdownEvent timeout after {_waitTimeout}");
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/IFileHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Collector.Utilities.Interfaces
5 | {
6 | internal interface IFileHelper
7 | {
8 | ///
9 | /// Determines whether the specified file exists.
10 | ///
11 | /// The file to check.
12 | /// true if the caller has the required permissions and path contains the name of an existing file; otherwise, false.
13 | /// This method also returns false if path is null, an invalid path, or a zero-length string.
14 | /// If the caller does not have sufficient permissions to read the specified file,
15 | /// no exception is thrown and the method returns false regardless of the existence of path.
16 | bool Exists(string path);
17 |
18 | ///
19 | /// Creates a new file, writes the specified string to the file, and then closes the file.
20 | /// If the target file already exists, it is overwritten.
21 | ///
22 | /// The file to write to.
23 | /// The string to write to the file.
24 | void WriteAllText(string path, string contents);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/Extensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Linq;
5 | using Xunit.Abstractions;
6 | using Xunit.Sdk;
7 |
8 | namespace Coverlet.Tests.Xunit.Extensions
9 | {
10 | internal static class TestMethodExtensions
11 | {
12 | public static string EvaluateSkipConditions(this ITestMethod testMethod)
13 | {
14 | ITypeInfo testClass = testMethod.TestClass.Class;
15 | IAssemblyInfo assembly = testMethod.TestClass.TestCollection.TestAssembly.Assembly;
16 | System.Collections.Generic.IEnumerable conditionAttributes = testMethod.Method
17 | .GetCustomAttributes(typeof(ITestCondition))
18 | .Concat(testClass.GetCustomAttributes(typeof(ITestCondition)))
19 | .Concat(assembly.GetCustomAttributes(typeof(ITestCondition)))
20 | .OfType()
21 | .Select(attributeInfo => attributeInfo.Attribute);
22 |
23 | foreach (ITestCondition condition in conditionAttributes)
24 | {
25 | if (!condition.IsMet)
26 | {
27 | return condition.SkipReason;
28 | }
29 | }
30 |
31 | return null;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildThisFileDirectory)
5 | Debug
6 | $(MSBuildThisFileDirectory)bin\$(Configuration)\Packages\
7 | true
8 | true
9 | true
10 | snupkg
11 | true
12 | true
13 | preview
14 | true
15 | preview
16 | $(NoWarn);NU5105
17 |
18 | https://api.nuget.org/v3/index.json;
19 |
20 |
21 |
22 |
23 | true
24 | true
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 | using System.Runtime.CompilerServices;
6 |
7 | [assembly: AssemblyKeyFile("coverlet.collector.snk")]
8 | [assembly: InternalsVisibleTo("coverlet.core.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100757cf9291d78a82e5bb58a827a3c46c2f959318327ad30d1b52e918321ffbd847fb21565b8576d2a3a24562a93e86c77a298b564a0f1b98f63d7a1441a3a8bcc206da3ed09d5dacc76e122a109a9d3ac608e21a054d667a2bae98510a1f0f653c0e6f58f42b4b3934f6012f5ec4a09b3dfd3e14d437ede1424bdb722aead64ad")]
9 | [assembly: InternalsVisibleTo("coverlet.collector.tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ed0ed6af9693182615b8dcadc83c918b8d36312f86cefc69539d67d4189cd1b89420e7c3871802ffef7f5ca7816c68ad856c77bf7c230cc07824d96aa5d1237eebd30e246b9a14e22695fb26b40c800f74ea96619092cbd3a5d430d6c003fc7a82e8ccd1e315b935105d9232fe9e99e8d7ff54bba6f191959338d4a3169df9b3")]
10 | // Needed to mock internal type https://github.com/Moq/moq4/wiki/Quickstart#advanced-features
11 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
--------------------------------------------------------------------------------
/THIRD-PARTY-NOTICES.txt:
--------------------------------------------------------------------------------
1 | coverlet uses third-party libraries or other resources that may be
2 | distributed under licenses different than the coverlet software.
3 |
4 | In the event that we accidentally failed to list a required notice, please
5 | bring it to our attention by posting an issue.
6 |
7 | The attached notices are provided for information only.
8 |
9 |
10 | License notice for ConsoleTables
11 | --------------------------------
12 |
13 | The MIT License (MIT)
14 |
15 | Copyright (c) 2012 Khalid Abuhakmeh
16 |
17 | Permission is hereby granted, free of charge, to any person obtaining a copy
18 | of this software and associated documentation files (the "Software"), to deal
19 | in the Software without restriction, including without limitation the rights
20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 | copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 |
24 | The above copyright notice and this permission notice shall be included in all
25 | copies or substantial portions of the Software.
26 |
27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 | SOFTWARE.
34 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Reporters/JsonReporterTests.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Coverlet.Core.Abstractions;
5 | using Moq;
6 | using System;
7 | using Xunit;
8 |
9 | namespace Coverlet.Core.Reporters.Tests
10 | {
11 | public class JsonReporterTests
12 | {
13 | [Fact]
14 | public void TestReport()
15 | {
16 | var result = new CoverageResult();
17 | result.Identifier = Guid.NewGuid().ToString();
18 |
19 | var lines = new Lines();
20 | lines.Add(1, 1);
21 | lines.Add(2, 0);
22 |
23 | var methods = new Methods();
24 | string methodString = "System.Void Coverlet.Core.Reporters.Tests.JsonReporterTests.TestReport()";
25 | methods.Add(methodString, new Method());
26 | methods[methodString].Lines = lines;
27 |
28 | var classes = new Classes();
29 | classes.Add("Coverlet.Core.Reporters.Tests.JsonReporterTests", methods);
30 |
31 | var documents = new Documents();
32 | documents.Add("doc.cs", classes);
33 |
34 | result.Modules = new Modules();
35 | result.Modules.Add("module", documents);
36 |
37 | var reporter = new JsonReporter();
38 | Assert.NotEqual("{\n}", reporter.Report(result, new Mock().Object));
39 | Assert.NotEqual(string.Empty, reporter.Report(result, new Mock().Object));
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/coverlet.console/coverlet.console.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net5.0
6 | coverlet
7 | true
8 | coverlet.console
9 |
10 |
11 |
12 |
13 | $(AssemblyTitle)
14 | tonerdo
15 | Coverlet is a cross platform code coverage tool for .NET, with support for line, branch and method coverage.
16 | coverage;testing;unit-test;lcov;opencover;quality
17 | https://raw.githubusercontent.com/tonerdo/coverlet/master/_assets/coverlet-icon.svg?sanitize=true
18 | coverlet-icon.png
19 | https://github.com/coverlet-coverage/coverlet
20 | MIT
21 | git
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Documentation/DriversFeatures.md:
--------------------------------------------------------------------------------
1 | # Driver feature differences
2 |
3 | All Coverlet drivers share the same coverage engine. Since version 3.0.0, we've consolidated versioning across drivers, so for every new release, all drivers will have the same version number.
4 |
5 | We think that keeping the versions in sync better expresses the set of features every release will have. This does not mean that all drivers will support every functionality/feature or have the same behaviours, since they are limited by the context they're running in.
6 |
7 | In the table below we keep track of main differences:
8 |
9 | | Feature | MSBuild | .NET Tool | DataCollectors |
10 | |:-----------------------------------|:--------------|--------------|------------------|
11 | | .NET Core support(>= 2.0) | Yes | Yes | Yes |
12 | | .NET Framework support(>= 4.6.1) | Yes | Yes | Yes(since 3.0.0) |
13 | | Show result on console | Yes | Yes | No |
14 | | Deterministic reports output folder| Yes | Yes | No |
15 | | Merge reports | Yes | Yes | No |
16 | | Coverage threshold validation | Yes | Yes | No |
17 | | Deterministic build support | Yes | No | Yes |
18 |
19 | When possible, we advice you to use the collectors integration (VSTest engine integration), since it is fully integrated inside the test pipeline and does not suffer from the [known issues](KnownIssues.md) of the other drivers.
20 |
--------------------------------------------------------------------------------
/src/coverlet.core/Symbols/BranchPoint.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Diagnostics;
6 |
7 | namespace Coverlet.Core.Symbols
8 | {
9 | ///
10 | /// a branch point
11 | ///
12 | [DebuggerDisplay("StartLine = {StartLine}")]
13 | internal class BranchPoint
14 | {
15 | ///
16 | /// Line of the branching instruction
17 | ///
18 | public int StartLine { get; set; }
19 |
20 | ///
21 | /// A path that can be taken
22 | ///
23 | public int Path { get; set; }
24 |
25 | ///
26 | /// An order of the point within the method
27 | ///
28 | public UInt32 Ordinal { get; set; }
29 |
30 | ///
31 | /// List of OffsetPoints between Offset and EndOffset (exclusive)
32 | ///
33 | public System.Collections.Generic.List OffsetPoints { get; set; }
34 |
35 | ///
36 | /// The IL offset of the point
37 | ///
38 | public int Offset { get; set; }
39 |
40 | ///
41 | /// Last Offset == EndOffset.
42 | /// Can be same as Offset
43 | ///
44 | public int EndOffset { get; set; }
45 |
46 | ///
47 | /// The url to the document if an entry was not mapped to an id
48 | ///
49 | public string Document { get; set; }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/coverlet.msbuild.tasks/coverlet.msbuild.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 |
5 |
6 |
7 |
8 |
9 | false
10 | false
11 |
12 | false
13 | false
14 | json
15 | $([MSBuild]::EnsureTrailingSlash('$(MSBuildProjectDirectory)'))
16 | 0
17 | line,branch,method
18 | minimum
19 |
20 |
21 | $(MSBuildThisFileDirectory)
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Documentation/Examples/MSBuild/MergeWith/HowTo.md:
--------------------------------------------------------------------------------
1 | **Run from solution root sln**
2 |
3 | To merge report togheter you need to run separate test and merge in one `json` format file.
4 | Last command will join and create final needed format file.
5 |
6 | ```
7 | dotnet test XUnitTestProject1\XUnitTestProject1.csproj /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/
8 | dotnet test XUnitTestProject2\XUnitTestProject2.csproj /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json"
9 | dotnet test XUnitTestProject3\XUnitTestProject3.csproj /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat="opencover"
10 | ```
11 |
12 | You can merge also running `dotnet test` and merge with single command from a solution file, but you need to ensure that tests will run sequentially(`-m:1`). This slow down testing but avoid invalid coverage result.
13 |
14 | ```
15 | dotnet test /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat=\"opencover,json\" -m:1
16 | ```
17 | N.B. You need to specify `json` format plus another format(the final one), because Coverlet can only merge proprietary format. At the end you can delete temporary `coverage.json` file.
18 |
19 | You can also merge the coverage result and generate another valid format to export the content than opencover, like cobertura.
20 |
21 | ```
22 | dotnet test /p:CollectCoverage=true /p:CoverletOutput=../CoverageResults/ /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat=\"cobertura,json\" -m:1
23 | ```
24 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.AsyncForeach.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace Coverlet.Core.Samples.Tests
10 | {
11 | public class AsyncForeach
12 | {
13 | async public ValueTask SumWithATwist(IAsyncEnumerable ints)
14 | {
15 | int sum = 0;
16 |
17 | await foreach (int i in ints)
18 | {
19 | if (i > 0)
20 | {
21 | sum += i;
22 | }
23 | else
24 | {
25 | sum = 0;
26 | }
27 | }
28 |
29 | return sum;
30 | }
31 |
32 |
33 | async public ValueTask Sum(IAsyncEnumerable ints)
34 | {
35 | int sum = 0;
36 |
37 | await foreach (int i in ints)
38 | {
39 | sum += i;
40 | }
41 |
42 | return sum;
43 | }
44 |
45 |
46 | async public ValueTask SumEmpty()
47 | {
48 | int sum = 0;
49 |
50 | await foreach (int i in AsyncEnumerable.Empty())
51 | {
52 | sum += i;
53 | }
54 |
55 | return sum;
56 | }
57 |
58 | public async ValueTask GenericAsyncForeach(IAsyncEnumerable ints)
59 | {
60 | await foreach (int obj in ints)
61 | {
62 | await Task.Delay(1);
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/IDirectoryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Collector.Utilities.Interfaces
5 | {
6 | interface IDirectoryHelper
7 | {
8 | ///
9 | /// Determines whether the specified directory exists.
10 | ///
11 | /// The directory to check.
12 | /// true if the caller has the required permissions and path contains the name of an existing directory; otherwise, false.
13 | /// This method also returns false if path is null, an invalid path, or a zero-length string.
14 | /// If the caller does not have sufficient permissions to read the specified file,
15 | /// no exception is thrown and the method returns false regardless of the existence of path.
16 | bool Exists(string path);
17 |
18 | ///
19 | /// Creates all directories and subdirectories in the specified path unless they already exist.
20 | ///
21 | /// The directory to create.
22 | void CreateDirectory(string directory);
23 |
24 | ///
25 | /// Deletes the specified directory and, if indicated, any subdirectories and files in the directory.
26 | ///
27 | /// The name of the directory to remove.
28 | /// true to remove directories, subdirectories, and files in path; otherwise, false.
29 | void Delete(string path, bool recursive);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.Yield.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | namespace Coverlet.Core.Samples.Tests
4 | {
5 | public class Yield
6 | {
7 | public System.Collections.Generic.IEnumerable One()
8 | {
9 | yield return 1;
10 | }
11 |
12 | public System.Collections.Generic.IEnumerable Two()
13 | {
14 | yield return 1;
15 | yield return 2;
16 | }
17 |
18 | public System.Collections.Generic.IEnumerable OneWithSwitch(int n)
19 | {
20 | int result;
21 | switch (n)
22 | {
23 | case 0:
24 | result = 10;
25 | break;
26 | case 1:
27 | result = 11;
28 | break;
29 | case 2:
30 | result = 12;
31 | break;
32 | default:
33 | result = -1;
34 | break;
35 | }
36 |
37 | yield return result;
38 | }
39 |
40 | public System.Collections.Generic.IEnumerable Three()
41 | {
42 | yield return 1;
43 | yield return 2;
44 | yield return 3;
45 | }
46 |
47 | public System.Collections.Generic.IEnumerable Enumerable(System.Collections.Generic.IList ls)
48 | {
49 | foreach (
50 | var item
51 | in
52 | ls
53 | )
54 | {
55 | yield return item;
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/eng/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | branches:
3 | include: ["master", "*_validate"]
4 | paths:
5 | exclude: [".github", "doc", "*.md"]
6 |
7 | jobs:
8 | - job: Windows
9 | displayName: Windows
10 | continueOnError: 'true'
11 | strategy:
12 | matrix:
13 | Debug:
14 | buildConfiguration: "Debug"
15 | Release:
16 | buildConfiguration: "Release"
17 | pool:
18 | vmImage: 'windows-latest'
19 | steps:
20 | - template: build.yml
21 | - task: CopyFiles@2
22 | displayName: Collect packages
23 | inputs:
24 | SourceFolder: bin\$(BuildConfiguration)\Packages
25 | Contents: |
26 | *.nupkg
27 | *.snupkg
28 | TargetFolder: $(Build.ArtifactStagingDirectory)\Packages
29 | condition: eq(variables['BuildConfiguration'], 'Release')
30 | - task: PublishBuildArtifacts@1
31 | displayName: Publish packages as build artifacts
32 | inputs:
33 | PathtoPublish: $(Build.ArtifactStagingDirectory)\Packages
34 | ArtifactName: Packages
35 | publishLocation: Container
36 | condition: eq(variables['BuildConfiguration'], 'Release')
37 |
38 | - job: macOS
39 | displayName: macOS
40 | continueOnError: 'true'
41 | strategy:
42 | matrix:
43 | Debug:
44 | buildConfiguration: "Debug"
45 | Release:
46 | buildConfiguration: "Release"
47 | pool:
48 | vmImage: 'macOS-latest'
49 | steps:
50 | - template: build.yml
51 |
52 | - job: Linux
53 | displayName: Linux
54 | continueOnError: 'true'
55 | strategy:
56 | matrix:
57 | Debug:
58 | buildConfiguration: "Debug"
59 | Release:
60 | buildConfiguration: "Release"
61 | pool:
62 | vmImage: 'ubuntu-latest'
63 | steps:
64 | - template: build.yml
65 |
--------------------------------------------------------------------------------
/src/coverlet.console/Logging/ConsoleLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Core.Abstractions;
6 | using static System.Console;
7 |
8 | namespace Coverlet.Console.Logging
9 | {
10 | class ConsoleLogger : ILogger
11 | {
12 | private static readonly object s_sync = new();
13 |
14 | public LogLevel Level { get; set; } = LogLevel.Normal;
15 |
16 | public void LogError(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Red);
17 |
18 | public void LogError(Exception exception) => LogError(exception.ToString());
19 |
20 | public void LogInformation(string message, bool important = false) => Log(important ? LogLevel.Minimal : LogLevel.Normal, message, ForegroundColor);
21 |
22 | public void LogVerbose(string message) => Log(LogLevel.Detailed, message, ForegroundColor);
23 |
24 | public void LogWarning(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Yellow);
25 |
26 | private void Log(LogLevel level, string message, ConsoleColor color)
27 | {
28 | if (level < Level) return;
29 |
30 | lock (s_sync)
31 | {
32 | ConsoleColor currentForegroundColor;
33 | if (color != (currentForegroundColor = ForegroundColor))
34 | {
35 | ForegroundColor = color;
36 | WriteLine(message);
37 | ForegroundColor = currentForegroundColor;
38 | }
39 | else
40 | {
41 | WriteLine(message);
42 | }
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/coverlet.core/CoveragePrepareResult.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using System.Runtime.Serialization;
6 | using Coverlet.Core.Instrumentation;
7 |
8 | namespace Coverlet.Core
9 | {
10 | // Followed safe serializer guide, will emit xml format
11 | // https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2300-do-not-use-insecure-deserializer-binaryformatter?view=vs-2019
12 | // https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2301-do-not-call-binaryformatter-deserialize-without-first-setting-binaryformatter-binder?view=vs-2019
13 | [DataContract]
14 | internal class CoveragePrepareResult
15 | {
16 | [DataMember]
17 | public string Identifier { get; set; }
18 | [DataMember]
19 | public string ModuleOrDirectory { get; set; }
20 | [DataMember]
21 | public string MergeWith { get; set; }
22 | [DataMember]
23 | public bool UseSourceLink { get; set; }
24 | [DataMember]
25 | public InstrumenterResult[] Results { get; set; }
26 | [DataMember]
27 | public CoverageParameters Parameters { get; set; }
28 |
29 | public static CoveragePrepareResult Deserialize(Stream serializedInstrumentState)
30 | {
31 | return (CoveragePrepareResult)new DataContractSerializer(typeof(CoveragePrepareResult)).ReadObject(serializedInstrumentState);
32 | }
33 |
34 | public static Stream Serialize(CoveragePrepareResult instrumentState)
35 | {
36 | var ms = new MemoryStream();
37 | new DataContractSerializer(typeof(CoveragePrepareResult)).WriteObject(ms, instrumentState);
38 | ms.Position = 0;
39 | return ms;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/CoverletConstants.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Coverlet.Collector.Utilities
5 | {
6 | internal static class CoverletConstants
7 | {
8 | public const string FriendlyName = "XPlat code coverage";
9 | public const string DefaultUri = @"datacollector://Microsoft/CoverletCodeCoverage/1.0";
10 | public const string DataCollectorName = "CoverletCoverageDataCollector";
11 | public const string DefaultReportFormat = "cobertura";
12 | public const string DefaultFileName = "coverage";
13 | public const string IncludeFiltersElementName = "Include";
14 | public const string IncludeDirectoriesElementName = "IncludeDirectory";
15 | public const string ExcludeFiltersElementName = "Exclude";
16 | public const string ExcludeSourceFilesElementName = "ExcludeByFile";
17 | public const string ExcludeAttributesElementName = "ExcludeByAttribute";
18 | public const string MergeWithElementName = "MergeWith";
19 | public const string UseSourceLinkElementName = "UseSourceLink";
20 | public const string SingleHitElementName = "SingleHit";
21 | public const string IncludeTestAssemblyElementName = "IncludeTestAssembly";
22 | public const string TestSourcesPropertyName = "TestSources";
23 | public const string ReportFormatElementName = "Format";
24 | public const string DefaultExcludeFilter = "[coverlet.*]*";
25 | public const string InProcDataCollectorName = "CoverletInProcDataCollector";
26 | public const string SkipAutoProps = "SkipAutoProps";
27 | public const string DoesNotReturnAttributesElementName = "DoesNotReturnAttribute";
28 | public const string DeterministicReport = "DeterministicReport";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Documentation/ConsumeNightlyBuild.md:
--------------------------------------------------------------------------------
1 | # Consume nightly build
2 |
3 | To consume nightly builds, create a `NuGet.Config` in your root solution directory and add the following content:
4 |
5 | ```xml
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ```
18 |
19 | ## Install packages
20 |
21 | ### Visual Studio:
22 |
23 | \
24 | Example:\
25 | 
26 |
27 | ### NuGet (Package Manager console):
28 | ```powershell
29 | PM> Install-Package coverlet.msbuild -Version X.X.X-preview.X.XXX -Source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
30 | ```
31 | Example:
32 | ```powershell
33 | PM> Install-Package coverlet.msbuild -Version 3.0.4-preview.4.g5de0ad7d60 -Source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
34 | ```
35 |
36 | ### .NET CLI:
37 | ```bash
38 | dotnet add package coverlet.msbuild --version X.X.X-preview.X.XXX --source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
39 | ```
40 | Example:
41 | ```bash
42 | dotnet add package coverlet.msbuild --version 3.0.4-preview.4.g5de0ad7d60 --source https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json
43 | ```
44 |
45 | ### MSBuild project file:
46 |
47 | ```xml
48 |
49 | ```
50 | Example:
51 | ```xml
52 |
53 | ```
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.VisualStudio.TestPlatform.ObjectModel;
5 |
6 | namespace Coverlet.Collector.Utilities
7 | {
8 | ///
9 | /// Test platform eqttrace
10 | ///
11 | internal class TestPlatformEqtTrace
12 | {
13 | public bool IsInfoEnabled => EqtTrace.IsInfoEnabled;
14 | public bool IsVerboseEnabled => EqtTrace.IsVerboseEnabled;
15 |
16 | ///
17 | /// Verbose logger
18 | ///
19 | /// Format
20 | /// Args
21 | public void Verbose(string format, params object[] args)
22 | {
23 | EqtTrace.Verbose($"[coverlet]{format}", args);
24 | }
25 |
26 | ///
27 | /// Warning logger
28 | ///
29 | /// Format
30 | /// Args
31 | public void Warning(string format, params object[] args)
32 | {
33 | EqtTrace.Warning($"[coverlet]{format}", args);
34 | }
35 |
36 | ///
37 | /// Info logger
38 | ///
39 | /// Format
40 | /// Args
41 | public void Info(string format, params object[] args)
42 | {
43 | EqtTrace.Info($"[coverlet]{format}", args);
44 | }
45 |
46 | ///
47 | /// Error logger
48 | ///
49 | /// Format
50 | /// Args
51 | public void Error(string format, params object[] args)
52 | {
53 | EqtTrace.Error($"[coverlet]{format}", args);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Reporters/LcovReporterTests.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Coverlet.Core.Abstractions;
5 | using Moq;
6 | using System;
7 | using Xunit;
8 |
9 | namespace Coverlet.Core.Reporters.Tests
10 | {
11 | public class LcovReporterTests
12 | {
13 | [Fact]
14 | public void TestReport()
15 | {
16 | var result = new CoverageResult();
17 | result.Parameters = new CoverageParameters();
18 | result.Identifier = Guid.NewGuid().ToString();
19 |
20 | var lines = new Lines();
21 | lines.Add(1, 1);
22 | lines.Add(2, 0);
23 |
24 | var branches = new Branches();
25 | branches.Add(new BranchInfo { Line = 1, Hits = 1, Offset = 23, EndOffset = 24, Path = 0, Ordinal = 1 });
26 | branches.Add(new BranchInfo { Line = 1, Hits = 0, Offset = 23, EndOffset = 27, Path = 1, Ordinal = 2 });
27 |
28 | var methods = new Methods();
29 | string methodString = "System.Void Coverlet.Core.Reporters.Tests.LcovReporterTests.TestReport()";
30 | methods.Add(methodString, new Method());
31 | methods[methodString].Lines = lines;
32 | methods[methodString].Branches = branches;
33 |
34 | var classes = new Classes();
35 | classes.Add("Coverlet.Core.Reporters.Tests.LcovReporterTests", methods);
36 |
37 | var documents = new Documents();
38 | documents.Add("doc.cs", classes);
39 | result.Modules = new Modules();
40 | result.Modules.Add("module", documents);
41 |
42 | var reporter = new LcovReporter();
43 | string report = reporter.Report(result, new Mock().Object);
44 |
45 | Assert.NotEmpty(report);
46 | Assert.Equal("SF:doc.cs", report.Split(Environment.NewLine)[0]);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/coverlet.collector/Utilities/Interfaces/ICoverageWrapper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Coverlet.Collector.DataCollection;
5 | using Coverlet.Core;
6 | using Coverlet.Core.Abstractions;
7 |
8 | namespace Coverlet.Collector.Utilities.Interfaces
9 | {
10 | ///
11 | /// Wrapper interface for Coverage class in coverlet.core
12 | /// Since the class is not testable, this interface is used to abstract methods for mocking in unit tests.
13 | ///
14 | internal interface ICoverageWrapper
15 | {
16 | ///
17 | /// Creates a coverage object from given coverlet settings
18 | ///
19 | /// Coverlet settings
20 | /// Coverlet logger
21 | /// Coverlet instrumentationHelper
22 | /// Coverlet fileSystem
23 | /// Coverlet sourceRootTranslator
24 | ///
25 | /// Coverage object
26 | Coverage CreateCoverage(CoverletSettings settings, ILogger logger, IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper);
27 |
28 | ///
29 | /// Gets the coverage result from provided coverage object
30 | ///
31 | /// Coverage
32 | /// The coverage result
33 | CoverageResult GetCoverageResult(Coverage coverage);
34 |
35 | ///
36 | /// Prepares modules for getting coverage.
37 | /// Wrapper over coverage.PrepareModules
38 | ///
39 | ///
40 | void PrepareModules(Coverage coverage);
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/coverlet.tests.xunit.extensions/ConditionalFact.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Xunit;
6 | using Xunit.Abstractions;
7 | using Xunit.Sdk;
8 |
9 | namespace Coverlet.Tests.Xunit.Extensions
10 | {
11 | [AttributeUsage(AttributeTargets.Method)]
12 | [XunitTestCaseDiscoverer("Coverlet.Tests.Xunit.Extensions." + nameof(ConditionalFactDiscoverer), "coverlet.tests.xunit.extensions")]
13 | public class ConditionalFact : FactAttribute { }
14 |
15 | internal class ConditionalFactDiscoverer : FactDiscoverer
16 | {
17 | public ConditionalFactDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) { }
18 |
19 | protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
20 | {
21 | return new SkippableTestCase(testMethod.EvaluateSkipConditions(), DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod);
22 | }
23 | }
24 |
25 | internal class SkippableTestCase : XunitTestCase
26 | {
27 | private readonly string _skipReason;
28 |
29 | [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
30 | public SkippableTestCase() { }
31 |
32 | public SkippableTestCase(string skipReason, IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, object[] testMethodArguments = null)
33 | : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments)
34 | {
35 | _skipReason = skipReason;
36 | }
37 | protected override string GetSkipReason(IAttributeInfo factAttribute)
38 | {
39 | return _skipReason ?? base.GetSkipReason(factAttribute);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/FileSystem.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Core.Abstractions;
6 |
7 | namespace Coverlet.Core.Helpers
8 | {
9 | internal class FileSystem : IFileSystem
10 | {
11 | // We need to partial mock this method on tests
12 | public virtual bool Exists(string path)
13 | {
14 | return File.Exists(path);
15 | }
16 |
17 | public void WriteAllText(string path, string contents)
18 | {
19 | File.WriteAllText(path, contents);
20 | }
21 |
22 | public string ReadAllText(string path)
23 | {
24 | return File.ReadAllText(path);
25 | }
26 |
27 | // We need to partial mock this method on tests
28 | public virtual Stream OpenRead(string path)
29 | {
30 | return File.OpenRead(path);
31 | }
32 |
33 | public void Copy(string sourceFileName, string destFileName, bool overwrite)
34 | {
35 | File.Copy(sourceFileName, destFileName, overwrite);
36 | }
37 |
38 | public void Delete(string path)
39 | {
40 | File.Delete(path);
41 | }
42 |
43 | // We need to partial mock this method on tests
44 | public virtual Stream NewFileStream(string path, FileMode mode)
45 | {
46 | return new FileStream(path, mode);
47 | }
48 |
49 | // We need to partial mock this method on tests
50 | public virtual Stream NewFileStream(string path, FileMode mode, FileAccess access)
51 | {
52 | return new FileStream(path, mode, access);
53 | }
54 |
55 | public string[] ReadAllLines(string path)
56 | {
57 | return File.ReadAllLines(path);
58 | }
59 |
60 | // Escape format characters in file names
61 | internal static string EscapeFileName(string fileName)
62 | {
63 | return fileName?.Replace("{", "{{").Replace("}", "}}");
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Samples/Instrumentation.ExcludeFromCoverage.Issue670.cs:
--------------------------------------------------------------------------------
1 | // Remember to use full name because adding new using directives change line numbers
2 |
3 | namespace Coverlet.Core.Samples.Tests
4 | {
5 | public class MethodsWithExcludeFromCodeCoverageAttr_Issue670
6 | {
7 | public void Test(string input)
8 | {
9 | MethodsWithExcludeFromCodeCoverageAttr_Issue670_Startup obj = new MethodsWithExcludeFromCodeCoverageAttr_Issue670_Startup();
10 | obj.ObjectExtension(input);
11 | }
12 | }
13 |
14 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
15 | public class MethodsWithExcludeFromCodeCoverageAttr_Issue670_Startup
16 | {
17 | public void UseExceptionHandler(System.Action action)
18 | {
19 | action(this);
20 | }
21 |
22 | public async void Run(System.Func func)
23 | {
24 | await func(new MethodsWithExcludeFromCodeCoverageAttr_Issue670_Context());
25 | }
26 | }
27 |
28 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
29 | public class MethodsWithExcludeFromCodeCoverageAttr_Issue670_Context
30 | {
31 | public System.Threading.Tasks.Task SimulateAsyncWork(int val)
32 | {
33 | return System.Threading.Tasks.Task.Delay(System.Math.Min(val, 50));
34 | }
35 | }
36 |
37 | public static class MethodsWithExcludeFromCodeCoverageAttr_Issue670_Ext
38 | {
39 | [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
40 | public static void ObjectExtension(this Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr_Issue670_Startup obj, string input)
41 | {
42 | obj.UseExceptionHandler(o =>
43 | {
44 | o.Run(async context =>
45 | {
46 | if (context != null)
47 | {
48 | await context.SimulateAsyncWork(input.Length);
49 | }
50 | });
51 | });
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/src/coverlet.collector/DataCollection/CoverletLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Coverlet.Collector.Utilities;
6 | using Coverlet.Core.Abstractions;
7 |
8 | namespace Coverlet.Collector.DataCollection
9 | {
10 | ///
11 | /// Coverlet logger
12 | ///
13 | internal class CoverletLogger : ILogger
14 | {
15 | private readonly TestPlatformEqtTrace _eqtTrace;
16 | private readonly TestPlatformLogger _logger;
17 |
18 | public CoverletLogger(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger)
19 | {
20 | _eqtTrace = eqtTrace;
21 | _logger = logger;
22 | }
23 |
24 | ///
25 | /// Logs error
26 | ///
27 | /// Error message
28 | public void LogError(string message)
29 | {
30 | _logger.LogWarning(message);
31 | }
32 |
33 | ///
34 | /// Logs error
35 | ///
36 | /// Exception to log
37 | public void LogError(Exception exception)
38 | {
39 | _logger.LogWarning(exception.ToString());
40 | }
41 |
42 | ///
43 | /// Logs information
44 | ///
45 | /// Information message
46 | /// importance
47 | public void LogInformation(string message, bool important = false)
48 | {
49 | _eqtTrace.Info(message);
50 | }
51 |
52 | ///
53 | /// Logs verbose
54 | ///
55 | /// Verbose message
56 | public void LogVerbose(string message)
57 | {
58 | _eqtTrace.Verbose(message);
59 | }
60 |
61 | ///
62 | /// Logs warning
63 | ///
64 | /// Warning message
65 | public void LogWarning(string message)
66 | {
67 | _eqtTrace.Warning(message);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Coverage/CoverageTests.AsyncIterator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using System.Threading.Tasks;
6 | using Coverlet.Core.Samples.Tests;
7 | using Xunit;
8 |
9 | namespace Coverlet.Core.Tests
10 | {
11 | public partial class CoverageTests
12 | {
13 | [Fact]
14 | public void AsyncIterator()
15 | {
16 | string path = Path.GetTempFileName();
17 | try
18 | {
19 | FunctionExecutor.Run(async (string[] pathSerialize) =>
20 | {
21 | CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance =>
22 | {
23 | int res = ((Task)instance.Issue1104_Repro()).GetAwaiter().GetResult();
24 |
25 | return Task.CompletedTask;
26 | }, persistPrepareResultToFile: pathSerialize[0]);
27 | return 0;
28 | }, new string[] { path });
29 |
30 | TestInstrumentationHelper.GetCoverageResult(path)
31 | .Document("Instrumentation.AsyncIterator.cs")
32 | .AssertLinesCovered(BuildConfiguration.Debug,
33 | // Issue1104_Repro()
34 | (14, 1), (15, 1), (17, 203), (18, 100), (19, 100), (20, 100), (22, 1), (23, 1),
35 | // CreateSequenceAsync()
36 | (26, 1), (27, 202), (28, 100), (29, 100), (30, 100), (31, 100), (32, 1)
37 | )
38 | .AssertBranchesCovered(BuildConfiguration.Debug,
39 | // Issue1104_Repro(),
40 | (17, 0, 1), (17, 1, 100),
41 | // CreateSequenceAsync()
42 | (27, 0, 1), (27, 1, 100)
43 | )
44 | .ExpectedTotalNumberOfBranches(BuildConfiguration.Debug, 2);
45 | }
46 | finally
47 | {
48 | File.Delete(path);
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Coverage/CoverageTests.AwaitUsing.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using System.Threading.Tasks;
6 | using Coverlet.Core.Samples.Tests;
7 | using Xunit;
8 |
9 | namespace Coverlet.Core.Tests
10 | {
11 | public partial class CoverageTests
12 | {
13 | [Fact]
14 | public void AwaitUsing()
15 | {
16 | string path = Path.GetTempFileName();
17 | try
18 | {
19 | FunctionExecutor.Run(async (string[] pathSerialize) =>
20 | {
21 | CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance =>
22 | {
23 | ((ValueTask)instance.HasAwaitUsing()).GetAwaiter().GetResult();
24 | ((Task)instance.Issue914_Repro()).GetAwaiter().GetResult();
25 |
26 | return Task.CompletedTask;
27 | }, persistPrepareResultToFile: pathSerialize[0]);
28 | return 0;
29 | }, new string[] { path });
30 |
31 | TestInstrumentationHelper.GetCoverageResult(path)
32 | .Document("Instrumentation.AwaitUsing.cs")
33 | .AssertLinesCovered(BuildConfiguration.Debug,
34 | // HasAwaitUsing()
35 | (13, 1), (14, 1), (15, 1), (16, 1), (17, 1),
36 | // Issue914_Repro()
37 | (21, 1), (22, 1), (23, 1), (24, 1),
38 | // Issue914_Repro_Example1()
39 | (28, 1), (29, 1), (30, 1),
40 | // Issue914_Repro_Example2()
41 | (34, 1), (35, 1), (36, 1), (37, 1),
42 | // MyTransaction.DisposeAsync()
43 | (43, 2), (44, 2), (45, 2)
44 | )
45 | .ExpectedTotalNumberOfBranches(BuildConfiguration.Debug, 0);
46 | }
47 | finally
48 | {
49 | File.Delete(path);
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are highly welcome, however, except for very small changes, kindly file an issue and let's have a discussion before you open a pull request.
4 |
5 | ## Requirements
6 |
7 | .NET SDK 2.2 https://dotnet.microsoft.com/download/dotnet-core/2.2
8 | .NET SDK 3.1 https://dotnet.microsoft.com/download/dotnet-core/3.1
9 |
10 | ## Building the Project
11 |
12 | Clone this repo:
13 |
14 | git clone https://github.com/coverlet-coverage/coverlet.git
15 | cd coverlet
16 |
17 | Building, testing, and packing use all the standard dotnet commands:
18 |
19 | dotnet restore
20 | dotnet build --no-restore
21 | dotnet pack
22 | dotnet test --no-build /p:CollectCoverage=true /p:Include=\"[coverlet.collector]*,[coverlet.core]*,[coverlet.msbuild.tasks]*\" /p:Exclude=\"[coverlet.core.tests.samples.netstandard]*,[coverlet.tests.xunit.extensions]*\"
23 |
24 | NB. You need to `pack` before testing because we have some integration testing that consume packages
25 |
26 | ## Performance testing
27 |
28 | There is a simple performance test for the hit counting instrumentation in the test project `coverlet.core.performancetest`. Build the project with the msbuild step above and then run:
29 |
30 | dotnet test /p:CollectCoverage=true test/coverlet.core.performancetest/
31 |
32 | The duration of the test can be tweaked by changing the number of iterations in the `[InlineData]` in the `PerformanceTest` class.
33 |
34 | For more realistic testing it is recommended to try out any changes to the hit counting code paths on large, realistic projects. If you don't have any handy https://github.com/dotnet/corefx is an excellent candidate. [This page](https://github.com/dotnet/corefx/blob/master/Documentation/building/code-coverage.md) describes how to run code coverage tests for both the full solution and for individual projects with coverlet from nuget. Suitable projects (listed in order of escalating test durations):
35 |
36 | * System.Collections.Concurrent.Tests
37 | * System.Collections.Tests
38 | * System.Reflection.Metadata.Tests
39 | * System.Xml.Linq.Events.Tests
40 | * System.Runtime.Serialization.Formatters.Tests
41 |
42 | Change to the directory of the library and run the msbuild code coverage command:
43 |
44 | dotnet test /p:Coverage=true
45 |
46 | To run with a development version of coverlet call `dotnet run` instead of the installed coverlet version, e.g.:
47 |
48 | dotnet test /p:Coverage=true /p:CoverageExecutablePath="dotnet run -p C:\...\coverlet\src\coverlet.console\coverlet.console.csproj"
49 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Helpers/RetryHelperTests.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Xunit;
6 |
7 | namespace Coverlet.Core.Helpers.Tests
8 | {
9 | public class RetryHelperTests
10 | {
11 | [Fact]
12 | public void TestRetryWithFixedRetryBackoff()
13 | {
14 | Func retryStrategy = () =>
15 | {
16 | return TimeSpan.FromMilliseconds(1);
17 | };
18 |
19 | var target = new RetryTarget();
20 | try
21 | {
22 | new RetryHelper().Retry(() => target.TargetActionThrows(), retryStrategy, 7);
23 | }
24 | catch
25 | {
26 | Assert.Equal(7, target.Calls);
27 | }
28 | }
29 |
30 | [Fact]
31 | public void TestRetryWithExponentialRetryBackoff()
32 | {
33 | int currentSleep = 6;
34 | Func retryStrategy = () =>
35 | {
36 | var sleep = TimeSpan.FromMilliseconds(currentSleep);
37 | currentSleep *= 2;
38 | return sleep;
39 | };
40 |
41 | var target = new RetryTarget();
42 | try
43 | {
44 | new RetryHelper().Retry(() => target.TargetActionThrows(), retryStrategy, 3);
45 | }
46 | catch
47 | {
48 | Assert.Equal(3, target.Calls);
49 | Assert.Equal(24, currentSleep);
50 | }
51 | }
52 |
53 | [Fact]
54 | public void TestRetryFinishesIfSuccessful()
55 | {
56 | Func retryStrategy = () =>
57 | {
58 | return TimeSpan.FromMilliseconds(1);
59 | };
60 |
61 | var target = new RetryTarget();
62 | new RetryHelper().Retry(() => target.TargetActionThrows5Times(), retryStrategy, 20);
63 | Assert.Equal(6, target.Calls);
64 | }
65 |
66 | }
67 |
68 | public class RetryTarget
69 | {
70 | public int Calls { get; set; }
71 | public void TargetActionThrows()
72 | {
73 | Calls++;
74 | throw new Exception("Simulating Failure");
75 | }
76 | public void TargetActionThrows5Times()
77 | {
78 | Calls++;
79 | if (Calls < 6) throw new Exception("Simulating Failure");
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/test/coverlet.core.tests/Coverage/CoverageTests.IntegerOverflow.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 | using Coverlet.Core.Abstractions;
6 | using Coverlet.Core.Instrumentation;
7 | using Moq;
8 | using Xunit;
9 |
10 | namespace Coverlet.Core.Tests
11 | {
12 | public partial class CoverageTests
13 | {
14 | [Fact]
15 | public void CoverageResult_NegativeLineCoverage_TranslatedToMaxValueOfInt32()
16 | {
17 | var instrumenterResult = new InstrumenterResult
18 | {
19 | HitsFilePath = "HitsFilePath",
20 | SourceLink = "SourceLink",
21 | ModulePath = "ModulePath"
22 | };
23 |
24 | instrumenterResult.HitCandidates.Add(new HitCandidate(false, 0, 1, 1));
25 |
26 | var document = new Document
27 | {
28 | Index = 0,
29 | Path = "Path0"
30 | };
31 |
32 | document.Lines.Add(1, new Line
33 | {
34 | Class = "Class0",
35 | Hits = 0,
36 | Method = "Method0",
37 | Number = 1
38 | });
39 |
40 | instrumenterResult.Documents.Add("document", document);
41 |
42 | var coveragePrepareResult = new CoveragePrepareResult
43 | {
44 | UseSourceLink = true,
45 | Results = new[] {instrumenterResult},
46 | Parameters = new CoverageParameters()
47 | };
48 |
49 | Stream memoryStream = new MemoryStream();
50 | var binaryWriter = new BinaryWriter(memoryStream);
51 | binaryWriter.Write(1);
52 | binaryWriter.Write(-1);
53 | memoryStream.Position = 0;
54 |
55 | var fileSystemMock = new Mock();
56 | fileSystemMock.Setup(x => x.Exists(It.IsAny())).Returns(true);
57 | fileSystemMock.Setup(x => x.NewFileStream(It.IsAny(), FileMode.Open, FileAccess.Read))
58 | .Returns(memoryStream);
59 |
60 | var coverage = new Coverage(coveragePrepareResult, new Mock().Object, new Mock().Object,
61 | fileSystemMock.Object, new Mock().Object);
62 |
63 | CoverageResult coverageResult = coverage.GetCoverageResult();
64 | coverageResult.Document("document").AssertLinesCovered(BuildConfiguration.Debug, (1, int.MaxValue));
65 |
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/coverlet.core/Helpers/RetryHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Toni Solarin-Sodara
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Threading;
7 | using Coverlet.Core.Abstractions;
8 |
9 | namespace Coverlet.Core.Helpers
10 | {
11 | // A slightly amended version of the code found here: https://stackoverflow.com/a/1563234/186184
12 | // This code allows for varying backoff strategies through the use of Func.
13 | internal class RetryHelper : IRetryHelper
14 | {
15 | ///
16 | /// Retry a void method.
17 | ///
18 | /// The action to perform
19 | /// A function returning a Timespan defining the backoff strategy to use.
20 | /// The maximum number of retries before bailing out. Defaults to 3.
21 | public void Retry(
22 | Action action,
23 | Func backoffStrategy,
24 | int maxAttemptCount = 3)
25 | {
26 | Do