using System; using System.IO; using System.Linq; using System.Threading.Tasks; using Coverlet.Core.Abstracts; using Coverlet.Core.Helpers; using Coverlet.Core.Samples.Tests; using Coverlet.Tests.RemoteExecutor; using Moq; using Xunit; namespace Coverlet.Core.Tests { public partial class CoverageTests { [Fact] public void TestCoverageSkipModule__AssemblyMarkedAsExcludeFromCodeCoverage() { Mock partialMockFileSystem = new Mock(); partialMockFileSystem.CallBase = true; partialMockFileSystem.Setup(fs => fs.NewFileStream(It.IsAny(), It.IsAny(), It.IsAny())).Returns((string path, FileMode mode, FileAccess access) => { return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); }); var loggerMock = new Mock(); string excludedbyattributeDll = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "TestAssets"), "coverlet.tests.projectsample.excludedbyattribute.dll").First(); // test skip module include test assembly feature var coverage = new Coverage(excludedbyattributeDll, new string[] { "[coverlet.tests.projectsample.excludedbyattribute*]*" }, Array.Empty(), Array.Empty(), Array.Empty(), Array.Empty(), true, false, string.Empty, false, loggerMock.Object, _instrumentationHelper, partialMockFileSystem.Object); CoveragePrepareResult result = coverage.PrepareModules(); Assert.Empty(result.Results); loggerMock.Verify(l => l.LogVerbose(It.IsAny())); } [Fact] public void ExcludeFromCodeCoverage_CompilerGeneratedMethodsAndTypes() { string path = Path.GetTempFileName(); try { RemoteExecutor.Invoke(async pathSerialize => { CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance => { ((Task)instance.Test("test")).ConfigureAwait(false).GetAwaiter().GetResult(); return Task.CompletedTask; }, persistPrepareResultToFile: pathSerialize); return 0; }, path).Dispose(); CoverageResult result = TestInstrumentationHelper.GetCoverageResult(path); var document = result.Document("Instrumentation.ExcludeFromCoverage.cs"); // Invoking method "Test" of class "MethodsWithExcludeFromCodeCoverageAttr" we expect to cover 100% lines for MethodsWithExcludeFromCodeCoverageAttr Assert.DoesNotContain(document.Lines, l => (l.Value.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr" || // Compiler generated l.Value.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr/")) && l.Value.Hits == 0); // and 0% for MethodsWithExcludeFromCodeCoverageAttr2 Assert.DoesNotContain(document.Lines, l => (l.Value.Class == "Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2" || // Compiler generated l.Value.Class.StartsWith("Coverlet.Core.Samples.Tests.MethodsWithExcludeFromCodeCoverageAttr2/")) && l.Value.Hits == 1); } finally { File.Delete(path); } } [Fact] public void ExcludeFromCodeCoverage_CompilerGeneratedMethodsAndTypes_NestedMembers() { string path = Path.GetTempFileName(); try { RemoteExecutor.Invoke(async pathSerialize => { CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance => { instance.Test(); return Task.CompletedTask; }, persistPrepareResultToFile: pathSerialize); return 0; }, path).Dispose(); CoverageResult result = TestInstrumentationHelper.GetCoverageResult(path); result.Document("Instrumentation.ExcludeFromCoverage.NestedStateMachines.cs") .AssertLinesCovered(BuildConfiguration.Debug, (14, 1), (15, 1), (16, 1)) .AssertNonInstrumentedLines(BuildConfiguration.Debug, 9, 11); } finally { File.Delete(path); } } [Fact] public void ExcludeFromCodeCoverageCompilerGeneratedMethodsAndTypes_Issue670() { string path = Path.GetTempFileName(); try { RemoteExecutor.Invoke(async pathSerialize => { CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance => { instance.Test("test"); return Task.CompletedTask; }, persistPrepareResultToFile: pathSerialize); return 0; }, path).Dispose(); CoverageResult result = TestInstrumentationHelper.GetCoverageResult(path); result.Document("Instrumentation.ExcludeFromCoverage.Issue670.cs") .AssertLinesCovered(BuildConfiguration.Debug, (8, 1), (9, 1), (10, 1), (11, 1)) .AssertNonInstrumentedLines(BuildConfiguration.Debug, 15, 53); } finally { File.Delete(path); } } [Fact] public void ExcludeFromCodeCoverageNextedTypes() { string path = Path.GetTempFileName(); try { RemoteExecutor.Invoke(async pathSerialize => { CoveragePrepareResult coveragePrepareResult = await TestInstrumentationHelper.Run(instance => { Assert.Equal(42, instance.Run()); return Task.CompletedTask; }, persistPrepareResultToFile: pathSerialize); return 0; }, path).Dispose(); TestInstrumentationHelper.GetCoverageResult(path) .Document("Instrumentation.ExcludeFromCoverage.cs") .AssertLinesCovered(BuildConfiguration.Debug, (143, 1)) .AssertNonInstrumentedLines(BuildConfiguration.Debug, 146, 160); } finally { File.Delete(path); } } } }