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