diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index c01898168..66868c027 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Release date 2021-01-24 +### Packages +coverlet.msbuild 3.0.2 +coverlet.console 3.0.2 +coverlet.collector 3.0.2 + +### Fixed + +-Fix multi-line lambda coverage regression [#1060](https://github.com/coverlet-coverage/coverlet/pull/1060) +-Opt-in reachability helper to mitigate resolution issue [#1061](https://github.com/coverlet-coverage/coverlet/pull/1061) + ## Release date 2021-01-16 ### Packages coverlet.msbuild 3.0.1 diff --git a/Documentation/MSBuildIntegration.md b/Documentation/MSBuildIntegration.md index 5d6675523..e036c0a51 100644 --- a/Documentation/MSBuildIntegration.md +++ b/Documentation/MSBuildIntegration.md @@ -173,7 +173,7 @@ Syntax: `/p:SkipAutoProps=true` ### Methods that do not return -Methods that do not return can be marked with attributes to cause statements after them to be excluded from coverage. `DoesNotReturnAttribute` is included by default. +Methods that do not return can be marked with attributes to cause statements after them to be excluded from coverage. Attributes can be specified with the following syntax. Syntax: `/p:DoesNotReturnAttribute="DoesNotReturnAttribute,OtherAttribute"` diff --git a/Documentation/ReleasePlan.md b/Documentation/ReleasePlan.md index 7beaf70ed..75c1dc809 100644 --- a/Documentation/ReleasePlan.md +++ b/Documentation/ReleasePlan.md @@ -13,35 +13,24 @@ PATCH version when you make backwards-compatible bug fixes. Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. ``` -## Release Calendar - We release 3 components as NuGet packages: -**coverlet.msbuild.nupkg** -**coverlet.console.nupkg** -**coverlet.collector.nupkg** - -We plan 1 release [once per quarter](https://en.wikipedia.org/wiki/Calendar_year) if there is *at least* 1 new commit of source code on master. This release may be a major, minor, or patch version upgrade from the previous release depending on impact to consumers. -**We release intermediate packages in case of severe bug or to unblock users.** +**coverlet.msbuild.nupkg** +**coverlet.console.nupkg** +**coverlet.collector.nupkg** ### Current versions | Package | Version | |:----------------------|:--------| -|**coverlet.msbuild** | 3.0.1 | -|**coverlet.console** | 3.0.1 | -|**coverlet.collector** | 3.0.1 | - -### Proposed next versions +|**coverlet.msbuild** | 3.0.2 | +|**coverlet.console** | 3.0.2 | +|**coverlet.collector** | 3.0.2 | -We bump version based on Semantic Versioning 2.0.0 spec: - -1. If we add features to **coverlet.core.dll** we bump MINOR version of all packages. -1. If we do breaking changes on **coverlet.core.dll** we bump MAJOR version of all packages. -1. We MANUALLY bump versions on production release, so we have different release plan between prod and nigntly packages. | Release Date | coverlet.msbuild | coverlet.console | coverlet.collector| commit hash | notes | | :-----------------|:-----------------|:------------------|:------------------|:-----------------------------------------|:-------------------------------| +| 24 January 2021 | 3.0.2 | 3.0.2 | 3.0.2 | ed918515492193fd154b60270d440c40fa30fee9 | Fix regressions | | 16 January 2021 | 3.0.1 | 3.0.1 | 3.0.1 | 1b45fd89245369ae94407e7a77bdfee112042486 | Fix severe coverage regression | | 09 January 2021 | 3.0.0 | 3.0.0 | 3.0.0 | 1e77f9d2183a320e8991bfc296460e793301931f | Align versions numbers | | 30 May 2020 | 2.9.0 | 1.7.2 | 1.3.0 | 83a38d45b3f9c231d705bfed849efbf41b3aaa86 | deterministic build support | @@ -51,8 +40,6 @@ We bump version based on Semantic Versioning 2.0.0 spec: | 01 July 2019 | 2.6.3 | 1.5.3 | 1.0.1 | e1593359497fdfe6befbb86304b8f4e09a656d14 | | | 06 June 2019 | 2.6.2 | 1.5.2 | 1.0.0 | 3e7eac9df094c22335711a298d359890aed582e8 | first collector release | -*< date > Expected next release date - To get the list of commits between two version use git command ```bash git log --oneline hashbefore currenthash diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs index e2a74a18a..cdee8156a 100644 --- a/src/coverlet.core/Coverage.cs +++ b/src/coverlet.core/Coverage.cs @@ -405,8 +405,8 @@ private void CalculateCoverage() { if (hitCandidate != hitCandidateToCompare && !hitCandidateToCompare.isBranch) { - if (hitCandidateToCompare.start >= hitCandidate.start && - hitCandidateToCompare.end <= hitCandidate.end) + if (hitCandidateToCompare.start > hitCandidate.start && + hitCandidateToCompare.end < hitCandidate.end) { for (int i = hitCandidateToCompare.start; i <= (hitCandidateToCompare.end == 0 ? hitCandidateToCompare.start : hitCandidateToCompare.end); diff --git a/src/coverlet.core/Instrumentation/Instrumenter.cs b/src/coverlet.core/Instrumentation/Instrumenter.cs index d7ae86447..575be13be 100644 --- a/src/coverlet.core/Instrumentation/Instrumenter.cs +++ b/src/coverlet.core/Instrumentation/Instrumenter.cs @@ -81,7 +81,7 @@ public Instrumenter( _fileSystem = fileSystem; _sourceRootTranslator = sourceRootTranslator; _cecilSymbolHelper = cecilSymbolHelper; - _doesNotReturnAttributes = PrepareAttributes(doesNotReturnAttributes, nameof(DoesNotReturnAttribute)); + _doesNotReturnAttributes = PrepareAttributes(doesNotReturnAttributes); _skipAutoProps = skipAutoProps; } diff --git a/src/coverlet.core/coverlet.core.csproj b/src/coverlet.core/coverlet.core.csproj index ce67bae19..2b2ab8a70 100644 --- a/src/coverlet.core/coverlet.core.csproj +++ b/src/coverlet.core/coverlet.core.csproj @@ -3,7 +3,7 @@ Library netstandard2.0 - 5.6.1 + 5.6.2 false diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.DoesNotReturn.cs b/test/coverlet.core.tests/Coverage/CoverageTests.DoesNotReturn.cs index e9e955b0c..67219a6ec 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.DoesNotReturn.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.DoesNotReturn.cs @@ -23,7 +23,7 @@ public void NoBranches_DoesNotReturnAttribute_InstrumentsCorrect() catch (Exception) { } return Task.CompletedTask; - }, persistPrepareResultToFile: pathSerialize[0]); + }, persistPrepareResultToFile: pathSerialize[0], doesNotReturnAttributes: _ => new string[] { "DoesNotReturnAttribute" }); return 0; @@ -183,7 +183,7 @@ public void CallsGenericMethodDoesNotReturn_DoesNotReturnAttribute_InstrumentsCo catch (Exception) { } return Task.CompletedTask; - }, persistPrepareResultToFile: pathSerialize[0]); + }, persistPrepareResultToFile: pathSerialize[0], doesNotReturnAttributes: _ => new string[] { "DoesNotReturnAttribute" }); return 0; @@ -215,7 +215,7 @@ public void CallsGenericClassDoesNotReturn_DoesNotReturnAttribute_InstrumentsCor catch (Exception) { } return Task.CompletedTask; - }, persistPrepareResultToFile: pathSerialize[0]); + }, persistPrepareResultToFile: pathSerialize[0], doesNotReturnAttributes: _ => new string[] { "DoesNotReturnAttribute" }); return 0; @@ -247,7 +247,7 @@ public void WithLeave_DoesNotReturnAttribute_InstrumentsCorrect() catch (Exception) { } return Task.CompletedTask; - }, persistPrepareResultToFile: pathSerialize[0]); + }, persistPrepareResultToFile: pathSerialize[0], doesNotReturnAttributes: _ => new string[] { "DoesNotReturnAttribute" }); return 0; @@ -279,7 +279,7 @@ public void FiltersAndFinallies_DoesNotReturnAttribute_InstrumentsCorrect() catch (Exception) { } return Task.CompletedTask; - }, persistPrepareResultToFile: pathSerialize[0]); + }, persistPrepareResultToFile: pathSerialize[0], doesNotReturnAttributes: _ => new string[] { "DoesNotReturnAttribute" }); return 0; diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.Lambda.cs b/test/coverlet.core.tests/Coverage/CoverageTests.Lambda.cs index 6ef519102..37b3e76aa 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.Lambda.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.Lambda.cs @@ -102,5 +102,40 @@ public void Lambda_Issue760() File.Delete(path); } } + + [Fact] + public void Issue_1056() + { + string path = Path.GetTempFileName(); + try + { + FunctionExecutor.Run(async (string[] pathSerialize) => + { + CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance => + { + instance.T1(); + return Task.CompletedTask; + }, + persistPrepareResultToFile: pathSerialize[0]); + + return 0; + }, new string[] { path }); + + TestInstrumentationHelper.GetCoverageResult(path) + .Document("Instrumentation.Lambda.cs") + .AssertLinesCoveredFromTo(BuildConfiguration.Debug, 110, 119) + .AssertLinesCoveredFromTo(BuildConfiguration.Debug, 122, 124) + .AssertLinesCoveredFromTo(BuildConfiguration.Debug, 127, 129) + .AssertLinesCoveredFromTo(BuildConfiguration.Debug, 131, 131) + .AssertLinesCovered(BuildConfiguration.Debug, (110, 1), (111, 2), (112, 2), (113, 2), (114, 2), (115, 2), (116, 2), (117, 2), (118, 2), (119, 1), + (122, 2), (123, 2), (124, 2), + (127, 2), (128, 2), (129, 2), + (131, 4)); + } + finally + { + File.Delete(path); + } + } } } \ No newline at end of file diff --git a/test/coverlet.core.tests/Coverage/InstrumenterHelper.Assertions.cs b/test/coverlet.core.tests/Coverage/InstrumenterHelper.Assertions.cs index 92da3b47e..07f3e2bad 100644 --- a/test/coverlet.core.tests/Coverage/InstrumenterHelper.Assertions.cs +++ b/test/coverlet.core.tests/Coverage/InstrumenterHelper.Assertions.cs @@ -246,6 +246,11 @@ public static Document AssertLinesCoveredAllBut(this Document document, BuildCon return document; } + public static Document AssertLinesCoveredFromTo(this Document document, int from, int to) + { + return AssertLinesCoveredFromTo(document, BuildConfiguration.Debug | BuildConfiguration.Release, from, to); + } + public static Document AssertLinesCoveredFromTo(this Document document, BuildConfiguration configuration, int from, int to) { if (document is null) diff --git a/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs b/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs index e548996f1..9b8f913b9 100644 --- a/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs +++ b/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs @@ -70,6 +70,7 @@ public static CoverageResult GetCoverageResult(string filePath) async public static Task Run(Func callMethod, Func includeFilter = null, Func excludeFilter = null, + Func doesNotReturnAttributes = null, string persistPrepareResultToFile = null, bool disableRestoreModules = false, bool skipAutoProps = false) @@ -111,7 +112,8 @@ async public static Task Run(Func callM SingleHit = false, MergeWith = string.Empty, UseSourceLink = false, - SkipAutoProps = skipAutoProps + SkipAutoProps = skipAutoProps, + DoesNotReturnAttributes = doesNotReturnAttributes?.Invoke(fileName) }; // Instrument module diff --git a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs index 76019b9d6..005c995fb 100644 --- a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs +++ b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs @@ -252,7 +252,7 @@ private InstrumenterTest CreateInstrumentor(bool fakeCoreLibModule = false, stri new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), new FileSystem(), new Mock().Object, new SourceRootTranslator(new Mock().Object, new FileSystem())); module = Path.Combine(directory.FullName, destModule); - Instrumenter instrumenter = new Instrumenter(module, identifier, Array.Empty(), Array.Empty(), Array.Empty(), attributesToIgnore, Array.Empty(), false, false, + Instrumenter instrumenter = new Instrumenter(module, identifier, Array.Empty(), Array.Empty(), Array.Empty(), attributesToIgnore, new string[] { "DoesNotReturnAttribute" }, false, false, _mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper()); return new InstrumenterTest { @@ -590,7 +590,7 @@ public int SampleMethod() excludedAttributes, Array.Empty(), false, false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper()); InstrumenterResult result = instrumenter.Instrument(); - if(expectedExcludes) + if (expectedExcludes) { Assert.Empty(result.Documents); loggerMock.Verify(l => l.LogVerbose(It.IsAny())); @@ -783,6 +783,6 @@ public void TestReachabilityHelper() instrumenterTest.Directory.Delete(true); } - + } } diff --git a/test/coverlet.core.tests/Samples/Instrumentation.Lambda.cs b/test/coverlet.core.tests/Samples/Instrumentation.Lambda.cs index b179b7ebf..dcf4ffee1 100644 --- a/test/coverlet.core.tests/Samples/Instrumentation.Lambda.cs +++ b/test/coverlet.core.tests/Samples/Instrumentation.Lambda.cs @@ -103,4 +103,31 @@ public async Task Foreach() return sum; } } + + public class Issue_1056 + { + public void T1() + { + Do(x => WriteLine(x.GetType().Name)); + Do(x => WriteLine(x + .GetType() + .Name)); + Do2(x => x.GetType().Name.Length); + Do2(x => x.GetType() + .Name + .Length); + } + + private static void Do(System.Action action) + { + action(new object()); + } + + private static object Do2(System.Func func) + { + return func(new object()); + } + + public void WriteLine(string str) { } + } } diff --git a/version.json b/version.json index f1a321557..a65a8a5e4 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "3.0.2-preview.{height}", + "version": "3.0.3-preview.{height}", "publicReleaseRefSpec": [ "^refs/heads/master$" ],