From c9cd5d86aa49a2f3b77bfc6687c29efb0b609d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 17 Feb 2022 19:12:22 +0100 Subject: [PATCH 1/2] Increase severity of some rules and fix instances --- .editorconfig | 20 ++ .../DataCollection/AttachmentManager.cs | 17 +- .../DataCollection/CoverageManager.cs | 8 +- .../CoverletCoverageCollector.cs | 53 ++-- .../DataCollection/CoverletLogger.cs | 10 +- .../DataCollection/CoverletSettingsParser.cs | 45 ++- .../CoverletInProcDataCollector.cs | 16 +- .../Utilities/TestPlatformEqtTrace.cs | 14 +- src/coverlet.console/Logging/ConsoleLogger.cs | 5 +- src/coverlet.console/Program.cs | 15 +- src/coverlet.core/Coverage.cs | 2 +- src/coverlet.core/CoverageResult.cs | 20 +- src/coverlet.core/CoverageSummary.cs | 50 ++-- .../Helpers/InstrumentationHelper.cs | 56 ++-- .../Helpers/SourceRootTranslator.cs | 2 +- .../Instrumentation/CecilAssemblyResolver.cs | 52 ++-- .../Instrumentation/Instrumenter.cs | 278 +++++++++--------- .../Instrumentation/ModuleTrackerTemplate.cs | 138 +++++---- .../Instrumentation/ReachabilityHelper.cs | 34 ++- .../Reporters/CoberturaReporter.cs | 35 +-- src/coverlet.core/Reporters/LcovReporter.cs | 7 +- .../Reporters/OpenCoverReporter.cs | 29 +- .../Reporters/TeamCityReporter.cs | 15 +- .../Symbols/CecilSymbolHelper.cs | 18 +- .../CoverageResultTask.cs | 19 +- .../InstrumentationTask.cs | 12 +- .../AttachmentManagerTests.cs | 12 +- .../CoverletCoverageDataCollectorTests.cs | 30 +- .../CoverletSettingsParserTests.cs | 27 +- .../Coverage/CoverageSummaryTests.cs | 98 +++--- .../Coverage/CoverageTests.cs | 2 +- .../Coverage/InstrumenterHelper.cs | 12 +- .../CoverageResultTests.cs | 18 +- .../Helpers/InstrumentationHelperTests.cs | 2 +- .../Instrumentation/InstrumenterTests.cs | 42 ++- .../ModuleTrackerTemplateTests.cs | 42 ++- .../Symbols/CecilSymbolHelperTests.cs | 22 +- test/coverlet.integration.tests/BaseTest.cs | 36 +-- test/coverlet.integration.tests/DotnetTool.cs | 2 +- test/coverlet.integration.tests/Msbuild.cs | 2 +- 40 files changed, 624 insertions(+), 693 deletions(-) diff --git a/.editorconfig b/.editorconfig index 26d6da3ab..b8554bead 100644 --- a/.editorconfig +++ b/.editorconfig @@ -87,6 +87,22 @@ dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion dotnet_style_prefer_auto_properties = true:warning dotnet_style_prefer_conditional_expression_over_assignment = true:silent dotnet_style_prefer_conditional_expression_over_return = true:silent +# CA1805: Do not initialize unnecessarily +dotnet_diagnostic.CA1805.severity = warning +# CA1822: Mark members as static +dotnet_diagnostic.CA1822.severity = warning +# IDE0063: Use simple 'using' statement +dotnet_diagnostic.IDE0063.severity = warning +# IDE0057: Use range operator +dotnet_diagnostic.IDE0057.severity = warning +# IDE0075: Simplify conditional expression +dotnet_diagnostic.IDE0075.severity = warning +# IDE0071: Simplify interpolation +dotnet_diagnostic.IDE0071.severity = warning +# CA1829: Use Length/Count property instead of Count() when available +dotnet_diagnostic.CA1829.severity = warning +# CA1827: Do not use Count() or LongCount() when Any() can be used +dotnet_diagnostic.CA1827.severity = warning ############################### # Naming Conventions # ############################### @@ -114,6 +130,10 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal dotnet_naming_style.camel_case_underscore_style.required_prefix = _ dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case +# IDE1006: Naming Styles +dotnet_diagnostic.IDE1006.severity = warning +# IDE0090: Use 'new(...)' +dotnet_diagnostic.IDE0090.severity = warning ############################### # C# Coding Conventions # ############################### diff --git a/src/coverlet.collector/DataCollection/AttachmentManager.cs b/src/coverlet.collector/DataCollection/AttachmentManager.cs index 8259f71f3..d2f302bef 100644 --- a/src/coverlet.collector/DataCollection/AttachmentManager.cs +++ b/src/coverlet.collector/DataCollection/AttachmentManager.cs @@ -17,7 +17,6 @@ namespace Coverlet.Collector.DataCollection internal class AttachmentManager : IDisposable { private readonly DataCollectionSink _dataSink; - private readonly TestPlatformEqtTrace _eqtTrace; private readonly TestPlatformLogger _logger; private readonly DataCollectionContext _dataCollectionContext; private readonly IFileHelper _fileHelper; @@ -25,11 +24,10 @@ internal class AttachmentManager : IDisposable private readonly ICountDownEvent _countDownEvent; private readonly string _reportDirectory; - public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, TestPlatformEqtTrace eqtTrace, ICountDownEvent countDownEvent) + public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, ICountDownEvent countDownEvent) : this(dataSink, dataCollectionContext, logger, - eqtTrace, Guid.NewGuid().ToString(), new FileHelper(), new DirectoryHelper(), @@ -37,13 +35,12 @@ public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext data { } - public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, TestPlatformEqtTrace eqtTrace, string reportDirectoryName, IFileHelper fileHelper, IDirectoryHelper directoryHelper, ICountDownEvent countDownEvent) + public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, string reportDirectoryName, IFileHelper fileHelper, IDirectoryHelper directoryHelper, ICountDownEvent countDownEvent) { // Store input variabless _dataSink = dataSink; _dataCollectionContext = dataCollectionContext; _logger = logger; - _eqtTrace = eqtTrace; _fileHelper = fileHelper; _directoryHelper = directoryHelper; _countDownEvent = countDownEvent; @@ -103,7 +100,7 @@ private string SaveCoverageReport(string report, string reportFileName) _directoryHelper.CreateDirectory(_reportDirectory); string filePath = Path.Combine(_reportDirectory, reportFileName); _fileHelper.WriteAllText(filePath, report); - _eqtTrace.Info("{0}: Saved coverage report to path: '{1}'", CoverletConstants.DataCollectorName, filePath); + TestPlatformEqtTrace.Info("{0}: Saved coverage report to path: '{1}'", CoverletConstants.DataCollectorName, filePath); return filePath; } @@ -123,7 +120,7 @@ public void OnSendFileCompleted(object sender, AsyncCompletedEventArgs e) { try { - _eqtTrace.Verbose("{0}: SendFileCompleted received", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Verbose("{0}: SendFileCompleted received", CoverletConstants.DataCollectorName); } catch (Exception ex) { @@ -144,12 +141,12 @@ private void SendAttachment(string attachmentPath) if (_fileHelper.Exists(attachmentPath)) { // Send coverage attachment to test platform. - _eqtTrace.Verbose("{0}: Sending attachment to test platform", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Verbose("{0}: Sending attachment to test platform", CoverletConstants.DataCollectorName); _dataSink.SendFileAsync(_dataCollectionContext, attachmentPath, false); } else { - _eqtTrace.Warning("{0}: Attachment file does not exist", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Warning("{0}: Attachment file does not exist", CoverletConstants.DataCollectorName); } } @@ -163,7 +160,7 @@ private void CleanupReportDirectory() if (_directoryHelper.Exists(_reportDirectory)) { _directoryHelper.Delete(_reportDirectory, true); - _eqtTrace.Verbose("{0}: Deleted report directory: '{1}'", CoverletConstants.DataCollectorName, _reportDirectory); + TestPlatformEqtTrace.Verbose("{0}: Deleted report directory: '{1}'", CoverletConstants.DataCollectorName, _reportDirectory); } } catch (Exception ex) diff --git a/src/coverlet.collector/DataCollection/CoverageManager.cs b/src/coverlet.collector/DataCollection/CoverageManager.cs index 89ec41eb1..62fb5152b 100644 --- a/src/coverlet.collector/DataCollection/CoverageManager.cs +++ b/src/coverlet.collector/DataCollection/CoverageManager.cs @@ -24,15 +24,15 @@ internal class CoverageManager private readonly ISourceRootTranslator _sourceRootTranslator; public IReporter[] Reporters { get; } - public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, ICoverageWrapper coverageWrapper, - IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper) + public CoverageManager(CoverletSettings settings, TestPlatformLogger logger, ICoverageWrapper coverageWrapper, IInstrumentationHelper instrumentationHelper, + IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper) : this(settings, settings.ReportFormats.Select(format => { var reporterFactory = new ReporterFactory(format); if (!reporterFactory.IsValidFormat()) { - eqtTrace.Warning($"Invalid report format '{format}'"); + TestPlatformEqtTrace.Warning($"Invalid report format '{format}'"); return null; } else @@ -40,7 +40,7 @@ public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace, return reporterFactory.CreateReporter(); } }).Where(r => r != null).ToArray(), - new CoverletLogger(eqtTrace, logger), + new CoverletLogger(logger), coverageWrapper, instrumentationHelper, fileSystem, sourceRootTranslator, cecilSymbolHelper) { } diff --git a/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs b/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs index cccbd3d10..1cc08b454 100644 --- a/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs +++ b/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs @@ -23,10 +23,9 @@ namespace Coverlet.Collector.DataCollection [DataCollectorFriendlyName(CoverletConstants.FriendlyName)] public class CoverletCoverageCollector : DataCollector { - private readonly TestPlatformEqtTrace _eqtTrace; private readonly ICoverageWrapper _coverageWrapper; private readonly ICountDownEventFactory _countDownEventFactory; - private readonly Func _serviceCollectionFactory; + private readonly Func _serviceCollectionFactory; private DataCollectionEvents _events; private TestPlatformLogger _logger; @@ -36,19 +35,18 @@ public class CoverletCoverageCollector : DataCollector private CoverageManager _coverageManager; private IServiceProvider _serviceProvider; - public CoverletCoverageCollector() : this(new TestPlatformEqtTrace(), new CoverageWrapper(), new CollectorCountdownEventFactory(), GetDefaultServiceCollection) + public CoverletCoverageCollector() : this(new CoverageWrapper(), new CollectorCountdownEventFactory(), GetDefaultServiceCollection) { } - internal CoverletCoverageCollector(TestPlatformEqtTrace eqtTrace, ICoverageWrapper coverageWrapper, ICountDownEventFactory countDownEventFactory, Func serviceCollectionFactory) : base() + internal CoverletCoverageCollector(ICoverageWrapper coverageWrapper, ICountDownEventFactory countDownEventFactory, Func serviceCollectionFactory) : base() { - _eqtTrace = eqtTrace; _coverageWrapper = coverageWrapper; _countDownEventFactory = countDownEventFactory; _serviceCollectionFactory = serviceCollectionFactory; } - private void AttachDebugger() + private static void AttachDebugger() { if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_DATACOLLECTOR_OUTOFPROC_DEBUG"), out int result) && result == 1) { @@ -75,9 +73,9 @@ public override void Initialize( AttachDebugger(); - if (_eqtTrace.IsInfoEnabled) + if (TestPlatformEqtTrace.IsInfoEnabled) { - _eqtTrace.Info("Initializing {0} with configuration: '{1}'", CoverletConstants.DataCollectorName, configurationElement?.OuterXml); + TestPlatformEqtTrace.Info("Initializing {0} with configuration: '{1}'", CoverletConstants.DataCollectorName, configurationElement?.OuterXml); } // Store input variables @@ -98,7 +96,7 @@ public override void Initialize( /// Disposing flag protected override void Dispose(bool disposing) { - _eqtTrace.Verbose("{0}: Disposing", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Verbose("{0}: Disposing", CoverletConstants.DataCollectorName); // Unregister events if (_events != null) @@ -122,22 +120,21 @@ protected override void Dispose(bool disposing) /// Event args private void OnSessionStart(object sender, SessionStartEventArgs sessionStartEventArgs) { - _eqtTrace.Verbose("{0}: SessionStart received", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Verbose("{0}: SessionStart received", CoverletConstants.DataCollectorName); try { // Get coverlet settings IEnumerable testModules = GetTestModules(sessionStartEventArgs); - var coverletSettingsParser = new CoverletSettingsParser(_eqtTrace); - CoverletSettings coverletSettings = coverletSettingsParser.Parse(_configurationElement, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(_configurationElement, testModules); // Build services container - _serviceProvider = _serviceCollectionFactory(_eqtTrace, _logger, coverletSettings.TestModule).BuildServiceProvider(); + _serviceProvider = _serviceCollectionFactory(_logger, coverletSettings.TestModule).BuildServiceProvider(); // Get coverage and attachment managers - _coverageManager = new CoverageManager(coverletSettings, _eqtTrace, _logger, _coverageWrapper, - _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService(), - _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService()); + _coverageManager = new CoverageManager(coverletSettings, _logger, _coverageWrapper, _serviceProvider.GetRequiredService(), + _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService(), + _serviceProvider.GetRequiredService()); // Instrument modules _coverageManager.InstrumentModules(); @@ -158,25 +155,23 @@ private void OnSessionEnd(object sender, SessionEndEventArgs e) { try { - _eqtTrace.Verbose("{0}: SessionEnd received", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Verbose("{0}: SessionEnd received", CoverletConstants.DataCollectorName); // Get coverage reports IEnumerable<(string report, string fileName)> coverageReports = _coverageManager?.GetCoverageReports(); - if (coverageReports != null && coverageReports.Count() > 0) + if (coverageReports != null && coverageReports.Any()) { // Send result attachments to test platform. - using (var attachmentManager = new AttachmentManager(_dataSink, _dataCollectionContext, _logger, _eqtTrace, _countDownEventFactory.Create(coverageReports.Count(), TimeSpan.FromSeconds(30)))) + using var attachmentManager = new AttachmentManager(_dataSink, _dataCollectionContext, _logger, _countDownEventFactory.Create(coverageReports.Count(), TimeSpan.FromSeconds(30))); + foreach ((string report, string fileName) in coverageReports) { - foreach ((string report, string fileName) in coverageReports) - { - attachmentManager.SendCoverageReport(report, fileName); - } + attachmentManager.SendCoverageReport(report, fileName); } } else { - _eqtTrace.Verbose("{0}: No coverage reports specified", CoverletConstants.DataCollectorName); + TestPlatformEqtTrace.Verbose("{0}: No coverage reports specified", CoverletConstants.DataCollectorName); } } catch (Exception ex) @@ -191,14 +186,14 @@ private void OnSessionEnd(object sender, SessionEndEventArgs e) /// /// Event args /// Test modules list - private IEnumerable GetTestModules(SessionStartEventArgs sessionStartEventArgs) + private static IEnumerable GetTestModules(SessionStartEventArgs sessionStartEventArgs) { try { IEnumerable testModules = GetPropertyValueWrapper(sessionStartEventArgs); - if (_eqtTrace.IsInfoEnabled) + if (TestPlatformEqtTrace.IsInfoEnabled) { - _eqtTrace.Info("{0}: TestModules: '{1}'", + TestPlatformEqtTrace.Info("{0}: TestModules: '{1}'", CoverletConstants.DataCollectorName, string.Join(",", testModules ?? Enumerable.Empty())); } @@ -220,13 +215,13 @@ private static IEnumerable GetPropertyValueWrapper(SessionStartEventArgs return sessionStartEventArgs.GetPropertyValue>(CoverletConstants.TestSourcesPropertyName); } - private static IServiceCollection GetDefaultServiceCollection(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) + private static IServiceCollection GetDefaultServiceCollection(TestPlatformLogger logger, string testModule) { IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(logger)); // We need to keep singleton/static semantics serviceCollection.AddSingleton(); // We cache resolutions diff --git a/src/coverlet.collector/DataCollection/CoverletLogger.cs b/src/coverlet.collector/DataCollection/CoverletLogger.cs index 42eb6a1b2..ecb582e94 100644 --- a/src/coverlet.collector/DataCollection/CoverletLogger.cs +++ b/src/coverlet.collector/DataCollection/CoverletLogger.cs @@ -12,12 +12,10 @@ namespace Coverlet.Collector.DataCollection /// internal class CoverletLogger : ILogger { - private readonly TestPlatformEqtTrace _eqtTrace; private readonly TestPlatformLogger _logger; - public CoverletLogger(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger) + public CoverletLogger(TestPlatformLogger logger) { - _eqtTrace = eqtTrace; _logger = logger; } @@ -46,7 +44,7 @@ public void LogError(Exception exception) /// importance public void LogInformation(string message, bool important = false) { - _eqtTrace.Info(message); + TestPlatformEqtTrace.Info(message); } /// @@ -55,7 +53,7 @@ public void LogInformation(string message, bool important = false) /// Verbose message public void LogVerbose(string message) { - _eqtTrace.Verbose(message); + TestPlatformEqtTrace.Verbose(message); } /// @@ -64,7 +62,7 @@ public void LogVerbose(string message) /// Warning message public void LogWarning(string message) { - _eqtTrace.Warning(message); + TestPlatformEqtTrace.Warning(message); } } } diff --git a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs index d18d1553d..13ccf88b6 100644 --- a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs +++ b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs @@ -13,22 +13,15 @@ namespace Coverlet.Collector.DataCollection /// /// Coverlet settings parser /// - internal class CoverletSettingsParser + internal static class CoverletSettingsParser { - private readonly TestPlatformEqtTrace _eqtTrace; - - public CoverletSettingsParser(TestPlatformEqtTrace eqtTrace) - { - _eqtTrace = eqtTrace; - } - /// /// Parser coverlet settings /// /// Configuration element /// Test modules /// Coverlet settings - public CoverletSettings Parse(XmlElement configurationElement, IEnumerable testModules) + public static CoverletSettings Parse(XmlElement configurationElement, IEnumerable testModules) { var coverletSettings = new CoverletSettings { @@ -53,9 +46,9 @@ public CoverletSettings Parse(XmlElement configurationElement, IEnumerable /// Test modules /// Test module - private string ParseTestModule(IEnumerable testModules) + private static string ParseTestModule(IEnumerable testModules) { // Validate if at least one source present. if (testModules == null || !testModules.Any()) @@ -86,7 +79,7 @@ private string ParseTestModule(IEnumerable testModules) /// /// Configuration element /// Report formats - private string[] ParseReportFormats(XmlElement configurationElement) + private static string[] ParseReportFormats(XmlElement configurationElement) { string[] formats = Array.Empty(); if (configurationElement != null) @@ -103,7 +96,7 @@ private string[] ParseReportFormats(XmlElement configurationElement) /// /// Configuration element /// Filters to include - private string[] ParseIncludeFilters(XmlElement configurationElement) + private static string[] ParseIncludeFilters(XmlElement configurationElement) { XmlElement includeFiltersElement = configurationElement[CoverletConstants.IncludeFiltersElementName]; return SplitElement(includeFiltersElement); @@ -114,7 +107,7 @@ private string[] ParseIncludeFilters(XmlElement configurationElement) /// /// Configuration element /// Directories to include - private string[] ParseIncludeDirectories(XmlElement configurationElement) + private static string[] ParseIncludeDirectories(XmlElement configurationElement) { XmlElement includeDirectoriesElement = configurationElement[CoverletConstants.IncludeDirectoriesElementName]; return SplitElement(includeDirectoriesElement); @@ -125,7 +118,7 @@ private string[] ParseIncludeDirectories(XmlElement configurationElement) /// /// Configuration element /// Filters to exclude - private string[] ParseExcludeFilters(XmlElement configurationElement) + private static string[] ParseExcludeFilters(XmlElement configurationElement) { var excludeFilters = new List { CoverletConstants.DefaultExcludeFilter }; @@ -147,7 +140,7 @@ private string[] ParseExcludeFilters(XmlElement configurationElement) /// /// Configuration element /// Source files to exclude - private string[] ParseExcludeSourceFiles(XmlElement configurationElement) + private static string[] ParseExcludeSourceFiles(XmlElement configurationElement) { XmlElement excludeSourceFilesElement = configurationElement[CoverletConstants.ExcludeSourceFilesElementName]; return SplitElement(excludeSourceFilesElement); @@ -158,7 +151,7 @@ private string[] ParseExcludeSourceFiles(XmlElement configurationElement) /// /// Configuration element /// Attributes to exclude - private string[] ParseExcludeAttributes(XmlElement configurationElement) + private static string[] ParseExcludeAttributes(XmlElement configurationElement) { XmlElement excludeAttributesElement = configurationElement[CoverletConstants.ExcludeAttributesElementName]; return SplitElement(excludeAttributesElement); @@ -169,7 +162,7 @@ private string[] ParseExcludeAttributes(XmlElement configurationElement) /// /// Configuration element /// Merge with attribute - private string ParseMergeWith(XmlElement configurationElement) + private static string ParseMergeWith(XmlElement configurationElement) { XmlElement mergeWithElement = configurationElement[CoverletConstants.MergeWithElementName]; return mergeWithElement?.InnerText; @@ -180,7 +173,7 @@ private string ParseMergeWith(XmlElement configurationElement) /// /// Configuration element /// Use source link flag - private bool ParseUseSourceLink(XmlElement configurationElement) + private static bool ParseUseSourceLink(XmlElement configurationElement) { XmlElement useSourceLinkElement = configurationElement[CoverletConstants.UseSourceLinkElementName]; bool.TryParse(useSourceLinkElement?.InnerText, out bool useSourceLink); @@ -192,7 +185,7 @@ private bool ParseUseSourceLink(XmlElement configurationElement) /// /// Configuration element /// Single hit flag - private bool ParseSingleHit(XmlElement configurationElement) + private static bool ParseSingleHit(XmlElement configurationElement) { XmlElement singleHitElement = configurationElement[CoverletConstants.SingleHitElementName]; bool.TryParse(singleHitElement?.InnerText, out bool singleHit); @@ -204,7 +197,7 @@ private bool ParseSingleHit(XmlElement configurationElement) /// /// Configuration element /// ParseDeterministicReport flag - private bool ParseDeterministicReport(XmlElement configurationElement) + private static bool ParseDeterministicReport(XmlElement configurationElement) { XmlElement deterministicReportElement = configurationElement[CoverletConstants.DeterministicReport]; bool.TryParse(deterministicReportElement?.InnerText, out bool deterministicReport); @@ -216,7 +209,7 @@ private bool ParseDeterministicReport(XmlElement configurationElement) /// /// Configuration element /// Include Test Assembly Flag - private bool ParseIncludeTestAssembly(XmlElement configurationElement) + private static bool ParseIncludeTestAssembly(XmlElement configurationElement) { XmlElement includeTestAssemblyElement = configurationElement[CoverletConstants.IncludeTestAssemblyElementName]; bool.TryParse(includeTestAssemblyElement?.InnerText, out bool includeTestAssembly); @@ -228,7 +221,7 @@ private bool ParseIncludeTestAssembly(XmlElement configurationElement) /// /// Configuration element /// Include Test Assembly Flag - private bool ParseSkipAutoProps(XmlElement configurationElement) + private static bool ParseSkipAutoProps(XmlElement configurationElement) { XmlElement skipAutoPropsElement = configurationElement[CoverletConstants.SkipAutoProps]; bool.TryParse(skipAutoPropsElement?.InnerText, out bool skipAutoProps); @@ -240,7 +233,7 @@ private bool ParseSkipAutoProps(XmlElement configurationElement) /// /// Configuration element /// DoesNotReturn attributes - private string[] ParseDoesNotReturnAttributes(XmlElement configurationElement) + private static string[] ParseDoesNotReturnAttributes(XmlElement configurationElement) { XmlElement doesNotReturnAttributesElement = configurationElement[CoverletConstants.DoesNotReturnAttributesElementName]; return SplitElement(doesNotReturnAttributesElement); @@ -251,7 +244,7 @@ private string[] ParseDoesNotReturnAttributes(XmlElement configurationElement) /// /// The element to split /// An array of the values in the element - private string[] SplitElement(XmlElement element) + private static string[] SplitElement(XmlElement element) { return element?.InnerText?.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray(); } diff --git a/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs b/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs index 0ab4066a0..089e6d983 100644 --- a/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs +++ b/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs @@ -16,10 +16,9 @@ namespace Coverlet.Collector.DataCollection { public class CoverletInProcDataCollector : InProcDataCollection { - private TestPlatformEqtTrace _eqtTrace; - private bool _enableExceptionLog = false; + private bool _enableExceptionLog; - private void AttachDebugger() + private static void AttachDebugger() { if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_DATACOLLECTOR_INPROC_DEBUG"), out int result) && result == 1) { @@ -41,8 +40,7 @@ public void Initialize(IDataCollectionSink dataCollectionSink) AttachDebugger(); EnableExceptionLog(); - _eqtTrace = new TestPlatformEqtTrace(); - _eqtTrace.Verbose("Initialize CoverletInProcDataCollector"); + TestPlatformEqtTrace.Verbose("Initialize CoverletInProcDataCollector"); } public void TestCaseEnd(TestCaseEndArgs testCaseEndArgs) @@ -65,17 +63,17 @@ public void TestSessionEnd(TestSessionEndArgs testSessionEndArgs) try { - _eqtTrace.Verbose($"Calling ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); + TestPlatformEqtTrace.Verbose($"Calling ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); MethodInfo unloadModule = injectedInstrumentationClass.GetMethod(nameof(ModuleTrackerTemplate.UnloadModule), new[] { typeof(object), typeof(EventArgs) }); unloadModule.Invoke(null, new[] { (object)this, EventArgs.Empty }); injectedInstrumentationClass.GetField("FlushHitFile", BindingFlags.Static | BindingFlags.Public).SetValue(null, false); - _eqtTrace.Verbose($"Called ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); + TestPlatformEqtTrace.Verbose($"Called ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); } catch (Exception ex) { if (_enableExceptionLog) { - _eqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex); + TestPlatformEqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex); string errorMessage = string.Format(Resources.FailedToUnloadModule, CoverletConstants.InProcDataCollectorName); throw new CoverletDataCollectorException(errorMessage, ex); } @@ -120,7 +118,7 @@ private Type GetInstrumentationClass(Assembly assembly) } } - _eqtTrace.Warning(exceptionString.ToString()); + TestPlatformEqtTrace.Warning(exceptionString.ToString()); } return null; diff --git a/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs b/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs index 7c02f6d03..a1233e37f 100644 --- a/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs +++ b/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs @@ -8,17 +8,17 @@ namespace Coverlet.Collector.Utilities /// /// Test platform eqttrace /// - internal class TestPlatformEqtTrace + internal static class TestPlatformEqtTrace { - public bool IsInfoEnabled => EqtTrace.IsInfoEnabled; - public bool IsVerboseEnabled => EqtTrace.IsVerboseEnabled; + public static bool IsInfoEnabled => EqtTrace.IsInfoEnabled; + public static bool IsVerboseEnabled => EqtTrace.IsVerboseEnabled; /// /// Verbose logger /// /// Format /// Args - public void Verbose(string format, params object[] args) + public static void Verbose(string format, params object[] args) { EqtTrace.Verbose($"[coverlet]{format}", args); } @@ -28,7 +28,7 @@ public void Verbose(string format, params object[] args) /// /// Format /// Args - public void Warning(string format, params object[] args) + public static void Warning(string format, params object[] args) { EqtTrace.Warning($"[coverlet]{format}", args); } @@ -38,7 +38,7 @@ public void Warning(string format, params object[] args) /// /// Format /// Args - public void Info(string format, params object[] args) + public static void Info(string format, params object[] args) { EqtTrace.Info($"[coverlet]{format}", args); } @@ -48,7 +48,7 @@ public void Info(string format, params object[] args) /// /// Format /// Args - public void Error(string format, params object[] args) + public static void Error(string format, params object[] args) { EqtTrace.Error($"[coverlet]{format}", args); } diff --git a/src/coverlet.console/Logging/ConsoleLogger.cs b/src/coverlet.console/Logging/ConsoleLogger.cs index 1752ddc43..d0e07132c 100644 --- a/src/coverlet.console/Logging/ConsoleLogger.cs +++ b/src/coverlet.console/Logging/ConsoleLogger.cs @@ -9,7 +9,8 @@ namespace Coverlet.Console.Logging { class ConsoleLogger : ILogger { - private static readonly object _sync = new object(); + private static readonly object s_sync = new(); + public LogLevel Level { get; set; } = LogLevel.Normal; public void LogError(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Red); @@ -26,7 +27,7 @@ private void Log(LogLevel level, string message, ConsoleColor color) { if (level < Level) return; - lock (_sync) + lock (s_sync) { ConsoleColor currentForegroundColor; if (color != (currentForegroundColor = ForegroundColor)) diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index 25f5f7350..33f6f77bd 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -231,11 +231,10 @@ static int Main(string[] args) } var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method"); - var summary = new CoverageSummary(); - CoverageDetails linePercentCalculation = summary.CalculateLineCoverage(result.Modules); - CoverageDetails branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules); - CoverageDetails methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules); + CoverageDetails linePercentCalculation = CoverageSummary.CalculateLineCoverage(result.Modules); + CoverageDetails branchPercentCalculation = CoverageSummary.CalculateBranchCoverage(result.Modules); + CoverageDetails methodPercentCalculation = CoverageSummary.CalculateMethodCoverage(result.Modules); double totalLinePercent = linePercentCalculation.Percent; double totalBranchPercent = branchPercentCalculation.Percent; @@ -247,9 +246,9 @@ static int Main(string[] args) foreach (KeyValuePair _module in result.Modules) { - double linePercent = summary.CalculateLineCoverage(_module.Value).Percent; - double branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent; - double methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent; + double linePercent = CoverageSummary.CalculateLineCoverage(_module.Value).Percent; + double branchPercent = CoverageSummary.CalculateBranchCoverage(_module.Value).Percent; + double methodPercent = CoverageSummary.CalculateMethodCoverage(_module.Value).Percent; coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{InvariantFormat(linePercent)}%", $"{InvariantFormat(branchPercent)}%", $"{InvariantFormat(methodPercent)}%"); } @@ -269,7 +268,7 @@ static int Main(string[] args) exitCode += (int)CommandExitCodes.TestFailed; } - ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, dThresholdStat); + ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, dThresholdStat); if (thresholdTypeFlags != ThresholdTypeFlags.None) { exitCode += (int)CommandExitCodes.CoverageBelowThreshold; diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs index ecd9a834d..b53cdf5d8 100644 --- a/src/coverlet.core/Coverage.cs +++ b/src/coverlet.core/Coverage.cs @@ -330,7 +330,7 @@ private bool BranchInCompilerGeneratedClass(string methodName) return false; } - private Method GetMethodWithSameLineInSameDocument(Classes documentClasses, string compilerGeneratedClassName, int branchLine) + private static Method GetMethodWithSameLineInSameDocument(Classes documentClasses, string compilerGeneratedClassName, int branchLine) { foreach (KeyValuePair @class in documentClasses) { diff --git a/src/coverlet.core/CoverageResult.cs b/src/coverlet.core/CoverageResult.cs index 4e981346b..d646aba20 100644 --- a/src/coverlet.core/CoverageResult.cs +++ b/src/coverlet.core/CoverageResult.cs @@ -111,7 +111,7 @@ public void Merge(Modules modules) } } - public ThresholdTypeFlags GetThresholdTypesBelowThreshold(CoverageSummary summary, Dictionary thresholdTypeFlagValues, ThresholdStatistic thresholdStat) + public ThresholdTypeFlags GetThresholdTypesBelowThreshold(Dictionary thresholdTypeFlagValues, ThresholdStatistic thresholdStat) { ThresholdTypeFlags thresholdTypeFlags = ThresholdTypeFlags.None; switch (thresholdStat) @@ -123,9 +123,9 @@ public ThresholdTypeFlags GetThresholdTypesBelowThreshold(CoverageSummary summar foreach (KeyValuePair module in Modules) { - double line = summary.CalculateLineCoverage(module.Value).Percent; - double branch = summary.CalculateBranchCoverage(module.Value).Percent; - double method = summary.CalculateMethodCoverage(module.Value).Percent; + double line = CoverageSummary.CalculateLineCoverage(module.Value).Percent; + double branch = CoverageSummary.CalculateBranchCoverage(module.Value).Percent; + double method = CoverageSummary.CalculateMethodCoverage(module.Value).Percent; thresholdTypeFlags = CompareThresholdValues(thresholdTypeFlagValues, thresholdTypeFlags, line, branch, method); } @@ -133,18 +133,18 @@ public ThresholdTypeFlags GetThresholdTypesBelowThreshold(CoverageSummary summar break; case ThresholdStatistic.Average: { - double line = summary.CalculateLineCoverage(Modules).AverageModulePercent; - double branch = summary.CalculateBranchCoverage(Modules).AverageModulePercent; - double method = summary.CalculateMethodCoverage(Modules).AverageModulePercent; + double line = CoverageSummary.CalculateLineCoverage(Modules).AverageModulePercent; + double branch = CoverageSummary.CalculateBranchCoverage(Modules).AverageModulePercent; + double method = CoverageSummary.CalculateMethodCoverage(Modules).AverageModulePercent; thresholdTypeFlags = CompareThresholdValues(thresholdTypeFlagValues, thresholdTypeFlags, line, branch, method); } break; case ThresholdStatistic.Total: { - double line = summary.CalculateLineCoverage(Modules).Percent; - double branch = summary.CalculateBranchCoverage(Modules).Percent; - double method = summary.CalculateMethodCoverage(Modules).Percent; + double line = CoverageSummary.CalculateLineCoverage(Modules).Percent; + double branch = CoverageSummary.CalculateBranchCoverage(Modules).Percent; + double method = CoverageSummary.CalculateMethodCoverage(Modules).Percent; thresholdTypeFlags = CompareThresholdValues(thresholdTypeFlagValues, thresholdTypeFlags, line, branch, method); } diff --git a/src/coverlet.core/CoverageSummary.cs b/src/coverlet.core/CoverageSummary.cs index a56cda454..6d942270e 100644 --- a/src/coverlet.core/CoverageSummary.cs +++ b/src/coverlet.core/CoverageSummary.cs @@ -7,9 +7,9 @@ namespace Coverlet.Core { - internal class CoverageSummary + internal static class CoverageSummary { - public CoverageDetails CalculateLineCoverage(Lines lines) + public static CoverageDetails CalculateLineCoverage(Lines lines) { var details = new CoverageDetails(); details.Covered = lines.Where(l => l.Value > 0).Count(); @@ -17,7 +17,7 @@ public CoverageDetails CalculateLineCoverage(Lines lines) return details; } - public CoverageDetails CalculateLineCoverage(Methods methods) + public static CoverageDetails CalculateLineCoverage(Methods methods) { var details = new CoverageDetails(); foreach (KeyValuePair method in methods) @@ -29,7 +29,7 @@ public CoverageDetails CalculateLineCoverage(Methods methods) return details; } - public CoverageDetails CalculateLineCoverage(Classes classes) + public static CoverageDetails CalculateLineCoverage(Classes classes) { var details = new CoverageDetails(); foreach (KeyValuePair @class in classes) @@ -41,7 +41,7 @@ public CoverageDetails CalculateLineCoverage(Classes classes) return details; } - public CoverageDetails CalculateLineCoverage(Documents documents) + public static CoverageDetails CalculateLineCoverage(Documents documents) { var details = new CoverageDetails(); foreach (KeyValuePair document in documents) @@ -53,7 +53,7 @@ public CoverageDetails CalculateLineCoverage(Documents documents) return details; } - public CoverageDetails CalculateLineCoverage(Modules modules) + public static CoverageDetails CalculateLineCoverage(Modules modules) { var details = new CoverageDetails { Modules = modules }; double accumPercent = 0.0D; @@ -72,7 +72,7 @@ public CoverageDetails CalculateLineCoverage(Modules modules) return details; } - public CoverageDetails CalculateBranchCoverage(IList branches) + public static CoverageDetails CalculateBranchCoverage(IList branches) { var details = new CoverageDetails(); details.Covered = branches.Count(bi => bi.Hits > 0); @@ -80,7 +80,7 @@ public CoverageDetails CalculateBranchCoverage(IList branches) return details; } - public int CalculateNpathComplexity(IList branches) + public static int CalculateNpathComplexity(IList branches) { // Adapted from OpenCover see https://github.com/OpenCover/opencover/blob/master/main/OpenCover.Framework/Persistance/BasePersistance.cs#L419 if (!branches.Any()) @@ -114,47 +114,47 @@ public int CalculateNpathComplexity(IList branches) return npath; } - public int CalculateCyclomaticComplexity(IList branches) + public static int CalculateCyclomaticComplexity(IList branches) { return Math.Max(1, branches.Count); } - public int CalculateCyclomaticComplexity(Methods methods) + public static int CalculateCyclomaticComplexity(Methods methods) { return methods.Values.Select(m => CalculateCyclomaticComplexity(m.Branches)).Sum(); } - public int CalculateMaxCyclomaticComplexity(Methods methods) + public static int CalculateMaxCyclomaticComplexity(Methods methods) { return methods.Values.Select(m => CalculateCyclomaticComplexity(m.Branches)).DefaultIfEmpty(1).Max(); } - public int CalculateMinCyclomaticComplexity(Methods methods) + public static int CalculateMinCyclomaticComplexity(Methods methods) { return methods.Values.Select(m => CalculateCyclomaticComplexity(m.Branches)).DefaultIfEmpty(1).Min(); } - public int CalculateCyclomaticComplexity(Modules modules) + public static int CalculateCyclomaticComplexity(Modules modules) { return modules.Values.Select(CalculateCyclomaticComplexity).Sum(); } - public int CalculateMaxCyclomaticComplexity(Modules modules) + public static int CalculateMaxCyclomaticComplexity(Modules modules) { return modules.Values.Select(CalculateCyclomaticComplexity).DefaultIfEmpty(1).Max(); } - public int CalculateMinCyclomaticComplexity(Modules modules) + public static int CalculateMinCyclomaticComplexity(Modules modules) { return modules.Values.Select(CalculateCyclomaticComplexity).DefaultIfEmpty(1).Min(); } - public int CalculateCyclomaticComplexity(Documents documents) + public static int CalculateCyclomaticComplexity(Documents documents) { return documents.Values.SelectMany(c => c.Values.Select(CalculateCyclomaticComplexity)).Sum(); } - public CoverageDetails CalculateBranchCoverage(Methods methods) + public static CoverageDetails CalculateBranchCoverage(Methods methods) { var details = new CoverageDetails(); foreach (KeyValuePair method in methods) @@ -166,7 +166,7 @@ public CoverageDetails CalculateBranchCoverage(Methods methods) return details; } - public CoverageDetails CalculateBranchCoverage(Classes classes) + public static CoverageDetails CalculateBranchCoverage(Classes classes) { var details = new CoverageDetails(); foreach (KeyValuePair @class in classes) @@ -178,7 +178,7 @@ public CoverageDetails CalculateBranchCoverage(Classes classes) return details; } - public CoverageDetails CalculateBranchCoverage(Documents documents) + public static CoverageDetails CalculateBranchCoverage(Documents documents) { var details = new CoverageDetails(); foreach (KeyValuePair document in documents) @@ -190,7 +190,7 @@ public CoverageDetails CalculateBranchCoverage(Documents documents) return details; } - public CoverageDetails CalculateBranchCoverage(Modules modules) + public static CoverageDetails CalculateBranchCoverage(Modules modules) { var details = new CoverageDetails { Modules = modules }; double accumPercent = 0.0D; @@ -209,7 +209,7 @@ public CoverageDetails CalculateBranchCoverage(Modules modules) return details; } - public CoverageDetails CalculateMethodCoverage(Lines lines) + public static CoverageDetails CalculateMethodCoverage(Lines lines) { var details = new CoverageDetails(); details.Covered = lines.Any(l => l.Value > 0) ? 1 : 0; @@ -217,7 +217,7 @@ public CoverageDetails CalculateMethodCoverage(Lines lines) return details; } - public CoverageDetails CalculateMethodCoverage(Methods methods) + public static CoverageDetails CalculateMethodCoverage(Methods methods) { var details = new CoverageDetails(); IEnumerable> methodsWithLines = methods.Where(m => m.Value.Lines.Count > 0); @@ -230,7 +230,7 @@ public CoverageDetails CalculateMethodCoverage(Methods methods) return details; } - public CoverageDetails CalculateMethodCoverage(Classes classes) + public static CoverageDetails CalculateMethodCoverage(Classes classes) { var details = new CoverageDetails(); foreach (KeyValuePair @class in classes) @@ -242,7 +242,7 @@ public CoverageDetails CalculateMethodCoverage(Classes classes) return details; } - public CoverageDetails CalculateMethodCoverage(Documents documents) + public static CoverageDetails CalculateMethodCoverage(Documents documents) { var details = new CoverageDetails(); foreach (KeyValuePair document in documents) @@ -254,7 +254,7 @@ public CoverageDetails CalculateMethodCoverage(Documents documents) return details; } - public CoverageDetails CalculateMethodCoverage(Modules modules) + public static CoverageDetails CalculateMethodCoverage(Modules modules) { var details = new CoverageDetails { Modules = modules }; double accumPercent = 0.0D; diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index d546ecc27..70dd7b677 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -18,7 +18,7 @@ namespace Coverlet.Core.Helpers internal class InstrumentationHelper : IInstrumentationHelper { private const int RetryAttempts = 12; - private readonly ConcurrentDictionary _backupList = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _backupList = new(); private readonly IRetryHelper _retryHelper; private readonly IFileSystem _fileSystem; private readonly ISourceRootTranslator _sourceRootTranslator; @@ -83,27 +83,25 @@ public string[] GetCoverableModules(string moduleOrAppDirectory, string[] direct public bool HasPdb(string module, out bool embedded) { embedded = false; - using (Stream moduleStream = _fileSystem.OpenRead(module)) - using (var peReader = new PEReader(moduleStream)) + using Stream moduleStream = _fileSystem.OpenRead(module); + using var peReader = new PEReader(moduleStream); + foreach (DebugDirectoryEntry entry in peReader.ReadDebugDirectory()) { - foreach (DebugDirectoryEntry entry in peReader.ReadDebugDirectory()) + if (entry.Type == DebugDirectoryEntryType.CodeView) { - if (entry.Type == DebugDirectoryEntryType.CodeView) + CodeViewDebugDirectoryData codeViewData = peReader.ReadCodeViewDebugDirectoryData(entry); + if (_sourceRootTranslator.ResolveFilePath(codeViewData.Path) == $"{Path.GetFileNameWithoutExtension(module)}.pdb") { - CodeViewDebugDirectoryData codeViewData = peReader.ReadCodeViewDebugDirectoryData(entry); - if (_sourceRootTranslator.ResolveFilePath(codeViewData.Path) == $"{Path.GetFileNameWithoutExtension(module)}.pdb") - { - // PDB is embedded - embedded = true; - return true; - } - - return _fileSystem.Exists(_sourceRootTranslator.ResolveFilePath(codeViewData.Path)); + // PDB is embedded + embedded = true; + return true; } - } - return false; + return _fileSystem.Exists(_sourceRootTranslator.ResolveFilePath(codeViewData.Path)); + } } + + return false; } public bool EmbeddedPortablePdbHasLocalSource(string module, out string firstNotFoundDocument) @@ -116,17 +114,15 @@ public bool EmbeddedPortablePdbHasLocalSource(string module, out string firstNot { if (entry.Type == DebugDirectoryEntryType.EmbeddedPortablePdb) { - using (MetadataReaderProvider embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(entry)) - { - MetadataReader metadataReader = embeddedMetadataProvider.GetMetadataReader(); + using MetadataReaderProvider embeddedMetadataProvider = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(entry); + MetadataReader metadataReader = embeddedMetadataProvider.GetMetadataReader(); - (bool allDocumentsMatch, string notFoundDocument) = MatchDocumentsWithSources(metadataReader); + (bool allDocumentsMatch, string notFoundDocument) = MatchDocumentsWithSources(metadataReader); - if (!allDocumentsMatch) - { - firstNotFoundDocument = notFoundDocument; - return false; - } + if (!allDocumentsMatch) + { + firstNotFoundDocument = notFoundDocument; + return false; } } } @@ -388,7 +384,7 @@ public void SetLogger(ILogger logger) _logger = logger; } - private bool IsTypeFilterMatch(string module, string type, string[] filters) + private static bool IsTypeFilterMatch(string module, string type, string[] filters) { Debug.Assert(module != null); Debug.Assert(filters != null); @@ -408,7 +404,7 @@ private bool IsTypeFilterMatch(string module, string type, string[] filters) return false; } - private string GetBackupPath(string module, string identifier) + private static string GetBackupPath(string module, string identifier) { return Path.Combine( Path.GetTempPath(), @@ -428,14 +424,14 @@ TimeSpan retryStrategy() return retryStrategy; } - private string WildcardToRegex(string pattern) + private static string WildcardToRegex(string pattern) { return "^" + Regex.Escape(pattern). Replace("\\*", ".*"). Replace("\\?", "?") + "$"; } - private bool IsAssembly(string filePath) + private static bool IsAssembly(string filePath) { Debug.Assert(filePath != null); @@ -453,7 +449,7 @@ private bool IsAssembly(string filePath) } } - private bool IsUnknownModuleInFSharpAssembly(Guid languageGuid, string docName) + private static bool IsUnknownModuleInFSharpAssembly(Guid languageGuid, string docName) { // https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md#document-table-0x30 return languageGuid.Equals(new Guid("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3")) diff --git a/src/coverlet.core/Helpers/SourceRootTranslator.cs b/src/coverlet.core/Helpers/SourceRootTranslator.cs index f03c83ff5..4d50fbf81 100644 --- a/src/coverlet.core/Helpers/SourceRootTranslator.cs +++ b/src/coverlet.core/Helpers/SourceRootTranslator.cs @@ -48,7 +48,7 @@ public SourceRootTranslator(string moduleTestPath, ILogger logger, IFileSystem f _sourceToDeterministicPathMapping = LoadSourceToDeterministicPathMapping(_sourceRootMapping); } - private Dictionary> LoadSourceToDeterministicPathMapping(Dictionary> sourceRootMapping) + private static Dictionary> LoadSourceToDeterministicPathMapping(Dictionary> sourceRootMapping) { if (sourceRootMapping is null) { diff --git a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs index 0f89edf5f..6a781485d 100644 --- a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs +++ b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs @@ -17,21 +17,21 @@ namespace Coverlet.Core.Instrumentation /// In case of testing different runtime i.e. netfx we could find netstandard.dll in folder. /// netstandard.dll is a forward only lib, there is no IL but only forwards to "runtime" implementation. /// For some classes implementation are in different assembly for different runtime for instance: - /// + /// /// For NetFx 4.7 /// // Token: 0x2700072C RID: 1836 /// .class extern forwarder System.Security.Cryptography.X509Certificates.StoreName /// { /// .assembly extern System - /// } - /// + /// } + /// /// For netcoreapp2.2 /// Token: 0x2700072C RID: 1836 /// .class extern forwarder System.Security.Cryptography.X509Certificates.StoreName /// { /// .assembly extern System.Security.Cryptography.X509Certificates /// } - /// + /// /// There is a concrete possibility that Cecil cannot find implementation and throws StackOverflow exception https://github.com/jbevain/cecil/issues/575 /// This custom resolver check if requested lib is a "official" netstandard.dll and load once of "current runtime" with /// correct forwards. @@ -39,10 +39,10 @@ namespace Coverlet.Core.Instrumentation /// internal class NetstandardAwareAssemblyResolver : DefaultAssemblyResolver { - private static readonly System.Reflection.Assembly _netStandardAssembly; - private static readonly string _name; - private static readonly byte[] _publicKeyToken; - private static readonly AssemblyDefinition _assemblyDefinition; + private static readonly System.Reflection.Assembly s_netStandardAssembly; + private static readonly string s_name; + private static readonly byte[] s_publicKeyToken; + private static readonly AssemblyDefinition s_assemblyDefinition; private readonly string _modulePath; private readonly Lazy _compositeResolver; @@ -53,11 +53,11 @@ static NetstandardAwareAssemblyResolver() try { // To be sure to load information of "real" runtime netstandard implementation - _netStandardAssembly = System.Reflection.Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location), "netstandard.dll")); - System.Reflection.AssemblyName name = _netStandardAssembly.GetName(); - _name = name.Name; - _publicKeyToken = name.GetPublicKeyToken(); - _assemblyDefinition = AssemblyDefinition.ReadAssembly(_netStandardAssembly.Location); + s_netStandardAssembly = System.Reflection.Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location), "netstandard.dll")); + System.Reflection.AssemblyName name = s_netStandardAssembly.GetName(); + s_name = name.Name; + s_publicKeyToken = name.GetPublicKeyToken(); + s_assemblyDefinition = AssemblyDefinition.ReadAssembly(s_netStandardAssembly.Location); } catch (FileNotFoundException) { @@ -70,7 +70,7 @@ public NetstandardAwareAssemblyResolver(string modulePath, ILogger logger) _modulePath = modulePath; _logger = logger; - // this is lazy because we cannot create AspNetCoreSharedFrameworkResolver if not on .NET Core runtime, + // this is lazy because we cannot create AspNetCoreSharedFrameworkResolver if not on .NET Core runtime, // runtime folders are different _compositeResolver = new Lazy(() => new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[] { @@ -82,26 +82,26 @@ public NetstandardAwareAssemblyResolver(string modulePath, ILogger logger) } // Check name and public key but not version that could be different - private bool CheckIfSearchingNetstandard(AssemblyNameReference name) + private static bool CheckIfSearchingNetstandard(AssemblyNameReference name) { - if (_netStandardAssembly is null) + if (s_netStandardAssembly is null) { return false; } - if (_name != name.Name) + if (s_name != name.Name) { return false; } - if (name.PublicKeyToken.Length != _publicKeyToken.Length) + if (name.PublicKeyToken.Length != s_publicKeyToken.Length) { return false; } for (int i = 0; i < name.PublicKeyToken.Length; i++) { - if (_publicKeyToken[i] != name.PublicKeyToken[i]) + if (s_publicKeyToken[i] != name.PublicKeyToken[i]) { return false; } @@ -114,7 +114,7 @@ public override AssemblyDefinition Resolve(AssemblyNameReference name) { if (CheckIfSearchingNetstandard(name)) { - return _assemblyDefinition; + return s_assemblyDefinition; } else { @@ -136,21 +136,21 @@ public override AssemblyDefinition Resolve(AssemblyNameReference name) } } - private bool IsDotNetCore() + private static bool IsDotNetCore() { // object for .NET Framework is inside mscorlib.dll return Path.GetFileName(typeof(object).Assembly.Location) == "System.Private.CoreLib.dll"; } /// - /// + /// /// We try to manually load assembly. /// To work test project needs to use /// /// /// true /// - /// + /// /// Runtime configuration file doc https://github.com/dotnet/cli/blob/master/Documentation/specs/runtime-configuration-file.md /// /// @@ -202,7 +202,7 @@ internal AssemblyDefinition TryWithCustomResolverOnDotNetCore(AssemblyNameRefere catch (Exception ex) { // if we don't find a lib go on - _logger.LogVerbose($"TryWithCustomResolverOnDotNetCore exception: {ex.ToString()}"); + _logger.LogVerbose($"TryWithCustomResolverOnDotNetCore exception: {ex}"); } } } @@ -218,8 +218,8 @@ internal AssemblyDefinition TryWithCustomResolverOnDotNetCore(AssemblyNameRefere internal class AspNetCoreSharedFrameworkResolver : ICompilationAssemblyResolver { - private readonly string[] _aspNetSharedFrameworkDirs = null; - private readonly ILogger _logger = null; + private readonly string[] _aspNetSharedFrameworkDirs; + private readonly ILogger _logger; public AspNetCoreSharedFrameworkResolver(ILogger logger) { diff --git a/src/coverlet.core/Instrumentation/Instrumenter.cs b/src/coverlet.core/Instrumentation/Instrumenter.cs index 9b2ca6fc7..87aade96f 100644 --- a/src/coverlet.core/Instrumentation/Instrumenter.cs +++ b/src/coverlet.core/Instrumentation/Instrumenter.cs @@ -49,7 +49,7 @@ internal class Instrumenter private readonly string[] _doesNotReturnAttributes; private ReachabilityHelper _reachabilityHelper; - public bool SkipModule { get; set; } = false; + public bool SkipModule { get; set; } public Instrumenter( string module, @@ -185,158 +185,150 @@ private bool Is_System_Threading_Interlocked_CoreLib_Type(TypeDefinition type) // locking issues if we do it while writing. private void CreateReachabilityHelper() { - using (Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.Read)) - using (var resolver = new NetstandardAwareAssemblyResolver(_module, _logger)) + using Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.Read); + using var resolver = new NetstandardAwareAssemblyResolver(_module, _logger); + resolver.AddSearchDirectory(Path.GetDirectoryName(_module)); + var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver }; + if (_isCoreLibrary) { - resolver.AddSearchDirectory(Path.GetDirectoryName(_module)); - var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver }; - if (_isCoreLibrary) - { - parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider(); - } - - using (var module = ModuleDefinition.ReadModule(stream, parameters)) - { - _reachabilityHelper = ReachabilityHelper.CreateForModule(module, _doesNotReturnAttributes, _logger); - } + parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider(); } + + using var module = ModuleDefinition.ReadModule(stream, parameters); + _reachabilityHelper = ReachabilityHelper.CreateForModule(module, _doesNotReturnAttributes, _logger); } private void InstrumentModule() { CreateReachabilityHelper(); - using (Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.ReadWrite)) - using (var resolver = new NetstandardAwareAssemblyResolver(_module, _logger)) + using Stream stream = _fileSystem.NewFileStream(_module, FileMode.Open, FileAccess.ReadWrite); + using var resolver = new NetstandardAwareAssemblyResolver(_module, _logger); + resolver.AddSearchDirectory(Path.GetDirectoryName(_module)); + var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver }; + if (_isCoreLibrary) { - resolver.AddSearchDirectory(Path.GetDirectoryName(_module)); - var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver }; - if (_isCoreLibrary) + parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider(); + } + + using var module = ModuleDefinition.ReadModule(stream, parameters); + foreach (CustomAttribute customAttribute in module.Assembly.CustomAttributes) + { + if (IsExcludeAttribute(customAttribute)) { - parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider(); + _logger.LogVerbose($"Excluded module: '{module}' for assembly level attribute {customAttribute.AttributeType.FullName}"); + SkipModule = true; + return; } + } - using (var module = ModuleDefinition.ReadModule(stream, parameters)) - { - foreach (CustomAttribute customAttribute in module.Assembly.CustomAttributes) - { - if (IsExcludeAttribute(customAttribute)) - { - _logger.LogVerbose($"Excluded module: '{module}' for assembly level attribute {customAttribute.AttributeType.FullName}"); - SkipModule = true; - return; - } - } + bool containsAppContext = module.GetType(nameof(System), nameof(AppContext)) != null; + IEnumerable types = module.GetTypes(); + AddCustomModuleTrackerToModule(module); - bool containsAppContext = module.GetType(nameof(System), nameof(AppContext)) != null; - IEnumerable types = module.GetTypes(); - AddCustomModuleTrackerToModule(module); + CustomDebugInformation sourceLinkDebugInfo = module.CustomDebugInformations.FirstOrDefault(c => c.Kind == CustomDebugInformationKind.SourceLink); + if (sourceLinkDebugInfo != null) + { + _result.SourceLink = ((SourceLinkDebugInformation)sourceLinkDebugInfo).Content; + } - CustomDebugInformation sourceLinkDebugInfo = module.CustomDebugInformations.FirstOrDefault(c => c.Kind == CustomDebugInformationKind.SourceLink); - if (sourceLinkDebugInfo != null) + foreach (TypeDefinition type in types) + { + if ( + !Is_System_Threading_Interlocked_CoreLib_Type(type) && + !IsTypeExcluded(type) && + _instrumentationHelper.IsTypeIncluded(_module, type.FullName, _parameters.IncludeFilters) + ) + { + if (IsSynthesizedMemberToBeExcluded(type)) { - _result.SourceLink = ((SourceLinkDebugInformation)sourceLinkDebugInfo).Content; + (_excludedCompilerGeneratedTypes ??= new List()).Add(type.FullName); } - - foreach (TypeDefinition type in types) + else { - if ( - !Is_System_Threading_Interlocked_CoreLib_Type(type) && - !IsTypeExcluded(type) && - _instrumentationHelper.IsTypeIncluded(_module, type.FullName, _parameters.IncludeFilters) - ) - { - if (IsSynthesizedMemberToBeExcluded(type)) - { - (_excludedCompilerGeneratedTypes ??= new List()).Add(type.FullName); - } - else - { - InstrumentType(type); - } - } + InstrumentType(type); } + } + } - // Fixup the custom tracker class constructor, according to all instrumented types - if (_customTrackerRegisterUnloadEventsMethod == null) - { - _customTrackerRegisterUnloadEventsMethod = new MethodReference( - nameof(ModuleTrackerTemplate.RegisterUnloadEvents), module.TypeSystem.Void, _customTrackerTypeDef); - } + // Fixup the custom tracker class constructor, according to all instrumented types + if (_customTrackerRegisterUnloadEventsMethod == null) + { + _customTrackerRegisterUnloadEventsMethod = new MethodReference( + nameof(ModuleTrackerTemplate.RegisterUnloadEvents), module.TypeSystem.Void, _customTrackerTypeDef); + } - Instruction lastInstr = _customTrackerClassConstructorIl.Body.Instructions.Last(); + Instruction lastInstr = _customTrackerClassConstructorIl.Body.Instructions.Last(); - if (!containsAppContext) - { - // For "normal" cases, where the instrumented assembly is not the core library, we add a call to - // RegisterUnloadEvents to the static constructor of the generated custom tracker. Due to static - // initialization constraints, the core library is handled separately below. - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Call, _customTrackerRegisterUnloadEventsMethod)); - } + if (!containsAppContext) + { + // For "normal" cases, where the instrumented assembly is not the core library, we add a call to + // RegisterUnloadEvents to the static constructor of the generated custom tracker. Due to static + // initialization constraints, the core library is handled separately below. + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Call, _customTrackerRegisterUnloadEventsMethod)); + } - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4, _result.HitCandidates.Count)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Newarr, module.TypeSystem.Int32)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsArray)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldstr, _result.HitsFilePath)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsFilePath)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(_parameters.SingleHit ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerSingleHit)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4_1)); - _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerFlushHitFile)); - - if (containsAppContext) + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4, _result.HitCandidates.Count)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Newarr, module.TypeSystem.Int32)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsArray)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldstr, _result.HitsFilePath)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsFilePath)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(_parameters.SingleHit ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerSingleHit)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4_1)); + _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerFlushHitFile)); + + if (containsAppContext) + { + // Handle the core library by instrumenting System.AppContext.OnProcessExit to directly call + // the UnloadModule method of the custom tracker type. This avoids loops between the static + // initialization of the custom tracker and the static initialization of the hosting AppDomain + // (which for the core library case will be instrumented code). + var eventArgsType = new TypeReference(nameof(System), nameof(EventArgs), module, module.TypeSystem.CoreLibrary); + var customTrackerUnloadModule = new MethodReference(nameof(ModuleTrackerTemplate.UnloadModule), module.TypeSystem.Void, _customTrackerTypeDef); + customTrackerUnloadModule.Parameters.Add(new ParameterDefinition(module.TypeSystem.Object)); + customTrackerUnloadModule.Parameters.Add(new ParameterDefinition(eventArgsType)); + + var appContextType = new TypeReference(nameof(System), nameof(AppContext), module, module.TypeSystem.CoreLibrary); + MethodDefinition onProcessExitMethod = new MethodReference("OnProcessExit", module.TypeSystem.Void, appContextType).Resolve(); + ILProcessor onProcessExitIl = onProcessExitMethod.Body.GetILProcessor(); + + // Put the OnProcessExit body inside try/finally to ensure the call to the UnloadModule. + Instruction lastInst = onProcessExitMethod.Body.Instructions.Last(); + var firstNullParam = Instruction.Create(OpCodes.Ldnull); + var secondNullParam = Instruction.Create(OpCodes.Ldnull); + var callUnload = Instruction.Create(OpCodes.Call, customTrackerUnloadModule); + onProcessExitIl.InsertAfter(lastInst, firstNullParam); + onProcessExitIl.InsertAfter(firstNullParam, secondNullParam); + onProcessExitIl.InsertAfter(secondNullParam, callUnload); + var endFinally = Instruction.Create(OpCodes.Endfinally); + onProcessExitIl.InsertAfter(callUnload, endFinally); + Instruction ret = onProcessExitIl.Create(OpCodes.Ret); + Instruction leaveAfterFinally = onProcessExitIl.Create(OpCodes.Leave, ret); + onProcessExitIl.InsertAfter(endFinally, ret); + foreach (Instruction inst in onProcessExitMethod.Body.Instructions.ToArray()) + { + // Patch ret to leave after the finally + if (inst.OpCode == OpCodes.Ret && inst != ret) { - // Handle the core library by instrumenting System.AppContext.OnProcessExit to directly call - // the UnloadModule method of the custom tracker type. This avoids loops between the static - // initialization of the custom tracker and the static initialization of the hosting AppDomain - // (which for the core library case will be instrumented code). - var eventArgsType = new TypeReference(nameof(System), nameof(EventArgs), module, module.TypeSystem.CoreLibrary); - var customTrackerUnloadModule = new MethodReference(nameof(ModuleTrackerTemplate.UnloadModule), module.TypeSystem.Void, _customTrackerTypeDef); - customTrackerUnloadModule.Parameters.Add(new ParameterDefinition(module.TypeSystem.Object)); - customTrackerUnloadModule.Parameters.Add(new ParameterDefinition(eventArgsType)); - - var appContextType = new TypeReference(nameof(System), nameof(AppContext), module, module.TypeSystem.CoreLibrary); - MethodDefinition onProcessExitMethod = new MethodReference("OnProcessExit", module.TypeSystem.Void, appContextType).Resolve(); - ILProcessor onProcessExitIl = onProcessExitMethod.Body.GetILProcessor(); - - // Put the OnProcessExit body inside try/finally to ensure the call to the UnloadModule. - Instruction lastInst = onProcessExitMethod.Body.Instructions.Last(); - var firstNullParam = Instruction.Create(OpCodes.Ldnull); - var secondNullParam = Instruction.Create(OpCodes.Ldnull); - var callUnload = Instruction.Create(OpCodes.Call, customTrackerUnloadModule); - onProcessExitIl.InsertAfter(lastInst, firstNullParam); - onProcessExitIl.InsertAfter(firstNullParam, secondNullParam); - onProcessExitIl.InsertAfter(secondNullParam, callUnload); - var endFinally = Instruction.Create(OpCodes.Endfinally); - onProcessExitIl.InsertAfter(callUnload, endFinally); - Instruction ret = onProcessExitIl.Create(OpCodes.Ret); - Instruction leaveAfterFinally = onProcessExitIl.Create(OpCodes.Leave, ret); - onProcessExitIl.InsertAfter(endFinally, ret); - foreach (Instruction inst in onProcessExitMethod.Body.Instructions.ToArray()) - { - // Patch ret to leave after the finally - if (inst.OpCode == OpCodes.Ret && inst != ret) - { - Instruction leaveBodyInstAfterFinally = onProcessExitIl.Create(OpCodes.Leave, ret); - Instruction prevInst = inst.Previous; - onProcessExitMethod.Body.Instructions.Remove(inst); - onProcessExitIl.InsertAfter(prevInst, leaveBodyInstAfterFinally); - } - } - var handler = new ExceptionHandler(ExceptionHandlerType.Finally) - { - TryStart = onProcessExitIl.Body.Instructions.First(), - TryEnd = firstNullParam, - HandlerStart = firstNullParam, - HandlerEnd = ret - }; - - onProcessExitMethod.Body.ExceptionHandlers.Add(handler); + Instruction leaveBodyInstAfterFinally = onProcessExitIl.Create(OpCodes.Leave, ret); + Instruction prevInst = inst.Previous; + onProcessExitMethod.Body.Instructions.Remove(inst); + onProcessExitIl.InsertAfter(prevInst, leaveBodyInstAfterFinally); } - - module.Write(stream, new WriterParameters { WriteSymbols = true }); } + var handler = new ExceptionHandler(ExceptionHandlerType.Finally) + { + TryStart = onProcessExitIl.Body.Instructions.First(), + TryEnd = firstNullParam, + HandlerStart = firstNullParam, + HandlerEnd = ret + }; + + onProcessExitMethod.Body.ExceptionHandlers.Add(handler); } + + module.Write(stream, new WriterParameters { WriteSymbols = true }); } private void AddCustomModuleTrackerToModule(ModuleDefinition module) @@ -837,7 +829,7 @@ private bool IsSynthesizedMemberToBeExcluded(IMemberDefinition definition) // Check if the name is synthesized by the compiler // Refer to https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs // to see how the compiler generate names for lambda, local function, yield or async/await expressions - internal bool IsSynthesizedNameOf(string name, string methodName, int methodOrdinal) + internal static bool IsSynthesizedNameOf(string name, string methodName, int methodOrdinal) { return // Lambda method @@ -864,52 +856,52 @@ public IMetadataImporter GetMetadataImporter(ModuleDefinition module) private class CoreLibMetadataImporter : IMetadataImporter { - private readonly ModuleDefinition module; - private readonly DefaultMetadataImporter defaultMetadataImporter; + private readonly ModuleDefinition _module; + private readonly DefaultMetadataImporter _defaultMetadataImporter; public CoreLibMetadataImporter(ModuleDefinition module) { - this.module = module; - defaultMetadataImporter = new DefaultMetadataImporter(module); + _module = module; + _defaultMetadataImporter = new DefaultMetadataImporter(module); } public AssemblyNameReference ImportReference(AssemblyNameReference reference) { - return defaultMetadataImporter.ImportReference(reference); + return _defaultMetadataImporter.ImportReference(reference); } public TypeReference ImportReference(TypeReference type, IGenericParameterProvider context) { - TypeReference importedRef = defaultMetadataImporter.ImportReference(type, context); - importedRef.GetElementType().Scope = module.TypeSystem.CoreLibrary; + TypeReference importedRef = _defaultMetadataImporter.ImportReference(type, context); + importedRef.GetElementType().Scope = _module.TypeSystem.CoreLibrary; return importedRef; } public FieldReference ImportReference(FieldReference field, IGenericParameterProvider context) { - FieldReference importedRef = defaultMetadataImporter.ImportReference(field, context); - importedRef.FieldType.GetElementType().Scope = module.TypeSystem.CoreLibrary; + FieldReference importedRef = _defaultMetadataImporter.ImportReference(field, context); + importedRef.FieldType.GetElementType().Scope = _module.TypeSystem.CoreLibrary; return importedRef; } public MethodReference ImportReference(MethodReference method, IGenericParameterProvider context) { - MethodReference importedRef = defaultMetadataImporter.ImportReference(method, context); - importedRef.DeclaringType.GetElementType().Scope = module.TypeSystem.CoreLibrary; + MethodReference importedRef = _defaultMetadataImporter.ImportReference(method, context); + importedRef.DeclaringType.GetElementType().Scope = _module.TypeSystem.CoreLibrary; foreach (ParameterDefinition parameter in importedRef.Parameters) { - if (parameter.ParameterType.Scope == module.TypeSystem.CoreLibrary) + if (parameter.ParameterType.Scope == _module.TypeSystem.CoreLibrary) { continue; } - parameter.ParameterType.GetElementType().Scope = module.TypeSystem.CoreLibrary; + parameter.ParameterType.GetElementType().Scope = _module.TypeSystem.CoreLibrary; } - if (importedRef.ReturnType.Scope != module.TypeSystem.CoreLibrary) + if (importedRef.ReturnType.Scope != _module.TypeSystem.CoreLibrary) { - importedRef.ReturnType.GetElementType().Scope = module.TypeSystem.CoreLibrary; + importedRef.ReturnType.GetElementType().Scope = _module.TypeSystem.CoreLibrary; } return importedRef; diff --git a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs index b538143be..600fe91b1 100644 --- a/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs +++ b/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs @@ -26,8 +26,8 @@ internal static class ModuleTrackerTemplate public static int[] HitsArray; public static bool SingleHit; public static bool FlushHitFile; - private static readonly bool _enableLog = int.TryParse(Environment.GetEnvironmentVariable("COVERLET_ENABLETRACKERLOG"), out int result) ? result == 1 : false; - private static readonly string _sessionId = Guid.NewGuid().ToString(); + private static readonly bool s_enableLog = int.TryParse(Environment.GetEnvironmentVariable("COVERLET_ENABLETRACKERLOG"), out int result) && result == 1; + private static readonly string s_sessionId = Guid.NewGuid().ToString(); static ModuleTrackerTemplate() { @@ -83,100 +83,94 @@ public static void UnloadModule(object sender, EventArgs e) { // The same module can be unloaded multiple times in the same process via different app domains. // Use a global mutex to ensure no concurrent access. - using (var mutex = new Mutex(true, Path.GetFileNameWithoutExtension(HitsFilePath) + "_Mutex", out bool createdNew)) + using var mutex = new Mutex(true, Path.GetFileNameWithoutExtension(HitsFilePath) + "_Mutex", out bool createdNew); + if (!createdNew) { - if (!createdNew) - { - mutex.WaitOne(); - } + mutex.WaitOne(); + } - if (FlushHitFile) + if (FlushHitFile) + { + try { - try - { - // Claim the current hits array and reset it to prevent double-counting scenarios. - int[] hitsArray = Interlocked.Exchange(ref HitsArray, new int[HitsArray.Length]); + // Claim the current hits array and reset it to prevent double-counting scenarios. + int[] hitsArray = Interlocked.Exchange(ref HitsArray, new int[HitsArray.Length]); - WriteLog($"Unload called for '{Assembly.GetExecutingAssembly().Location}' by '{sender ?? "null"}'"); - WriteLog($"Flushing hit file '{HitsFilePath}'"); + WriteLog($"Unload called for '{Assembly.GetExecutingAssembly().Location}' by '{sender ?? "null"}'"); + WriteLog($"Flushing hit file '{HitsFilePath}'"); - bool failedToCreateNewHitsFile = false; - try + bool failedToCreateNewHitsFile = false; + try + { + using var fs = new FileStream(HitsFilePath, FileMode.CreateNew); + using var bw = new BinaryWriter(fs); + bw.Write(hitsArray.Length); + foreach (int hitCount in hitsArray) { - using (var fs = new FileStream(HitsFilePath, FileMode.CreateNew)) - using (var bw = new BinaryWriter(fs)) - { - bw.Write(hitsArray.Length); - foreach (int hitCount in hitsArray) - { - bw.Write(hitCount); - } - } + bw.Write(hitCount); } - catch (Exception ex) + } + catch (Exception ex) + { + WriteLog($"Failed to create new hits file '{HitsFilePath}' -> '{ex.Message}'"); + failedToCreateNewHitsFile = true; + } + + if (failedToCreateNewHitsFile) + { + // Update the number of hits by adding value on disk with the ones on memory. + // This path should be triggered only in the case of multiple AppDomain unloads. + using var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); + using var br = new BinaryReader(fs); + using var bw = new BinaryWriter(fs); + int hitsLength = br.ReadInt32(); + WriteLog($"Current hits found '{hitsLength}'"); + + if (hitsLength != hitsArray.Length) { - WriteLog($"Failed to create new hits file '{HitsFilePath}' -> '{ex.Message}'"); - failedToCreateNewHitsFile = true; + throw new InvalidOperationException($"{HitsFilePath} has {hitsLength} entries but on memory {nameof(HitsArray)} has {hitsArray.Length}"); } - if (failedToCreateNewHitsFile) + for (int i = 0; i < hitsLength; ++i) { - // Update the number of hits by adding value on disk with the ones on memory. - // This path should be triggered only in the case of multiple AppDomain unloads. - using (var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) - using (var br = new BinaryReader(fs)) - using (var bw = new BinaryWriter(fs)) + int oldHitCount = br.ReadInt32(); + bw.Seek(-sizeof(int), SeekOrigin.Current); + if (SingleHit) + { + bw.Write(hitsArray[i] + oldHitCount > 0 ? 1 : 0); + } + else { - int hitsLength = br.ReadInt32(); - WriteLog($"Current hits found '{hitsLength}'"); - - if (hitsLength != hitsArray.Length) - { - throw new InvalidOperationException($"{HitsFilePath} has {hitsLength} entries but on memory {nameof(HitsArray)} has {hitsArray.Length}"); - } - - for (int i = 0; i < hitsLength; ++i) - { - int oldHitCount = br.ReadInt32(); - bw.Seek(-sizeof(int), SeekOrigin.Current); - if (SingleHit) - { - bw.Write(hitsArray[i] + oldHitCount > 0 ? 1 : 0); - } - else - { - bw.Write(hitsArray[i] + oldHitCount); - } - } + bw.Write(hitsArray[i] + oldHitCount); } } + } - WriteHits(sender); + WriteHits(sender); - WriteLog($"Hit file '{HitsFilePath}' flushed, size {new FileInfo(HitsFilePath).Length}"); - WriteLog("--------------------------------"); - } - catch (Exception ex) - { - WriteLog(ex.ToString()); - throw; - } + WriteLog($"Hit file '{HitsFilePath}' flushed, size {new FileInfo(HitsFilePath).Length}"); + WriteLog("--------------------------------"); + } + catch (Exception ex) + { + WriteLog(ex.ToString()); + throw; } - - // On purpose this is not under a try-finally: it is better to have an exception if there was any error writing the hits file - // this case is relevant when instrumenting corelib since multiple processes can be running against the same instrumented dll. - mutex.ReleaseMutex(); } + + // On purpose this is not under a try-finally: it is better to have an exception if there was any error writing the hits file + // this case is relevant when instrumenting corelib since multiple processes can be running against the same instrumented dll. + mutex.ReleaseMutex(); } private static void WriteHits(object sender) { - if (_enableLog) + if (s_enableLog) { var currentAssembly = Assembly.GetExecutingAssembly(); var location = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(currentAssembly.Location), "TrackersHitsLog")); location.Create(); - string logFile = Path.Combine(location.FullName, $"{Path.GetFileName(currentAssembly.Location)}_{DateTime.UtcNow.Ticks}_{_sessionId}.txt"); + string logFile = Path.Combine(location.FullName, $"{Path.GetFileName(currentAssembly.Location)}_{DateTime.UtcNow.Ticks}_{s_sessionId}.txt"); using (var fs = new FileStream(HitsFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) using (var log = new FileStream(logFile, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None)) using (var logWriter = new StreamWriter(log)) @@ -195,12 +189,12 @@ private static void WriteHits(object sender) private static void WriteLog(string logText) { - if (_enableLog) + if (s_enableLog) { // We don't set path as global var to keep benign possible errors inside try/catch // I'm not sure that location will be ok in every scenario string location = Assembly.GetExecutingAssembly().Location; - File.AppendAllText(Path.Combine(Path.GetDirectoryName(location), Path.GetFileName(location) + "_tracker.txt"), $"[{DateTime.UtcNow} S:{_sessionId} T:{Thread.CurrentThread.ManagedThreadId}]{logText}{Environment.NewLine}"); + File.AppendAllText(Path.Combine(Path.GetDirectoryName(location), Path.GetFileName(location) + "_tracker.txt"), $"[{DateTime.UtcNow} S:{s_sessionId} T:{Thread.CurrentThread.ManagedThreadId}]{logText}{Environment.NewLine}"); } } } diff --git a/src/coverlet.core/Instrumentation/ReachabilityHelper.cs b/src/coverlet.core/Instrumentation/ReachabilityHelper.cs index dee555a21..f5526dcd3 100644 --- a/src/coverlet.core/Instrumentation/ReachabilityHelper.cs +++ b/src/coverlet.core/Instrumentation/ReachabilityHelper.cs @@ -100,9 +100,9 @@ private readonly struct BranchInstruction /// /// Returns true if this branch has multiple targets. /// - public bool HasMultiTargets => _TargetOffset == -1; + public bool HasMultiTargets => _targetOffset == -1; - private readonly int _TargetOffset; + private readonly int _targetOffset; /// /// Target of the branch, assuming it has a single target. @@ -118,11 +118,11 @@ public int TargetOffset throw new InvalidOperationException($"{HasMultiTargets} is true"); } - return _TargetOffset; + return _targetOffset; } } - private readonly ImmutableArray _TargetOffsets; + private readonly ImmutableArray _targetOffsets; /// /// Targets of the branch, assuming it has multiple targets. @@ -138,15 +138,15 @@ public ImmutableArray TargetOffsets throw new InvalidOperationException($"{HasMultiTargets} is false"); } - return _TargetOffsets; + return _targetOffsets; } } public BranchInstruction(int offset, int targetOffset) { Offset = offset; - _TargetOffset = targetOffset; - _TargetOffsets = ImmutableArray.Empty; + _targetOffset = targetOffset; + _targetOffsets = ImmutableArray.Empty; } public BranchInstruction(int offset, ImmutableArray targetOffset) @@ -157,8 +157,8 @@ public BranchInstruction(int offset, ImmutableArray targetOffset) } Offset = offset; - _TargetOffset = -1; - _TargetOffsets = targetOffset; + _targetOffset = -1; + _targetOffsets = targetOffset; } public override string ToString() @@ -169,7 +169,9 @@ public override string ToString() /// OpCodes that transfer control code, even if they do not /// introduce branch points. /// +#pragma warning disable IDE1006 // Naming Styles private static readonly ImmutableHashSet BRANCH_OPCODES = +#pragma warning restore IDE1006 // Naming Styles ImmutableHashSet.CreateRange( new[] { @@ -224,7 +226,9 @@ public override string ToString() /// OpCodes that unconditionally transfer control, so there /// is not "fall through" branch target. /// +#pragma warning disable IDE1006 // Naming Styles private static readonly ImmutableHashSet UNCONDITIONAL_BRANCH_OPCODES = +#pragma warning restore IDE1006 // Naming Styles ImmutableHashSet.CreateRange( new[] { @@ -235,11 +239,11 @@ public override string ToString() } ); - private readonly ImmutableHashSet DoesNotReturnMethods; + private readonly ImmutableHashSet _doesNotReturnMethods; private ReachabilityHelper(ImmutableHashSet doesNotReturnMethods) { - DoesNotReturnMethods = doesNotReturnMethods; + _doesNotReturnMethods = doesNotReturnMethods; } /// @@ -372,7 +376,7 @@ public ImmutableArray FindUnreachableIL(Collection.Empty; } @@ -527,7 +531,7 @@ private static (int? SingleTargetOffset, ImmutableArray MultiTargetOffsets) /// /// Calculates which ranges of IL are unreachable, given blocks which have head and tail reachability calculated. /// - private ImmutableArray DetermineUnreachableRanges(ImmutableArray blocks, int lastInstructionOffset) + private static ImmutableArray DetermineUnreachableRanges(ImmutableArray blocks, int lastInstructionOffset) { ImmutableArray.Builder ret = ImmutableArray.CreateBuilder(); @@ -580,7 +584,7 @@ private ImmutableArray DetermineUnreachableRanges(ImmutableArr /// /// "Tail reachability" will have already been determined in CreateBlocks. /// - private void DetermineHeadReachability(ImmutableArray blocks) + private static void DetermineHeadReachability(ImmutableArray blocks) { var blockLookup = blocks.ToImmutableDictionary(b => b.StartOffset); @@ -791,7 +795,7 @@ private bool DoesNotReturn(Instruction instr) return false; } - return DoesNotReturnMethods.Contains(mtd.MetadataToken); + return _doesNotReturnMethods.Contains(mtd.MetadataToken); } /// diff --git a/src/coverlet.core/Reporters/CoberturaReporter.cs b/src/coverlet.core/Reporters/CoberturaReporter.cs index 0daff6a69..85f773a48 100644 --- a/src/coverlet.core/Reporters/CoberturaReporter.cs +++ b/src/coverlet.core/Reporters/CoberturaReporter.cs @@ -24,15 +24,13 @@ internal class CoberturaReporter : IReporter public string Report(CoverageResult result, ISourceRootTranslator sourceRootTranslator) { - var summary = new CoverageSummary(); - - CoverageDetails lineCoverage = summary.CalculateLineCoverage(result.Modules); - CoverageDetails branchCoverage = summary.CalculateBranchCoverage(result.Modules); + CoverageDetails lineCoverage = CoverageSummary.CalculateLineCoverage(result.Modules); + CoverageDetails branchCoverage = CoverageSummary.CalculateBranchCoverage(result.Modules); var xml = new XDocument(); var coverage = new XElement("coverage"); - coverage.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); - coverage.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); + coverage.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); + coverage.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); coverage.Add(new XAttribute("version", "1.9")); coverage.Add(new XAttribute("timestamp", (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds)); @@ -50,9 +48,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran { var package = new XElement("package"); package.Add(new XAttribute("name", Path.GetFileNameWithoutExtension(module.Key))); - package.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - package.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - package.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(module.Value))); + package.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + package.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + package.Add(new XAttribute("complexity", CoverageSummary.CalculateCyclomaticComplexity(module.Value))); var classes = new XElement("classes"); foreach (KeyValuePair document in module.Value) @@ -71,9 +69,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran fileName = sourceRootTranslator.ResolveDeterministicPath(document.Key); } @class.Add(new XAttribute("filename", fileName)); - @class.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - @class.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - @class.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(cls.Value))); + @class.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + @class.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + @class.Add(new XAttribute("complexity", CoverageSummary.CalculateCyclomaticComplexity(cls.Value))); var classLines = new XElement("lines"); var methods = new XElement("methods"); @@ -87,9 +85,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran var method = new XElement("method"); method.Add(new XAttribute("name", meth.Key.Split(':').Last().Split('(').First())); method.Add(new XAttribute("signature", "(" + meth.Key.Split(':').Last().Split('(').Last())); - method.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(meth.Value.Lines).Percent / 100).ToString(CultureInfo.InvariantCulture))); - method.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(meth.Value.Branches).Percent / 100).ToString(CultureInfo.InvariantCulture))); - method.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(meth.Value.Branches))); + method.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(meth.Value.Lines).Percent / 100).ToString(CultureInfo.InvariantCulture))); + method.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(meth.Value.Branches).Percent / 100).ToString(CultureInfo.InvariantCulture))); + method.Add(new XAttribute("complexity", CoverageSummary.CalculateCyclomaticComplexity(meth.Value.Branches))); var lines = new XElement("lines"); foreach (KeyValuePair ln in meth.Value.Lines) @@ -103,7 +101,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran if (isBranchPoint) { var branches = meth.Value.Branches.Where(b => b.Line == ln.Key).ToList(); - CoverageDetails branchInfoCoverage = summary.CalculateBranchCoverage(branches); + CoverageDetails branchInfoCoverage = CoverageSummary.CalculateBranchCoverage(branches); line.Add(new XAttribute("condition-coverage", $"{branchInfoCoverage.Percent.ToString(CultureInfo.InvariantCulture)}% ({branchInfoCoverage.Covered.ToString(CultureInfo.InvariantCulture)}/{branchInfoCoverage.Total.ToString(CultureInfo.InvariantCulture)})")); var conditions = new XElement("conditions"); var byOffset = branches.GroupBy(b => b.Offset).ToDictionary(b => b.Key, b => b.ToList()); @@ -111,15 +109,14 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran { var condition = new XElement("condition"); condition.Add(new XAttribute("number", entry.Key)); - condition.Add(new XAttribute("type", entry.Value.Count() > 2 ? "switch" : "jump")); // Just guessing here - condition.Add(new XAttribute("coverage", $"{summary.CalculateBranchCoverage(entry.Value).Percent.ToString(CultureInfo.InvariantCulture)}%")); + condition.Add(new XAttribute("type", entry.Value.Count > 2 ? "switch" : "jump")); // Just guessing here + condition.Add(new XAttribute("coverage", $"{CoverageSummary.CalculateBranchCoverage(entry.Value).Percent.ToString(CultureInfo.InvariantCulture)}%")); conditions.Add(condition); } line.Add(conditions); } - lines.Add(line); classLines.Add(line); } diff --git a/src/coverlet.core/Reporters/LcovReporter.cs b/src/coverlet.core/Reporters/LcovReporter.cs index 5b7471f42..c13fa43f6 100644 --- a/src/coverlet.core/Reporters/LcovReporter.cs +++ b/src/coverlet.core/Reporters/LcovReporter.cs @@ -23,16 +23,15 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran throw new NotSupportedException("Deterministic report not supported by lcov reporter"); } - var summary = new CoverageSummary(); var lcov = new List(); foreach (KeyValuePair module in result.Modules) { foreach (KeyValuePair doc in module.Value) { - CoverageDetails docLineCoverage = summary.CalculateLineCoverage(doc.Value); - CoverageDetails docBranchCoverage = summary.CalculateBranchCoverage(doc.Value); - CoverageDetails docMethodCoverage = summary.CalculateMethodCoverage(doc.Value); + CoverageDetails docLineCoverage = CoverageSummary.CalculateLineCoverage(doc.Value); + CoverageDetails docBranchCoverage = CoverageSummary.CalculateBranchCoverage(doc.Value); + CoverageDetails docMethodCoverage = CoverageSummary.CalculateMethodCoverage(doc.Value); lcov.Add("SF:" + doc.Key); foreach (KeyValuePair @class in doc.Value) diff --git a/src/coverlet.core/Reporters/OpenCoverReporter.cs b/src/coverlet.core/Reporters/OpenCoverReporter.cs index 2e42c2894..941fc81e0 100644 --- a/src/coverlet.core/Reporters/OpenCoverReporter.cs +++ b/src/coverlet.core/Reporters/OpenCoverReporter.cs @@ -26,7 +26,6 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran throw new NotSupportedException("Deterministic report not supported by openCover reporter"); } - var summary = new CoverageSummary(); var xml = new XDocument(); var coverage = new XElement("CoverageSession"); var coverageSummary = new XElement("Summary"); @@ -77,10 +76,10 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran if (meth.Value.Lines.Count == 0) continue; - CoverageDetails methLineCoverage = summary.CalculateLineCoverage(meth.Value.Lines); - CoverageDetails methBranchCoverage = summary.CalculateBranchCoverage(meth.Value.Branches); - int methCyclomaticComplexity = summary.CalculateCyclomaticComplexity(meth.Value.Branches); - int methNpathComplexity = summary.CalculateNpathComplexity(meth.Value.Branches); + CoverageDetails methLineCoverage = CoverageSummary.CalculateLineCoverage(meth.Value.Lines); + CoverageDetails methBranchCoverage = CoverageSummary.CalculateBranchCoverage(meth.Value.Branches); + int methCyclomaticComplexity = CoverageSummary.CalculateCyclomaticComplexity(meth.Value.Branches); + int methNpathComplexity = CoverageSummary.CalculateNpathComplexity(meth.Value.Branches); var method = new XElement("Method"); @@ -123,7 +122,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran foreach (System.Collections.Generic.KeyValuePair lines in meth.Value.Lines) { BranchInfo[] lineBranches = meth.Value.Branches.Where(branchInfo => branchInfo.Line == lines.Key).ToArray(); - CoverageDetails branchCoverage = summary.CalculateBranchCoverage(lineBranches); + CoverageDetails branchCoverage = CoverageSummary.CalculateBranchCoverage(lineBranches); var sequencePoint = new XElement("SequencePoint"); sequencePoint.Add(new XAttribute("vc", lines.Value.ToString())); @@ -194,11 +193,11 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran if (classVisited) visitedClasses++; - CoverageDetails classLineCoverage = summary.CalculateLineCoverage(cls.Value); - CoverageDetails classBranchCoverage = summary.CalculateBranchCoverage(cls.Value); - CoverageDetails classMethodCoverage = summary.CalculateMethodCoverage(cls.Value); - int classMaxCyclomaticComplexity = summary.CalculateMaxCyclomaticComplexity(cls.Value); - int classMinCyclomaticComplexity = summary.CalculateMinCyclomaticComplexity(cls.Value); + CoverageDetails classLineCoverage = CoverageSummary.CalculateLineCoverage(cls.Value); + CoverageDetails classBranchCoverage = CoverageSummary.CalculateBranchCoverage(cls.Value); + CoverageDetails classMethodCoverage = CoverageSummary.CalculateMethodCoverage(cls.Value); + int classMaxCyclomaticComplexity = CoverageSummary.CalculateMaxCyclomaticComplexity(cls.Value); + int classMinCyclomaticComplexity = CoverageSummary.CalculateMinCyclomaticComplexity(cls.Value); classSummary.Add(new XAttribute("numSequencePoints", classLineCoverage.Total.ToString())); classSummary.Add(new XAttribute("visitedSequencePoints", classLineCoverage.Covered.ToString())); @@ -226,10 +225,10 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran modules.Add(module); } - CoverageDetails moduleLineCoverage = summary.CalculateLineCoverage(result.Modules); - CoverageDetails moduleBranchCoverage = summary.CalculateBranchCoverage(result.Modules); - int moduleMaxCyclomaticComplexity = summary.CalculateMaxCyclomaticComplexity(result.Modules); - int moduleMinCyclomaticComplexity = summary.CalculateMinCyclomaticComplexity(result.Modules); + CoverageDetails moduleLineCoverage = CoverageSummary.CalculateLineCoverage(result.Modules); + CoverageDetails moduleBranchCoverage = CoverageSummary.CalculateBranchCoverage(result.Modules); + int moduleMaxCyclomaticComplexity = CoverageSummary.CalculateMaxCyclomaticComplexity(result.Modules); + int moduleMinCyclomaticComplexity = CoverageSummary.CalculateMinCyclomaticComplexity(result.Modules); coverageSummary.Add(new XAttribute("numSequencePoints", moduleLineCoverage.Total.ToString())); coverageSummary.Add(new XAttribute("visitedSequencePoints", moduleLineCoverage.Covered.ToString())); diff --git a/src/coverlet.core/Reporters/TeamCityReporter.cs b/src/coverlet.core/Reporters/TeamCityReporter.cs index 365f20e46..51971f673 100644 --- a/src/coverlet.core/Reporters/TeamCityReporter.cs +++ b/src/coverlet.core/Reporters/TeamCityReporter.cs @@ -24,10 +24,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran } // Calculate coverage - var summary = new CoverageSummary(); - CoverageDetails overallLineCoverage = summary.CalculateLineCoverage(result.Modules); - CoverageDetails overallBranchCoverage = summary.CalculateBranchCoverage(result.Modules); - CoverageDetails overallMethodCoverage = summary.CalculateMethodCoverage(result.Modules); + CoverageDetails overallLineCoverage = CoverageSummary.CalculateLineCoverage(result.Modules); + CoverageDetails overallBranchCoverage = CoverageSummary.CalculateBranchCoverage(result.Modules); + CoverageDetails overallMethodCoverage = CoverageSummary.CalculateMethodCoverage(result.Modules); // Report coverage var stringBuilder = new StringBuilder(); @@ -39,7 +38,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran return stringBuilder.ToString(); } - private void OutputLineCoverage(CoverageDetails coverageDetails, StringBuilder builder) + private static void OutputLineCoverage(CoverageDetails coverageDetails, StringBuilder builder) { // The number of covered lines OutputTeamCityServiceMessage("CodeCoverageAbsLCovered", coverageDetails.Covered, builder); @@ -48,7 +47,7 @@ private void OutputLineCoverage(CoverageDetails coverageDetails, StringBuilder b OutputTeamCityServiceMessage("CodeCoverageAbsLTotal", coverageDetails.Total, builder); } - private void OutputBranchCoverage(CoverageDetails coverageDetails, StringBuilder builder) + private static void OutputBranchCoverage(CoverageDetails coverageDetails, StringBuilder builder) { // The number of covered branches OutputTeamCityServiceMessage("CodeCoverageAbsBCovered", coverageDetails.Covered, builder); @@ -57,7 +56,7 @@ private void OutputBranchCoverage(CoverageDetails coverageDetails, StringBuilder OutputTeamCityServiceMessage("CodeCoverageAbsBTotal", coverageDetails.Total, builder); } - private void OutputMethodCoverage(CoverageDetails coverageDetails, StringBuilder builder) + private static void OutputMethodCoverage(CoverageDetails coverageDetails, StringBuilder builder) { // The number of covered methods OutputTeamCityServiceMessage("CodeCoverageAbsMCovered", coverageDetails.Covered, builder); @@ -66,7 +65,7 @@ private void OutputMethodCoverage(CoverageDetails coverageDetails, StringBuilder OutputTeamCityServiceMessage("CodeCoverageAbsMTotal", coverageDetails.Total, builder); } - private void OutputTeamCityServiceMessage(string key, double value, StringBuilder builder) + private static void OutputTeamCityServiceMessage(string key, double value, StringBuilder builder) { builder.AppendLine($"##teamcity[buildStatisticValue key='{key}' value='{value.ToString("0.##", new CultureInfo("en-US"))}']"); } diff --git a/src/coverlet.core/Symbols/CecilSymbolHelper.cs b/src/coverlet.core/Symbols/CecilSymbolHelper.cs index 23789124a..dd8eb1238 100644 --- a/src/coverlet.core/Symbols/CecilSymbolHelper.cs +++ b/src/coverlet.core/Symbols/CecilSymbolHelper.cs @@ -20,8 +20,8 @@ internal class CecilSymbolHelper : ICecilSymbolHelper { private const int StepOverLineCode = 0xFEEFEE; // Create single instance, we cannot collide because we use full method name as key - private readonly ConcurrentDictionary _compilerGeneratedBranchesToExclude = new ConcurrentDictionary(); - private readonly ConcurrentDictionary> _sequencePointOffsetToSkip = new ConcurrentDictionary>(); + private readonly ConcurrentDictionary _compilerGeneratedBranchesToExclude = new(); + private readonly ConcurrentDictionary> _sequencePointOffsetToSkip = new(); // In case of nested compiler generated classes, only the root one presents the CompilerGenerated attribute. // So let's search up to the outermost declaring type to find the attribute @@ -83,7 +83,8 @@ private static bool IsMoveNextInsideEnumerator(MethodDefinition methodDefinition { return false; } - if (methodDefinition.DeclaringType.CustomAttributes.Count(ca => ca.AttributeType.FullName == typeof(CompilerGeneratedAttribute).FullName) > 0) + + if (methodDefinition.DeclaringType.CustomAttributes.Any(ca => ca.AttributeType.FullName == typeof(CompilerGeneratedAttribute).FullName)) { foreach (InterfaceImplementation implementedInterface in methodDefinition.DeclaringType.Interfaces) { @@ -465,7 +466,6 @@ private static bool SkipGeneratedBranchesForAwaitForeach(List instr CheckIfExceptionThrown(instructions, instruction, currentIndex) || CheckThrownExceptionType(instructions, instruction, currentIndex); - // The pattern for the "should we stay in the loop or not?", which we don't // want to skip (so we have no method to try to find it), looks like this: // @@ -477,7 +477,6 @@ private static bool SkipGeneratedBranchesForAwaitForeach(List instr // the "call" and branch, but it's the same idea either way: branch // if GetResult() returned true. - static bool CheckForAsyncEnumerator(List instructions, Instruction instruction, int currentIndex) { // We're looking for the following pattern, which checks whether a @@ -506,7 +505,6 @@ static bool CheckForAsyncEnumerator(List instructions, Instruction return false; } - static bool CheckIfExceptionThrown(List instructions, Instruction instruction, int currentIndex) { // Here, we want to find a pattern where we're checking whether a @@ -564,7 +562,6 @@ instructions[j].Operand is MethodReference callRef && return false; } - static bool CheckThrownExceptionType(List instructions, Instruction instruction, int currentIndex) { // In this case, we're looking for a branch generated by the compiler to @@ -617,7 +614,6 @@ private static bool SkipGeneratedBranchesForAwaitUsing(List instruc return CheckForSkipDisposal(instructions, instruction, currentIndex) || CheckForCleanup(instructions, instruction, currentIndex); - static bool CheckForSkipDisposal(List instructions, Instruction instruction, int currentIndex) { // The async state machine generated for an "await using" contains a branch @@ -727,7 +723,6 @@ instructions[i].Operand is FieldDefinition reloadedField && return false; } - static bool CheckForCleanup(List instructions, Instruction instruction, int currentIndex) { // The pattern we're looking for here is this: @@ -812,7 +807,6 @@ private static bool SkipGeneratedBranchesForAsyncIterator(List inst return CheckForStateSwitch(instructions, instruction, currentIndex) || DisposeCheck(instructions, instruction, currentIndex); - static bool CheckForStateSwitch(List instructions, Instruction instruction, int currentIndex) { // The pattern we're looking for here is this one: @@ -890,7 +884,7 @@ static bool DisposeCheck(List instructions, Instruction instruction } } - private bool SkipGeneratedBranchesForEnumeratorCancellationAttribute(List instructions, Instruction instruction) + private static bool SkipGeneratedBranchesForEnumeratorCancellationAttribute(List instructions, Instruction instruction) { // For async-enumerable methods an additional cancellation token despite the default one can be passed. // The EnumeratorCancellation attribute marks the parameter whose value is received by GetAsyncEnumerator(CancellationToken). @@ -1219,7 +1213,7 @@ await ... IL_00eb: br.s IL_00ed ... */ - public bool SkipNotCoverableInstructionAfterExceptionRethrowInsiceCatchBlock(MethodDefinition methodDefinition, Instruction instruction) + public static bool SkipNotCoverableInstructionAfterExceptionRethrowInsiceCatchBlock(MethodDefinition methodDefinition, Instruction instruction) { if (!IsMoveNextInsideAsyncStateMachine(methodDefinition)) { diff --git a/src/coverlet.msbuild.tasks/CoverageResultTask.cs b/src/coverlet.msbuild.tasks/CoverageResultTask.cs index 642d2a92b..d78f87db7 100644 --- a/src/coverlet.msbuild.tasks/CoverageResultTask.cs +++ b/src/coverlet.msbuild.tasks/CoverageResultTask.cs @@ -152,9 +152,9 @@ public override bool Execute() if (Threshold.Contains(',')) { IEnumerable thresholdValues = Threshold.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(t => t.Trim()); - if (thresholdValues.Count() != thresholdTypeFlagQueue.Count()) + if (thresholdValues.Count() != thresholdTypeFlagQueue.Count) { - throw new Exception($"Threshold type flag count ({thresholdTypeFlagQueue.Count()}) and values count ({thresholdValues.Count()}) doesn't match"); + throw new Exception($"Threshold type flag count ({thresholdTypeFlagQueue.Count}) and values count ({thresholdValues.Count()}) doesn't match"); } foreach (string threshold in thresholdValues) @@ -190,11 +190,10 @@ public override bool Execute() } var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method"); - var summary = new CoverageSummary(); - CoverageDetails linePercentCalculation = summary.CalculateLineCoverage(result.Modules); - CoverageDetails branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules); - CoverageDetails methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules); + CoverageDetails linePercentCalculation = CoverageSummary.CalculateLineCoverage(result.Modules); + CoverageDetails branchPercentCalculation = CoverageSummary.CalculateBranchCoverage(result.Modules); + CoverageDetails methodPercentCalculation = CoverageSummary.CalculateMethodCoverage(result.Modules); double totalLinePercent = linePercentCalculation.Percent; double totalBranchPercent = branchPercentCalculation.Percent; @@ -206,9 +205,9 @@ public override bool Execute() foreach (KeyValuePair module in result.Modules) { - double linePercent = summary.CalculateLineCoverage(module.Value).Percent; - double branchPercent = summary.CalculateBranchCoverage(module.Value).Percent; - double methodPercent = summary.CalculateMethodCoverage(module.Value).Percent; + double linePercent = CoverageSummary.CalculateLineCoverage(module.Value).Percent; + double branchPercent = CoverageSummary.CalculateBranchCoverage(module.Value).Percent; + double methodPercent = CoverageSummary.CalculateMethodCoverage(module.Value).Percent; coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{InvariantFormat(linePercent)}%", $"{InvariantFormat(branchPercent)}%", $"{InvariantFormat(methodPercent)}%"); } @@ -225,7 +224,7 @@ public override bool Execute() Console.WriteLine(coverageTable.ToStringAlternative()); - ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStat); + ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStat); if (thresholdTypeFlags != ThresholdTypeFlags.None) { var exceptionMessageBuilder = new StringBuilder(); diff --git a/src/coverlet.msbuild.tasks/InstrumentationTask.cs b/src/coverlet.msbuild.tasks/InstrumentationTask.cs index e84327dd0..2acf94145 100644 --- a/src/coverlet.msbuild.tasks/InstrumentationTask.cs +++ b/src/coverlet.msbuild.tasks/InstrumentationTask.cs @@ -55,7 +55,7 @@ public InstrumentationTask() _logger = new MSBuildLogger(Log); } - private void AttachDebugger() + private static void AttachDebugger() { if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_MSBUILD_INSTRUMENTATIONTASK_DEBUG"), out int result) && result == 1) { @@ -112,13 +112,9 @@ public override bool Execute() CoveragePrepareResult prepareResult = coverage.PrepareModules(); InstrumenterState = new TaskItem(System.IO.Path.GetTempFileName()); - using (Stream instrumentedStateFile = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open, FileAccess.Write)) - { - using (Stream serializedState = CoveragePrepareResult.Serialize(prepareResult)) - { - serializedState.CopyTo(instrumentedStateFile); - } - } + using Stream instrumentedStateFile = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open, FileAccess.Write); + using Stream serializedState = CoveragePrepareResult.Serialize(prepareResult); + serializedState.CopyTo(instrumentedStateFile); } catch (Exception ex) { diff --git a/test/coverlet.collector.tests/AttachmentManagerTests.cs b/test/coverlet.collector.tests/AttachmentManagerTests.cs index 9e021212d..e54c5a9e7 100644 --- a/test/coverlet.collector.tests/AttachmentManagerTests.cs +++ b/test/coverlet.collector.tests/AttachmentManagerTests.cs @@ -20,7 +20,6 @@ public class AttachmentManagerTests private readonly Mock _mockDataCollectionSink; private readonly DataCollectionContext _dataCollectionContext; private readonly TestPlatformLogger _testPlatformLogger; - private readonly TestPlatformEqtTrace _eqtTrace; private readonly Mock _mockFileHelper; private readonly Mock _mockDirectoryHelper; private readonly Mock _mockCountDownEvent; @@ -33,13 +32,12 @@ public AttachmentManagerTests() var testcase = new TestCase { Id = Guid.NewGuid() }; _dataCollectionContext = new DataCollectionContext(testcase); _testPlatformLogger = new TestPlatformLogger(_mockDataCollectionLogger.Object, _dataCollectionContext); - _eqtTrace = new TestPlatformEqtTrace(); _mockFileHelper = new Mock(); _mockDirectoryHelper = new Mock(); _mockCountDownEvent = new Mock(); _attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, - _eqtTrace, @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); + @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); } [Fact] @@ -59,7 +57,7 @@ public void SendCoverageReportShouldSaveReportToFile() public void SendCoverageReportShouldThrowExceptionWhenFailedToSaveReportToFile() { _attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, - _eqtTrace, @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); + @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); string coverageReport = "" + "" @@ -76,7 +74,7 @@ public void SendCoverageReportShouldSendAttachmentToTestPlatform() { DirectoryInfo directory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())); _attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, - _eqtTrace, directory.ToString(), new FileHelper(), _mockDirectoryHelper.Object, _mockCountDownEvent.Object); + directory.ToString(), new FileHelper(), _mockDirectoryHelper.Object, _mockCountDownEvent.Object); string coverageReport = "" + "" @@ -96,7 +94,7 @@ public void OnDisposeAttachmentManagerShouldCleanUpReportDirectory() { var mockDirectoryHelper = new Mock(); mockDirectoryHelper.Setup(x => x.Exists(It.Is(y => y.Contains(@"E:\temp")))).Returns(true); - using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, _eqtTrace, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) + using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) { _mockDataCollectionSink.Raise(x => x.SendFileCompleted += null, new AsyncCompletedEventArgs(null, false, null)); } @@ -110,7 +108,7 @@ public void OnDisposeAttachmentManagerShouldThrowCoverletDataCollectorExceptionI var mockDirectoryHelper = new Mock(); mockDirectoryHelper.Setup(x => x.Exists(It.Is(y => y.Contains(@"E:\temp")))).Returns(true); mockDirectoryHelper.Setup(x => x.Delete(It.Is(y => y.Contains(@"E:\temp")), true)).Throws(new FileNotFoundException()); - using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, _eqtTrace, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) + using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) { _mockDataCollectionSink.Raise(x => x.SendFileCompleted += null, new AsyncCompletedEventArgs(null, false, null)); } diff --git a/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs b/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs index 66fb8bd67..0e11630c7 100644 --- a/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs +++ b/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs @@ -52,7 +52,7 @@ public CoverletCoverageDataCollectorTests() [Fact] public void OnSessionStartShouldInitializeCoverageWithCorrectCoverletSettings() { - Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -61,13 +61,13 @@ public void OnSessionStartShouldInitializeCoverageWithCorrectCoverletSettings() serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), _mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(_mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, @@ -86,7 +86,7 @@ public void OnSessionStartShouldInitializeCoverageWithCorrectCoverletSettings() [Fact] public void OnSessionStartShouldPrepareModulesForCoverage() { - Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -95,13 +95,13 @@ public void OnSessionStartShouldPrepareModulesForCoverage() serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), _mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(_mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, @@ -142,19 +142,19 @@ public void OnSessionStartShouldPrepareModulesForCoverage() [Fact] public void OnSessionEndShouldSendGetCoverageReportToTestPlatform() { - Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, @@ -187,7 +187,7 @@ public void OnSessionEndShouldSendGetCoverageReportToTestPlatform() [InlineData("json,cobertura,lcov", 3)] public void OnSessionEndShouldSendCoverageReportsForMultipleFormatsToTestPlatform(string formats, int sendReportsCount) { - Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -196,13 +196,13 @@ public void OnSessionEndShouldSendCoverageReportsForMultipleFormatsToTestPlatfor serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); IList reporters = formats.Split(',').Select(f => new ReporterFactory(f).CreateReporter()).Where(x => x != null).ToList(); var mockDataCollectionSink = new Mock(); @@ -240,7 +240,7 @@ public void OnSessionEndShouldSendCoverageReportsForMultipleFormatsToTestPlatfor [Fact] public void OnSessionStartShouldLogWarningIfInstrumentationFailed() { - Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -249,13 +249,13 @@ public void OnSessionStartShouldLogWarningIfInstrumentationFailed() serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), _mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(_mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, diff --git a/test/coverlet.collector.tests/CoverletSettingsParserTests.cs b/test/coverlet.collector.tests/CoverletSettingsParserTests.cs index 0e3286e06..1268fe200 100644 --- a/test/coverlet.collector.tests/CoverletSettingsParserTests.cs +++ b/test/coverlet.collector.tests/CoverletSettingsParserTests.cs @@ -12,17 +12,10 @@ namespace Coverlet.Collector.Tests { public class CoverletSettingsParserTests { - private readonly CoverletSettingsParser _coverletSettingsParser; - - public CoverletSettingsParserTests() - { - _coverletSettingsParser = new CoverletSettingsParser(new TestPlatformEqtTrace()); - } - [Fact] public void ParseShouldThrowCoverletDataCollectorExceptionIfTestModulesIsNull() { - string message = Assert.Throws(() => _coverletSettingsParser.Parse(null, null)).Message; + string message = Assert.Throws(() => CoverletSettingsParser.Parse(null, null)).Message; Assert.Equal("CoverletCoverageDataCollector: No test modules found", message); } @@ -30,7 +23,7 @@ public void ParseShouldThrowCoverletDataCollectorExceptionIfTestModulesIsNull() [Fact] public void ParseShouldThrowCoverletDataCollectorExceptionIfTestModulesIsEmpty() { - string message = Assert.Throws(() => _coverletSettingsParser.Parse(null, Enumerable.Empty())).Message; + string message = Assert.Throws(() => CoverletSettingsParser.Parse(null, Enumerable.Empty())).Message; Assert.Equal("CoverletCoverageDataCollector: No test modules found", message); } @@ -40,7 +33,7 @@ public void ParseShouldSelectFirstTestModuleFromTestModulesList() { var testModules = new List { "module1.dll", "module2.dll", "module3.dll" }; - CoverletSettings coverletSettings = _coverletSettingsParser.Parse(null, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(null, testModules); Assert.Equal("module1.dll", coverletSettings.TestModule); } @@ -81,7 +74,7 @@ public void ParseShouldCorrectlyParseConfigurationElement(string includeFilters, CreateCoverletNodes(doc, configElement, CoverletConstants.DeterministicReport, "true"); CreateCoverletNodes(doc, configElement, CoverletConstants.DoesNotReturnAttributesElementName, doesNotReturnAttributes); - CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); Assert.Equal("abc.dll", coverletSettings.TestModule); Assert.Equal("[*]*", coverletSettings.IncludeFilters[0]); @@ -119,7 +112,7 @@ public void ParseShouldCorrectlyParseConfigurationElementWithNullInnerText() CreateCoverletNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeSourceFilesElementName); CreateCoverletNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeAttributesElementName); - CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); Assert.Equal("abc.dll", coverletSettings.TestModule); Assert.Empty(coverletSettings.IncludeFilters); @@ -136,7 +129,7 @@ public void ParseShouldCorrectlyParseConfigurationElementWithNullElements() var doc = new XmlDocument(); XmlElement configElement = doc.CreateElement("Configuration"); - CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); Assert.Equal("abc.dll", coverletSettings.TestModule); Assert.Null(coverletSettings.IncludeFilters); @@ -166,7 +159,7 @@ public void ParseShouldCorrectlyParseMultipleFormats(string formats, int formats XmlElement configElement = doc.CreateElement("Configuration"); CreateCoverletNodes(doc, configElement, CoverletConstants.ReportFormatElementName, formats); - CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); Assert.Equal(expectedReportFormats, coverletSettings.ReportFormats); Assert.Equal(formatsCount, coverletSettings.ReportFormats.Length); @@ -183,19 +176,19 @@ public void ParseShouldUseDefaultFormatWhenNoFormatSpecified(string formats) XmlElement configElement = doc.CreateElement("Configuration"); CreateCoverletNodes(doc, configElement, CoverletConstants.ReportFormatElementName, formats); - CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); Assert.Equal(defaultFormat, coverletSettings.ReportFormats[0]); } - private void CreateCoverletNodes(XmlDocument doc, XmlElement configElement, string nodeSetting, string nodeValue) + private static void CreateCoverletNodes(XmlDocument doc, XmlElement configElement, string nodeSetting, string nodeValue) { XmlNode node = doc.CreateNode("element", nodeSetting, string.Empty); node.InnerText = nodeValue; configElement.AppendChild(node); } - private void CreateCoverletNullInnerTextNodes(XmlDocument doc, XmlElement configElement, string nodeSetting) + private static void CreateCoverletNullInnerTextNodes(XmlDocument doc, XmlElement configElement, string nodeSetting) { XmlNode node = doc.CreateNode("element", nodeSetting, string.Empty); node.InnerText = null; diff --git a/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs b/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs index 1a04e2021..5677af2ca 100644 --- a/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs @@ -126,139 +126,125 @@ private void SetupDataMultipleModule() [Fact] public void TestCalculateLineCoverage_NoModules() { - var summary = new CoverageSummary(); var modules = new Modules(); - Assert.Equal(0, summary.CalculateLineCoverage(modules).Percent); - Assert.Equal(0, summary.CalculateLineCoverage(modules).AverageModulePercent); - Assert.Equal(0, summary.CalculateBranchCoverage(modules).Percent); - Assert.Equal(0, summary.CalculateBranchCoverage(modules).AverageModulePercent); - Assert.Equal(0, summary.CalculateMethodCoverage(modules).Percent); - Assert.Equal(0, summary.CalculateMethodCoverage(modules).AverageModulePercent); + Assert.Equal(0, CoverageSummary.CalculateLineCoverage(modules).Percent); + Assert.Equal(0, CoverageSummary.CalculateLineCoverage(modules).AverageModulePercent); + Assert.Equal(0, CoverageSummary.CalculateBranchCoverage(modules).Percent); + Assert.Equal(0, CoverageSummary.CalculateBranchCoverage(modules).AverageModulePercent); + Assert.Equal(0, CoverageSummary.CalculateMethodCoverage(modules).Percent); + Assert.Equal(0, CoverageSummary.CalculateMethodCoverage(modules).AverageModulePercent); } [Fact] public void TestCalculateLineCoverage_SingleModule() { - var summary = new CoverageSummary(); - System.Collections.Generic.KeyValuePair module = _averageCalculationSingleModule.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(50, summary.CalculateLineCoverage(_averageCalculationSingleModule).AverageModulePercent); - Assert.Equal(50, summary.CalculateLineCoverage(module.Value).Percent); - Assert.Equal(50, summary.CalculateLineCoverage(document.Value).Percent); - Assert.Equal(50, summary.CalculateLineCoverage(@class.Value).Percent); - Assert.Equal(50, summary.CalculateLineCoverage(method.Value.Lines).Percent); + Assert.Equal(50, CoverageSummary.CalculateLineCoverage(_averageCalculationSingleModule).AverageModulePercent); + Assert.Equal(50, CoverageSummary.CalculateLineCoverage(module.Value).Percent); + Assert.Equal(50, CoverageSummary.CalculateLineCoverage(document.Value).Percent); + Assert.Equal(50, CoverageSummary.CalculateLineCoverage(@class.Value).Percent); + Assert.Equal(50, CoverageSummary.CalculateLineCoverage(method.Value.Lines).Percent); } [Fact] public void TestCalculateLineCoverage_MultiModule() { - var summary = new CoverageSummary(); Documents documentsFirstModule = _averageCalculationMultiModule["module"]; Documents documentsSecondModule = _averageCalculationMultiModule["aditionalModule"]; - Assert.Equal(37.5, summary.CalculateLineCoverage(_averageCalculationMultiModule).AverageModulePercent); - Assert.Equal(50, summary.CalculateLineCoverage(documentsFirstModule.First().Value).Percent); + Assert.Equal(37.5, CoverageSummary.CalculateLineCoverage(_averageCalculationMultiModule).AverageModulePercent); + Assert.Equal(50, CoverageSummary.CalculateLineCoverage(documentsFirstModule.First().Value).Percent); - Assert.Equal(33.33, summary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(0).Value.Lines).Percent); // covered 1 of 3 - Assert.Equal(0, summary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(1).Value.Lines).Percent); // covered 0 of 1 - Assert.Equal(25, summary.CalculateLineCoverage(documentsSecondModule.First().Value).Percent); // covered 1 of 4 lines + Assert.Equal(33.33, CoverageSummary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(0).Value.Lines).Percent); // covered 1 of 3 + Assert.Equal(0, CoverageSummary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(1).Value.Lines).Percent); // covered 0 of 1 + Assert.Equal(25, CoverageSummary.CalculateLineCoverage(documentsSecondModule.First().Value).Percent); // covered 1 of 4 lines } [Fact] public void TestCalculateBranchCoverage_SingleModule() { - var summary = new CoverageSummary(); - System.Collections.Generic.KeyValuePair module = _averageCalculationSingleModule.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(100, summary.CalculateBranchCoverage(_averageCalculationSingleModule).AverageModulePercent); - Assert.Equal(100, summary.CalculateBranchCoverage(module.Value).Percent); - Assert.Equal(100, summary.CalculateBranchCoverage(document.Value).Percent); - Assert.Equal(100, summary.CalculateBranchCoverage(@class.Value).Percent); - Assert.Equal(100, summary.CalculateBranchCoverage(method.Value.Branches).Percent); + Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(_averageCalculationSingleModule).AverageModulePercent); + Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(module.Value).Percent); + Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(document.Value).Percent); + Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(@class.Value).Percent); + Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(method.Value.Branches).Percent); } [Fact] public void TestCalculateBranchCoverage_MultiModule() { - var summary = new CoverageSummary(); Documents documentsFirstModule = _averageCalculationMultiModule["module"]; Documents documentsSecondModule = _averageCalculationMultiModule["aditionalModule"]; - Assert.Equal(83.33, summary.CalculateBranchCoverage(_averageCalculationMultiModule).AverageModulePercent); - Assert.Equal(100, summary.CalculateBranchCoverage(documentsFirstModule.First().Value).Percent); - Assert.Equal(66.66, summary.CalculateBranchCoverage(documentsSecondModule.First().Value).Percent); + Assert.Equal(83.33, CoverageSummary.CalculateBranchCoverage(_averageCalculationMultiModule).AverageModulePercent); + Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(documentsFirstModule.First().Value).Percent); + Assert.Equal(66.66, CoverageSummary.CalculateBranchCoverage(documentsSecondModule.First().Value).Percent); } [Fact] public void TestCalculateMethodCoverage_SingleModule() { - var summary = new CoverageSummary(); - System.Collections.Generic.KeyValuePair module = _averageCalculationSingleModule.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(100, summary.CalculateMethodCoverage(_averageCalculationSingleModule).AverageModulePercent); - Assert.Equal(100, summary.CalculateMethodCoverage(module.Value).Percent); - Assert.Equal(100, summary.CalculateMethodCoverage(document.Value).Percent); - Assert.Equal(100, summary.CalculateMethodCoverage(@class.Value).Percent); - Assert.Equal(100, summary.CalculateMethodCoverage(method.Value.Lines).Percent); + Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(_averageCalculationSingleModule).AverageModulePercent); + Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(module.Value).Percent); + Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(document.Value).Percent); + Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(@class.Value).Percent); + Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(method.Value.Lines).Percent); } [Fact] public void TestCalculateMethodCoverage_MultiModule() { - var summary = new CoverageSummary(); Documents documentsFirstModule = _averageCalculationMultiModule["module"]; Documents documentsSecondModule = _averageCalculationMultiModule["aditionalModule"]; - Assert.Equal(75, summary.CalculateMethodCoverage(_averageCalculationMultiModule).AverageModulePercent); - Assert.Equal(100, summary.CalculateMethodCoverage(documentsFirstModule.First().Value).Percent); - Assert.Equal(50, summary.CalculateMethodCoverage(documentsSecondModule.First().Value).Percent); + Assert.Equal(75, CoverageSummary.CalculateMethodCoverage(_averageCalculationMultiModule).AverageModulePercent); + Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(documentsFirstModule.First().Value).Percent); + Assert.Equal(50, CoverageSummary.CalculateMethodCoverage(documentsSecondModule.First().Value).Percent); } [Fact] public void TestCalculateLineCoveragePercentage_ArithmeticPrecisionCheck() { - var summary = new CoverageSummary(); - System.Collections.Generic.KeyValuePair module = _moduleArithmeticPrecision.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(16.66, summary.CalculateLineCoverage(_moduleArithmeticPrecision).AverageModulePercent); - Assert.Equal(16.66, summary.CalculateLineCoverage(module.Value).Percent); - Assert.Equal(16.66, summary.CalculateLineCoverage(document.Value).Percent); - Assert.Equal(16.66, summary.CalculateLineCoverage(@class.Value).Percent); - Assert.Equal(16.66, summary.CalculateLineCoverage(method.Value.Lines).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(_moduleArithmeticPrecision).AverageModulePercent); + Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(module.Value).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(document.Value).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(@class.Value).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(method.Value.Lines).Percent); } [Fact] public void TestCalculateBranchCoveragePercentage_ArithmeticPrecisionCheck() { - var summary = new CoverageSummary(); - System.Collections.Generic.KeyValuePair module = _moduleArithmeticPrecision.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(16.66, summary.CalculateBranchCoverage(_moduleArithmeticPrecision).AverageModulePercent); - Assert.Equal(16.66, summary.CalculateBranchCoverage(module.Value).Percent); - Assert.Equal(16.66, summary.CalculateBranchCoverage(document.Value).Percent); - Assert.Equal(16.66, summary.CalculateBranchCoverage(@class.Value).Percent); - Assert.Equal(16.66, summary.CalculateBranchCoverage(method.Value.Branches).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(_moduleArithmeticPrecision).AverageModulePercent); + Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(module.Value).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(document.Value).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(@class.Value).Percent); + Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(method.Value.Branches).Percent); } } } diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.cs b/test/coverlet.core.tests/Coverage/CoverageTests.cs index e6bf461eb..06be97c72 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.cs @@ -13,7 +13,7 @@ namespace Coverlet.Core.Tests { public partial class CoverageTests { - private readonly Mock _mockLogger = new Mock(); + private readonly Mock _mockLogger = new(); [Fact] public void TestCoverage() diff --git a/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs b/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs index efc0138a8..8cb5eca7f 100644 --- a/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs +++ b/test/coverlet.core.tests/Coverage/InstrumenterHelper.cs @@ -23,7 +23,7 @@ namespace Coverlet.Core.Tests { static class TestInstrumentationHelper { - private static IServiceProvider _processWideContainer; + private static IServiceProvider s_processWideContainer; /// /// caller sample: TestInstrumentationHelper.GenerateHtmlReport(result, sourceFileFilter: @"+**\Samples\Instrumentation.cs"); @@ -64,9 +64,9 @@ public static CoverageResult GetCoverageResult(string filePath) { Assert.DoesNotContain("not found for module: ", message); }); - _processWideContainer.GetRequiredService().SetLogger(logger.Object); + s_processWideContainer.GetRequiredService().SetLogger(logger.Object); var coveragePrepareResultLoaded = CoveragePrepareResult.Deserialize(result); - var coverage = new Coverage(coveragePrepareResultLoaded, logger.Object, _processWideContainer.GetService(), new FileSystem(), new SourceRootTranslator(new Mock().Object, new FileSystem())); + var coverage = new Coverage(coveragePrepareResultLoaded, logger.Object, s_processWideContainer.GetService(), new FileSystem(), new SourceRootTranslator(new Mock().Object, new FileSystem())); return coverage.GetCoverageResult(); } @@ -121,7 +121,7 @@ public static async Task Run(Func callM // Instrument module var coverage = new Coverage(newPath, parameters, new Logger(logFile), - _processWideContainer.GetService(), _processWideContainer.GetService(), _processWideContainer.GetService(), _processWideContainer.GetService()); + s_processWideContainer.GetService(), s_processWideContainer.GetService(), s_processWideContainer.GetService(), s_processWideContainer.GetService()); CoveragePrepareResult prepareResult = coverage.PrepareModules(); Assert.Single(prepareResult.Results); @@ -153,7 +153,7 @@ public static async Task Run(Func callM private static void SetTestContainer(string testModule = null, bool disableRestoreModules = false) { - LazyInitializer.EnsureInitialized(ref _processWideContainer, () => + LazyInitializer.EnsureInitialized(ref s_processWideContainer, () => { var serviceCollection = new ServiceCollection(); serviceCollection.AddTransient(); @@ -291,7 +291,7 @@ public override void RestoreOriginalModules() public abstract class ExternalProcessExecutionTest { - protected FunctionExecutor FunctionExecutor = new FunctionExecutor( + protected FunctionExecutor FunctionExecutor = new( o => { o.StartInfo.RedirectStandardError = true; diff --git a/test/coverlet.core.tests/CoverageResultTests.cs b/test/coverlet.core.tests/CoverageResultTests.cs index fd5450909..a879dbd12 100644 --- a/test/coverlet.core.tests/CoverageResultTests.cs +++ b/test/coverlet.core.tests/CoverageResultTests.cs @@ -57,7 +57,6 @@ public void TestGetThresholdTypesBelowThresholdLine() var result = new CoverageResult(); result.Modules = _modules; - var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 90 }, @@ -67,7 +66,7 @@ public void TestGetThresholdTypesBelowThresholdLine() ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.Line, resThresholdTypeFlags); } @@ -77,7 +76,6 @@ public void TestGetThresholdTypesBelowThresholdMethod() var result = new CoverageResult(); result.Modules = _modules; - var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 50 }, @@ -87,7 +85,7 @@ public void TestGetThresholdTypesBelowThresholdMethod() ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.Method, resThresholdTypeFlags); } @@ -97,7 +95,6 @@ public void TestGetThresholdTypesBelowThresholdBranch() var result = new CoverageResult(); result.Modules = _modules; - var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 50 }, @@ -107,7 +104,7 @@ public void TestGetThresholdTypesBelowThresholdBranch() ThresholdStatistic thresholdStatic = ThresholdStatistic.Total; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.Branch, resThresholdTypeFlags); } @@ -117,7 +114,6 @@ public void TestGetThresholdTypesBelowThresholdAllGood() var result = new CoverageResult(); result.Modules = _modules; - var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 50 }, @@ -127,7 +123,7 @@ public void TestGetThresholdTypesBelowThresholdAllGood() ThresholdStatistic thresholdStatic = ThresholdStatistic.Average; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.None, resThresholdTypeFlags); } @@ -137,7 +133,6 @@ public void TestGetThresholdTypesBelowThresholdAllFail() var result = new CoverageResult(); result.Modules = _modules; - var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 100 }, @@ -148,7 +143,7 @@ public void TestGetThresholdTypesBelowThresholdAllFail() ThresholdTypeFlags thresholdTypeFlags = ThresholdTypeFlags.Line | ThresholdTypeFlags.Branch | ThresholdTypeFlags.Method; ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); Assert.Equal(thresholdTypeFlags, resThresholdTypeFlags); } @@ -158,7 +153,6 @@ public void TestGetThresholdTypesBelowThresholdWhenNoModuleInstrumented() var result = new CoverageResult(); result.Modules = new Modules(); - var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 80 }, @@ -169,7 +163,7 @@ public void TestGetThresholdTypesBelowThresholdWhenNoModuleInstrumented() ThresholdTypeFlags thresholdTypeFlags = ThresholdTypeFlags.Line | ThresholdTypeFlags.Branch | ThresholdTypeFlags.Method; ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); Assert.Equal(thresholdTypeFlags, resThresholdTypeFlags); } } diff --git a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs index 031b8a5d0..d0883ae61 100644 --- a/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs +++ b/test/coverlet.core.tests/Helpers/InstrumentationHelperTests.cs @@ -15,7 +15,7 @@ namespace Coverlet.Core.Helpers.Tests public class InstrumentationHelperTests { private readonly InstrumentationHelper _instrumentationHelper = - new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), new FileSystem(), new Mock().Object, new SourceRootTranslator(typeof(InstrumentationHelperTests).Assembly.Location, new Mock().Object, new FileSystem())); + new(new ProcessExitHandler(), new RetryHelper(), new FileSystem(), new Mock().Object, new SourceRootTranslator(typeof(InstrumentationHelperTests).Assembly.Location, new Mock().Object, new FileSystem())); [Fact] public void TestGetDependencies() diff --git a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs index 907f5cc66..ad43f7e56 100644 --- a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs +++ b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs @@ -26,12 +26,12 @@ namespace Coverlet.Core.Instrumentation.Tests { public class InstrumenterTests : IDisposable { - private readonly Mock _mockLogger = new Mock(); - private Action disposeAction; + private readonly Mock _mockLogger = new(); + private Action _disposeAction; public void Dispose() { - disposeAction?.Invoke(); + _disposeAction?.Invoke(); } [ConditionalFact] @@ -192,9 +192,7 @@ public void TestInstrument_ClassesWithMethodWithCustomExcludeAttributeAreExclude Document doc = result.Documents.Values.FirstOrDefault(d => Path.GetFileName(d.Path) == "Samples.cs"); Assert.NotNull(doc); -#pragma warning disable CS0612 // Type or member is obsolete bool found = doc.Lines.Values.Any(l => l.Method.Equals($"System.String Coverlet.Core.Samples.Tests.{testClassName}::Method(System.String)")); -#pragma warning restore CS0612 // Type or member is obsolete Assert.False(found, "Method decorated with with exclude attribute should be excluded"); instrumenterTest.Directory.Delete(true); @@ -211,14 +209,10 @@ public void TestInstrument_ClassesWithPropertyWithCustomExcludeAttributeAreExclu Document doc = result.Documents.Values.FirstOrDefault(d => Path.GetFileName(d.Path) == "Samples.cs"); Assert.NotNull(doc); -#pragma warning disable CS0612 // Type or member is obsolete bool getFound = doc.Lines.Values.Any(l => l.Method.Equals($"System.String Coverlet.Core.Samples.Tests.{testClassName}::get_Property()")); -#pragma warning restore CS0612 // Type or member is obsolete Assert.False(getFound, "Property getter decorated with with exclude attribute should be excluded"); -#pragma warning disable CS0612 // Type or member is obsolete bool setFound = doc.Lines.Values.Any(l => l.Method.Equals($"System.String Coverlet.Core.Samples.Tests.{testClassName}::set_Property()")); -#pragma warning restore CS0612 // Type or member is obsolete Assert.False(setFound, "Property setter decorated with with exclude attribute should be excluded"); instrumenterTest.Directory.Delete(true); @@ -587,7 +581,7 @@ public int SampleMethod() string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(tempDirectory); - disposeAction = () => Directory.Delete(tempDirectory, true); + _disposeAction = () => Directory.Delete(tempDirectory, true); var partialMockFileSystem = new Mock(); partialMockFileSystem.CallBase = true; @@ -656,10 +650,10 @@ public void TestInstrument_LambdaInsideMethodWithExcludeAttributeAreExcluded() Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLambda(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLambda(System.String)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 0)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 0)); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLambda(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 1)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 1)); Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLambda(System.String)"); instrumenterTest.Directory.Delete(true); @@ -677,15 +671,15 @@ public void TestInstrument_LocalFunctionInsideMethodWithExcludeAttributeAreExclu Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLocalFunction(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLocalFunction(System.String)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr" && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); Assert.Contains(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr" && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLocalFunction(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2" && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLocalFunction(System.String)"); Assert.Contains(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2" && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); instrumenterTest.Directory.Delete(true); } @@ -700,13 +694,13 @@ public void TestInstrument_YieldInsideMethodWithExcludeAttributeAreExcluded() Assert.NotNull(doc); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); instrumenterTest.Directory.Delete(true); } @@ -721,13 +715,13 @@ public void TestInstrument_AsyncAwaitInsideMethodWithExcludeAttributeAreExcluded Assert.NotNull(doc); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); + Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); instrumenterTest.Directory.Delete(true); } diff --git a/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs b/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs index c0b8dd282..7cd5f2943 100644 --- a/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs +++ b/test/coverlet.core.tests/Instrumentation/ModuleTrackerTemplateTests.cs @@ -30,7 +30,7 @@ public void Dispose() public class ModuleTrackerTemplateTests : ExternalProcessExecutionTest { - private static readonly Task _success = Task.FromResult(0); + private static readonly Task s_success = Task.FromResult(0); [Fact] public void HitsFileCorrectlyWritten() @@ -44,7 +44,7 @@ public void HitsFileCorrectlyWritten() int[] expectedHitsArray = new[] { 1, 2, 0, 3 }; Assert.Equal(expectedHitsArray, ReadHitsFile()); - return _success; + return s_success; }); } @@ -57,7 +57,7 @@ public void HitsFileWithDifferentNumberOfEntriesCausesExceptionOnUnload() WriteHitsFile(new[] { 1, 2, 3 }); ModuleTrackerTemplate.HitsArray = new[] { 1 }; Assert.Throws(() => ModuleTrackerTemplate.UnloadModule(null, null)); - return _success; + return s_success; }); } @@ -94,7 +94,7 @@ static void HitIndex(object index) } } - return _success; + return s_success; }); } @@ -113,7 +113,7 @@ public void MultipleSequentialUnloadsHaveCorrectTotalData() int[] expectedHitsArray = new[] { 0, 4, 4, 4 }; Assert.Equal(expectedHitsArray, ReadHitsFile()); - return _success; + return s_success; }); } @@ -149,32 +149,28 @@ public void MutexBlocksMultipleWriters() } - private void WriteHitsFile(int[] hitsArray) + private static void WriteHitsFile(int[] hitsArray) { - using (var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Create)) - using (var bw = new BinaryWriter(fs)) + using var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Create); + using var bw = new BinaryWriter(fs); + bw.Write(hitsArray.Length); + foreach (int hitCount in hitsArray) { - bw.Write(hitsArray.Length); - foreach (int hitCount in hitsArray) - { - bw.Write(hitCount); - } + bw.Write(hitCount); } } - private int[] ReadHitsFile() + private static int[] ReadHitsFile() { - using (var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Open)) - using (var br = new BinaryReader(fs)) + using var fs = new FileStream(ModuleTrackerTemplate.HitsFilePath, FileMode.Open); + using var br = new BinaryReader(fs); + int[] hitsArray = new int[br.ReadInt32()]; + for (int i = 0; i < hitsArray.Length; ++i) { - int[] hitsArray = new int[br.ReadInt32()]; - for (int i = 0; i < hitsArray.Length; ++i) - { - hitsArray[i] = br.ReadInt32(); - } - - return hitsArray; + hitsArray[i] = br.ReadInt32(); } + + return hitsArray; } } } diff --git a/test/coverlet.core.tests/Symbols/CecilSymbolHelperTests.cs b/test/coverlet.core.tests/Symbols/CecilSymbolHelperTests.cs index 7ea79155b..8b6e46c6d 100644 --- a/test/coverlet.core.tests/Symbols/CecilSymbolHelperTests.cs +++ b/test/coverlet.core.tests/Symbols/CecilSymbolHelperTests.cs @@ -41,7 +41,7 @@ public void GetBranchPoints_OneBranch() // assert Assert.NotNull(points); - Assert.Equal(2, points.Count()); + Assert.Equal(2, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(0, points[0].Path); Assert.Equal(1, points[1].Path); @@ -61,7 +61,7 @@ public void GetBranchPoints_Using_Where_GeneratedBranchesIgnored() // act System.Collections.Generic.IReadOnlyList points = _cecilSymbolHelper.GetBranchPoints(method); - Assert.Equal(2, points.Count()); + Assert.Equal(2, points.Count); } [Fact] @@ -89,7 +89,7 @@ public void GetBranchPoints_TwoBranch() // assert Assert.NotNull(points); - Assert.Equal(4, points.Count()); + Assert.Equal(4, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[2].Offset, points[3].Offset); Assert.Equal(28, points[0].StartLine); @@ -108,7 +108,7 @@ public void GetBranchPoints_CompleteIf() // assert Assert.NotNull(points); - Assert.Equal(2, points.Count()); + Assert.Equal(2, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(35, points[0].StartLine); Assert.Equal(35, points[1].StartLine); @@ -127,7 +127,7 @@ public void GetBranchPoints_Switch() // assert Assert.NotNull(points); - Assert.Equal(4, points.Count()); + Assert.Equal(4, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[0].Offset, points[2].Offset); Assert.Equal(3, points[3].Path); @@ -150,7 +150,7 @@ public void GetBranchPoints_SwitchWithDefault() // assert Assert.NotNull(points); - Assert.Equal(4, points.Count()); + Assert.Equal(4, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[0].Offset, points[2].Offset); Assert.Equal(3, points[3].Path); @@ -173,7 +173,7 @@ public void GetBranchPoints_SwitchWithBreaks() // assert Assert.NotNull(points); - Assert.Equal(4, points.Count()); + Assert.Equal(4, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[0].Offset, points[2].Offset); Assert.Equal(3, points[3].Path); @@ -196,7 +196,7 @@ public void GetBranchPoints_SwitchWithMultipleCases() // assert Assert.NotNull(points); - Assert.Equal(4, points.Count()); + Assert.Equal(4, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[0].Offset, points[2].Offset); Assert.Equal(points[0].Offset, points[3].Offset); @@ -351,7 +351,7 @@ public void GetBranchPoints_IgnoresMostBranchesIn_AwaitForeachStateMachine() // We do expect there to be a two-way branch (stay in the loop or not?) on // the line containing "await foreach". Assert.NotNull(points); - Assert.Equal(2, points.Count()); + Assert.Equal(2, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(204, points[0].StartLine); Assert.Equal(204, points[1].StartLine); @@ -375,7 +375,7 @@ public void GetBranchPoints_IgnoresMostBranchesIn_AwaitForeachStateMachine_WithB // containing "await foreach" and the other being the "if" statement inside // the loop. Assert.NotNull(points); - Assert.Equal(4, points.Count()); + Assert.Equal(4, points.Count); Assert.Equal(points[0].Offset, points[1].Offset); Assert.Equal(points[2].Offset, points[3].Offset); Assert.Equal(219, points[0].StartLine); @@ -399,7 +399,7 @@ public void GetBranchPoints_IgnoresExtraBranchesIn_AsyncIteratorStateMachine() // assert // We do expect the "for" loop to be a branch with two branch points, but that's it. Assert.NotNull(points); - Assert.Equal(2, points.Count()); + Assert.Equal(2, points.Count); Assert.Equal(237, points[0].StartLine); Assert.Equal(237, points[1].StartLine); } diff --git a/test/coverlet.integration.tests/BaseTest.cs b/test/coverlet.integration.tests/BaseTest.cs index 6072740c7..4e8fd52f9 100644 --- a/test/coverlet.integration.tests/BaseTest.cs +++ b/test/coverlet.integration.tests/BaseTest.cs @@ -24,9 +24,9 @@ public enum BuildConfiguration public abstract class BaseTest { - private static int _folderSuffix = 0; + private static int s_folderSuffix; - protected BuildConfiguration GetAssemblyBuildConfiguration() + protected static BuildConfiguration GetAssemblyBuildConfiguration() { #if DEBUG return BuildConfiguration.Debug; @@ -37,7 +37,7 @@ protected BuildConfiguration GetAssemblyBuildConfiguration() throw new NotSupportedException($"Build configuration not supported"); } - private protected string GetPackageVersion(string filter) + private protected static string GetPackageVersion(string filter) { if (!Directory.Exists($"../../../../../bin/{GetAssemblyBuildConfiguration()}/Packages")) { @@ -51,9 +51,9 @@ private protected string GetPackageVersion(string filter) return manifest.Metadata.Version.OriginalVersion; } - private protected ClonedTemplateProject CloneTemplateProject(bool cleanupOnDispose = true, string testSDKVersion = "16.5.0") + private protected static ClonedTemplateProject CloneTemplateProject(bool cleanupOnDispose = true, string testSDKVersion = "16.5.0") { - DirectoryInfo finalRoot = Directory.CreateDirectory($"{Guid.NewGuid().ToString("N").Substring(0, 6)}{Interlocked.Increment(ref _folderSuffix)}"); + DirectoryInfo finalRoot = Directory.CreateDirectory($"{Guid.NewGuid().ToString("N")[..6]}{Interlocked.Increment(ref s_folderSuffix)}"); foreach (string file in (Directory.GetFiles($"../../../../coverlet.integration.template", "*.cs") .Union(Directory.GetFiles($"../../../../coverlet.integration.template", "*.csproj") .Union(Directory.GetFiles($"../../../../coverlet.integration.template", "nuget.config"))))) @@ -79,7 +79,7 @@ private protected ClonedTemplateProject CloneTemplateProject(bool cleanupOnDispo return new ClonedTemplateProject(finalRoot.FullName, cleanupOnDispose); } - private protected bool RunCommand(string command, string arguments, out string standardOutput, out string standardError, string workingDirectory = "") + private protected static bool RunCommand(string command, string arguments, out string standardOutput, out string standardError, string workingDirectory = "") { Debug.WriteLine($"BaseTest.RunCommand: {command} {arguments}\nWorkingDirectory: {workingDirectory}"); var psi = new ProcessStartInfo(command, arguments); @@ -96,12 +96,12 @@ private protected bool RunCommand(string command, string arguments, out string s return commandProcess.ExitCode == 0; } - private protected bool DotnetCli(string arguments, out string standardOutput, out string standardError, string workingDirectory = "") + private protected static bool DotnetCli(string arguments, out string standardOutput, out string standardError, string workingDirectory = "") { return RunCommand("dotnet", arguments, out standardOutput, out standardError, workingDirectory); } - private protected void UpdateNugeConfigtWithLocalPackageFolder(string projectPath) + private protected static void UpdateNugeConfigtWithLocalPackageFolder(string projectPath) { string nugetFile = Path.Combine(projectPath, "nuget.config"); if (!File.Exists(nugetFile)) @@ -123,7 +123,7 @@ private protected void UpdateNugeConfigtWithLocalPackageFolder(string projectPat xml.Save(nugetFile); } - private void SetIsTestProjectTrue(string projectPath) + private static void SetIsTestProjectTrue(string projectPath) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -143,7 +143,7 @@ private void SetIsTestProjectTrue(string projectPath) xml.Save(csproj); } - private protected void AddMicrosoftNETTestSdkRef(string projectPath, string version) + private protected static void AddMicrosoftNETTestSdkRef(string projectPath, string version) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -163,7 +163,7 @@ private protected void AddMicrosoftNETTestSdkRef(string projectPath, string vers xml.Save(csproj); } - private protected void AddCoverletMsbuildRef(string projectPath) + private protected static void AddCoverletMsbuildRef(string projectPath) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -182,7 +182,7 @@ private protected void AddCoverletMsbuildRef(string projectPath) xml.Save(csproj); } - private protected void AddCoverletCollectosRef(string projectPath) + private protected static void AddCoverletCollectosRef(string projectPath) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -201,13 +201,13 @@ private protected void AddCoverletCollectosRef(string projectPath) xml.Save(csproj); } - private protected string AddCollectorRunsettingsFile(string projectPath, string includeFilter = "[coverletsamplelib.integration.template]*DeepThought", bool sourceLink = false, bool deterministicReport = false) + private protected static string AddCollectorRunsettingsFile(string projectPath, string includeFilter = "[coverletsamplelib.integration.template]*DeepThought", bool sourceLink = false, bool deterministicReport = false) { string runSettings = $@" - - + + json,cobertura @@ -227,7 +227,7 @@ private protected string AddCollectorRunsettingsFile(string projectPath, string return runsettingsPath; } - private protected void AssertCoverage(ClonedTemplateProject clonedTemplateProject, string filter = "coverage.json", string standardOutput = "") + private protected static void AssertCoverage(ClonedTemplateProject clonedTemplateProject, string filter = "coverage.json", string standardOutput = "") { if (GetAssemblyBuildConfiguration() == BuildConfiguration.Debug) { @@ -246,7 +246,7 @@ private protected void AssertCoverage(ClonedTemplateProject clonedTemplateProjec } } - private protected void UpdateProjectTargetFramework(ClonedTemplateProject project, params string[] targetFrameworks) + private protected static void UpdateProjectTargetFramework(ClonedTemplateProject project, params string[] targetFrameworks) { if (targetFrameworks is null || targetFrameworks.Length == 0) { @@ -283,7 +283,7 @@ private protected void UpdateProjectTargetFramework(ClonedTemplateProject projec xml.Save(project.ProjectFileNamePath); } - private protected void PinSDK(ClonedTemplateProject project, string sdkVersion) + private protected static void PinSDK(ClonedTemplateProject project, string sdkVersion) { if (project is null) { diff --git a/test/coverlet.integration.tests/DotnetTool.cs b/test/coverlet.integration.tests/DotnetTool.cs index 58f2521ac..42a916241 100644 --- a/test/coverlet.integration.tests/DotnetTool.cs +++ b/test/coverlet.integration.tests/DotnetTool.cs @@ -10,7 +10,7 @@ namespace Coverlet.Integration.Tests { public class DotnetGlobalTools : BaseTest { - private string InstallTool(string projectPath) + private static string InstallTool(string projectPath) { _ = DotnetCli($"tool install coverlet.console --version {GetPackageVersion("*console*.nupkg")} --tool-path \"{Path.Combine(projectPath, "coverletTool")}\"", out string standardOutput, out _, projectPath); Assert.Contains("was successfully installed.", standardOutput); diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index b79f356cf..47cc17cc8 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -16,7 +16,7 @@ public Msbuild() _buildConfiguration = GetAssemblyBuildConfiguration().ToString(); } - private ClonedTemplateProject PrepareTemplateProject() + private static ClonedTemplateProject PrepareTemplateProject() { ClonedTemplateProject clonedTemplateProject = CloneTemplateProject(); UpdateNugeConfigtWithLocalPackageFolder(clonedTemplateProject.ProjectRootPath!); From 72fab2aae02cc72483192964633ec8932cd59aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 24 Feb 2022 11:15:05 +0100 Subject: [PATCH 2/2] Revert static changes to public API + address review feedback --- .editorconfig | 8 +- .../DataCollection/AttachmentManager.cs | 17 ++-- .../DataCollection/CoverageManager.cs | 8 +- .../CoverletCoverageCollector.cs | 45 +++++---- .../DataCollection/CoverletLogger.cs | 10 +- .../DataCollection/CoverletSettingsParser.cs | 15 ++- .../CoverletInProcDataCollector.cs | 14 +-- .../Utilities/TestPlatformEqtTrace.cs | 14 +-- src/coverlet.console/Logging/ConsoleLogger.cs | 2 +- src/coverlet.console/Program.cs | 15 +-- src/coverlet.core/CoverageResult.cs | 20 ++-- src/coverlet.core/CoverageSummary.cs | 50 +++++----- .../Instrumentation/Instrumenter.cs | 2 +- .../Instrumentation/ReachabilityHelper.cs | 12 +-- .../Reporters/CoberturaReporter.cs | 36 +++---- src/coverlet.core/Reporters/LcovReporter.cs | 7 +- .../Reporters/OpenCoverReporter.cs | 29 +++--- .../Reporters/TeamCityReporter.cs | 7 +- .../Symbols/CecilSymbolHelper.cs | 2 +- .../CoverageResultTask.cs | 15 +-- .../InstrumentationTask.cs | 2 +- .../AttachmentManagerTests.cs | 12 ++- .../CoverletCoverageDataCollectorTests.cs | 30 +++--- .../CoverletSettingsParserTests.cs | 23 +++-- .../Coverage/CoverageSummaryTests.cs | 98 +++++++++++-------- .../CoverageResultTests.cs | 18 ++-- .../Instrumentation/InstrumenterTests.cs | 28 +++--- test/coverlet.integration.tests/BaseTest.cs | 32 +++--- test/coverlet.integration.tests/DotnetTool.cs | 2 +- test/coverlet.integration.tests/Msbuild.cs | 2 +- 30 files changed, 311 insertions(+), 264 deletions(-) diff --git a/.editorconfig b/.editorconfig index b8554bead..1227fcc9b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -89,8 +89,6 @@ dotnet_style_prefer_conditional_expression_over_assignment = true:silent dotnet_style_prefer_conditional_expression_over_return = true:silent # CA1805: Do not initialize unnecessarily dotnet_diagnostic.CA1805.severity = warning -# CA1822: Mark members as static -dotnet_diagnostic.CA1822.severity = warning # IDE0063: Use simple 'using' statement dotnet_diagnostic.IDE0063.severity = warning # IDE0057: Use range operator @@ -109,14 +107,14 @@ dotnet_diagnostic.CA1827.severity = warning # Name all constant fields using PascalCase dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style dotnet_naming_symbols.constant_fields.applicable_kinds = field dotnet_naming_symbols.constant_fields.required_modifiers = const dotnet_naming_style.pascal_case_style.capitalization = pascal_case # Static fields should have s_ prefix dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields -dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style +dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style dotnet_naming_symbols.static_fields.applicable_kinds = field dotnet_naming_symbols.static_fields.required_modifiers = static dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected @@ -125,7 +123,7 @@ dotnet_naming_style.static_prefix_style.capitalization = camel_case # Internal and private fields should be _camelCase dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields -dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style dotnet_naming_symbols.private_internal_fields.applicable_kinds = field dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal dotnet_naming_style.camel_case_underscore_style.required_prefix = _ diff --git a/src/coverlet.collector/DataCollection/AttachmentManager.cs b/src/coverlet.collector/DataCollection/AttachmentManager.cs index d2f302bef..8259f71f3 100644 --- a/src/coverlet.collector/DataCollection/AttachmentManager.cs +++ b/src/coverlet.collector/DataCollection/AttachmentManager.cs @@ -17,6 +17,7 @@ namespace Coverlet.Collector.DataCollection internal class AttachmentManager : IDisposable { private readonly DataCollectionSink _dataSink; + private readonly TestPlatformEqtTrace _eqtTrace; private readonly TestPlatformLogger _logger; private readonly DataCollectionContext _dataCollectionContext; private readonly IFileHelper _fileHelper; @@ -24,10 +25,11 @@ internal class AttachmentManager : IDisposable private readonly ICountDownEvent _countDownEvent; private readonly string _reportDirectory; - public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, ICountDownEvent countDownEvent) + public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, TestPlatformEqtTrace eqtTrace, ICountDownEvent countDownEvent) : this(dataSink, dataCollectionContext, logger, + eqtTrace, Guid.NewGuid().ToString(), new FileHelper(), new DirectoryHelper(), @@ -35,12 +37,13 @@ public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext data { } - public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, string reportDirectoryName, IFileHelper fileHelper, IDirectoryHelper directoryHelper, ICountDownEvent countDownEvent) + public AttachmentManager(DataCollectionSink dataSink, DataCollectionContext dataCollectionContext, TestPlatformLogger logger, TestPlatformEqtTrace eqtTrace, string reportDirectoryName, IFileHelper fileHelper, IDirectoryHelper directoryHelper, ICountDownEvent countDownEvent) { // Store input variabless _dataSink = dataSink; _dataCollectionContext = dataCollectionContext; _logger = logger; + _eqtTrace = eqtTrace; _fileHelper = fileHelper; _directoryHelper = directoryHelper; _countDownEvent = countDownEvent; @@ -100,7 +103,7 @@ private string SaveCoverageReport(string report, string reportFileName) _directoryHelper.CreateDirectory(_reportDirectory); string filePath = Path.Combine(_reportDirectory, reportFileName); _fileHelper.WriteAllText(filePath, report); - TestPlatformEqtTrace.Info("{0}: Saved coverage report to path: '{1}'", CoverletConstants.DataCollectorName, filePath); + _eqtTrace.Info("{0}: Saved coverage report to path: '{1}'", CoverletConstants.DataCollectorName, filePath); return filePath; } @@ -120,7 +123,7 @@ public void OnSendFileCompleted(object sender, AsyncCompletedEventArgs e) { try { - TestPlatformEqtTrace.Verbose("{0}: SendFileCompleted received", CoverletConstants.DataCollectorName); + _eqtTrace.Verbose("{0}: SendFileCompleted received", CoverletConstants.DataCollectorName); } catch (Exception ex) { @@ -141,12 +144,12 @@ private void SendAttachment(string attachmentPath) if (_fileHelper.Exists(attachmentPath)) { // Send coverage attachment to test platform. - TestPlatformEqtTrace.Verbose("{0}: Sending attachment to test platform", CoverletConstants.DataCollectorName); + _eqtTrace.Verbose("{0}: Sending attachment to test platform", CoverletConstants.DataCollectorName); _dataSink.SendFileAsync(_dataCollectionContext, attachmentPath, false); } else { - TestPlatformEqtTrace.Warning("{0}: Attachment file does not exist", CoverletConstants.DataCollectorName); + _eqtTrace.Warning("{0}: Attachment file does not exist", CoverletConstants.DataCollectorName); } } @@ -160,7 +163,7 @@ private void CleanupReportDirectory() if (_directoryHelper.Exists(_reportDirectory)) { _directoryHelper.Delete(_reportDirectory, true); - TestPlatformEqtTrace.Verbose("{0}: Deleted report directory: '{1}'", CoverletConstants.DataCollectorName, _reportDirectory); + _eqtTrace.Verbose("{0}: Deleted report directory: '{1}'", CoverletConstants.DataCollectorName, _reportDirectory); } } catch (Exception ex) diff --git a/src/coverlet.collector/DataCollection/CoverageManager.cs b/src/coverlet.collector/DataCollection/CoverageManager.cs index 62fb5152b..89ec41eb1 100644 --- a/src/coverlet.collector/DataCollection/CoverageManager.cs +++ b/src/coverlet.collector/DataCollection/CoverageManager.cs @@ -24,15 +24,15 @@ internal class CoverageManager private readonly ISourceRootTranslator _sourceRootTranslator; public IReporter[] Reporters { get; } - public CoverageManager(CoverletSettings settings, TestPlatformLogger logger, ICoverageWrapper coverageWrapper, IInstrumentationHelper instrumentationHelper, - IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper) + public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, ICoverageWrapper coverageWrapper, + IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper) : this(settings, settings.ReportFormats.Select(format => { var reporterFactory = new ReporterFactory(format); if (!reporterFactory.IsValidFormat()) { - TestPlatformEqtTrace.Warning($"Invalid report format '{format}'"); + eqtTrace.Warning($"Invalid report format '{format}'"); return null; } else @@ -40,7 +40,7 @@ public CoverageManager(CoverletSettings settings, TestPlatformLogger logger, ICo return reporterFactory.CreateReporter(); } }).Where(r => r != null).ToArray(), - new CoverletLogger(logger), + new CoverletLogger(eqtTrace, logger), coverageWrapper, instrumentationHelper, fileSystem, sourceRootTranslator, cecilSymbolHelper) { } diff --git a/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs b/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs index 1cc08b454..e1b27a219 100644 --- a/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs +++ b/src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs @@ -23,9 +23,10 @@ namespace Coverlet.Collector.DataCollection [DataCollectorFriendlyName(CoverletConstants.FriendlyName)] public class CoverletCoverageCollector : DataCollector { + private readonly TestPlatformEqtTrace _eqtTrace; private readonly ICoverageWrapper _coverageWrapper; private readonly ICountDownEventFactory _countDownEventFactory; - private readonly Func _serviceCollectionFactory; + private readonly Func _serviceCollectionFactory; private DataCollectionEvents _events; private TestPlatformLogger _logger; @@ -35,18 +36,19 @@ public class CoverletCoverageCollector : DataCollector private CoverageManager _coverageManager; private IServiceProvider _serviceProvider; - public CoverletCoverageCollector() : this(new CoverageWrapper(), new CollectorCountdownEventFactory(), GetDefaultServiceCollection) + public CoverletCoverageCollector() : this(new TestPlatformEqtTrace(), new CoverageWrapper(), new CollectorCountdownEventFactory(), GetDefaultServiceCollection) { } - internal CoverletCoverageCollector(ICoverageWrapper coverageWrapper, ICountDownEventFactory countDownEventFactory, Func serviceCollectionFactory) : base() + internal CoverletCoverageCollector(TestPlatformEqtTrace eqtTrace, ICoverageWrapper coverageWrapper, ICountDownEventFactory countDownEventFactory, Func serviceCollectionFactory) : base() { + _eqtTrace = eqtTrace; _coverageWrapper = coverageWrapper; _countDownEventFactory = countDownEventFactory; _serviceCollectionFactory = serviceCollectionFactory; } - private static void AttachDebugger() + private void AttachDebugger() { if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_DATACOLLECTOR_OUTOFPROC_DEBUG"), out int result) && result == 1) { @@ -73,9 +75,9 @@ public override void Initialize( AttachDebugger(); - if (TestPlatformEqtTrace.IsInfoEnabled) + if (_eqtTrace.IsInfoEnabled) { - TestPlatformEqtTrace.Info("Initializing {0} with configuration: '{1}'", CoverletConstants.DataCollectorName, configurationElement?.OuterXml); + _eqtTrace.Info("Initializing {0} with configuration: '{1}'", CoverletConstants.DataCollectorName, configurationElement?.OuterXml); } // Store input variables @@ -96,7 +98,7 @@ public override void Initialize( /// Disposing flag protected override void Dispose(bool disposing) { - TestPlatformEqtTrace.Verbose("{0}: Disposing", CoverletConstants.DataCollectorName); + _eqtTrace.Verbose("{0}: Disposing", CoverletConstants.DataCollectorName); // Unregister events if (_events != null) @@ -120,21 +122,22 @@ protected override void Dispose(bool disposing) /// Event args private void OnSessionStart(object sender, SessionStartEventArgs sessionStartEventArgs) { - TestPlatformEqtTrace.Verbose("{0}: SessionStart received", CoverletConstants.DataCollectorName); + _eqtTrace.Verbose("{0}: SessionStart received", CoverletConstants.DataCollectorName); try { // Get coverlet settings IEnumerable testModules = GetTestModules(sessionStartEventArgs); - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(_configurationElement, testModules); + var coverletSettingsParser = new CoverletSettingsParser(_eqtTrace); + CoverletSettings coverletSettings = coverletSettingsParser.Parse(_configurationElement, testModules); // Build services container - _serviceProvider = _serviceCollectionFactory(_logger, coverletSettings.TestModule).BuildServiceProvider(); + _serviceProvider = _serviceCollectionFactory(_eqtTrace, _logger, coverletSettings.TestModule).BuildServiceProvider(); // Get coverage and attachment managers - _coverageManager = new CoverageManager(coverletSettings, _logger, _coverageWrapper, _serviceProvider.GetRequiredService(), - _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService(), - _serviceProvider.GetRequiredService()); + _coverageManager = new CoverageManager(coverletSettings, _eqtTrace, _logger, _coverageWrapper, + _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService(), + _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService()); // Instrument modules _coverageManager.InstrumentModules(); @@ -155,7 +158,7 @@ private void OnSessionEnd(object sender, SessionEndEventArgs e) { try { - TestPlatformEqtTrace.Verbose("{0}: SessionEnd received", CoverletConstants.DataCollectorName); + _eqtTrace.Verbose("{0}: SessionEnd received", CoverletConstants.DataCollectorName); // Get coverage reports IEnumerable<(string report, string fileName)> coverageReports = _coverageManager?.GetCoverageReports(); @@ -163,7 +166,7 @@ private void OnSessionEnd(object sender, SessionEndEventArgs e) if (coverageReports != null && coverageReports.Any()) { // Send result attachments to test platform. - using var attachmentManager = new AttachmentManager(_dataSink, _dataCollectionContext, _logger, _countDownEventFactory.Create(coverageReports.Count(), TimeSpan.FromSeconds(30))); + using var attachmentManager = new AttachmentManager(_dataSink, _dataCollectionContext, _logger, _eqtTrace, _countDownEventFactory.Create(coverageReports.Count(), TimeSpan.FromSeconds(30))); foreach ((string report, string fileName) in coverageReports) { attachmentManager.SendCoverageReport(report, fileName); @@ -171,7 +174,7 @@ private void OnSessionEnd(object sender, SessionEndEventArgs e) } else { - TestPlatformEqtTrace.Verbose("{0}: No coverage reports specified", CoverletConstants.DataCollectorName); + _eqtTrace.Verbose("{0}: No coverage reports specified", CoverletConstants.DataCollectorName); } } catch (Exception ex) @@ -186,14 +189,14 @@ private void OnSessionEnd(object sender, SessionEndEventArgs e) /// /// Event args /// Test modules list - private static IEnumerable GetTestModules(SessionStartEventArgs sessionStartEventArgs) + private IEnumerable GetTestModules(SessionStartEventArgs sessionStartEventArgs) { try { IEnumerable testModules = GetPropertyValueWrapper(sessionStartEventArgs); - if (TestPlatformEqtTrace.IsInfoEnabled) + if (_eqtTrace.IsInfoEnabled) { - TestPlatformEqtTrace.Info("{0}: TestModules: '{1}'", + _eqtTrace.Info("{0}: TestModules: '{1}'", CoverletConstants.DataCollectorName, string.Join(",", testModules ?? Enumerable.Empty())); } @@ -215,13 +218,13 @@ private static IEnumerable GetPropertyValueWrapper(SessionStartEventArgs return sessionStartEventArgs.GetPropertyValue>(CoverletConstants.TestSourcesPropertyName); } - private static IServiceCollection GetDefaultServiceCollection(TestPlatformLogger logger, string testModule) + private static IServiceCollection GetDefaultServiceCollection(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) { IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); // We need to keep singleton/static semantics serviceCollection.AddSingleton(); // We cache resolutions diff --git a/src/coverlet.collector/DataCollection/CoverletLogger.cs b/src/coverlet.collector/DataCollection/CoverletLogger.cs index ecb582e94..42eb6a1b2 100644 --- a/src/coverlet.collector/DataCollection/CoverletLogger.cs +++ b/src/coverlet.collector/DataCollection/CoverletLogger.cs @@ -12,10 +12,12 @@ namespace Coverlet.Collector.DataCollection /// internal class CoverletLogger : ILogger { + private readonly TestPlatformEqtTrace _eqtTrace; private readonly TestPlatformLogger _logger; - public CoverletLogger(TestPlatformLogger logger) + public CoverletLogger(TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger) { + _eqtTrace = eqtTrace; _logger = logger; } @@ -44,7 +46,7 @@ public void LogError(Exception exception) /// importance public void LogInformation(string message, bool important = false) { - TestPlatformEqtTrace.Info(message); + _eqtTrace.Info(message); } /// @@ -53,7 +55,7 @@ public void LogInformation(string message, bool important = false) /// Verbose message public void LogVerbose(string message) { - TestPlatformEqtTrace.Verbose(message); + _eqtTrace.Verbose(message); } /// @@ -62,7 +64,7 @@ public void LogVerbose(string message) /// Warning message public void LogWarning(string message) { - TestPlatformEqtTrace.Warning(message); + _eqtTrace.Warning(message); } } } diff --git a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs index 13ccf88b6..4440b24d8 100644 --- a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs +++ b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs @@ -13,15 +13,22 @@ namespace Coverlet.Collector.DataCollection /// /// Coverlet settings parser /// - internal static class CoverletSettingsParser + internal class CoverletSettingsParser { + private readonly TestPlatformEqtTrace _eqtTrace; + + public CoverletSettingsParser(TestPlatformEqtTrace eqtTrace) + { + _eqtTrace = eqtTrace; + } + /// /// Parser coverlet settings /// /// Configuration element /// Test modules /// Coverlet settings - public static CoverletSettings Parse(XmlElement configurationElement, IEnumerable testModules) + public CoverletSettings Parse(XmlElement configurationElement, IEnumerable testModules) { var coverletSettings = new CoverletSettings { @@ -46,9 +53,9 @@ public static CoverletSettings Parse(XmlElement configurationElement, IEnumerabl coverletSettings.ReportFormats = ParseReportFormats(configurationElement); coverletSettings.ExcludeFilters = ParseExcludeFilters(configurationElement); - if (TestPlatformEqtTrace.IsVerboseEnabled) + if (_eqtTrace.IsVerboseEnabled) { - TestPlatformEqtTrace.Verbose("{0}: Initializing coverlet process with settings: \"{1}\"", CoverletConstants.DataCollectorName, coverletSettings.ToString()); + _eqtTrace.Verbose("{0}: Initializing coverlet process with settings: \"{1}\"", CoverletConstants.DataCollectorName, coverletSettings.ToString()); } return coverletSettings; diff --git a/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs b/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs index 089e6d983..f682b2687 100644 --- a/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs +++ b/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs @@ -16,9 +16,10 @@ namespace Coverlet.Collector.DataCollection { public class CoverletInProcDataCollector : InProcDataCollection { + private TestPlatformEqtTrace _eqtTrace; private bool _enableExceptionLog; - private static void AttachDebugger() + private void AttachDebugger() { if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_DATACOLLECTOR_INPROC_DEBUG"), out int result) && result == 1) { @@ -40,7 +41,8 @@ public void Initialize(IDataCollectionSink dataCollectionSink) AttachDebugger(); EnableExceptionLog(); - TestPlatformEqtTrace.Verbose("Initialize CoverletInProcDataCollector"); + _eqtTrace = new TestPlatformEqtTrace(); + _eqtTrace.Verbose("Initialize CoverletInProcDataCollector"); } public void TestCaseEnd(TestCaseEndArgs testCaseEndArgs) @@ -63,17 +65,17 @@ public void TestSessionEnd(TestSessionEndArgs testSessionEndArgs) try { - TestPlatformEqtTrace.Verbose($"Calling ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); + _eqtTrace.Verbose($"Calling ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); MethodInfo unloadModule = injectedInstrumentationClass.GetMethod(nameof(ModuleTrackerTemplate.UnloadModule), new[] { typeof(object), typeof(EventArgs) }); unloadModule.Invoke(null, new[] { (object)this, EventArgs.Empty }); injectedInstrumentationClass.GetField("FlushHitFile", BindingFlags.Static | BindingFlags.Public).SetValue(null, false); - TestPlatformEqtTrace.Verbose($"Called ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); + _eqtTrace.Verbose($"Called ModuleTrackerTemplate.UnloadModule for '{injectedInstrumentationClass.Assembly.FullName}'"); } catch (Exception ex) { if (_enableExceptionLog) { - TestPlatformEqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex); + _eqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex); string errorMessage = string.Format(Resources.FailedToUnloadModule, CoverletConstants.InProcDataCollectorName); throw new CoverletDataCollectorException(errorMessage, ex); } @@ -118,7 +120,7 @@ private Type GetInstrumentationClass(Assembly assembly) } } - TestPlatformEqtTrace.Warning(exceptionString.ToString()); + _eqtTrace.Warning(exceptionString.ToString()); } return null; diff --git a/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs b/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs index a1233e37f..7c02f6d03 100644 --- a/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs +++ b/src/coverlet.collector/Utilities/TestPlatformEqtTrace.cs @@ -8,17 +8,17 @@ namespace Coverlet.Collector.Utilities /// /// Test platform eqttrace /// - internal static class TestPlatformEqtTrace + internal class TestPlatformEqtTrace { - public static bool IsInfoEnabled => EqtTrace.IsInfoEnabled; - public static bool IsVerboseEnabled => EqtTrace.IsVerboseEnabled; + public bool IsInfoEnabled => EqtTrace.IsInfoEnabled; + public bool IsVerboseEnabled => EqtTrace.IsVerboseEnabled; /// /// Verbose logger /// /// Format /// Args - public static void Verbose(string format, params object[] args) + public void Verbose(string format, params object[] args) { EqtTrace.Verbose($"[coverlet]{format}", args); } @@ -28,7 +28,7 @@ public static void Verbose(string format, params object[] args) /// /// Format /// Args - public static void Warning(string format, params object[] args) + public void Warning(string format, params object[] args) { EqtTrace.Warning($"[coverlet]{format}", args); } @@ -38,7 +38,7 @@ public static void Warning(string format, params object[] args) /// /// Format /// Args - public static void Info(string format, params object[] args) + public void Info(string format, params object[] args) { EqtTrace.Info($"[coverlet]{format}", args); } @@ -48,7 +48,7 @@ public static void Info(string format, params object[] args) /// /// Format /// Args - public static void Error(string format, params object[] args) + public void Error(string format, params object[] args) { EqtTrace.Error($"[coverlet]{format}", args); } diff --git a/src/coverlet.console/Logging/ConsoleLogger.cs b/src/coverlet.console/Logging/ConsoleLogger.cs index d0e07132c..1e41af504 100644 --- a/src/coverlet.console/Logging/ConsoleLogger.cs +++ b/src/coverlet.console/Logging/ConsoleLogger.cs @@ -10,7 +10,7 @@ namespace Coverlet.Console.Logging class ConsoleLogger : ILogger { private static readonly object s_sync = new(); - + public LogLevel Level { get; set; } = LogLevel.Normal; public void LogError(string message) => Log(LogLevel.Quiet, message, ConsoleColor.Red); diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index 33f6f77bd..25f5f7350 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -231,10 +231,11 @@ static int Main(string[] args) } var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method"); + var summary = new CoverageSummary(); - CoverageDetails linePercentCalculation = CoverageSummary.CalculateLineCoverage(result.Modules); - CoverageDetails branchPercentCalculation = CoverageSummary.CalculateBranchCoverage(result.Modules); - CoverageDetails methodPercentCalculation = CoverageSummary.CalculateMethodCoverage(result.Modules); + CoverageDetails linePercentCalculation = summary.CalculateLineCoverage(result.Modules); + CoverageDetails branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules); + CoverageDetails methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules); double totalLinePercent = linePercentCalculation.Percent; double totalBranchPercent = branchPercentCalculation.Percent; @@ -246,9 +247,9 @@ static int Main(string[] args) foreach (KeyValuePair _module in result.Modules) { - double linePercent = CoverageSummary.CalculateLineCoverage(_module.Value).Percent; - double branchPercent = CoverageSummary.CalculateBranchCoverage(_module.Value).Percent; - double methodPercent = CoverageSummary.CalculateMethodCoverage(_module.Value).Percent; + double linePercent = summary.CalculateLineCoverage(_module.Value).Percent; + double branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent; + double methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent; coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{InvariantFormat(linePercent)}%", $"{InvariantFormat(branchPercent)}%", $"{InvariantFormat(methodPercent)}%"); } @@ -268,7 +269,7 @@ static int Main(string[] args) exitCode += (int)CommandExitCodes.TestFailed; } - ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, dThresholdStat); + ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, dThresholdStat); if (thresholdTypeFlags != ThresholdTypeFlags.None) { exitCode += (int)CommandExitCodes.CoverageBelowThreshold; diff --git a/src/coverlet.core/CoverageResult.cs b/src/coverlet.core/CoverageResult.cs index d646aba20..4e981346b 100644 --- a/src/coverlet.core/CoverageResult.cs +++ b/src/coverlet.core/CoverageResult.cs @@ -111,7 +111,7 @@ public void Merge(Modules modules) } } - public ThresholdTypeFlags GetThresholdTypesBelowThreshold(Dictionary thresholdTypeFlagValues, ThresholdStatistic thresholdStat) + public ThresholdTypeFlags GetThresholdTypesBelowThreshold(CoverageSummary summary, Dictionary thresholdTypeFlagValues, ThresholdStatistic thresholdStat) { ThresholdTypeFlags thresholdTypeFlags = ThresholdTypeFlags.None; switch (thresholdStat) @@ -123,9 +123,9 @@ public ThresholdTypeFlags GetThresholdTypesBelowThreshold(Dictionary module in Modules) { - double line = CoverageSummary.CalculateLineCoverage(module.Value).Percent; - double branch = CoverageSummary.CalculateBranchCoverage(module.Value).Percent; - double method = CoverageSummary.CalculateMethodCoverage(module.Value).Percent; + double line = summary.CalculateLineCoverage(module.Value).Percent; + double branch = summary.CalculateBranchCoverage(module.Value).Percent; + double method = summary.CalculateMethodCoverage(module.Value).Percent; thresholdTypeFlags = CompareThresholdValues(thresholdTypeFlagValues, thresholdTypeFlags, line, branch, method); } @@ -133,18 +133,18 @@ public ThresholdTypeFlags GetThresholdTypesBelowThreshold(Dictionary l.Value > 0).Count(); @@ -17,7 +17,7 @@ public static CoverageDetails CalculateLineCoverage(Lines lines) return details; } - public static CoverageDetails CalculateLineCoverage(Methods methods) + public CoverageDetails CalculateLineCoverage(Methods methods) { var details = new CoverageDetails(); foreach (KeyValuePair method in methods) @@ -29,7 +29,7 @@ public static CoverageDetails CalculateLineCoverage(Methods methods) return details; } - public static CoverageDetails CalculateLineCoverage(Classes classes) + public CoverageDetails CalculateLineCoverage(Classes classes) { var details = new CoverageDetails(); foreach (KeyValuePair @class in classes) @@ -41,7 +41,7 @@ public static CoverageDetails CalculateLineCoverage(Classes classes) return details; } - public static CoverageDetails CalculateLineCoverage(Documents documents) + public CoverageDetails CalculateLineCoverage(Documents documents) { var details = new CoverageDetails(); foreach (KeyValuePair document in documents) @@ -53,7 +53,7 @@ public static CoverageDetails CalculateLineCoverage(Documents documents) return details; } - public static CoverageDetails CalculateLineCoverage(Modules modules) + public CoverageDetails CalculateLineCoverage(Modules modules) { var details = new CoverageDetails { Modules = modules }; double accumPercent = 0.0D; @@ -72,7 +72,7 @@ public static CoverageDetails CalculateLineCoverage(Modules modules) return details; } - public static CoverageDetails CalculateBranchCoverage(IList branches) + public CoverageDetails CalculateBranchCoverage(IList branches) { var details = new CoverageDetails(); details.Covered = branches.Count(bi => bi.Hits > 0); @@ -80,7 +80,7 @@ public static CoverageDetails CalculateBranchCoverage(IList branches return details; } - public static int CalculateNpathComplexity(IList branches) + public int CalculateNpathComplexity(IList branches) { // Adapted from OpenCover see https://github.com/OpenCover/opencover/blob/master/main/OpenCover.Framework/Persistance/BasePersistance.cs#L419 if (!branches.Any()) @@ -114,47 +114,47 @@ public static int CalculateNpathComplexity(IList branches) return npath; } - public static int CalculateCyclomaticComplexity(IList branches) + public int CalculateCyclomaticComplexity(IList branches) { return Math.Max(1, branches.Count); } - public static int CalculateCyclomaticComplexity(Methods methods) + public int CalculateCyclomaticComplexity(Methods methods) { return methods.Values.Select(m => CalculateCyclomaticComplexity(m.Branches)).Sum(); } - public static int CalculateMaxCyclomaticComplexity(Methods methods) + public int CalculateMaxCyclomaticComplexity(Methods methods) { return methods.Values.Select(m => CalculateCyclomaticComplexity(m.Branches)).DefaultIfEmpty(1).Max(); } - public static int CalculateMinCyclomaticComplexity(Methods methods) + public int CalculateMinCyclomaticComplexity(Methods methods) { return methods.Values.Select(m => CalculateCyclomaticComplexity(m.Branches)).DefaultIfEmpty(1).Min(); } - public static int CalculateCyclomaticComplexity(Modules modules) + public int CalculateCyclomaticComplexity(Modules modules) { return modules.Values.Select(CalculateCyclomaticComplexity).Sum(); } - public static int CalculateMaxCyclomaticComplexity(Modules modules) + public int CalculateMaxCyclomaticComplexity(Modules modules) { return modules.Values.Select(CalculateCyclomaticComplexity).DefaultIfEmpty(1).Max(); } - public static int CalculateMinCyclomaticComplexity(Modules modules) + public int CalculateMinCyclomaticComplexity(Modules modules) { return modules.Values.Select(CalculateCyclomaticComplexity).DefaultIfEmpty(1).Min(); } - public static int CalculateCyclomaticComplexity(Documents documents) + public int CalculateCyclomaticComplexity(Documents documents) { return documents.Values.SelectMany(c => c.Values.Select(CalculateCyclomaticComplexity)).Sum(); } - public static CoverageDetails CalculateBranchCoverage(Methods methods) + public CoverageDetails CalculateBranchCoverage(Methods methods) { var details = new CoverageDetails(); foreach (KeyValuePair method in methods) @@ -166,7 +166,7 @@ public static CoverageDetails CalculateBranchCoverage(Methods methods) return details; } - public static CoverageDetails CalculateBranchCoverage(Classes classes) + public CoverageDetails CalculateBranchCoverage(Classes classes) { var details = new CoverageDetails(); foreach (KeyValuePair @class in classes) @@ -178,7 +178,7 @@ public static CoverageDetails CalculateBranchCoverage(Classes classes) return details; } - public static CoverageDetails CalculateBranchCoverage(Documents documents) + public CoverageDetails CalculateBranchCoverage(Documents documents) { var details = new CoverageDetails(); foreach (KeyValuePair document in documents) @@ -190,7 +190,7 @@ public static CoverageDetails CalculateBranchCoverage(Documents documents) return details; } - public static CoverageDetails CalculateBranchCoverage(Modules modules) + public CoverageDetails CalculateBranchCoverage(Modules modules) { var details = new CoverageDetails { Modules = modules }; double accumPercent = 0.0D; @@ -209,7 +209,7 @@ public static CoverageDetails CalculateBranchCoverage(Modules modules) return details; } - public static CoverageDetails CalculateMethodCoverage(Lines lines) + public CoverageDetails CalculateMethodCoverage(Lines lines) { var details = new CoverageDetails(); details.Covered = lines.Any(l => l.Value > 0) ? 1 : 0; @@ -217,7 +217,7 @@ public static CoverageDetails CalculateMethodCoverage(Lines lines) return details; } - public static CoverageDetails CalculateMethodCoverage(Methods methods) + public CoverageDetails CalculateMethodCoverage(Methods methods) { var details = new CoverageDetails(); IEnumerable> methodsWithLines = methods.Where(m => m.Value.Lines.Count > 0); @@ -230,7 +230,7 @@ public static CoverageDetails CalculateMethodCoverage(Methods methods) return details; } - public static CoverageDetails CalculateMethodCoverage(Classes classes) + public CoverageDetails CalculateMethodCoverage(Classes classes) { var details = new CoverageDetails(); foreach (KeyValuePair @class in classes) @@ -242,7 +242,7 @@ public static CoverageDetails CalculateMethodCoverage(Classes classes) return details; } - public static CoverageDetails CalculateMethodCoverage(Documents documents) + public CoverageDetails CalculateMethodCoverage(Documents documents) { var details = new CoverageDetails(); foreach (KeyValuePair document in documents) @@ -254,7 +254,7 @@ public static CoverageDetails CalculateMethodCoverage(Documents documents) return details; } - public static CoverageDetails CalculateMethodCoverage(Modules modules) + public CoverageDetails CalculateMethodCoverage(Modules modules) { var details = new CoverageDetails { Modules = modules }; double accumPercent = 0.0D; diff --git a/src/coverlet.core/Instrumentation/Instrumenter.cs b/src/coverlet.core/Instrumentation/Instrumenter.cs index 87aade96f..51b18c07c 100644 --- a/src/coverlet.core/Instrumentation/Instrumenter.cs +++ b/src/coverlet.core/Instrumentation/Instrumenter.cs @@ -829,7 +829,7 @@ private bool IsSynthesizedMemberToBeExcluded(IMemberDefinition definition) // Check if the name is synthesized by the compiler // Refer to https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs // to see how the compiler generate names for lambda, local function, yield or async/await expressions - internal static bool IsSynthesizedNameOf(string name, string methodName, int methodOrdinal) + internal bool IsSynthesizedNameOf(string name, string methodName, int methodOrdinal) { return // Lambda method diff --git a/src/coverlet.core/Instrumentation/ReachabilityHelper.cs b/src/coverlet.core/Instrumentation/ReachabilityHelper.cs index f5526dcd3..1b4840d85 100644 --- a/src/coverlet.core/Instrumentation/ReachabilityHelper.cs +++ b/src/coverlet.core/Instrumentation/ReachabilityHelper.cs @@ -169,9 +169,7 @@ public override string ToString() /// OpCodes that transfer control code, even if they do not /// introduce branch points. /// -#pragma warning disable IDE1006 // Naming Styles - private static readonly ImmutableHashSet BRANCH_OPCODES = -#pragma warning restore IDE1006 // Naming Styles + private static readonly ImmutableHashSet s_branchOpCodes = ImmutableHashSet.CreateRange( new[] { @@ -226,9 +224,7 @@ public override string ToString() /// OpCodes that unconditionally transfer control, so there /// is not "fall through" branch target. /// -#pragma warning disable IDE1006 // Naming Styles - private static readonly ImmutableHashSet UNCONDITIONAL_BRANCH_OPCODES = -#pragma warning restore IDE1006 // Naming Styles + private static readonly ImmutableHashSet s_unconditionalBranchOpCodes = ImmutableHashSet.CreateRange( new[] { @@ -410,7 +406,7 @@ public ImmutableArray FindUnreachableIL(Collection multiTargetOffsets) = GetInstructionTargets(i, exceptionHandlers); @@ -457,7 +453,7 @@ private static (int? SingleTargetOffset, ImmutableArray MultiTargetOffsets) { // it's any of the B.*(_S)? or Leave(_S)? instructions - if (UNCONDITIONAL_BRANCH_OPCODES.Contains(i.OpCode)) + if (s_unconditionalBranchOpCodes.Contains(i.OpCode)) { multiTargetOffsets = ImmutableArray.Empty; singleTargetOffset = targetInstr.Offset; diff --git a/src/coverlet.core/Reporters/CoberturaReporter.cs b/src/coverlet.core/Reporters/CoberturaReporter.cs index 85f773a48..57571df9a 100644 --- a/src/coverlet.core/Reporters/CoberturaReporter.cs +++ b/src/coverlet.core/Reporters/CoberturaReporter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Toni Solarin-Sodara +// Copyright (c) Toni Solarin-Sodara // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; @@ -24,13 +24,15 @@ internal class CoberturaReporter : IReporter public string Report(CoverageResult result, ISourceRootTranslator sourceRootTranslator) { - CoverageDetails lineCoverage = CoverageSummary.CalculateLineCoverage(result.Modules); - CoverageDetails branchCoverage = CoverageSummary.CalculateBranchCoverage(result.Modules); + var summary = new CoverageSummary(); + + CoverageDetails lineCoverage = summary.CalculateLineCoverage(result.Modules); + CoverageDetails branchCoverage = summary.CalculateBranchCoverage(result.Modules); var xml = new XDocument(); var coverage = new XElement("coverage"); - coverage.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); - coverage.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); + coverage.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); + coverage.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(result.Modules).Percent / 100).ToString(CultureInfo.InvariantCulture))); coverage.Add(new XAttribute("version", "1.9")); coverage.Add(new XAttribute("timestamp", (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds)); @@ -48,9 +50,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran { var package = new XElement("package"); package.Add(new XAttribute("name", Path.GetFileNameWithoutExtension(module.Key))); - package.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - package.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - package.Add(new XAttribute("complexity", CoverageSummary.CalculateCyclomaticComplexity(module.Value))); + package.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + package.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(module.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + package.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(module.Value))); var classes = new XElement("classes"); foreach (KeyValuePair document in module.Value) @@ -69,9 +71,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran fileName = sourceRootTranslator.ResolveDeterministicPath(document.Key); } @class.Add(new XAttribute("filename", fileName)); - @class.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - @class.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); - @class.Add(new XAttribute("complexity", CoverageSummary.CalculateCyclomaticComplexity(cls.Value))); + @class.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + @class.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(cls.Value).Percent / 100).ToString(CultureInfo.InvariantCulture))); + @class.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(cls.Value))); var classLines = new XElement("lines"); var methods = new XElement("methods"); @@ -85,9 +87,9 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran var method = new XElement("method"); method.Add(new XAttribute("name", meth.Key.Split(':').Last().Split('(').First())); method.Add(new XAttribute("signature", "(" + meth.Key.Split(':').Last().Split('(').Last())); - method.Add(new XAttribute("line-rate", (CoverageSummary.CalculateLineCoverage(meth.Value.Lines).Percent / 100).ToString(CultureInfo.InvariantCulture))); - method.Add(new XAttribute("branch-rate", (CoverageSummary.CalculateBranchCoverage(meth.Value.Branches).Percent / 100).ToString(CultureInfo.InvariantCulture))); - method.Add(new XAttribute("complexity", CoverageSummary.CalculateCyclomaticComplexity(meth.Value.Branches))); + method.Add(new XAttribute("line-rate", (summary.CalculateLineCoverage(meth.Value.Lines).Percent / 100).ToString(CultureInfo.InvariantCulture))); + method.Add(new XAttribute("branch-rate", (summary.CalculateBranchCoverage(meth.Value.Branches).Percent / 100).ToString(CultureInfo.InvariantCulture))); + method.Add(new XAttribute("complexity", summary.CalculateCyclomaticComplexity(meth.Value.Branches))); var lines = new XElement("lines"); foreach (KeyValuePair ln in meth.Value.Lines) @@ -101,7 +103,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran if (isBranchPoint) { var branches = meth.Value.Branches.Where(b => b.Line == ln.Key).ToList(); - CoverageDetails branchInfoCoverage = CoverageSummary.CalculateBranchCoverage(branches); + CoverageDetails branchInfoCoverage = summary.CalculateBranchCoverage(branches); line.Add(new XAttribute("condition-coverage", $"{branchInfoCoverage.Percent.ToString(CultureInfo.InvariantCulture)}% ({branchInfoCoverage.Covered.ToString(CultureInfo.InvariantCulture)}/{branchInfoCoverage.Total.ToString(CultureInfo.InvariantCulture)})")); var conditions = new XElement("conditions"); var byOffset = branches.GroupBy(b => b.Offset).ToDictionary(b => b.Key, b => b.ToList()); @@ -110,7 +112,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran var condition = new XElement("condition"); condition.Add(new XAttribute("number", entry.Key)); condition.Add(new XAttribute("type", entry.Value.Count > 2 ? "switch" : "jump")); // Just guessing here - condition.Add(new XAttribute("coverage", $"{CoverageSummary.CalculateBranchCoverage(entry.Value).Percent.ToString(CultureInfo.InvariantCulture)}%")); + condition.Add(new XAttribute("coverage", $"{summary.CalculateBranchCoverage(entry.Value).Percent.ToString(CultureInfo.InvariantCulture)}%")); conditions.Add(condition); } @@ -231,4 +233,4 @@ private static string GetRelativePathFromBase(IEnumerable basePaths, str return path; } } -} \ No newline at end of file +} diff --git a/src/coverlet.core/Reporters/LcovReporter.cs b/src/coverlet.core/Reporters/LcovReporter.cs index c13fa43f6..5b7471f42 100644 --- a/src/coverlet.core/Reporters/LcovReporter.cs +++ b/src/coverlet.core/Reporters/LcovReporter.cs @@ -23,15 +23,16 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran throw new NotSupportedException("Deterministic report not supported by lcov reporter"); } + var summary = new CoverageSummary(); var lcov = new List(); foreach (KeyValuePair module in result.Modules) { foreach (KeyValuePair doc in module.Value) { - CoverageDetails docLineCoverage = CoverageSummary.CalculateLineCoverage(doc.Value); - CoverageDetails docBranchCoverage = CoverageSummary.CalculateBranchCoverage(doc.Value); - CoverageDetails docMethodCoverage = CoverageSummary.CalculateMethodCoverage(doc.Value); + CoverageDetails docLineCoverage = summary.CalculateLineCoverage(doc.Value); + CoverageDetails docBranchCoverage = summary.CalculateBranchCoverage(doc.Value); + CoverageDetails docMethodCoverage = summary.CalculateMethodCoverage(doc.Value); lcov.Add("SF:" + doc.Key); foreach (KeyValuePair @class in doc.Value) diff --git a/src/coverlet.core/Reporters/OpenCoverReporter.cs b/src/coverlet.core/Reporters/OpenCoverReporter.cs index 941fc81e0..2e42c2894 100644 --- a/src/coverlet.core/Reporters/OpenCoverReporter.cs +++ b/src/coverlet.core/Reporters/OpenCoverReporter.cs @@ -26,6 +26,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran throw new NotSupportedException("Deterministic report not supported by openCover reporter"); } + var summary = new CoverageSummary(); var xml = new XDocument(); var coverage = new XElement("CoverageSession"); var coverageSummary = new XElement("Summary"); @@ -76,10 +77,10 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran if (meth.Value.Lines.Count == 0) continue; - CoverageDetails methLineCoverage = CoverageSummary.CalculateLineCoverage(meth.Value.Lines); - CoverageDetails methBranchCoverage = CoverageSummary.CalculateBranchCoverage(meth.Value.Branches); - int methCyclomaticComplexity = CoverageSummary.CalculateCyclomaticComplexity(meth.Value.Branches); - int methNpathComplexity = CoverageSummary.CalculateNpathComplexity(meth.Value.Branches); + CoverageDetails methLineCoverage = summary.CalculateLineCoverage(meth.Value.Lines); + CoverageDetails methBranchCoverage = summary.CalculateBranchCoverage(meth.Value.Branches); + int methCyclomaticComplexity = summary.CalculateCyclomaticComplexity(meth.Value.Branches); + int methNpathComplexity = summary.CalculateNpathComplexity(meth.Value.Branches); var method = new XElement("Method"); @@ -122,7 +123,7 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran foreach (System.Collections.Generic.KeyValuePair lines in meth.Value.Lines) { BranchInfo[] lineBranches = meth.Value.Branches.Where(branchInfo => branchInfo.Line == lines.Key).ToArray(); - CoverageDetails branchCoverage = CoverageSummary.CalculateBranchCoverage(lineBranches); + CoverageDetails branchCoverage = summary.CalculateBranchCoverage(lineBranches); var sequencePoint = new XElement("SequencePoint"); sequencePoint.Add(new XAttribute("vc", lines.Value.ToString())); @@ -193,11 +194,11 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran if (classVisited) visitedClasses++; - CoverageDetails classLineCoverage = CoverageSummary.CalculateLineCoverage(cls.Value); - CoverageDetails classBranchCoverage = CoverageSummary.CalculateBranchCoverage(cls.Value); - CoverageDetails classMethodCoverage = CoverageSummary.CalculateMethodCoverage(cls.Value); - int classMaxCyclomaticComplexity = CoverageSummary.CalculateMaxCyclomaticComplexity(cls.Value); - int classMinCyclomaticComplexity = CoverageSummary.CalculateMinCyclomaticComplexity(cls.Value); + CoverageDetails classLineCoverage = summary.CalculateLineCoverage(cls.Value); + CoverageDetails classBranchCoverage = summary.CalculateBranchCoverage(cls.Value); + CoverageDetails classMethodCoverage = summary.CalculateMethodCoverage(cls.Value); + int classMaxCyclomaticComplexity = summary.CalculateMaxCyclomaticComplexity(cls.Value); + int classMinCyclomaticComplexity = summary.CalculateMinCyclomaticComplexity(cls.Value); classSummary.Add(new XAttribute("numSequencePoints", classLineCoverage.Total.ToString())); classSummary.Add(new XAttribute("visitedSequencePoints", classLineCoverage.Covered.ToString())); @@ -225,10 +226,10 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran modules.Add(module); } - CoverageDetails moduleLineCoverage = CoverageSummary.CalculateLineCoverage(result.Modules); - CoverageDetails moduleBranchCoverage = CoverageSummary.CalculateBranchCoverage(result.Modules); - int moduleMaxCyclomaticComplexity = CoverageSummary.CalculateMaxCyclomaticComplexity(result.Modules); - int moduleMinCyclomaticComplexity = CoverageSummary.CalculateMinCyclomaticComplexity(result.Modules); + CoverageDetails moduleLineCoverage = summary.CalculateLineCoverage(result.Modules); + CoverageDetails moduleBranchCoverage = summary.CalculateBranchCoverage(result.Modules); + int moduleMaxCyclomaticComplexity = summary.CalculateMaxCyclomaticComplexity(result.Modules); + int moduleMinCyclomaticComplexity = summary.CalculateMinCyclomaticComplexity(result.Modules); coverageSummary.Add(new XAttribute("numSequencePoints", moduleLineCoverage.Total.ToString())); coverageSummary.Add(new XAttribute("visitedSequencePoints", moduleLineCoverage.Covered.ToString())); diff --git a/src/coverlet.core/Reporters/TeamCityReporter.cs b/src/coverlet.core/Reporters/TeamCityReporter.cs index 51971f673..8ccb0d997 100644 --- a/src/coverlet.core/Reporters/TeamCityReporter.cs +++ b/src/coverlet.core/Reporters/TeamCityReporter.cs @@ -24,9 +24,10 @@ public string Report(CoverageResult result, ISourceRootTranslator sourceRootTran } // Calculate coverage - CoverageDetails overallLineCoverage = CoverageSummary.CalculateLineCoverage(result.Modules); - CoverageDetails overallBranchCoverage = CoverageSummary.CalculateBranchCoverage(result.Modules); - CoverageDetails overallMethodCoverage = CoverageSummary.CalculateMethodCoverage(result.Modules); + var summary = new CoverageSummary(); + CoverageDetails overallLineCoverage = summary.CalculateLineCoverage(result.Modules); + CoverageDetails overallBranchCoverage = summary.CalculateBranchCoverage(result.Modules); + CoverageDetails overallMethodCoverage = summary.CalculateMethodCoverage(result.Modules); // Report coverage var stringBuilder = new StringBuilder(); diff --git a/src/coverlet.core/Symbols/CecilSymbolHelper.cs b/src/coverlet.core/Symbols/CecilSymbolHelper.cs index dd8eb1238..a718c82bb 100644 --- a/src/coverlet.core/Symbols/CecilSymbolHelper.cs +++ b/src/coverlet.core/Symbols/CecilSymbolHelper.cs @@ -1213,7 +1213,7 @@ await ... IL_00eb: br.s IL_00ed ... */ - public static bool SkipNotCoverableInstructionAfterExceptionRethrowInsiceCatchBlock(MethodDefinition methodDefinition, Instruction instruction) + public bool SkipNotCoverableInstructionAfterExceptionRethrowInsiceCatchBlock(MethodDefinition methodDefinition, Instruction instruction) { if (!IsMoveNextInsideAsyncStateMachine(methodDefinition)) { diff --git a/src/coverlet.msbuild.tasks/CoverageResultTask.cs b/src/coverlet.msbuild.tasks/CoverageResultTask.cs index d78f87db7..23a29f7a5 100644 --- a/src/coverlet.msbuild.tasks/CoverageResultTask.cs +++ b/src/coverlet.msbuild.tasks/CoverageResultTask.cs @@ -190,10 +190,11 @@ public override bool Execute() } var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method"); + var summary = new CoverageSummary(); - CoverageDetails linePercentCalculation = CoverageSummary.CalculateLineCoverage(result.Modules); - CoverageDetails branchPercentCalculation = CoverageSummary.CalculateBranchCoverage(result.Modules); - CoverageDetails methodPercentCalculation = CoverageSummary.CalculateMethodCoverage(result.Modules); + CoverageDetails linePercentCalculation = summary.CalculateLineCoverage(result.Modules); + CoverageDetails branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules); + CoverageDetails methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules); double totalLinePercent = linePercentCalculation.Percent; double totalBranchPercent = branchPercentCalculation.Percent; @@ -205,9 +206,9 @@ public override bool Execute() foreach (KeyValuePair module in result.Modules) { - double linePercent = CoverageSummary.CalculateLineCoverage(module.Value).Percent; - double branchPercent = CoverageSummary.CalculateBranchCoverage(module.Value).Percent; - double methodPercent = CoverageSummary.CalculateMethodCoverage(module.Value).Percent; + double linePercent = summary.CalculateLineCoverage(module.Value).Percent; + double branchPercent = summary.CalculateBranchCoverage(module.Value).Percent; + double methodPercent = summary.CalculateMethodCoverage(module.Value).Percent; coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{InvariantFormat(linePercent)}%", $"{InvariantFormat(branchPercent)}%", $"{InvariantFormat(methodPercent)}%"); } @@ -224,7 +225,7 @@ public override bool Execute() Console.WriteLine(coverageTable.ToStringAlternative()); - ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStat); + ThresholdTypeFlags thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStat); if (thresholdTypeFlags != ThresholdTypeFlags.None) { var exceptionMessageBuilder = new StringBuilder(); diff --git a/src/coverlet.msbuild.tasks/InstrumentationTask.cs b/src/coverlet.msbuild.tasks/InstrumentationTask.cs index 2acf94145..2ec4910da 100644 --- a/src/coverlet.msbuild.tasks/InstrumentationTask.cs +++ b/src/coverlet.msbuild.tasks/InstrumentationTask.cs @@ -55,7 +55,7 @@ public InstrumentationTask() _logger = new MSBuildLogger(Log); } - private static void AttachDebugger() + private void AttachDebugger() { if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_MSBUILD_INSTRUMENTATIONTASK_DEBUG"), out int result) && result == 1) { diff --git a/test/coverlet.collector.tests/AttachmentManagerTests.cs b/test/coverlet.collector.tests/AttachmentManagerTests.cs index e54c5a9e7..9e021212d 100644 --- a/test/coverlet.collector.tests/AttachmentManagerTests.cs +++ b/test/coverlet.collector.tests/AttachmentManagerTests.cs @@ -20,6 +20,7 @@ public class AttachmentManagerTests private readonly Mock _mockDataCollectionSink; private readonly DataCollectionContext _dataCollectionContext; private readonly TestPlatformLogger _testPlatformLogger; + private readonly TestPlatformEqtTrace _eqtTrace; private readonly Mock _mockFileHelper; private readonly Mock _mockDirectoryHelper; private readonly Mock _mockCountDownEvent; @@ -32,12 +33,13 @@ public AttachmentManagerTests() var testcase = new TestCase { Id = Guid.NewGuid() }; _dataCollectionContext = new DataCollectionContext(testcase); _testPlatformLogger = new TestPlatformLogger(_mockDataCollectionLogger.Object, _dataCollectionContext); + _eqtTrace = new TestPlatformEqtTrace(); _mockFileHelper = new Mock(); _mockDirectoryHelper = new Mock(); _mockCountDownEvent = new Mock(); _attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, - @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); + _eqtTrace, @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); } [Fact] @@ -57,7 +59,7 @@ public void SendCoverageReportShouldSaveReportToFile() public void SendCoverageReportShouldThrowExceptionWhenFailedToSaveReportToFile() { _attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, - @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); + _eqtTrace, @"E:\temp", _mockFileHelper.Object, _mockDirectoryHelper.Object, _mockCountDownEvent.Object); string coverageReport = "" + "" @@ -74,7 +76,7 @@ public void SendCoverageReportShouldSendAttachmentToTestPlatform() { DirectoryInfo directory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())); _attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, - directory.ToString(), new FileHelper(), _mockDirectoryHelper.Object, _mockCountDownEvent.Object); + _eqtTrace, directory.ToString(), new FileHelper(), _mockDirectoryHelper.Object, _mockCountDownEvent.Object); string coverageReport = "" + "" @@ -94,7 +96,7 @@ public void OnDisposeAttachmentManagerShouldCleanUpReportDirectory() { var mockDirectoryHelper = new Mock(); mockDirectoryHelper.Setup(x => x.Exists(It.Is(y => y.Contains(@"E:\temp")))).Returns(true); - using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) + using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, _eqtTrace, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) { _mockDataCollectionSink.Raise(x => x.SendFileCompleted += null, new AsyncCompletedEventArgs(null, false, null)); } @@ -108,7 +110,7 @@ public void OnDisposeAttachmentManagerShouldThrowCoverletDataCollectorExceptionI var mockDirectoryHelper = new Mock(); mockDirectoryHelper.Setup(x => x.Exists(It.Is(y => y.Contains(@"E:\temp")))).Returns(true); mockDirectoryHelper.Setup(x => x.Delete(It.Is(y => y.Contains(@"E:\temp")), true)).Throws(new FileNotFoundException()); - using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) + using (var attachmentManager = new AttachmentManager(_mockDataCollectionSink.Object, _dataCollectionContext, _testPlatformLogger, _eqtTrace, @"E:\temp", _mockFileHelper.Object, mockDirectoryHelper.Object, _mockCountDownEvent.Object)) { _mockDataCollectionSink.Raise(x => x.SendFileCompleted += null, new AsyncCompletedEventArgs(null, false, null)); } diff --git a/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs b/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs index 0e11630c7..66fb8bd67 100644 --- a/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs +++ b/test/coverlet.collector.tests/CoverletCoverageDataCollectorTests.cs @@ -52,7 +52,7 @@ public CoverletCoverageDataCollectorTests() [Fact] public void OnSessionStartShouldInitializeCoverageWithCorrectCoverletSettings() { - Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -61,13 +61,13 @@ public void OnSessionStartShouldInitializeCoverageWithCorrectCoverletSettings() serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(_mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), _mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, @@ -86,7 +86,7 @@ public void OnSessionStartShouldInitializeCoverageWithCorrectCoverletSettings() [Fact] public void OnSessionStartShouldPrepareModulesForCoverage() { - Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -95,13 +95,13 @@ public void OnSessionStartShouldPrepareModulesForCoverage() serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(_mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), _mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, @@ -142,19 +142,19 @@ public void OnSessionStartShouldPrepareModulesForCoverage() [Fact] public void OnSessionEndShouldSendGetCoverageReportToTestPlatform() { - Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, @@ -187,7 +187,7 @@ public void OnSessionEndShouldSendGetCoverageReportToTestPlatform() [InlineData("json,cobertura,lcov", 3)] public void OnSessionEndShouldSendCoverageReportsForMultipleFormatsToTestPlatform(string formats, int sendReportsCount) { - Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -196,13 +196,13 @@ public void OnSessionEndShouldSendCoverageReportsForMultipleFormatsToTestPlatfor serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), new CoverageWrapper(), _mockCountDownEventFactory.Object, serviceCollectionFactory); IList reporters = formats.Split(',').Select(f => new ReporterFactory(f).CreateReporter()).Where(x => x != null).ToList(); var mockDataCollectionSink = new Mock(); @@ -240,7 +240,7 @@ public void OnSessionEndShouldSendCoverageReportsForMultipleFormatsToTestPlatfor [Fact] public void OnSessionStartShouldLogWarningIfInstrumentationFailed() { - Func serviceCollectionFactory = (TestPlatformLogger logger, string testModule) => + Func serviceCollectionFactory = (TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, string testModule) => { IServiceCollection serviceCollection = new ServiceCollection(); var fileSystem = new Mock(); @@ -249,13 +249,13 @@ public void OnSessionStartShouldLogWarningIfInstrumentationFailed() serviceCollection.AddTransient(); serviceCollection.AddTransient(); - serviceCollection.AddTransient(_ => new CoverletLogger(logger)); + serviceCollection.AddTransient(_ => new CoverletLogger(eqtTrace, logger)); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService())); serviceCollection.AddSingleton(); return serviceCollection; }; - _coverletCoverageDataCollector = new CoverletCoverageCollector(_mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); + _coverletCoverageDataCollector = new CoverletCoverageCollector(new TestPlatformEqtTrace(), _mockCoverageWrapper.Object, _mockCountDownEventFactory.Object, serviceCollectionFactory); _coverletCoverageDataCollector.Initialize( _configurationElement, _mockDataColectionEvents.Object, diff --git a/test/coverlet.collector.tests/CoverletSettingsParserTests.cs b/test/coverlet.collector.tests/CoverletSettingsParserTests.cs index 1268fe200..191bdb232 100644 --- a/test/coverlet.collector.tests/CoverletSettingsParserTests.cs +++ b/test/coverlet.collector.tests/CoverletSettingsParserTests.cs @@ -12,10 +12,17 @@ namespace Coverlet.Collector.Tests { public class CoverletSettingsParserTests { + private readonly CoverletSettingsParser _coverletSettingsParser; + + public CoverletSettingsParserTests() + { + _coverletSettingsParser = new CoverletSettingsParser(new TestPlatformEqtTrace()); + } + [Fact] public void ParseShouldThrowCoverletDataCollectorExceptionIfTestModulesIsNull() { - string message = Assert.Throws(() => CoverletSettingsParser.Parse(null, null)).Message; + string message = Assert.Throws(() => _coverletSettingsParser.Parse(null, null)).Message; Assert.Equal("CoverletCoverageDataCollector: No test modules found", message); } @@ -23,7 +30,7 @@ public void ParseShouldThrowCoverletDataCollectorExceptionIfTestModulesIsNull() [Fact] public void ParseShouldThrowCoverletDataCollectorExceptionIfTestModulesIsEmpty() { - string message = Assert.Throws(() => CoverletSettingsParser.Parse(null, Enumerable.Empty())).Message; + string message = Assert.Throws(() => _coverletSettingsParser.Parse(null, Enumerable.Empty())).Message; Assert.Equal("CoverletCoverageDataCollector: No test modules found", message); } @@ -33,7 +40,7 @@ public void ParseShouldSelectFirstTestModuleFromTestModulesList() { var testModules = new List { "module1.dll", "module2.dll", "module3.dll" }; - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(null, testModules); + CoverletSettings coverletSettings = _coverletSettingsParser.Parse(null, testModules); Assert.Equal("module1.dll", coverletSettings.TestModule); } @@ -74,7 +81,7 @@ public void ParseShouldCorrectlyParseConfigurationElement(string includeFilters, CreateCoverletNodes(doc, configElement, CoverletConstants.DeterministicReport, "true"); CreateCoverletNodes(doc, configElement, CoverletConstants.DoesNotReturnAttributesElementName, doesNotReturnAttributes); - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); Assert.Equal("abc.dll", coverletSettings.TestModule); Assert.Equal("[*]*", coverletSettings.IncludeFilters[0]); @@ -112,7 +119,7 @@ public void ParseShouldCorrectlyParseConfigurationElementWithNullInnerText() CreateCoverletNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeSourceFilesElementName); CreateCoverletNullInnerTextNodes(doc, configElement, CoverletConstants.ExcludeAttributesElementName); - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); Assert.Equal("abc.dll", coverletSettings.TestModule); Assert.Empty(coverletSettings.IncludeFilters); @@ -129,7 +136,7 @@ public void ParseShouldCorrectlyParseConfigurationElementWithNullElements() var doc = new XmlDocument(); XmlElement configElement = doc.CreateElement("Configuration"); - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); Assert.Equal("abc.dll", coverletSettings.TestModule); Assert.Null(coverletSettings.IncludeFilters); @@ -159,7 +166,7 @@ public void ParseShouldCorrectlyParseMultipleFormats(string formats, int formats XmlElement configElement = doc.CreateElement("Configuration"); CreateCoverletNodes(doc, configElement, CoverletConstants.ReportFormatElementName, formats); - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); Assert.Equal(expectedReportFormats, coverletSettings.ReportFormats); Assert.Equal(formatsCount, coverletSettings.ReportFormats.Length); @@ -176,7 +183,7 @@ public void ParseShouldUseDefaultFormatWhenNoFormatSpecified(string formats) XmlElement configElement = doc.CreateElement("Configuration"); CreateCoverletNodes(doc, configElement, CoverletConstants.ReportFormatElementName, formats); - CoverletSettings coverletSettings = CoverletSettingsParser.Parse(configElement, testModules); + CoverletSettings coverletSettings = _coverletSettingsParser.Parse(configElement, testModules); Assert.Equal(defaultFormat, coverletSettings.ReportFormats[0]); } diff --git a/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs b/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs index 5677af2ca..1a04e2021 100644 --- a/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageSummaryTests.cs @@ -126,125 +126,139 @@ private void SetupDataMultipleModule() [Fact] public void TestCalculateLineCoverage_NoModules() { + var summary = new CoverageSummary(); var modules = new Modules(); - Assert.Equal(0, CoverageSummary.CalculateLineCoverage(modules).Percent); - Assert.Equal(0, CoverageSummary.CalculateLineCoverage(modules).AverageModulePercent); - Assert.Equal(0, CoverageSummary.CalculateBranchCoverage(modules).Percent); - Assert.Equal(0, CoverageSummary.CalculateBranchCoverage(modules).AverageModulePercent); - Assert.Equal(0, CoverageSummary.CalculateMethodCoverage(modules).Percent); - Assert.Equal(0, CoverageSummary.CalculateMethodCoverage(modules).AverageModulePercent); + Assert.Equal(0, summary.CalculateLineCoverage(modules).Percent); + Assert.Equal(0, summary.CalculateLineCoverage(modules).AverageModulePercent); + Assert.Equal(0, summary.CalculateBranchCoverage(modules).Percent); + Assert.Equal(0, summary.CalculateBranchCoverage(modules).AverageModulePercent); + Assert.Equal(0, summary.CalculateMethodCoverage(modules).Percent); + Assert.Equal(0, summary.CalculateMethodCoverage(modules).AverageModulePercent); } [Fact] public void TestCalculateLineCoverage_SingleModule() { + var summary = new CoverageSummary(); + System.Collections.Generic.KeyValuePair module = _averageCalculationSingleModule.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(50, CoverageSummary.CalculateLineCoverage(_averageCalculationSingleModule).AverageModulePercent); - Assert.Equal(50, CoverageSummary.CalculateLineCoverage(module.Value).Percent); - Assert.Equal(50, CoverageSummary.CalculateLineCoverage(document.Value).Percent); - Assert.Equal(50, CoverageSummary.CalculateLineCoverage(@class.Value).Percent); - Assert.Equal(50, CoverageSummary.CalculateLineCoverage(method.Value.Lines).Percent); + Assert.Equal(50, summary.CalculateLineCoverage(_averageCalculationSingleModule).AverageModulePercent); + Assert.Equal(50, summary.CalculateLineCoverage(module.Value).Percent); + Assert.Equal(50, summary.CalculateLineCoverage(document.Value).Percent); + Assert.Equal(50, summary.CalculateLineCoverage(@class.Value).Percent); + Assert.Equal(50, summary.CalculateLineCoverage(method.Value.Lines).Percent); } [Fact] public void TestCalculateLineCoverage_MultiModule() { + var summary = new CoverageSummary(); Documents documentsFirstModule = _averageCalculationMultiModule["module"]; Documents documentsSecondModule = _averageCalculationMultiModule["aditionalModule"]; - Assert.Equal(37.5, CoverageSummary.CalculateLineCoverage(_averageCalculationMultiModule).AverageModulePercent); - Assert.Equal(50, CoverageSummary.CalculateLineCoverage(documentsFirstModule.First().Value).Percent); + Assert.Equal(37.5, summary.CalculateLineCoverage(_averageCalculationMultiModule).AverageModulePercent); + Assert.Equal(50, summary.CalculateLineCoverage(documentsFirstModule.First().Value).Percent); - Assert.Equal(33.33, CoverageSummary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(0).Value.Lines).Percent); // covered 1 of 3 - Assert.Equal(0, CoverageSummary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(1).Value.Lines).Percent); // covered 0 of 1 - Assert.Equal(25, CoverageSummary.CalculateLineCoverage(documentsSecondModule.First().Value).Percent); // covered 1 of 4 lines + Assert.Equal(33.33, summary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(0).Value.Lines).Percent); // covered 1 of 3 + Assert.Equal(0, summary.CalculateLineCoverage(documentsSecondModule.First().Value.First().Value.ElementAt(1).Value.Lines).Percent); // covered 0 of 1 + Assert.Equal(25, summary.CalculateLineCoverage(documentsSecondModule.First().Value).Percent); // covered 1 of 4 lines } [Fact] public void TestCalculateBranchCoverage_SingleModule() { + var summary = new CoverageSummary(); + System.Collections.Generic.KeyValuePair module = _averageCalculationSingleModule.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(_averageCalculationSingleModule).AverageModulePercent); - Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(module.Value).Percent); - Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(document.Value).Percent); - Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(@class.Value).Percent); - Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(method.Value.Branches).Percent); + Assert.Equal(100, summary.CalculateBranchCoverage(_averageCalculationSingleModule).AverageModulePercent); + Assert.Equal(100, summary.CalculateBranchCoverage(module.Value).Percent); + Assert.Equal(100, summary.CalculateBranchCoverage(document.Value).Percent); + Assert.Equal(100, summary.CalculateBranchCoverage(@class.Value).Percent); + Assert.Equal(100, summary.CalculateBranchCoverage(method.Value.Branches).Percent); } [Fact] public void TestCalculateBranchCoverage_MultiModule() { + var summary = new CoverageSummary(); Documents documentsFirstModule = _averageCalculationMultiModule["module"]; Documents documentsSecondModule = _averageCalculationMultiModule["aditionalModule"]; - Assert.Equal(83.33, CoverageSummary.CalculateBranchCoverage(_averageCalculationMultiModule).AverageModulePercent); - Assert.Equal(100, CoverageSummary.CalculateBranchCoverage(documentsFirstModule.First().Value).Percent); - Assert.Equal(66.66, CoverageSummary.CalculateBranchCoverage(documentsSecondModule.First().Value).Percent); + Assert.Equal(83.33, summary.CalculateBranchCoverage(_averageCalculationMultiModule).AverageModulePercent); + Assert.Equal(100, summary.CalculateBranchCoverage(documentsFirstModule.First().Value).Percent); + Assert.Equal(66.66, summary.CalculateBranchCoverage(documentsSecondModule.First().Value).Percent); } [Fact] public void TestCalculateMethodCoverage_SingleModule() { + var summary = new CoverageSummary(); + System.Collections.Generic.KeyValuePair module = _averageCalculationSingleModule.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(_averageCalculationSingleModule).AverageModulePercent); - Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(module.Value).Percent); - Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(document.Value).Percent); - Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(@class.Value).Percent); - Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(method.Value.Lines).Percent); + Assert.Equal(100, summary.CalculateMethodCoverage(_averageCalculationSingleModule).AverageModulePercent); + Assert.Equal(100, summary.CalculateMethodCoverage(module.Value).Percent); + Assert.Equal(100, summary.CalculateMethodCoverage(document.Value).Percent); + Assert.Equal(100, summary.CalculateMethodCoverage(@class.Value).Percent); + Assert.Equal(100, summary.CalculateMethodCoverage(method.Value.Lines).Percent); } [Fact] public void TestCalculateMethodCoverage_MultiModule() { + var summary = new CoverageSummary(); Documents documentsFirstModule = _averageCalculationMultiModule["module"]; Documents documentsSecondModule = _averageCalculationMultiModule["aditionalModule"]; - Assert.Equal(75, CoverageSummary.CalculateMethodCoverage(_averageCalculationMultiModule).AverageModulePercent); - Assert.Equal(100, CoverageSummary.CalculateMethodCoverage(documentsFirstModule.First().Value).Percent); - Assert.Equal(50, CoverageSummary.CalculateMethodCoverage(documentsSecondModule.First().Value).Percent); + Assert.Equal(75, summary.CalculateMethodCoverage(_averageCalculationMultiModule).AverageModulePercent); + Assert.Equal(100, summary.CalculateMethodCoverage(documentsFirstModule.First().Value).Percent); + Assert.Equal(50, summary.CalculateMethodCoverage(documentsSecondModule.First().Value).Percent); } [Fact] public void TestCalculateLineCoveragePercentage_ArithmeticPrecisionCheck() { + var summary = new CoverageSummary(); + System.Collections.Generic.KeyValuePair module = _moduleArithmeticPrecision.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(_moduleArithmeticPrecision).AverageModulePercent); - Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(module.Value).Percent); - Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(document.Value).Percent); - Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(@class.Value).Percent); - Assert.Equal(16.66, CoverageSummary.CalculateLineCoverage(method.Value.Lines).Percent); + Assert.Equal(16.66, summary.CalculateLineCoverage(_moduleArithmeticPrecision).AverageModulePercent); + Assert.Equal(16.66, summary.CalculateLineCoverage(module.Value).Percent); + Assert.Equal(16.66, summary.CalculateLineCoverage(document.Value).Percent); + Assert.Equal(16.66, summary.CalculateLineCoverage(@class.Value).Percent); + Assert.Equal(16.66, summary.CalculateLineCoverage(method.Value.Lines).Percent); } [Fact] public void TestCalculateBranchCoveragePercentage_ArithmeticPrecisionCheck() { + var summary = new CoverageSummary(); + System.Collections.Generic.KeyValuePair module = _moduleArithmeticPrecision.First(); System.Collections.Generic.KeyValuePair document = module.Value.First(); System.Collections.Generic.KeyValuePair @class = document.Value.First(); System.Collections.Generic.KeyValuePair method = @class.Value.First(); - Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(_moduleArithmeticPrecision).AverageModulePercent); - Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(module.Value).Percent); - Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(document.Value).Percent); - Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(@class.Value).Percent); - Assert.Equal(16.66, CoverageSummary.CalculateBranchCoverage(method.Value.Branches).Percent); + Assert.Equal(16.66, summary.CalculateBranchCoverage(_moduleArithmeticPrecision).AverageModulePercent); + Assert.Equal(16.66, summary.CalculateBranchCoverage(module.Value).Percent); + Assert.Equal(16.66, summary.CalculateBranchCoverage(document.Value).Percent); + Assert.Equal(16.66, summary.CalculateBranchCoverage(@class.Value).Percent); + Assert.Equal(16.66, summary.CalculateBranchCoverage(method.Value.Branches).Percent); } } } diff --git a/test/coverlet.core.tests/CoverageResultTests.cs b/test/coverlet.core.tests/CoverageResultTests.cs index a879dbd12..fd5450909 100644 --- a/test/coverlet.core.tests/CoverageResultTests.cs +++ b/test/coverlet.core.tests/CoverageResultTests.cs @@ -57,6 +57,7 @@ public void TestGetThresholdTypesBelowThresholdLine() var result = new CoverageResult(); result.Modules = _modules; + var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 90 }, @@ -66,7 +67,7 @@ public void TestGetThresholdTypesBelowThresholdLine() ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.Line, resThresholdTypeFlags); } @@ -76,6 +77,7 @@ public void TestGetThresholdTypesBelowThresholdMethod() var result = new CoverageResult(); result.Modules = _modules; + var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 50 }, @@ -85,7 +87,7 @@ public void TestGetThresholdTypesBelowThresholdMethod() ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.Method, resThresholdTypeFlags); } @@ -95,6 +97,7 @@ public void TestGetThresholdTypesBelowThresholdBranch() var result = new CoverageResult(); result.Modules = _modules; + var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 50 }, @@ -104,7 +107,7 @@ public void TestGetThresholdTypesBelowThresholdBranch() ThresholdStatistic thresholdStatic = ThresholdStatistic.Total; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.Branch, resThresholdTypeFlags); } @@ -114,6 +117,7 @@ public void TestGetThresholdTypesBelowThresholdAllGood() var result = new CoverageResult(); result.Modules = _modules; + var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 50 }, @@ -123,7 +127,7 @@ public void TestGetThresholdTypesBelowThresholdAllGood() ThresholdStatistic thresholdStatic = ThresholdStatistic.Average; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); Assert.Equal(ThresholdTypeFlags.None, resThresholdTypeFlags); } @@ -133,6 +137,7 @@ public void TestGetThresholdTypesBelowThresholdAllFail() var result = new CoverageResult(); result.Modules = _modules; + var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 100 }, @@ -143,7 +148,7 @@ public void TestGetThresholdTypesBelowThresholdAllFail() ThresholdTypeFlags thresholdTypeFlags = ThresholdTypeFlags.Line | ThresholdTypeFlags.Branch | ThresholdTypeFlags.Method; ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); Assert.Equal(thresholdTypeFlags, resThresholdTypeFlags); } @@ -153,6 +158,7 @@ public void TestGetThresholdTypesBelowThresholdWhenNoModuleInstrumented() var result = new CoverageResult(); result.Modules = new Modules(); + var summary = new CoverageSummary(); var thresholdTypeFlagValues = new Dictionary() { { ThresholdTypeFlags.Line, 80 }, @@ -163,7 +169,7 @@ public void TestGetThresholdTypesBelowThresholdWhenNoModuleInstrumented() ThresholdTypeFlags thresholdTypeFlags = ThresholdTypeFlags.Line | ThresholdTypeFlags.Branch | ThresholdTypeFlags.Method; ThresholdStatistic thresholdStatic = ThresholdStatistic.Minimum; - ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(thresholdTypeFlagValues, thresholdStatic); + ThresholdTypeFlags resThresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, thresholdTypeFlagValues, thresholdStatic); Assert.Equal(thresholdTypeFlags, resThresholdTypeFlags); } } diff --git a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs index ad43f7e56..189648834 100644 --- a/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs +++ b/test/coverlet.core.tests/Instrumentation/InstrumenterTests.cs @@ -650,10 +650,10 @@ public void TestInstrument_LambdaInsideMethodWithExcludeAttributeAreExcluded() Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLambda(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLambda(System.String)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 0)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 0)); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLambda(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 1)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLambda", 1)); Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLambda(System.String)"); instrumenterTest.Directory.Delete(true); @@ -671,15 +671,15 @@ public void TestInstrument_LocalFunctionInsideMethodWithExcludeAttributeAreExclu Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLocalFunction(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr::TestLocalFunction(System.String)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr" && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); Assert.Contains(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr" && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); Assert.DoesNotContain(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLocalFunction(System.String,System.Int32)"); Assert.DoesNotContain(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2" && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 7)); Assert.Contains(doc.Lines.Values, l => l.Method == "System.Int32 Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2::TestLocalFunction(System.String)"); Assert.Contains(doc.Lines.Values, l => l.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2" && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestLocalFunction", 6)); instrumenterTest.Directory.Delete(true); } @@ -694,13 +694,13 @@ public void TestInstrument_YieldInsideMethodWithExcludeAttributeAreExcluded() Assert.NotNull(doc); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 2)); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestYield", 3)); instrumenterTest.Directory.Delete(true); } @@ -715,13 +715,13 @@ public void TestInstrument_AsyncAwaitInsideMethodWithExcludeAttributeAreExcluded Assert.NotNull(doc); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); Assert.Contains(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 4)); Assert.DoesNotContain(doc.Lines.Values, l => l.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/") && - Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); + instrumenterTest.Instrumenter.IsSynthesizedNameOf(l.Method, "TestAsyncAwait", 5)); instrumenterTest.Directory.Delete(true); } diff --git a/test/coverlet.integration.tests/BaseTest.cs b/test/coverlet.integration.tests/BaseTest.cs index 4e8fd52f9..284373df3 100644 --- a/test/coverlet.integration.tests/BaseTest.cs +++ b/test/coverlet.integration.tests/BaseTest.cs @@ -26,7 +26,7 @@ public abstract class BaseTest { private static int s_folderSuffix; - protected static BuildConfiguration GetAssemblyBuildConfiguration() + protected BuildConfiguration GetAssemblyBuildConfiguration() { #if DEBUG return BuildConfiguration.Debug; @@ -37,7 +37,7 @@ protected static BuildConfiguration GetAssemblyBuildConfiguration() throw new NotSupportedException($"Build configuration not supported"); } - private protected static string GetPackageVersion(string filter) + private protected string GetPackageVersion(string filter) { if (!Directory.Exists($"../../../../../bin/{GetAssemblyBuildConfiguration()}/Packages")) { @@ -51,7 +51,7 @@ private protected static string GetPackageVersion(string filter) return manifest.Metadata.Version.OriginalVersion; } - private protected static ClonedTemplateProject CloneTemplateProject(bool cleanupOnDispose = true, string testSDKVersion = "16.5.0") + private protected ClonedTemplateProject CloneTemplateProject(bool cleanupOnDispose = true, string testSDKVersion = "16.5.0") { DirectoryInfo finalRoot = Directory.CreateDirectory($"{Guid.NewGuid().ToString("N")[..6]}{Interlocked.Increment(ref s_folderSuffix)}"); foreach (string file in (Directory.GetFiles($"../../../../coverlet.integration.template", "*.cs") @@ -79,7 +79,7 @@ private protected static ClonedTemplateProject CloneTemplateProject(bool cleanup return new ClonedTemplateProject(finalRoot.FullName, cleanupOnDispose); } - private protected static bool RunCommand(string command, string arguments, out string standardOutput, out string standardError, string workingDirectory = "") + private protected bool RunCommand(string command, string arguments, out string standardOutput, out string standardError, string workingDirectory = "") { Debug.WriteLine($"BaseTest.RunCommand: {command} {arguments}\nWorkingDirectory: {workingDirectory}"); var psi = new ProcessStartInfo(command, arguments); @@ -96,12 +96,12 @@ private protected static bool RunCommand(string command, string arguments, out s return commandProcess.ExitCode == 0; } - private protected static bool DotnetCli(string arguments, out string standardOutput, out string standardError, string workingDirectory = "") + private protected bool DotnetCli(string arguments, out string standardOutput, out string standardError, string workingDirectory = "") { return RunCommand("dotnet", arguments, out standardOutput, out standardError, workingDirectory); } - private protected static void UpdateNugeConfigtWithLocalPackageFolder(string projectPath) + private protected void UpdateNugeConfigtWithLocalPackageFolder(string projectPath) { string nugetFile = Path.Combine(projectPath, "nuget.config"); if (!File.Exists(nugetFile)) @@ -123,7 +123,7 @@ private protected static void UpdateNugeConfigtWithLocalPackageFolder(string pro xml.Save(nugetFile); } - private static void SetIsTestProjectTrue(string projectPath) + private void SetIsTestProjectTrue(string projectPath) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -143,7 +143,7 @@ private static void SetIsTestProjectTrue(string projectPath) xml.Save(csproj); } - private protected static void AddMicrosoftNETTestSdkRef(string projectPath, string version) + private protected void AddMicrosoftNETTestSdkRef(string projectPath, string version) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -163,7 +163,7 @@ private protected static void AddMicrosoftNETTestSdkRef(string projectPath, stri xml.Save(csproj); } - private protected static void AddCoverletMsbuildRef(string projectPath) + private protected void AddCoverletMsbuildRef(string projectPath) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -182,7 +182,7 @@ private protected static void AddCoverletMsbuildRef(string projectPath) xml.Save(csproj); } - private protected static void AddCoverletCollectosRef(string projectPath) + private protected void AddCoverletCollectosRef(string projectPath) { string csproj = Path.Combine(projectPath, "coverlet.integration.template.csproj"); if (!File.Exists(csproj)) @@ -201,13 +201,13 @@ private protected static void AddCoverletCollectosRef(string projectPath) xml.Save(csproj); } - private protected static string AddCollectorRunsettingsFile(string projectPath, string includeFilter = "[coverletsamplelib.integration.template]*DeepThought", bool sourceLink = false, bool deterministicReport = false) + private protected string AddCollectorRunsettingsFile(string projectPath, string includeFilter = "[coverletsamplelib.integration.template]*DeepThought", bool sourceLink = false, bool deterministicReport = false) { string runSettings = $@" - - + + json,cobertura @@ -227,7 +227,7 @@ private protected static string AddCollectorRunsettingsFile(string projectPath, return runsettingsPath; } - private protected static void AssertCoverage(ClonedTemplateProject clonedTemplateProject, string filter = "coverage.json", string standardOutput = "") + private protected void AssertCoverage(ClonedTemplateProject clonedTemplateProject, string filter = "coverage.json", string standardOutput = "") { if (GetAssemblyBuildConfiguration() == BuildConfiguration.Debug) { @@ -246,7 +246,7 @@ private protected static void AssertCoverage(ClonedTemplateProject clonedTemplat } } - private protected static void UpdateProjectTargetFramework(ClonedTemplateProject project, params string[] targetFrameworks) + private protected void UpdateProjectTargetFramework(ClonedTemplateProject project, params string[] targetFrameworks) { if (targetFrameworks is null || targetFrameworks.Length == 0) { @@ -283,7 +283,7 @@ private protected static void UpdateProjectTargetFramework(ClonedTemplateProject xml.Save(project.ProjectFileNamePath); } - private protected static void PinSDK(ClonedTemplateProject project, string sdkVersion) + private protected void PinSDK(ClonedTemplateProject project, string sdkVersion) { if (project is null) { diff --git a/test/coverlet.integration.tests/DotnetTool.cs b/test/coverlet.integration.tests/DotnetTool.cs index 42a916241..58f2521ac 100644 --- a/test/coverlet.integration.tests/DotnetTool.cs +++ b/test/coverlet.integration.tests/DotnetTool.cs @@ -10,7 +10,7 @@ namespace Coverlet.Integration.Tests { public class DotnetGlobalTools : BaseTest { - private static string InstallTool(string projectPath) + private string InstallTool(string projectPath) { _ = DotnetCli($"tool install coverlet.console --version {GetPackageVersion("*console*.nupkg")} --tool-path \"{Path.Combine(projectPath, "coverletTool")}\"", out string standardOutput, out _, projectPath); Assert.Contains("was successfully installed.", standardOutput); diff --git a/test/coverlet.integration.tests/Msbuild.cs b/test/coverlet.integration.tests/Msbuild.cs index 47cc17cc8..b79f356cf 100644 --- a/test/coverlet.integration.tests/Msbuild.cs +++ b/test/coverlet.integration.tests/Msbuild.cs @@ -16,7 +16,7 @@ public Msbuild() _buildConfiguration = GetAssemblyBuildConfiguration().ToString(); } - private static ClonedTemplateProject PrepareTemplateProject() + private ClonedTemplateProject PrepareTemplateProject() { ClonedTemplateProject clonedTemplateProject = CloneTemplateProject(); UpdateNugeConfigtWithLocalPackageFolder(clonedTemplateProject.ProjectRootPath!);