diff --git a/Documentation/GlobalTool.md b/Documentation/GlobalTool.md
index 01ff23b94..bb76dc9e5 100644
--- a/Documentation/GlobalTool.md
+++ b/Documentation/GlobalTool.md
@@ -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.
diff --git a/Documentation/MSBuildIntegration.md b/Documentation/MSBuildIntegration.md
index 0ef0c22f6..4b0032a9e 100644
--- a/Documentation/MSBuildIntegration.md
+++ b/Documentation/MSBuildIntegration.md
@@ -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 ```,```.
diff --git a/Documentation/VSTestIntegration.md b/Documentation/VSTestIntegration.md
index 0b5831336..6b35e976e 100644
--- a/Documentation/VSTestIntegration.md
+++ b/Documentation/VSTestIntegration.md
@@ -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?
false
true
true
+ true
diff --git a/README.md b/README.md
index 42e154614..6cbe84631 100644
--- a/README.md
+++ b/README.md
@@ -164,6 +164,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.
diff --git a/src/coverlet.collector/DataCollection/CoverageWrapper.cs b/src/coverlet.collector/DataCollection/CoverageWrapper.cs
index e65a918d6..d99e3bd8d 100644
--- a/src/coverlet.collector/DataCollection/CoverageWrapper.cs
+++ b/src/coverlet.collector/DataCollection/CoverageWrapper.cs
@@ -27,7 +27,8 @@ public Coverage CreateCoverage(CoverletSettings settings, ILogger coverletLogger
IncludeTestAssembly = settings.IncludeTestAssembly,
SingleHit = settings.SingleHit,
MergeWith = settings.MergeWith,
- UseSourceLink = settings.UseSourceLink
+ UseSourceLink = settings.UseSourceLink,
+ SkipAutoProps = settings.SkipAutoProps
};
return new Coverage(
diff --git a/src/coverlet.collector/DataCollection/CoverletSettings.cs b/src/coverlet.collector/DataCollection/CoverletSettings.cs
index 825cbfe36..eaa1afbb6 100644
--- a/src/coverlet.collector/DataCollection/CoverletSettings.cs
+++ b/src/coverlet.collector/DataCollection/CoverletSettings.cs
@@ -63,20 +63,26 @@ internal class CoverletSettings
///
public bool IncludeTestAssembly { get; set; }
+ ///
+ /// Neither track nor record auto-implemented properties.
+ ///
+ 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()));
- builder.AppendFormat("IncludeDirectories: '{0}', ", string.Join(",", this.IncludeDirectories ?? Enumerable.Empty()));
- builder.AppendFormat("ExcludeFilters: '{0}', ", string.Join(",", this.ExcludeFilters ?? Enumerable.Empty()));
- builder.AppendFormat("ExcludeSourceFiles: '{0}', ", string.Join(",", this.ExcludeSourceFiles ?? Enumerable.Empty()));
- builder.AppendFormat("ExcludeAttributes: '{0}', ", string.Join(",", this.ExcludeAttributes ?? Enumerable.Empty()));
- 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()));
+ builder.AppendFormat("IncludeDirectories: '{0}', ", string.Join(",", IncludeDirectories ?? Enumerable.Empty()));
+ builder.AppendFormat("ExcludeFilters: '{0}', ", string.Join(",", ExcludeFilters ?? Enumerable.Empty()));
+ builder.AppendFormat("ExcludeSourceFiles: '{0}', ", string.Join(",", ExcludeSourceFiles ?? Enumerable.Empty()));
+ builder.AppendFormat("ExcludeAttributes: '{0}', ", string.Join(",", ExcludeAttributes ?? Enumerable.Empty()));
+ 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();
}
diff --git a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs
index cbaaca3d1..ce37c237c 100644
--- a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs
+++ b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs
@@ -29,23 +29,24 @@ public CoverletSettings Parse(XmlElement configurationElement, IEnumerable
+ /// Parse skipautoprops flag
+ ///
+ /// Configuration element
+ /// Include Test Assembly Flag
+ private bool ParseSkipAutoProps(XmlElement configurationElement)
+ {
+ XmlElement skipAutoPropsElement = configurationElement[CoverletConstants.SkipAutoProps];
+ bool.TryParse(skipAutoPropsElement?.InnerText, out bool skipAutoProps);
+ return skipAutoProps;
+ }
+
///
/// Splits a comma separated elements into an array
///
diff --git a/src/coverlet.collector/Utilities/CoverletConstants.cs b/src/coverlet.collector/Utilities/CoverletConstants.cs
index d3e6469af..c89846a59 100644
--- a/src/coverlet.collector/Utilities/CoverletConstants.cs
+++ b/src/coverlet.collector/Utilities/CoverletConstants.cs
@@ -20,5 +20,6 @@ internal static class CoverletConstants
public const string ReportFormatElementName = "Format";
public const string DefaultExcludeFilter = "[coverlet.*]*";
public const string InProcDataCollectorName = "CoverletInProcDataCollector";
+ public const string SkipAutoProps = "SkipAutoProps";
}
}
diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs
index 16cc7fa44..0099b4db0 100644
--- a/src/coverlet.console/Program.cs
+++ b/src/coverlet.console/Program.cs
@@ -60,6 +60,7 @@ static int Main(string[] args)
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 @@ static int Main(string[] args)
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 @@ static int Main(string[] args)
fileSystem,
serviceProvider.GetRequiredService(),
serviceProvider.GetRequiredService());
- coverage.PrepareModules();
+ coverage.PrepareModules();
Process process = new Process();
process.StartInfo.FileName = target.Value();
diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs
index c19d007ce..7d6c6695c 100644
--- a/src/coverlet.core/Coverage.cs
+++ b/src/coverlet.core/Coverage.cs
@@ -23,6 +23,7 @@ internal class CoverageParameters
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 @@ internal class Coverage
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 @@ public Coverage(string module,
_fileSystem = fileSystem;
_sourceRootTranslator = sourceRootTranslator;
_cecilSymbolHelper = cecilSymbolHelper;
+ _skipAutoProps = parameters.SkipAutoProps;
_identifier = Guid.NewGuid().ToString();
_results = new List();
@@ -115,7 +118,19 @@ public CoveragePrepareResult PrepareModules()
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())
{
diff --git a/src/coverlet.core/Instrumentation/Instrumenter.cs b/src/coverlet.core/Instrumentation/Instrumenter.cs
index 23b8f3a26..6f99eabce 100644
--- a/src/coverlet.core/Instrumentation/Instrumenter.cs
+++ b/src/coverlet.core/Instrumentation/Instrumenter.cs
@@ -25,6 +25,7 @@ internal class Instrumenter
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 @@ public Instrumenter(
string[] excludedFiles,
string[] excludedAttributes,
bool singleHit,
+ bool skipAutoProps,
ILogger logger,
IInstrumentationHelper instrumentationHelper,
IFileSystem fileSystem,
@@ -84,6 +86,7 @@ public Instrumenter(
_fileSystem = fileSystem;
_sourceRootTranslator = sourceRootTranslator;
_cecilSymbolHelper = cecilSymbolHelper;
+ _skipAutoProps = skipAutoProps;
}
public bool CanInstrument()
@@ -432,6 +435,11 @@ private void InstrumentType(TypeDefinition type)
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);
diff --git a/src/coverlet.msbuild.tasks/CoverageResultTask.cs b/src/coverlet.msbuild.tasks/CoverageResultTask.cs
index 12a807ea5..704576f88 100644
--- a/src/coverlet.msbuild.tasks/CoverageResultTask.cs
+++ b/src/coverlet.msbuild.tasks/CoverageResultTask.cs
@@ -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 @@ public override bool Execute()
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 @@ public override bool Execute()
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 @@ public override bool Execute()
}
else
{
- ReportWriter writer = new ReportWriter(_coverletMultiTargetFrameworksCurrentTFM,
+ ReportWriter writer = new ReportWriter(CoverletMultiTargetFrameworksCurrentTFM,
directory,
- _output,
+ Output,
reporter,
fileSystem,
ServiceProvider.GetService(),
@@ -152,7 +117,7 @@ public override bool Execute()
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 @@ public override bool Execute()
}
}
- 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 @@ public override bool Execute()
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());
diff --git a/src/coverlet.msbuild.tasks/InstrumentationTask.cs b/src/coverlet.msbuild.tasks/InstrumentationTask.cs
index 98b35bce2..cb2a34784 100644
--- a/src/coverlet.msbuild.tasks/InstrumentationTask.cs
+++ b/src/coverlet.msbuild.tasks/InstrumentationTask.cs
@@ -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 @@ public override bool Execute()
serviceCollection.AddTransient(_ => _logger);
serviceCollection.AddTransient();
// We cache resolutions
- serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(_path, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService()));
+ serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(Path, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService()));
// We need to keep singleton/static semantics
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
@@ -142,18 +89,19 @@ public override bool Execute()
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(),
diff --git a/src/coverlet.msbuild.tasks/coverlet.msbuild.targets b/src/coverlet.msbuild.tasks/coverlet.msbuild.targets
index 4f3d4ee15..fefd1cbdb 100644
--- a/src/coverlet.msbuild.tasks/coverlet.msbuild.targets
+++ b/src/coverlet.msbuild.tasks/coverlet.msbuild.targets
@@ -5,7 +5,7 @@
diff --git a/test/coverlet.collector.tests/CoverletSettingsParserTests.cs b/test/coverlet.collector.tests/CoverletSettingsParserTests.cs
index 40d0ec112..dd56a6572 100644
--- a/test/coverlet.collector.tests/CoverletSettingsParserTests.cs
+++ b/test/coverlet.collector.tests/CoverletSettingsParserTests.cs
@@ -73,6 +73,7 @@ public void ParseShouldCorrectlyParseConfigurationElement(string includeFilters,
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 @@ public void ParseShouldCorrectlyParseConfigurationElement(string includeFilters,
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 @@ public void ParseShouldCorrectlyParseConfigurationElementWithNullInnerText()
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);
diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.AutoProps.cs b/test/coverlet.core.tests/Coverage/CoverageTests.AutoProps.cs
new file mode 100644
index 000000000..799912d27
--- /dev/null
+++ b/test/coverlet.core.tests/Coverage/CoverageTests.AutoProps.cs
@@ -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(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);
+ }
+ }
+ }
+}
diff --git a/test/coverlet.core.tests/Coverage/CoverageTest.Yield.cs b/test/coverlet.core.tests/Coverage/CoverageTests.Yield.cs
similarity index 100%
rename from test/coverlet.core.tests/Coverage/CoverageTest.Yield.cs
rename to test/coverlet.core.tests/Coverage/CoverageTests.Yield.cs
diff --git a/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs b/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs
index 2faabf3d7..e548996f1 100644
--- a/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs
+++ b/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs
@@ -67,7 +67,12 @@ public static CoverageResult GetCoverageResult(string filePath)
return coverage.GetCoverageResult();
}
- async public static Task Run(Func callMethod, Func includeFilter = null, Func excludeFilter = null, string persistPrepareResultToFile = null, bool disableRestoreModules = false)
+ async public static Task Run(Func callMethod,
+ Func includeFilter = null,
+ Func excludeFilter = null,
+ string persistPrepareResultToFile = null,
+ bool disableRestoreModules = false,
+ bool skipAutoProps = false)
{
if (persistPrepareResultToFile is null)
{
@@ -105,7 +110,8 @@ async public static Task Run(Func callM
IncludeTestAssembly = true,
SingleHit = false,
MergeWith = string.Empty,
- UseSourceLink = false
+ UseSourceLink = false,
+ SkipAutoProps = skipAutoProps
};
// Instrument module
diff --git a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs
index 78e5365b5..71ef28073 100644
--- a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs
+++ b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs
@@ -77,7 +77,7 @@ public void TestCoreLibInstrumentation()
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(), Array.Empty(), Array.Empty(),
- Array.Empty(), false, _mockLogger.Object, instrumentationHelper, partialMockFileSystem.Object, sourceRootTranslator, new CecilSymbolHelper());
+ Array.Empty(), false, false, _mockLogger.Object, instrumentationHelper, partialMockFileSystem.Object, sourceRootTranslator, new CecilSymbolHelper());
Assert.True(instrumenter.CanInstrument());
InstrumenterResult result = instrumenter.Instrument();
@@ -242,7 +242,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, false,
+ Instrumenter instrumenter = new Instrumenter(module, identifier, Array.Empty(), Array.Empty(), Array.Empty(), attributesToIgnore, false, false,
_mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper());
return new InstrumenterTest
{
@@ -420,7 +420,7 @@ public void SkipEmbeddedPpdbWithoutLocalSource()
new SourceRootTranslator(xunitDll, new Mock().Object, new FileSystem()));
Instrumenter instrumenter = new Instrumenter(xunitDll, "_xunit_instrumented", Array.Empty(), Array.Empty(), Array.Empty(),
- Array.Empty(), false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(xunitDll, loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
+ Array.Empty(), 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 @@ public void SkipEmbeddedPpdbWithoutLocalSource()
new SourceRootTranslator(sample, new Mock().Object, new FileSystem()));
instrumenter = new Instrumenter(sample, "_coverlet_tests_projectsample_empty", Array.Empty(), Array.Empty(), Array.Empty(),
- Array.Empty(), false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(sample, loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
+ Array.Empty(), 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 @@ public void SkipPpdbWithoutLocalSource()
string sample = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "TestAssets"), dllFileName).First();
var loggerMock = new Mock();
Instrumenter instrumenter = new Instrumenter(sample, "_75d9f96508d74def860a568f426ea4a4_instrumented", Array.Empty(), Array.Empty(), Array.Empty(),
- Array.Empty(), false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
+ Array.Empty(), 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 @@ public void TestInstrument_MissingModule()
new SourceRootTranslator(new Mock().Object, new FileSystem()));
var instrumenter = new Instrumenter("test", "_test_instrumented", Array.Empty(), Array.Empty(), Array.Empty(),
- Array.Empty(), false, loggerMock.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
+ Array.Empty(), 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()));
}
@@ -519,7 +519,7 @@ public void TestInstrument_AssemblyMarkedAsExcludeFromCodeCoverage()
new SourceRootTranslator(new Mock().Object, new FileSystem()));
Instrumenter instrumenter = new Instrumenter(excludedbyattributeDll, "_xunit_excludedbyattribute", Array.Empty(), Array.Empty(), Array.Empty(),
- Array.Empty(), false, loggerMock.Object, instrumentationHelper, partialMockFileSystem.Object, new SourceRootTranslator(loggerMock.Object, new FileSystem()), new CecilSymbolHelper());
+ Array.Empty(), 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()));
diff --git a/test/coverlet.core.tests/Samples/Instrumentation.AutoProps.cs b/test/coverlet.core.tests/Samples/Instrumentation.AutoProps.cs
new file mode 100644
index 000000000..4378ca9e7
--- /dev/null
+++ b/test/coverlet.core.tests/Samples/Instrumentation.AutoProps.cs
@@ -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;
+ }
+}