Skip to content

Commit a5af270

Browse files
authored
Merge pull request #384 from tonyhallett/fix-excludebyattribute-coverlet-unqualified-only
Fix excludebyattribute coverlet unqualified only
2 parents 6494314 + 3412781 commit a5af270

File tree

8 files changed

+368
-152
lines changed

8 files changed

+368
-152
lines changed

FineCodeCoverageTests/CoverletConsole_Tests.cs

Lines changed: 166 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,70 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Linq;
45
using System.Threading;
6+
using System.Threading.Tasks;
57
using AutoMoq;
68
using FineCodeCoverage.Core.Utilities;
79
using FineCodeCoverage.Engine.Coverlet;
810
using FineCodeCoverage.Engine.Model;
11+
using FineCodeCoverage.Engine.OpenCover;
912
using FineCodeCoverage.Options;
1013
using Moq;
1114
using NUnit.Framework;
1215

1316
namespace Test
1417
{
15-
public class CoverletConsoleUtil_Tests
18+
19+
public class CoverletExeArgumentsProvider_Tests
1620
{
17-
private AutoMoqer mocker;
18-
private CoverletConsoleUtil coverletConsoleUtil;
21+
[Test]
22+
public void Should_Have_ExcludeByAttribute_Setting_For_Each_ExcludeByAttribute()
23+
{
24+
var mockCoverageProject = SafeMockCoverageProject();
25+
mockCoverageProject.SetupGet(cp => cp.Settings.ExcludeByAttribute).Returns(new[] { "ExcludeByAttribute1", "ExcludeByAttribute2" });
1926

20-
[SetUp]
21-
public void SetUp()
27+
var coverletExeArgumentsProvider = new CoverletExeArgumentsProvider();
28+
var coverletSettings = coverletExeArgumentsProvider.GetArguments(mockCoverageProject.Object);
29+
30+
AssertHasSetting(coverletSettings, "--exclude-by-attribute ExcludeByAttribute1");
31+
AssertHasSetting(coverletSettings, "--exclude-by-attribute ExcludeByAttribute2");
32+
}
33+
34+
[Test] //https://github.com/coverlet-coverage/coverlet/issues/1589
35+
public void Should_Unqualified_Qualified_ExcludeByAttribute()
2236
{
23-
mocker = new AutoMoqer();
24-
coverletConsoleUtil = mocker.Create<CoverletConsoleUtil>();
37+
var mockCoverageProject = SafeMockCoverageProject();
38+
mockCoverageProject.SetupGet(cp => cp.Settings.ExcludeByAttribute).Returns(new[] { "Namespace.ExcludeByAttribute1"});
39+
40+
var coverletExeArgumentsProvider = new CoverletExeArgumentsProvider();
41+
var coverletSettings = coverletExeArgumentsProvider.GetArguments(mockCoverageProject.Object);
42+
43+
AssertHasSetting(coverletSettings, "--exclude-by-attribute ExcludeByAttribute1");
2544
}
26-
[Test]
27-
public void Should_Initilize_IFCCCoverletConsoleExeProvider()
45+
46+
private Mock<ICoverageProject> SafeMockCoverageProject()
2847
{
29-
var ct = CancellationToken.None;
30-
coverletConsoleUtil.Initialize("appDataFolder", ct);
31-
mocker.Verify<IFCCCoverletConsoleExecutor>(fccExeProvider => fccExeProvider.Initialize("appDataFolder", ct));
48+
var mockCoverageProject = new Mock<ICoverageProject>();
49+
mockCoverageProject.SetupGet(coverageProject => coverageProject.IncludedReferencedProjects).Returns(new List<string>());
50+
mockCoverageProject.SetupGet(coverageProject => coverageProject.ExcludedReferencedProjects).Returns(new List<string>());
51+
mockCoverageProject.SetupGet(coverageProject => coverageProject.Settings).Returns(new Mock<IAppOptions>().Object);
52+
return mockCoverageProject;
3253
}
3354

55+
private void AssertHasSetting(List<string> coverletSettings, string setting)
56+
{
57+
Assert.IsTrue(coverletSettings.Any(coverletSetting => coverletSetting == setting));
58+
}
59+
60+
private void AssertHasEscapedSetting(List<string> coverletSettings, string setting)
61+
{
62+
AssertHasSetting(coverletSettings, CommandLineArguments.AddQuotes(setting));
63+
}
64+
}
65+
66+
public class CoverletConsoleExecuteRequestProvider_Tests
67+
{
3468
[TestCase(0)]
3569
[TestCase(1)]
3670
[TestCase(2)]
@@ -50,7 +84,7 @@ public void Should_GetCoverletExePath_From_First_That_Returns_Non_Null(int provi
5084

5185
ExecuteRequest GetExecuteRequest(int order)
5286
{
53-
if(order != providingExeProvider)
87+
if (order != providingExeProvider)
5488
{
5589
return null;
5690
}
@@ -74,13 +108,13 @@ ExecuteRequest GetExecuteRequest(int order)
74108
{
75109
var order = i;
76110
var mockExeProvider = mockExecutors[i];
77-
mockExeProvider.Setup(p => p.GetRequest(coverageProject, coverletSettings)).Returns(GetExecuteRequest(i)).Callback<ICoverageProject,string>((_,__) =>
111+
mockExeProvider.Setup(p => p.GetRequest(coverageProject, coverletSettings)).Returns(GetExecuteRequest(i)).Callback<ICoverageProject, string>((_, __) =>
78112
{
79113
callOrder.Add(order);
80114
});
81115
}
82116

83-
var coverletConsoleUtil = new CoverletConsoleUtil(null, null, mockGlobalExecutor.Object, mockCustomPathExecutor.Object, mockLocalExecutor.Object, mockFCCCoverletConsoleExecutor.Object);
117+
var coverletConsoleUtil = new CoverletConsoleExecuteRequestProvider(mockGlobalExecutor.Object, mockCustomPathExecutor.Object, mockLocalExecutor.Object, mockFCCCoverletConsoleExecutor.Object);
84118

85119
var executeRequest = coverletConsoleUtil.GetExecuteRequest(coverageProject, coverletSettings);
86120

@@ -94,6 +128,123 @@ ExecuteRequest GetExecuteRequest(int order)
94128
}
95129

96130
}
131+
}
132+
133+
public class CoverletConsoleUtil_Tests
134+
{
135+
private AutoMoqer mocker;
136+
private CoverletConsoleUtil coverletConsoleUtil;
137+
private bool executed;
138+
private readonly List<string> coverletSettings = new List<string> { "setting1", "setting2" };
139+
private readonly ExecuteResponse successfulExecuteResponse = new ExecuteResponse { ExitCode = 3, Output = "Successful output" };
140+
141+
[SetUp]
142+
public void SetUp()
143+
{
144+
executed = false;
145+
mocker = new AutoMoqer();
146+
coverletConsoleUtil = mocker.Create<CoverletConsoleUtil>();
147+
}
148+
[Test]
149+
public void Should_Initilize_IFCCCoverletConsoleExeProvider()
150+
{
151+
var ct = CancellationToken.None;
152+
coverletConsoleUtil.Initialize("appDataFolder", ct);
153+
mocker.Verify<IFCCCoverletConsoleExecutor>(fccExeProvider => fccExeProvider.Initialize("appDataFolder", ct));
154+
}
155+
156+
[Test]
157+
public async Task Should_Execute_The_Request_From_The_Execute_Request_Provider_With_Space_Delimited_Settings()
158+
{
159+
await RunSuccessfullyAsync();
160+
161+
mocker.GetMock<IProcessUtil>().Verify();
162+
}
163+
164+
[Test]
165+
public async Task Should_Log_Settings_Before_Executing()
166+
{
167+
var mockLogger = mocker.GetMock<ILogger>();
168+
mockLogger.Setup(logger => logger.Log(It.IsAny<IEnumerable<string>>())).Callback<IEnumerable<string>>(messages =>
169+
{
170+
var msgList = messages as List<string>;
171+
Assert.Multiple(() =>
172+
{
173+
Assert.That(msgList[0], Is.EqualTo("Coverlet Run (TheProjectName) - Arguments"));
174+
Assert.That(msgList.Skip(1), Is.EqualTo(coverletSettings));
175+
Assert.That(executed, Is.False);
176+
});
177+
});
178+
179+
await RunSuccessfullyAsync();
180+
181+
mockLogger.Verify();
182+
}
183+
184+
[Test]
185+
public void Should_Throw_With_ExecuteResponse_Output_When_ExitCode_Is_Greater_Than_3()
186+
{
187+
var failureExecuteResponse = new ExecuteResponse { ExitCode = 4, Output = "failure message" };
188+
var exception = Assert.ThrowsAsync<Exception>(async() => await RunAsync(failureExecuteResponse));
189+
190+
Assert.That(exception.Message, Is.EqualTo("Error. Exit code: 4"));
191+
}
192+
193+
[Test]
194+
public void Should_Log_With_ExecuteResponse_ExitCode_And_Output_When_ExitCode_Is_Greater_Than_3()
195+
{
196+
var failureExecuteResponse = new ExecuteResponse { ExitCode = 4, Output = "failure message" };
197+
198+
Assert.ThrowsAsync<Exception>(() => RunAsync(failureExecuteResponse));
199+
200+
var mockLogger = mocker.GetMock<ILogger>();
201+
mockLogger.Verify(logger => logger.Log("Coverlet Run (TheProjectName) Error. Exit code: 4", "failure message"));
202+
}
203+
204+
[Test]
205+
public async Task Should_Log_The_ExecuteResponse_Output_On_Success()
206+
{
207+
var mockLogger = mocker.GetMock<ILogger>();
208+
mockLogger.Setup(logger => logger.Log(It.IsAny<string[]>())).Callback<string[]>(messages =>
209+
{
210+
Assert.Multiple(() =>
211+
{
212+
Assert.That(messages, Is.EqualTo(new string[] { "Coverlet Run (TheProjectName) - Output", successfulExecuteResponse.Output }));
213+
Assert.That(executed, Is.True);
214+
});
215+
216+
});
217+
218+
await RunSuccessfullyAsync();
219+
220+
mockLogger.Verify();
221+
}
222+
223+
private async Task RunSuccessfullyAsync()
224+
{
225+
await RunAsync(successfulExecuteResponse);
226+
}
227+
228+
private async Task RunAsync(ExecuteResponse executeResponse)
229+
{
230+
var mockCoverageProject = new Mock<ICoverageProject>();
231+
mockCoverageProject.SetupGet(cp => cp.ProjectName).Returns("TheProjectName");
232+
var coverageProject = mockCoverageProject.Object;
233+
var requestSettings = string.Join(" ", coverletSettings);
234+
var executeRequest = new ExecuteRequest { FilePath = "TheFilePath", Arguments = "TheArguments" };
235+
var cancellationToken = CancellationToken.None;
236+
237+
mocker.Setup<ICoverletExeArgumentsProvider, List<string>>(coverletExeArgumentsProvider => coverletExeArgumentsProvider.GetArguments(coverageProject)).Returns(coverletSettings);
238+
mocker.Setup<ICoverletConsoleExecuteRequestProvider, ExecuteRequest>(
239+
coverletConsoleExecuteRequestProvider => coverletConsoleExecuteRequestProvider.GetExecuteRequest(coverageProject, requestSettings)
240+
).Returns(executeRequest);
241+
var mockProcessUtil = mocker.GetMock<IProcessUtil>();
242+
mockProcessUtil.Setup(processUtil => processUtil.ExecuteAsync(executeRequest, cancellationToken))
243+
.Callback(() => executed = true)
244+
.ReturnsAsync(executeResponse);
245+
246+
await coverletConsoleUtil.RunAsync(coverageProject, cancellationToken);
247+
}
97248

98249
}
99250

FineCodeCoverageTests/CoverletDataCollectorUtil_RunAsync_Tests.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,18 @@ public async Task Should_Get_Settings_With_IncludeTestAssembly_From_CoverageProj
139139
mockDataCollectorSettingsBuilder.Verify(b => b.WithIncludeTestAssembly(projectIncludeTestAssembly, runSettingsIncludeTestAssembly));
140140
}
141141

142-
[Test]
143-
public async Task Should_Initialize_With_Options_And_Run_Settings_First()
142+
[TestCase(true)]
143+
[TestCase(false)]
144+
public async Task Should_Initialize_With_Options_And_Run_Settings_First(bool runSettingsOnly)
144145
{
145-
var settings = new Mock<IAppOptions>().Object;
146146
mockCoverageProject.Setup(cp => cp.RunSettingsFile).Returns(".runsettings");
147147
mockCoverageProject.Setup(cp => cp.CoverageOutputFolder).Returns("output");
148-
mockCoverageProject.Setup(cp => cp.Settings).Returns(settings);
148+
var mockSettings = new Mock<IAppOptions>();
149+
mockSettings.SetupGet(appOptions => appOptions.RunSettingsOnly).Returns(runSettingsOnly);
150+
mockCoverageProject.Setup(cp => cp.Settings).Returns(mockSettings.Object);
149151

150152
await coverletDataCollectorUtil.RunAsync(CancellationToken.None);
151-
mockDataCollectorSettingsBuilder.Verify(b => b.Initialize(settings, ".runsettings",Path.Combine("output","FCC.runsettings")));
153+
mockDataCollectorSettingsBuilder.Verify(b => b.Initialize(runSettingsOnly, ".runsettings",Path.Combine("output","FCC.runsettings")));
152154

153155
var invocations = mockDataCollectorSettingsBuilder.Invocations.GetEnumerator().ToIEnumerable().ToList();
154156
Assert.AreEqual(invocations.First().Method.Name, nameof(IDataCollectorSettingsBuilder.Initialize));

FineCodeCoverageTests/DataCollectorSettingsBuilder_Tests.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ public void DeleteRunSettings()
3636

3737
private void Initialize(bool runSettingsOnly = false)
3838
{
39-
var mockCoverageProjectSettings = new Mock<IAppOptions>();
40-
mockCoverageProjectSettings.Setup(o => o.RunSettingsOnly).Returns(runSettingsOnly);
41-
dataCollectorSettingsBuilder.Initialize(mockCoverageProjectSettings.Object, existingRunSettingsPath, generatedRunSettingsPath);
39+
dataCollectorSettingsBuilder.Initialize(runSettingsOnly, existingRunSettingsPath, generatedRunSettingsPath);
4240
}
4341

4442
#region arguments
@@ -88,7 +86,7 @@ public void Should_Set_ProjectDll_Quoted_When_WithProjectDll()
8886
[Test]
8987
public void Should_Set_RunSettings_As_Quoted_GeneratedRunSettings_When_Initialize()
9088
{
91-
dataCollectorSettingsBuilder.Initialize(null,".runsettings","generated.runsettings");
89+
dataCollectorSettingsBuilder.Initialize(false,".runsettings","generated.runsettings");
9290
Assert.AreEqual(dataCollectorSettingsBuilder.RunSettings,$"--settings {dataCollectorSettingsBuilder.Quote("generated.runsettings")}");
9391
}
9492

@@ -138,21 +136,22 @@ public void Should_Not_Fallback_To_Options_For_Exclude_If_RunSettingsOnly()
138136
Assert.IsNull(dataCollectorSettingsBuilder.Exclude);
139137
}
140138

141-
[Test]
142-
public void Should_Use_RunSettings_ExcludeByAttribute_If_Present()
139+
[Test] // https://github.com/coverlet-coverage/coverlet/issues/1589
140+
public void Should_Use_RunSettings_ExcludeByAttribute_If_Present_Unqualified()
143141
{
144142
Initialize();
145-
dataCollectorSettingsBuilder.WithExcludeByAttribute(new string[] { "from project" }, "from run settings");
146-
Assert.AreEqual("from run settings", dataCollectorSettingsBuilder.ExcludeByAttribute);
143+
dataCollectorSettingsBuilder.WithExcludeByAttribute(new string[] { "from project" }, "namespace.first,second");
144+
Assert.AreEqual("first,second", dataCollectorSettingsBuilder.ExcludeByAttribute);
147145
}
148146

149147
[Test]
150-
public void Should_Use_Project_ExcludeByAttribute_If_No_RunSettings()
148+
public void Should_Use_Project_ExcludeByAttribute_If_No_RunSettings_Unqualified()
151149
{
152-
dataCollectorSettingsBuilder.WithExcludeByAttribute(new string[] { "first", "second" }, null);
150+
dataCollectorSettingsBuilder.WithExcludeByAttribute(new string[] { "namespace.first", "second" }, null);
153151
Assert.AreEqual(dataCollectorSettingsBuilder.ExcludeByAttribute, "first,second");
154152
}
155153

154+
156155
[Test]
157156
public void Should_Use_Project_ExcludeByAttribute_If_No_RunSettings_Null()
158157
{
@@ -303,7 +302,7 @@ public void Should_Set_Corresponding_Property_For_RunSettings_Only_Elements()
303302
[TestCaseSource(nameof(BuildReturnsSettingsSource))]
304303
public void Should_Return_Dotnet_Test_Settings_When_Build(Action<DataCollectorSettingsBuilder> setUp, string expectedSettings)
305304
{
306-
dataCollectorSettingsBuilder.Initialize(new Mock<IAppOptions>().Object,null, generatedRunSettingsPath);
305+
dataCollectorSettingsBuilder.Initialize(false,null, generatedRunSettingsPath);
307306
setUp(dataCollectorSettingsBuilder);
308307
Assert.AreEqual(dataCollectorSettingsBuilder.Build(), expectedSettings);
309308
}
@@ -336,7 +335,7 @@ public void Should_Generate_RunSettings_When_Builds(Action<DataCollectorSettings
336335
XDocument.Parse(existingRunSettings).Save(existingRunSettingsPath);
337336
}
338337

339-
dataCollectorSettingsBuilder.Initialize(null,existingRunSettings == null ? null : existingRunSettingsPath, generatedRunSettingsPath);
338+
dataCollectorSettingsBuilder.Initialize(false,existingRunSettings == null ? null : existingRunSettingsPath, generatedRunSettingsPath);
340339
dataCollectorSettingsBuilder.Build();
341340

342341

0 commit comments

Comments
 (0)