imp + test + changelog (#1306)
This commit is contained in:
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
-Await foreach has wrong branch coverage when method is generic [#1210](https://github.com/coverlet-coverage/coverlet/issues/1210)
|
||||
-ExcludeFromCodeCoverage attribute on local functions ignores lambda expression [#1302](https://github.com/coverlet-coverage/coverlet/issues/1302)
|
||||
|
||||
## Release date 2022-02-06
|
||||
### Packages
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Coverlet.Core.Instrumentation
|
||||
private List<string> _excludedSourceFiles;
|
||||
private List<string> _branchesInCompiledGeneratedClass;
|
||||
private List<(MethodDefinition, int)> _excludedMethods;
|
||||
private List<string> _excludedLambdaMethods;
|
||||
private List<string> _excludedCompilerGeneratedTypes;
|
||||
private readonly string[] _doesNotReturnAttributes;
|
||||
private ReachabilityHelper _reachabilityHelper;
|
||||
@@ -500,12 +501,18 @@ namespace Coverlet.Core.Instrumentation
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_excludedLambdaMethods != null && _excludedLambdaMethods.Contains(method.FullName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!customAttributes.Any(IsExcludeAttribute))
|
||||
{
|
||||
InstrumentMethod(method);
|
||||
}
|
||||
else
|
||||
{
|
||||
(_excludedLambdaMethods ??= new List<string>()).AddRange(CollectLambdaMethodsInsideLocalFunction(method));
|
||||
(_excludedMethods ??= new List<(MethodDefinition, int)>()).Add((method, ordinal));
|
||||
}
|
||||
}
|
||||
@@ -842,6 +849,19 @@ namespace Coverlet.Core.Instrumentation
|
||||
(name.IndexOf($"<{methodName}>g__") != -1 && name.IndexOf($"|{methodOrdinal}_") != -1);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> CollectLambdaMethodsInsideLocalFunction(MethodDefinition methodDefinition)
|
||||
{
|
||||
if (!methodDefinition.Name.Contains(">g__")) yield break;
|
||||
|
||||
foreach (Instruction instruction in methodDefinition.Body.Instructions.ToList())
|
||||
{
|
||||
if (instruction.OpCode == OpCodes.Ldftn && instruction.Operand is MethodReference mr && mr.Name.Contains(">b__"))
|
||||
{
|
||||
yield return mr.FullName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A custom importer created specifically to allow the instrumentation of System.Private.CoreLib by
|
||||
/// removing the external references to netstandard that are generated when instrumenting a typical
|
||||
|
||||
@@ -277,5 +277,32 @@ namespace Coverlet.Core.Tests
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExcludeFromCodeCoverage_Issue1302()
|
||||
{
|
||||
string path = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
FunctionExecutor.Run(async (string[] pathSerialize) =>
|
||||
{
|
||||
CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run<Issue1302>(instance =>
|
||||
{
|
||||
instance.Run();
|
||||
return Task.CompletedTask;
|
||||
}, persistPrepareResultToFile: pathSerialize[0]);
|
||||
|
||||
return 0;
|
||||
}, new string[] { path });
|
||||
|
||||
TestInstrumentationHelper.GetCoverageResult(path)
|
||||
.Document("Instrumentation.ExcludeFromCoverage.Issue1302.cs")
|
||||
.AssertNonInstrumentedLines(BuildConfiguration.Debug, 10, 13);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Coverlet.Core.Samples.Tests
|
||||
{
|
||||
public class Issue1302
|
||||
{
|
||||
public void Run()
|
||||
{
|
||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||
static Func<string, bool> LocalFunction()
|
||||
{
|
||||
return myString => myString.Length == 10;
|
||||
}
|
||||
|
||||
LocalFunction();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user