Add skipautoprops feature (#912)

Add skipautoprops feature
This commit is contained in:
Marco Rossignoli
2020-08-03 19:38:59 +02:00
committed by GitHub
parent 778b697655
commit fdd2930df6
20 changed files with 217 additions and 168 deletions
+1
View File
@@ -36,6 +36,7 @@ Options:
--single-hit Specifies whether to limit code coverage hit reporting to a single hit for each location.
--merge-with Path to existing coverage result to merge.
--use-source-link Specifies whether to use SourceLink URIs in place of file system paths.
--skipautoprops Neither track nor record auto-implemented properties.
```
NB. For a [multiple value] options you have to specify values multiple times i.e.
+5
View File
@@ -157,6 +157,11 @@ Both `Exclude` and `Include` properties can be used together but `Exclude` takes
You can also include coverage of the test assembly itself by setting `/p:IncludeTestAssembly` to `true`.
### Skip auto-implemented properties
Neither track nor record auto-implemented properties.
Syntax: `/p:SkipAutoProps=true`
### Note for Powershell / VSTS users
To exclude or include multiple assemblies when using Powershell scripts or creating a .yaml file for a VSTS build ```%2c``` should be used as a separator. Msbuild will translate this symbol to ```,```.
+2
View File
@@ -79,6 +79,7 @@ These are a list of options that are supported by coverlet. These can be specifi
|SingleHit | Specifies whether to limit code coverage hit reporting to a single hit for each location.|
|UseSourceLink | Specifies whether to use SourceLink URIs in place of file system paths. |
|IncludeTestAssembly | Include coverage of the test assembly. |
|SkipAutoProps | Neither track nor record auto-implemented properties. |
How to specify these options via runsettings?
```
@@ -97,6 +98,7 @@ How to specify these options via runsettings?
<SingleHit>false</SingleHit>
<UseSourceLink>true</UseSourceLink>
<IncludeTestAssembly>true</IncludeTestAssembly>
<SkipAutoProps>true</SkipAutoProps>
</Configuration>
</DataCollector>
</DataCollectors>
+4
View File
@@ -167,6 +167,10 @@ to clarify expected behavior in our community.
For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
## Credits
Part of the code is based on work done by OpenCover team https://github.com/OpenCover
## License
This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
@@ -27,7 +27,8 @@ namespace Coverlet.Collector.DataCollection
IncludeTestAssembly = settings.IncludeTestAssembly,
SingleHit = settings.SingleHit,
MergeWith = settings.MergeWith,
UseSourceLink = settings.UseSourceLink
UseSourceLink = settings.UseSourceLink,
SkipAutoProps = settings.SkipAutoProps
};
return new Coverage(
@@ -63,20 +63,26 @@ namespace Coverlet.Collector.DataCollection
/// </summary>
public bool IncludeTestAssembly { get; set; }
/// <summary>
/// Neither track nor record auto-implemented properties.
/// </summary>
public bool SkipAutoProps { get; set; }
public override string ToString()
{
var builder = new StringBuilder();
builder.AppendFormat("TestModule: '{0}', ", this.TestModule);
builder.AppendFormat("IncludeFilters: '{0}', ", string.Join(",", this.IncludeFilters ?? Enumerable.Empty<string>()));
builder.AppendFormat("IncludeDirectories: '{0}', ", string.Join(",", this.IncludeDirectories ?? Enumerable.Empty<string>()));
builder.AppendFormat("ExcludeFilters: '{0}', ", string.Join(",", this.ExcludeFilters ?? Enumerable.Empty<string>()));
builder.AppendFormat("ExcludeSourceFiles: '{0}', ", string.Join(",", this.ExcludeSourceFiles ?? Enumerable.Empty<string>()));
builder.AppendFormat("ExcludeAttributes: '{0}', ", string.Join(",", this.ExcludeAttributes ?? Enumerable.Empty<string>()));
builder.AppendFormat("MergeWith: '{0}', ", this.MergeWith);
builder.AppendFormat("UseSourceLink: '{0}'", this.UseSourceLink);
builder.AppendFormat("SingleHit: '{0}'", this.SingleHit);
builder.AppendFormat("IncludeTestAssembly: '{0}'", this.IncludeTestAssembly);
builder.AppendFormat("TestModule: '{0}', ", TestModule);
builder.AppendFormat("IncludeFilters: '{0}', ", string.Join(",", IncludeFilters ?? Enumerable.Empty<string>()));
builder.AppendFormat("IncludeDirectories: '{0}', ", string.Join(",", IncludeDirectories ?? Enumerable.Empty<string>()));
builder.AppendFormat("ExcludeFilters: '{0}', ", string.Join(",", ExcludeFilters ?? Enumerable.Empty<string>()));
builder.AppendFormat("ExcludeSourceFiles: '{0}', ", string.Join(",", ExcludeSourceFiles ?? Enumerable.Empty<string>()));
builder.AppendFormat("ExcludeAttributes: '{0}', ", string.Join(",", ExcludeAttributes ?? Enumerable.Empty<string>()));
builder.AppendFormat("MergeWith: '{0}', ", MergeWith);
builder.AppendFormat("UseSourceLink: '{0}'", UseSourceLink);
builder.AppendFormat("SingleHit: '{0}'", SingleHit);
builder.AppendFormat("IncludeTestAssembly: '{0}'", IncludeTestAssembly);
builder.AppendFormat("SkipAutoProps: '{0}'", SkipAutoProps);
return builder.ToString();
}
@@ -29,23 +29,24 @@ namespace Coverlet.Collector.DataCollection
{
var coverletSettings = new CoverletSettings
{
TestModule = this.ParseTestModule(testModules)
TestModule = ParseTestModule(testModules)
};
if (configurationElement != null)
{
coverletSettings.IncludeFilters = this.ParseIncludeFilters(configurationElement);
coverletSettings.IncludeDirectories = this.ParseIncludeDirectories(configurationElement);
coverletSettings.ExcludeAttributes = this.ParseExcludeAttributes(configurationElement);
coverletSettings.ExcludeSourceFiles = this.ParseExcludeSourceFiles(configurationElement);
coverletSettings.MergeWith = this.ParseMergeWith(configurationElement);
coverletSettings.UseSourceLink = this.ParseUseSourceLink(configurationElement);
coverletSettings.SingleHit = this.ParseSingleHit(configurationElement);
coverletSettings.IncludeTestAssembly = this.ParseIncludeTestAssembly(configurationElement);
coverletSettings.IncludeFilters = ParseIncludeFilters(configurationElement);
coverletSettings.IncludeDirectories = ParseIncludeDirectories(configurationElement);
coverletSettings.ExcludeAttributes = ParseExcludeAttributes(configurationElement);
coverletSettings.ExcludeSourceFiles = ParseExcludeSourceFiles(configurationElement);
coverletSettings.MergeWith = ParseMergeWith(configurationElement);
coverletSettings.UseSourceLink = ParseUseSourceLink(configurationElement);
coverletSettings.SingleHit = ParseSingleHit(configurationElement);
coverletSettings.IncludeTestAssembly = ParseIncludeTestAssembly(configurationElement);
coverletSettings.SkipAutoProps = ParseSkipAutoProps(configurationElement);
}
coverletSettings.ReportFormats = this.ParseReportFormats(configurationElement);
coverletSettings.ExcludeFilters = this.ParseExcludeFilters(configurationElement);
coverletSettings.ReportFormats = ParseReportFormats(configurationElement);
coverletSettings.ExcludeFilters = ParseExcludeFilters(configurationElement);
if (_eqtTrace.IsVerboseEnabled)
{
@@ -205,6 +206,18 @@ namespace Coverlet.Collector.DataCollection
return includeTestAssembly;
}
/// <summary>
/// Parse skipautoprops flag
/// </summary>
/// <param name="configurationElement">Configuration element</param>
/// <returns>Include Test Assembly Flag</returns>
private bool ParseSkipAutoProps(XmlElement configurationElement)
{
XmlElement skipAutoPropsElement = configurationElement[CoverletConstants.SkipAutoProps];
bool.TryParse(skipAutoPropsElement?.InnerText, out bool skipAutoProps);
return skipAutoProps;
}
/// <summary>
/// Splits a comma separated elements into an array
/// </summary>
@@ -20,5 +20,6 @@
public const string ReportFormatElementName = "Format";
public const string DefaultExcludeFilter = "[coverlet.*]*";
public const string InProcDataCollectorName = "CoverletInProcDataCollector";
public const string SkipAutoProps = "SkipAutoProps";
}
}
+4 -2
View File
@@ -60,6 +60,7 @@ namespace Coverlet.Console
CommandOption excludeAttributes = app.Option("--exclude-by-attribute", "Attributes to exclude from code coverage.", CommandOptionType.MultipleValue);
CommandOption includeTestAssembly = app.Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.", CommandOptionType.NoValue);
CommandOption singleHit = app.Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location", CommandOptionType.NoValue);
CommandOption skipAutoProp = app.Option("--skipautoprops", "Neither track nor record auto-implemented properties.", CommandOptionType.NoValue);
CommandOption mergeWith = app.Option("--merge-with", "Path to existing coverage result to merge.", CommandOptionType.SingleValue);
CommandOption useSourceLink = app.Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.", CommandOptionType.NoValue);
@@ -87,7 +88,8 @@ namespace Coverlet.Console
IncludeTestAssembly = includeTestAssembly.HasValue(),
SingleHit = singleHit.HasValue(),
MergeWith = mergeWith.Value(),
UseSourceLink = useSourceLink.HasValue()
UseSourceLink = useSourceLink.HasValue(),
SkipAutoProps = skipAutoProp.HasValue()
};
Coverage coverage = new Coverage(module.Value,
@@ -97,7 +99,7 @@ namespace Coverlet.Console
fileSystem,
serviceProvider.GetRequiredService<ISourceRootTranslator>(),
serviceProvider.GetRequiredService<ICecilSymbolHelper>());
coverage.PrepareModules();
coverage.PrepareModules();
Process process = new Process();
process.StartInfo.FileName = target.Value();
+16 -1
View File
@@ -23,6 +23,7 @@ namespace Coverlet.Core
public bool SingleHit { get; set; }
public string MergeWith { get; set; }
public bool UseSourceLink { get; set; }
public bool SkipAutoProps { get; set; }
}
internal class Coverage
@@ -38,6 +39,7 @@ namespace Coverlet.Core
private bool _singleHit;
private string _mergeWith;
private bool _useSourceLink;
private bool _skipAutoProps;
private ILogger _logger;
private IInstrumentationHelper _instrumentationHelper;
private IFileSystem _fileSystem;
@@ -73,6 +75,7 @@ namespace Coverlet.Core
_fileSystem = fileSystem;
_sourceRootTranslator = sourceRootTranslator;
_cecilSymbolHelper = cecilSymbolHelper;
_skipAutoProps = parameters.SkipAutoProps;
_identifier = Guid.NewGuid().ToString();
_results = new List<InstrumenterResult>();
@@ -115,7 +118,19 @@ namespace Coverlet.Core
continue;
}
var instrumenter = new Instrumenter(module, _identifier, _excludeFilters, _includeFilters, _excludedSourceFiles, _excludeAttributes, _singleHit, _logger, _instrumentationHelper, _fileSystem, _sourceRootTranslator, _cecilSymbolHelper);
var instrumenter = new Instrumenter(module,
_identifier,
_excludeFilters,
_includeFilters,
_excludedSourceFiles,
_excludeAttributes,
_singleHit,
_skipAutoProps,
_logger,
_instrumentationHelper,
_fileSystem,
_sourceRootTranslator,
_cecilSymbolHelper);
if (instrumenter.CanInstrument())
{
@@ -25,6 +25,7 @@ namespace Coverlet.Core.Instrumentation
private readonly ExcludedFilesHelper _excludedFilesHelper;
private readonly string[] _excludedAttributes;
private readonly bool _singleHit;
private readonly bool _skipAutoProps;
private readonly bool _isCoreLibrary;
private readonly ILogger _logger;
private readonly IInstrumentationHelper _instrumentationHelper;
@@ -55,6 +56,7 @@ namespace Coverlet.Core.Instrumentation
string[] excludedFiles,
string[] excludedAttributes,
bool singleHit,
bool skipAutoProps,
ILogger logger,
IInstrumentationHelper instrumentationHelper,
IFileSystem fileSystem,
@@ -84,6 +86,7 @@ namespace Coverlet.Core.Instrumentation
_fileSystem = fileSystem;
_sourceRootTranslator = sourceRootTranslator;
_cecilSymbolHelper = cecilSymbolHelper;
_skipAutoProps = skipAutoProps;
}
public bool CanInstrument()
@@ -432,6 +435,11 @@ namespace Coverlet.Core.Instrumentation
if (actualMethod.IsGetter || actualMethod.IsSetter)
{
if (_skipAutoProps && actualMethod.CustomAttributes.Any(ca => ca.AttributeType.FullName == typeof(CompilerGeneratedAttribute).FullName))
{
continue;
}
PropertyDefinition prop = type.Properties.FirstOrDefault(p => (p.GetMethod ?? p.SetMethod).FullName.Equals(actualMethod.FullName));
if (prop?.HasCustomAttributes == true)
customAttributes = customAttributes.Union(prop.CustomAttributes);
@@ -14,62 +14,27 @@ namespace Coverlet.MSbuild.Tasks
{
public class CoverageResultTask : BaseTask
{
private string _output;
private string _format;
private double _threshold;
private string _thresholdType;
private string _thresholdStat;
private string _coverletMultiTargetFrameworksCurrentTFM;
private ITaskItem _instrumenterState;
private MSBuildLogger _logger;
[Required]
public string Output
{
get { return _output; }
set { _output = value; }
}
public string Output { get; set; }
[Required]
public string OutputFormat
{
get { return _format; }
set { _format = value; }
}
public string OutputFormat { get; set; }
[Required]
public double Threshold
{
get { return _threshold; }
set { _threshold = value; }
}
public double Threshold { get; set; }
[Required]
public string ThresholdType
{
get { return _thresholdType; }
set { _thresholdType = value; }
}
public string ThresholdType { get; set; }
[Required]
public string ThresholdStat
{
get { return _thresholdStat; }
set { _thresholdStat = value; }
}
public string ThresholdStat { get; set; }
[Required]
public ITaskItem InstrumenterState
{
get { return _instrumenterState; }
set { _instrumenterState = value; }
}
public ITaskItem InstrumenterState { get; set; }
public string CoverletMultiTargetFrameworksCurrentTFM
{
get { return _coverletMultiTargetFrameworksCurrentTFM; }
set { _coverletMultiTargetFrameworksCurrentTFM = value; }
}
public string CoverletMultiTargetFrameworksCurrentTFM { get; set; }
public CoverageResultTask()
{
@@ -111,7 +76,7 @@ namespace Coverlet.MSbuild.Tasks
CoverageResult result = coverage.GetCoverageResult();
var directory = Path.GetDirectoryName(_output);
var directory = Path.GetDirectoryName(Output);
if (directory == string.Empty)
{
directory = Directory.GetCurrentDirectory();
@@ -121,7 +86,7 @@ namespace Coverlet.MSbuild.Tasks
Directory.CreateDirectory(directory);
}
var formats = _format.Split(',');
var formats = OutputFormat.Split(',');
foreach (var format in formats)
{
var reporter = new ReporterFactory(format).CreateReporter();
@@ -138,9 +103,9 @@ namespace Coverlet.MSbuild.Tasks
}
else
{
ReportWriter writer = new ReportWriter(_coverletMultiTargetFrameworksCurrentTFM,
ReportWriter writer = new ReportWriter(CoverletMultiTargetFrameworksCurrentTFM,
directory,
_output,
Output,
reporter,
fileSystem,
ServiceProvider.GetService<IConsole>(),
@@ -152,7 +117,7 @@ namespace Coverlet.MSbuild.Tasks
var thresholdTypeFlags = ThresholdTypeFlags.None;
var thresholdStat = ThresholdStatistic.Minimum;
foreach (var thresholdType in _thresholdType.Split(',').Select(t => t.Trim()))
foreach (var thresholdType in ThresholdType.Split(',').Select(t => t.Trim()))
{
if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
{
@@ -168,11 +133,11 @@ namespace Coverlet.MSbuild.Tasks
}
}
if (_thresholdStat.Equals("average", StringComparison.OrdinalIgnoreCase))
if (ThresholdStat.Equals("average", StringComparison.OrdinalIgnoreCase))
{
thresholdStat = ThresholdStatistic.Average;
}
else if (_thresholdStat.Equals("total", StringComparison.OrdinalIgnoreCase))
else if (ThresholdStat.Equals("total", StringComparison.OrdinalIgnoreCase))
{
thresholdStat = ThresholdStatistic.Total;
}
@@ -214,23 +179,23 @@ namespace Coverlet.MSbuild.Tasks
Console.WriteLine(coverageTable.ToStringAlternative());
thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, _threshold, thresholdTypeFlags, thresholdStat);
thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, Threshold, thresholdTypeFlags, thresholdStat);
if (thresholdTypeFlags != ThresholdTypeFlags.None)
{
var exceptionMessageBuilder = new StringBuilder();
if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
{
exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {_threshold}");
exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {Threshold}");
}
if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
{
exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {_threshold}");
exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {Threshold}");
}
if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
{
exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {_threshold}");
exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {Threshold}");
}
throw new Exception(exceptionMessageBuilder.ToString());
@@ -15,86 +15,33 @@ namespace Coverlet.MSbuild.Tasks
{
public class InstrumentationTask : BaseTask
{
private string _path;
private string _include;
private string _includeDirectory;
private string _exclude;
private string _excludeByFile;
private string _excludeByAttribute;
private bool _includeTestAssembly;
private bool _singleHit;
private string _mergeWith;
private bool _useSourceLink;
private ITaskItem _instrumenterState;
private readonly MSBuildLogger _logger;
[Required]
public string Path
{
get { return _path; }
set { _path = value; }
}
public string Path { get; set; }
public string Include
{
get { return _include; }
set { _include = value; }
}
public string Include { get; set; }
public string IncludeDirectory
{
get { return _includeDirectory; }
set { _includeDirectory = value; }
}
public string IncludeDirectory { get; set; }
public string Exclude
{
get { return _exclude; }
set { _exclude = value; }
}
public string Exclude { get; set; }
public string ExcludeByFile
{
get { return _excludeByFile; }
set { _excludeByFile = value; }
}
public string ExcludeByFile { get; set; }
public string ExcludeByAttribute
{
get { return _excludeByAttribute; }
set { _excludeByAttribute = value; }
}
public string ExcludeByAttribute { get; set; }
public bool IncludeTestAssembly
{
get { return _includeTestAssembly; }
set { _includeTestAssembly = value; }
}
public bool IncludeTestAssembly { get; set; }
public bool SingleHit
{
get { return _singleHit; }
set { _singleHit = value; }
}
public bool SingleHit { get; set; }
public string MergeWith
{
get { return _mergeWith; }
set { _mergeWith = value; }
}
public string MergeWith { get; set; }
public bool UseSourceLink
{
get { return _useSourceLink; }
set { _useSourceLink = value; }
}
public bool UseSourceLink { get; set; }
public bool SkipAutoProps { get; set; }
[Output]
public ITaskItem InstrumenterState
{
get { return _instrumenterState; }
set { _instrumenterState = value; }
}
public ITaskItem InstrumenterState { get; set; }
public InstrumentationTask()
{
@@ -129,7 +76,7 @@ namespace Coverlet.MSbuild.Tasks
serviceCollection.AddTransient<ILogger, MSBuildLogger>(_ => _logger);
serviceCollection.AddTransient<IRetryHelper, RetryHelper>();
// We cache resolutions
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider => new SourceRootTranslator(_path, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>()));
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider => new SourceRootTranslator(Path, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>()));
// We need to keep singleton/static semantics
serviceCollection.AddSingleton<IInstrumentationHelper, InstrumentationHelper>();
serviceCollection.AddSingleton<ICecilSymbolHelper, CecilSymbolHelper>();
@@ -142,18 +89,19 @@ namespace Coverlet.MSbuild.Tasks
CoverageParameters parameters = new CoverageParameters
{
IncludeFilters = _include?.Split(','),
IncludeDirectories = _includeDirectory?.Split(','),
ExcludeFilters = _exclude?.Split(','),
ExcludedSourceFiles = _excludeByFile?.Split(','),
ExcludeAttributes = _excludeByAttribute?.Split(','),
IncludeTestAssembly = _includeTestAssembly,
SingleHit = _singleHit,
MergeWith = _mergeWith,
UseSourceLink = _useSourceLink
IncludeFilters = Include?.Split(','),
IncludeDirectories = IncludeDirectory?.Split(','),
ExcludeFilters = Exclude?.Split(','),
ExcludedSourceFiles = ExcludeByFile?.Split(','),
ExcludeAttributes = ExcludeByAttribute?.Split(','),
IncludeTestAssembly = IncludeTestAssembly,
SingleHit = SingleHit,
MergeWith = MergeWith,
UseSourceLink = UseSourceLink,
SkipAutoProps = SkipAutoProps
};
Coverage coverage = new Coverage(_path,
Coverage coverage = new Coverage(Path,
parameters,
_logger,
ServiceProvider.GetService<IInstrumentationHelper>(),
@@ -5,7 +5,7 @@
<Target Name="ReferencedPathMaps" BeforeTargets="CoreCompile" DependsOnTargets="ResolveProjectReferences" >
<MSBuild Projects="@(AnnotatedProjects->'%(FullPath)')"
Targets="CoverletGetPathMap"
Targets="CoverletGetPathMap"
Properties="TargetFramework=%(AnnotatedProjects.NearestTargetFramework)"
SkipNonexistentTargets="true">
<Output TaskParameter="TargetOutputs"
@@ -38,7 +38,8 @@
IncludeTestAssembly="$(IncludeTestAssembly)"
SingleHit="$(SingleHit)"
MergeWith="$(MergeWith)"
UseSourceLink="$(UseSourceLink)" >
UseSourceLink="$(UseSourceLink)"
SkipAutoProps="$(SkipAutoProps)" >
<Output TaskParameter="InstrumenterState" PropertyName="InstrumenterState"/>
</Coverlet.MSbuild.Tasks.InstrumentationTask>
</Target>
@@ -73,6 +73,7 @@ namespace Coverlet.Collector.Tests
this.CreateCoverletNodes(doc, configElement, CoverletConstants.UseSourceLinkElementName, "false");
this.CreateCoverletNodes(doc, configElement, CoverletConstants.SingleHitElementName, "true");
this.CreateCoverletNodes(doc, configElement, CoverletConstants.IncludeTestAssemblyElementName, "true");
this.CreateCoverletNodes(doc, configElement, CoverletConstants.SkipAutoProps, "true");
CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules);
@@ -90,10 +91,11 @@ namespace Coverlet.Collector.Tests
Assert.Equal("[coverlet.*]*", coverletSettings.ExcludeFilters[0]);
Assert.Equal("[coverlet.*.tests?]*", coverletSettings.ExcludeFilters[1]);
Assert.Equal("[coverlet.*.tests.*]*", coverletSettings.ExcludeFilters[2]);
Assert.False(coverletSettings.UseSourceLink);
Assert.True(coverletSettings.SingleHit);
Assert.True(coverletSettings.IncludeTestAssembly);
Assert.True(coverletSettings.SkipAutoProps);
}
[Fact]
@@ -104,7 +106,7 @@ namespace Coverlet.Collector.Tests
var configElement = doc.CreateElement("Configuration");
this.CreateCoverleteNullInnerTextNodes(doc, configElement, CoverletConstants.IncludeFiltersElementName);
this.CreateCoverleteNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeFiltersElementName);
this.CreateCoverleteNullInnerTextNodes(doc, configElement, CoverletConstants.IncludeDirectoriesElementName);
this.CreateCoverleteNullInnerTextNodes(doc, configElement, CoverletConstants.IncludeDirectoriesElementName);
this.CreateCoverleteNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeSourceFilesElementName);
this.CreateCoverleteNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeAttributesElementName);
@@ -0,0 +1,54 @@
using System.IO;
using System.Threading.Tasks;
using Coverlet.Core.Samples.Tests;
using Xunit;
namespace Coverlet.Core.Tests
{
public partial class CoverageTests
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public void SkipAutoProps(bool skipAutoProps)
{
string path = Path.GetTempFileName();
try
{
FunctionExecutor.Run(async (string[] parameters) =>
{
CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run<AutoProps>(instance =>
{
instance.AutoPropsNonInit = 10;
instance.AutoPropsInit = 20;
int readVal = instance.AutoPropsNonInit;
readVal = instance.AutoPropsInit;
return Task.CompletedTask;
},
persistPrepareResultToFile: parameters[0], skipAutoProps: bool.Parse(parameters[1]));
return 0;
}, new string[] { path, skipAutoProps.ToString() });
if (skipAutoProps)
{
TestInstrumentationHelper.GetCoverageResult(path)
.Document("Instrumentation.AutoProps.cs")
.AssertNonInstrumentedLines(BuildConfiguration.Debug, 12, 12)
.AssertLinesCoveredFromTo(BuildConfiguration.Debug, 7, 11)
.AssertLinesCovered(BuildConfiguration.Debug, (13, 1));
}
else
{
TestInstrumentationHelper.GetCoverageResult(path)
.Document("Instrumentation.AutoProps.cs")
.AssertLinesCoveredFromTo(BuildConfiguration.Debug, 7, 13);
}
}
finally
{
File.Delete(path);
}
}
}
}
@@ -67,7 +67,12 @@ namespace Coverlet.Core.Tests
return coverage.GetCoverageResult();
}
async public static Task<CoveragePrepareResult> Run<T>(Func<dynamic, Task> callMethod, Func<string, string[]> includeFilter = null, Func<string, string[]> excludeFilter = null, string persistPrepareResultToFile = null, bool disableRestoreModules = false)
async public static Task<CoveragePrepareResult> Run<T>(Func<dynamic, Task> callMethod,
Func<string, string[]> includeFilter = null,
Func<string, string[]> excludeFilter = null,
string persistPrepareResultToFile = null,
bool disableRestoreModules = false,
bool skipAutoProps = false)
{
if (persistPrepareResultToFile is null)
{
@@ -105,7 +110,8 @@ namespace Coverlet.Core.Tests
IncludeTestAssembly = true,
SingleHit = false,
MergeWith = string.Empty,
UseSourceLink = false
UseSourceLink = false,
SkipAutoProps = skipAutoProps
};
// Instrument module
@@ -77,7 +77,7 @@ namespace Coverlet.Core.Instrumentation.Tests
InstrumentationHelper instrumentationHelper =
new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), partialMockFileSystem.Object, _mockLogger.Object, sourceRootTranslator);
Instrumenter instrumenter = new Instrumenter(Path.Combine(directory.FullName, files[0]), "_coverlet_instrumented", Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(),
Array.Empty<string>(), false, _mockLogger.Object, instrumentationHelper, partialMockFileSystem.Object, sourceRootTranslator, new CecilSymbolHelper());
Array.Empty<string>(), false, false, _mockLogger.Object, instrumentationHelper, partialMockFileSystem.Object, sourceRootTranslator, new CecilSymbolHelper());
Assert.True(instrumenter.CanInstrument());
InstrumenterResult result = instrumenter.Instrument();
@@ -242,7 +242,7 @@ namespace Coverlet.Core.Instrumentation.Tests
new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), new FileSystem(), new Mock<ILogger>().Object, new SourceRootTranslator(new Mock<ILogger>().Object, new FileSystem()));
module = Path.Combine(directory.FullName, destModule);
Instrumenter instrumenter = new Instrumenter(module, identifier, Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), attributesToIgnore, false,
Instrumenter instrumenter = new Instrumenter(module, identifier, Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), attributesToIgnore, false, false,
_mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper());
return new InstrumenterTest
{
@@ -420,7 +420,7 @@ namespace Coverlet.Core.Instrumentation.Tests
new SourceRootTranslator(xunitDll, new Mock<ILogger>().Object, new FileSystem()));
Instrumenter instrumenter = new Instrumenter(xunitDll, "_xunit_instrumented", Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(),
Array.Empty<string>(), false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(xunitDll, loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Array.Empty<string>(), false, false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(xunitDll, loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Assert.True(instrumentationHelper.HasPdb(xunitDll, out bool embedded));
Assert.True(embedded);
Assert.False(instrumenter.CanInstrument());
@@ -433,7 +433,7 @@ namespace Coverlet.Core.Instrumentation.Tests
new SourceRootTranslator(sample, new Mock<ILogger>().Object, new FileSystem()));
instrumenter = new Instrumenter(sample, "_coverlet_tests_projectsample_empty", Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(),
Array.Empty<string>(), false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(sample, loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Array.Empty<string>(), false, false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(sample, loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Assert.True(instrumentationHelper.HasPdb(sample, out embedded));
Assert.False(embedded);
@@ -479,7 +479,7 @@ namespace Coverlet.Core.Instrumentation.Tests
string sample = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "TestAssets"), dllFileName).First();
var loggerMock = new Mock<ILogger>();
Instrumenter instrumenter = new Instrumenter(sample, "_75d9f96508d74def860a568f426ea4a4_instrumented", Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(),
Array.Empty<string>(), false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Array.Empty<string>(), false, false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Assert.True(instrumentationHelper.HasPdb(sample, out bool embedded));
Assert.False(embedded);
Assert.False(instrumenter.CanInstrument());
@@ -496,7 +496,7 @@ namespace Coverlet.Core.Instrumentation.Tests
new SourceRootTranslator(new Mock<ILogger>().Object, new FileSystem()));
var instrumenter = new Instrumenter("test", "_test_instrumented", Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(),
Array.Empty<string>(), false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Array.Empty<string>(), false, false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Assert.False(instrumenter.CanInstrument());
loggerMock.Verify(l => l.LogWarning(It.IsAny<string>()));
}
@@ -519,7 +519,7 @@ namespace Coverlet.Core.Instrumentation.Tests
new SourceRootTranslator(new Mock<ILogger>().Object, new FileSystem()));
Instrumenter instrumenter = new Instrumenter(excludedbyattributeDll, "_xunit_excludedbyattribute", Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(),
Array.Empty<string>(), false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
Array.Empty<string>(), false, false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
InstrumenterResult result = instrumenter.Instrument();
Assert.Empty(result.Documents);
loggerMock.Verify(l => l.LogVerbose(It.IsAny<string>()));
@@ -0,0 +1,15 @@
using System;
namespace Coverlet.Core.Samples.Tests
{
public class AutoProps
{
private int _myVal = 0;
public AutoProps()
{
_myVal = new Random().Next();
}
public int AutoPropsNonInit { get; set; }
public int AutoPropsInit { get; set; } = 10;
}
}