diff --git a/FineCodeCoverage/FineCodeCoverage.csproj b/FineCodeCoverage/FineCodeCoverage.csproj
index 49d4574d..1ff524ce 100644
--- a/FineCodeCoverage/FineCodeCoverage.csproj
+++ b/FineCodeCoverage/FineCodeCoverage.csproj
@@ -147,9 +147,6 @@
4.1.1
-
- 1.4.1
-
3.11.0
@@ -182,6 +179,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ 16.10.31320.204
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/FineCodeCoverage2022/FineCodeCoverage2022.csproj b/FineCodeCoverage2022/FineCodeCoverage2022.csproj
index a74d9eb6..d734cd3e 100644
--- a/FineCodeCoverage2022/FineCodeCoverage2022.csproj
+++ b/FineCodeCoverage2022/FineCodeCoverage2022.csproj
@@ -146,9 +146,6 @@
4.1.1
-
- 1.4.1
-
4.10.0
@@ -181,6 +178,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ 17.10.40170
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/FineCodeCoverageTests/CoverageProject_Tests.cs b/FineCodeCoverageTests/CoverageProject_Tests.cs
index 7cc1016b..48b96888 100644
--- a/FineCodeCoverageTests/CoverageProject_Tests.cs
+++ b/FineCodeCoverageTests/CoverageProject_Tests.cs
@@ -12,7 +12,7 @@ public class CoverageProject_Tests
[SetUp]
public void SetUp()
{
- coverageProject = new CoverageProject(null, null, null, null, null, false);
+ coverageProject = new CoverageProject(null, null, null, null);
tempProjectFilePath = Path.Combine(Path.GetTempPath(), "testproject.csproj");
coverageProject.ProjectFile = tempProjectFilePath;
}
diff --git a/FineCodeCoverageTests/CoverletConsole_Tests.cs b/FineCodeCoverageTests/CoverletConsole_Tests.cs
index 2cbe7342..62a6b734 100644
--- a/FineCodeCoverageTests/CoverletConsole_Tests.cs
+++ b/FineCodeCoverageTests/CoverletConsole_Tests.cs
@@ -8,7 +8,6 @@
using FineCodeCoverage.Core.Utilities;
using FineCodeCoverage.Engine.Coverlet;
using FineCodeCoverage.Engine.Model;
-using FineCodeCoverage.Engine.OpenCover;
using FineCodeCoverage.Options;
using Moq;
using NUnit.Framework;
@@ -46,8 +45,8 @@ public void Should_Unqualified_Qualified_ExcludeByAttribute()
private Mock SafeMockCoverageProject()
{
var mockCoverageProject = new Mock();
- mockCoverageProject.SetupGet(coverageProject => coverageProject.IncludedReferencedProjects).Returns(new List());
- mockCoverageProject.SetupGet(coverageProject => coverageProject.ExcludedReferencedProjects).Returns(new List());
+ mockCoverageProject.SetupGet(coverageProject => coverageProject.IncludedReferencedProjects).Returns(new List());
+ mockCoverageProject.SetupGet(coverageProject => coverageProject.ExcludedReferencedProjects).Returns(new List());
mockCoverageProject.SetupGet(coverageProject => coverageProject.Settings).Returns(new Mock().Object);
return mockCoverageProject;
}
diff --git a/FineCodeCoverageTests/CoverletDataCollectorUtil_RunAsync_Tests.cs b/FineCodeCoverageTests/CoverletDataCollectorUtil_RunAsync_Tests.cs
index 0aaa407e..537d6192 100644
--- a/FineCodeCoverageTests/CoverletDataCollectorUtil_RunAsync_Tests.cs
+++ b/FineCodeCoverageTests/CoverletDataCollectorUtil_RunAsync_Tests.cs
@@ -36,8 +36,8 @@ public void SetUp()
mockCoverageProject = new Mock();
mockCoverageProject.Setup(cp => cp.Settings).Returns(new Mock().Object);
mockCoverageProject.Setup(cp => cp.CoverageOutputFolder).Returns("");
- mockCoverageProject.Setup(cp => cp.ExcludedReferencedProjects).Returns(new List());
- mockCoverageProject.Setup(cp => cp.IncludedReferencedProjects).Returns(new List());
+ mockCoverageProject.Setup(cp => cp.ExcludedReferencedProjects).Returns(new List());
+ mockCoverageProject.Setup(cp => cp.IncludedReferencedProjects).Returns(new List());
mockRunSettingsCoverletConfiguration = new Mock();
coverletDataCollectorUtil.runSettingsCoverletConfiguration = mockRunSettingsCoverletConfiguration.Object;
coverletDataCollectorUtil.coverageProject = mockCoverageProject.Object;
@@ -76,7 +76,7 @@ public async Task Should_Get_Settings_With_Exclude_From_CoverageProject_And_RunS
var projectExclude = new string[] { "excluded" };
mockCoverageProject.Setup(cp => cp.Settings.Exclude).Returns(projectExclude);
mockCoverageProject.Setup(cp => cp.CoverageOutputFolder).Returns("");
- var referencedExcluded = new List { "referencedExcluded" };
+ var referencedExcluded = new List { new ReferencedProject("","referencedExcluded",true) };
mockCoverageProject.Setup(cp => cp.ExcludedReferencedProjects).Returns(referencedExcluded);
mockRunSettingsCoverletConfiguration.Setup(rsc => rsc.Exclude).Returns("rsexclude");
await coverletDataCollectorUtil.RunAsync(CancellationToken.None);
@@ -86,7 +86,7 @@ public async Task Should_Get_Settings_With_Exclude_From_CoverageProject_And_RunS
[Test]
public async Task Should_Not_Throw_When_Project_Setttings_Exclude_Is_Null_Async()
{
- var referencedExcluded = new List { "referencedExcluded" };
+ var referencedExcluded = new List { new ReferencedProject("", "referencedExcluded", true) };
mockCoverageProject.Setup(cp => cp.ExcludedReferencedProjects).Returns(referencedExcluded);
mockCoverageProject.Setup(cp => cp.CoverageOutputFolder).Returns("");
mockRunSettingsCoverletConfiguration.Setup(rsc => rsc.Exclude).Returns("rsexclude");
diff --git a/FineCodeCoverageTests/Initializer_Tests.cs b/FineCodeCoverageTests/Initializer_Tests.cs
index 08cf04e8..613d081f 100644
--- a/FineCodeCoverageTests/Initializer_Tests.cs
+++ b/FineCodeCoverageTests/Initializer_Tests.cs
@@ -8,6 +8,7 @@
using FineCodeCoverage.Core.Initialization;
using FineCodeCoverage.Engine;
using FineCodeCoverage.Engine.Model;
+using Moq;
using NUnit.Framework;
namespace Test
@@ -50,7 +51,7 @@ public async Task Should_Log_Initializing_When_Initialize_Async()
private async Task InitializeWithExceptionAsync(Action callback = null)
{
var initializeException = new Exception("initialize exception");
- mocker.Setup(a => a.Initialize()).Throws(initializeException);
+ mocker.Setup(fccEngine => fccEngine.Initialize(It.IsAny())).Throws(initializeException);
await initializer.InitializeAsync(CancellationToken.None);
callback?.Invoke(initializeException);
@@ -97,22 +98,18 @@ public async Task Should_Initialize_Dependencies_In_Order_Async()
{
var disposalToken = CancellationToken.None;
List callOrder = new List();
- mocker.GetMock().Setup(cp => cp.Initialize()).Callback(() =>
- {
- callOrder.Add(1);
- });
mocker.GetMock().Setup(engine => engine.Initialize(disposalToken)).Callback(() =>
{
- callOrder.Add(2);
+ callOrder.Add(1);
});
mocker.GetMock().Setup(firstTimeToolWindowOpener => firstTimeToolWindowOpener.OpenIfFirstTimeAsync(disposalToken)).Callback(() =>
{
- callOrder.Add(3);
+ callOrder.Add(2);
});
await initializer.InitializeAsync(disposalToken);
- Assert.AreEqual(new List { 1, 2, 3 }, callOrder);
+ Assert.AreEqual(new List { 1, 2 }, callOrder);
}
}
}
\ No newline at end of file
diff --git a/FineCodeCoverageTests/MsCodeCoverage/MsCodeCoverageRunSettingsService_IsCollecting_Tests.cs b/FineCodeCoverageTests/MsCodeCoverage/MsCodeCoverageRunSettingsService_IsCollecting_Tests.cs
index 423c1140..9573963b 100644
--- a/FineCodeCoverageTests/MsCodeCoverage/MsCodeCoverageRunSettingsService_IsCollecting_Tests.cs
+++ b/FineCodeCoverageTests/MsCodeCoverage/MsCodeCoverageRunSettingsService_IsCollecting_Tests.cs
@@ -215,8 +215,8 @@ public async Task Should_Set_UserRunSettingsProjectDetailsLookup_For_IRunSetting
SetupAppOptionsProvider(RunMsCodeCoverage.IfInRunSettings);
var projectSettings = new Mock().Object;
- var excludedReferencedProjects = new List();
- var includedReferencedProjects = new List();
+ var excludedReferencedProjects = new List();
+ var includedReferencedProjects = new List();
var coverageProjects = new List
{
CreateCoverageProject(null),
@@ -531,8 +531,8 @@ private ICoverageProject CreateCoverageProject(
IAppOptions settings = null,
string coverageOutputFolder = "",
string testDllFile = "",
- List excludedReferencedProjects = null,
- List includedReferencedProjects = null,
+ List excludedReferencedProjects = null,
+ List includedReferencedProjects = null,
string projectFile = ""
)
{
diff --git a/FineCodeCoverageTests/MsCodeCoverage/RunSettingsTemplateReplacementsFactory_Tests.cs b/FineCodeCoverageTests/MsCodeCoverage/RunSettingsTemplateReplacementsFactory_Tests.cs
index 9feac54e..f3315a49 100644
--- a/FineCodeCoverageTests/MsCodeCoverage/RunSettingsTemplateReplacementsFactory_Tests.cs
+++ b/FineCodeCoverageTests/MsCodeCoverage/RunSettingsTemplateReplacementsFactory_Tests.cs
@@ -61,8 +61,8 @@ internal class RunSettingsTemplateReplacementsFactory_UserRunSettings_Tests
private class TestUserRunSettingsProjectDetails : IUserRunSettingsProjectDetails
{
- public List ExcludedReferencedProjects { get; set; }
- public List IncludedReferencedProjects { get; set; }
+ public List ExcludedReferencedProjects { get; set; }
+ public List IncludedReferencedProjects { get; set; }
public string CoverageOutputFolder { get; set; }
public IMsCodeCoverageOptions Settings { get; set; }
public string TestDllFile { get; set; }
@@ -91,8 +91,8 @@ public void Should_Set_The_TestAdapter()
CoverageOutputFolder = "",
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
};
@@ -119,8 +119,8 @@ public void Should_Set_The_ResultsDirectory_To_The_First_OutputFolder(string out
CoverageOutputFolder = outputFolder1,
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
{
@@ -130,8 +130,8 @@ public void Should_Set_The_ResultsDirectory_To_The_First_OutputFolder(string out
CoverageOutputFolder = outputFolder2,
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
{
@@ -182,8 +182,8 @@ TestMsCodeCoverageOptions CreateSettings(string id)
CoverageOutputFolder = "",
TestDllFile = "",
Settings = CreateSettings("1"),
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
{
@@ -193,8 +193,8 @@ TestMsCodeCoverageOptions CreateSettings(string id)
CoverageOutputFolder = "",
TestDllFile = "",
Settings = CreateSettings("2"),
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
{
@@ -247,8 +247,8 @@ public void Should_Add_The_Test_Assembly_Regex_Escaped_To_Module_Excludes_When_I
IncludeTestAssembly = includeTestAssembly1,
ModulePathsExclude = new string[]{ "ModulePathExclude"}
},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
TestDllFile = @"Some\Path1"
}
},
@@ -258,8 +258,8 @@ public void Should_Add_The_Test_Assembly_Regex_Escaped_To_Module_Excludes_When_I
{
CoverageOutputFolder = "",
Settings = new TestMsCodeCoverageOptions{ IncludeTestAssembly = includeTestAssembly2},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
TestDllFile = @"Some\Path2"
}
},
@@ -304,8 +304,8 @@ public void Should_Add_Regexed_IncludedExcluded_Referenced_Projects_To_ModulePat
ModulePathsExclude = new string[] { "ModulePathExclude" },
ModulePathsInclude = new string[] { "ModulePathInclude" }
},
- ExcludedReferencedProjects = new List { "ExcludedReferenced1" },
- IncludedReferencedProjects = new List { "IncludedReferenced1" },
+ ExcludedReferencedProjects = new List { new ReferencedProject("", "ExcludedReferenced1", true) },
+ IncludedReferencedProjects = new List { new ReferencedProject("", "IncludedReferenced1", true) },
}
},
{
@@ -315,18 +315,18 @@ public void Should_Add_Regexed_IncludedExcluded_Referenced_Projects_To_ModulePat
CoverageOutputFolder = "",
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions { IncludeTestAssembly = !included },
- ExcludedReferencedProjects = new List { "ExcludedReferenced2" },
- IncludedReferencedProjects = new List { "IncludedReferenced2" },
+ ExcludedReferencedProjects = new List { new ReferencedProject("", "ExcludedReferenced2", true) },
+ IncludedReferencedProjects = new List { new ReferencedProject("", "IncludedReferenced2", true) },
}
},
};
var projectDetails = userRunSettingsProjectDetailsLookup.Select(kvp => kvp.Value).ToList();
- IEnumerable allReferencedProjects = projectDetails.SelectMany(pd => included ? pd.IncludedReferencedProjects : pd.ExcludedReferencedProjects);
+ IEnumerable allReferencedProjects = projectDetails.SelectMany(pd => included ? pd.IncludedReferencedProjects : pd.ExcludedReferencedProjects);
- string GetExpectedExcludedOrIncludedEscaped(IEnumerable excludedOrIncludedReferenced)
+ string GetExpectedExcludedOrIncludedEscaped(IEnumerable excludedOrIncludedReferenced)
{
- return string.Join("", excludedOrIncludedReferenced.Select(referenced => ModulePathElement(MsCodeCoverageRegex.RegexModuleName(referenced))));
+ return string.Join("", excludedOrIncludedReferenced.Select(referenced => ModulePathElement(MsCodeCoverageRegex.RegexModuleName(referenced.AssemblyName,true))));
}
var expectedExcludes = GetExpectedExcludedOrIncludedEscaped(allReferencedProjects) + ModulePathElement(included ? "ModulePathInclude" : "ModulePathExclude");
@@ -352,8 +352,8 @@ public void Should_Be_Null_TestAdapter_Replacement_When_Null()
CoverageOutputFolder = "",
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
{
@@ -363,8 +363,8 @@ public void Should_Be_Null_TestAdapter_Replacement_When_Null()
CoverageOutputFolder = "",
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
}
};
@@ -394,8 +394,8 @@ public void Should_Be_Disabled_When_All_Projects_Are_Disabled(bool project1Enabl
CoverageOutputFolder = "",
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ Enabled = project1Enabled, IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
},
{
@@ -405,8 +405,8 @@ public void Should_Be_Disabled_When_All_Projects_Are_Disabled(bool project1Enabl
CoverageOutputFolder = "",
TestDllFile = "",
Settings = new TestMsCodeCoverageOptions{ Enabled = project2Enabled, IncludeTestAssembly = true},
- ExcludedReferencedProjects = new List(),
- IncludedReferencedProjects = new List(),
+ ExcludedReferencedProjects = new List(),
+ IncludedReferencedProjects = new List(),
}
}
};
@@ -451,8 +451,8 @@ private ICoverageProject CreateCoverageProject(Action> fu
var mockSettings = new Mock();
mockSettings.Setup(settings => settings.IncludeTestAssembly).Returns(includeTestAssembly);
var mockCoverageProject = new Mock();
- mockCoverageProject.Setup(cp => cp.ExcludedReferencedProjects).Returns(new List());
- mockCoverageProject.Setup(cp => cp.IncludedReferencedProjects).Returns(new List());
+ mockCoverageProject.Setup(cp => cp.ExcludedReferencedProjects).Returns(new List());
+ mockCoverageProject.Setup(cp => cp.IncludedReferencedProjects).Returns(new List());
mockCoverageProject.Setup(cp => cp.TestDllFile).Returns("");
mockCoverageProject.Setup(cp => cp.Settings).Returns(mockSettings.Object);
furtherSetup?.Invoke(mockCoverageProject);
@@ -587,15 +587,15 @@ public void Should_Have_ModulePathsExclude_Replacements_From_ExcludedReferencedP
var coverageProject = CreateCoverageProject(mock =>
{
mock.Setup(cp => cp.Settings).Returns(msCodeCoverageOptions);
- mock.Setup(cp => cp.ExcludedReferencedProjects).Returns(new List
+ mock.Setup(cp => cp.ExcludedReferencedProjects).Returns(new List
{
- "ModuleName"
+ new ReferencedProject("","ModuleName",true)
});
mock.Setup(cp => cp.TestDllFile).Returns(@"Path\To\Test.dll");
});
var replacements = runSettingsTemplateReplacementsFactory.Create(coverageProject, null);
- var expectedModulePathsExclude = $"{ModulePathElement(MsCodeCoverageRegex.RegexModuleName("ModuleName"))}{ModulePathElement(MsCodeCoverageRegex.RegexEscapePath(@"Path\To\Test.dll"))}{ModulePathElement("FromSettings")}";
+ var expectedModulePathsExclude = $"{ModulePathElement(MsCodeCoverageRegex.RegexModuleName("ModuleName", true))}{ModulePathElement(MsCodeCoverageRegex.RegexEscapePath(@"Path\To\Test.dll"))}{ModulePathElement("FromSettings")}";
Assert.AreEqual(expectedModulePathsExclude, replacements.ModulePathsExclude);
}
@@ -611,15 +611,15 @@ public void Should_Have_ModulePathsInclude_Replacements_From_IncludedReferencedP
var coverageProject = CreateCoverageProject(mock =>
{
mock.Setup(cp => cp.Settings).Returns(msCodeCoverageOptions);
- mock.Setup(cp => cp.IncludedReferencedProjects).Returns(new List
+ mock.Setup(cp => cp.IncludedReferencedProjects).Returns(new List
{
- "ModuleName"
+ new ReferencedProject("", "ModuleName", true)
});
mock.Setup(cp => cp.TestDllFile).Returns(@"Path\To\Test.dll");
});
var replacements = runSettingsTemplateReplacementsFactory.Create(coverageProject, null);
- var expectedModulePathsInclude = $"{ModulePathElement(MsCodeCoverageRegex.RegexModuleName("ModuleName"))}{ModulePathElement(MsCodeCoverageRegex.RegexEscapePath(@"Path\To\Test.dll"))}{ModulePathElement("FromSettings")}";
+ var expectedModulePathsInclude = $"{ModulePathElement(MsCodeCoverageRegex.RegexModuleName("ModuleName",true))}{ModulePathElement(MsCodeCoverageRegex.RegexEscapePath(@"Path\To\Test.dll"))}{ModulePathElement("FromSettings")}";
Assert.AreEqual(expectedModulePathsInclude, replacements.ModulePathsInclude);
}
diff --git a/FineCodeCoverageTests/OpenCoverExeArgumentsProvider_Tests.cs b/FineCodeCoverageTests/OpenCoverExeArgumentsProvider_Tests.cs
index 8e242cd3..127eabb4 100644
--- a/FineCodeCoverageTests/OpenCoverExeArgumentsProvider_Tests.cs
+++ b/FineCodeCoverageTests/OpenCoverExeArgumentsProvider_Tests.cs
@@ -222,7 +222,7 @@ public void Should_Safely_Filter_Include_Project_IncludedReferencedProjects_Spac
var openCoverExeArgumentsProvider = new OpenCoverExeArgumentsProvider();
var mockCoverageProject = SafeMockCoverageProject();
mockCoverageProject.Setup(coverageProject => coverageProject.IncludedReferencedProjects)
- .Returns(new List { "Referenced1", "Referenced2" });
+ .Returns(new List { new ReferencedProject("", "Referenced1", true), new ReferencedProject("", "Referenced2", true) });
var arguments = openCoverExeArgumentsProvider.Provide(mockCoverageProject.Object, "");
@@ -241,7 +241,7 @@ public void Should_Safely_Filter_Exclude_Project_ExcludedReferencedProjects_Spac
var openCoverExeArgumentsProvider = new OpenCoverExeArgumentsProvider();
var mockCoverageProject = SafeMockCoverageProject();
mockCoverageProject.Setup(coverageProject => coverageProject.ExcludedReferencedProjects)
- .Returns(new List { "Referenced1", "Referenced2" });
+ .Returns(new List { new ReferencedProject("", "Referenced1", true), new ReferencedProject("", "Referenced2", true) });
var arguments = openCoverExeArgumentsProvider.Provide(mockCoverageProject.Object, "");
@@ -264,8 +264,8 @@ public void Should_Safely_Filter_Exclude_Trimmed_Project_Excludes_Trimmed_Of_Spa
private Mock SafeMockCoverageProject()
{
var mockCoverageProject = new Mock();
- mockCoverageProject.SetupGet(coverageProject => coverageProject.IncludedReferencedProjects).Returns(new List());
- mockCoverageProject.SetupGet(coverageProject => coverageProject.ExcludedReferencedProjects).Returns(new List());
+ mockCoverageProject.SetupGet(coverageProject => coverageProject.IncludedReferencedProjects).Returns(new List());
+ mockCoverageProject.SetupGet(coverageProject => coverageProject.ExcludedReferencedProjects).Returns(new List());
mockCoverageProject.SetupGet(coverageProject => coverageProject.Settings).Returns(new Mock().Object);
return mockCoverageProject;
}
diff --git a/FineCodeCoverageTests/ReferencedProject_Tests.cs b/FineCodeCoverageTests/ReferencedProject_Tests.cs
index 74e5d3bd..9b0c152f 100644
--- a/FineCodeCoverageTests/ReferencedProject_Tests.cs
+++ b/FineCodeCoverageTests/ReferencedProject_Tests.cs
@@ -1,5 +1,5 @@
using System.IO;
-using FineCodeCoverage.Core.Model;
+using FineCodeCoverage.Engine.Model;
using NUnit.Framework;
namespace Test
@@ -24,7 +24,7 @@ public void Should_ExcludeFromCodeCoverage_If_Has_Project_Property_FCCExcludeFro
{
var property = addProperty ? $"<{ReferencedProject.excludeFromCodeCoveragePropertyName}/>" : "";
WriteProperty(property);
- var referencedProject = new ReferencedProject(tempProjectFilePath, "");
+ var referencedProject = new ReferencedProject(tempProjectFilePath, "",true);
Assert.AreEqual(addProperty, referencedProject.ExcludeFromCodeCoverage);
}
diff --git a/SharedProject/Core/Coverlet/Console/CoverletConsoleUtil.cs b/SharedProject/Core/Coverlet/Console/CoverletConsoleUtil.cs
index 148032c4..fe2239c5 100644
--- a/SharedProject/Core/Coverlet/Console/CoverletConsoleUtil.cs
+++ b/SharedProject/Core/Coverlet/Console/CoverletConsoleUtil.cs
@@ -37,7 +37,7 @@ public List GetArguments(ICoverageProject project)
coverletSettings.Add($@"--exclude ""{value.Replace("\"", "\\\"").Trim(' ', '\'')}""");
}
- foreach (var referencedProjectExcludedFromCodeCoverage in project.ExcludedReferencedProjects)
+ foreach (var referencedProjectExcludedFromCodeCoverage in project.ExcludedReferencedProjects.Select(rp => rp.AssemblyName))
{
coverletSettings.Add($@"--exclude ""[{referencedProjectExcludedFromCodeCoverage}]*""");
}
@@ -47,7 +47,7 @@ public List GetArguments(ICoverageProject project)
coverletSettings.Add($@"--include ""{value.Replace("\"", "\\\"").Trim(' ', '\'')}""");
}
- foreach (var includedReferencedProject in project.IncludedReferencedProjects)
+ foreach (var includedReferencedProject in project.IncludedReferencedProjects.Select(rp => rp.AssemblyName))
{
coverletSettings.Add($@"--include ""[{includedReferencedProject}]*""");
}
diff --git a/SharedProject/Core/Coverlet/DataCollector/CoverletDataCollectorUtil.cs b/SharedProject/Core/Coverlet/DataCollector/CoverletDataCollectorUtil.cs
index 44a7a3fd..296b80d9 100644
--- a/SharedProject/Core/Coverlet/DataCollector/CoverletDataCollectorUtil.cs
+++ b/SharedProject/Core/Coverlet/DataCollector/CoverletDataCollectorUtil.cs
@@ -172,7 +172,7 @@ private string GetSettings()
dataCollectorSettingsBuilder
.WithResultsDirectory(coverageProject.CoverageOutputFolder);
- string[] projectExcludes = coverageProject.ExcludedReferencedProjects.Select(erp => $"[{erp}]*").ToArray();
+ string[] projectExcludes = coverageProject.ExcludedReferencedProjects.Select(erp => $"[{erp.AssemblyName}]*").ToArray();
if(coverageProject.Settings.Exclude != null)
{
projectExcludes = projectExcludes.Concat(SanitizeExcludesOrIncludes(coverageProject.Settings.Exclude)).ToArray();
@@ -190,7 +190,7 @@ private string GetSettings()
SanitizeExcludesOrIncludes(coverageProject.Settings.ExcludeByAttribute),
runSettingsCoverletConfiguration.ExcludeByAttribute);
- string[] projectIncludes = coverageProject.IncludedReferencedProjects.Select(irp => $"[{irp}]*").ToArray();
+ string[] projectIncludes = coverageProject.IncludedReferencedProjects.Select(irp => $"[{irp.AssemblyName}]*").ToArray();
if(coverageProject.Settings.Include != null)
{
projectIncludes = projectIncludes.Concat(SanitizeExcludesOrIncludes(coverageProject.Settings.Include)).ToArray();
diff --git a/SharedProject/Core/Initialization/Initializer.cs b/SharedProject/Core/Initialization/Initializer.cs
index 5ed0fb54..341b421c 100644
--- a/SharedProject/Core/Initialization/Initializer.cs
+++ b/SharedProject/Core/Initialization/Initializer.cs
@@ -3,7 +3,6 @@
using System.Threading;
using System.Threading.Tasks;
using FineCodeCoverage.Engine;
-using FineCodeCoverage.Engine.Model;
namespace FineCodeCoverage.Core.Initialization
{
@@ -15,7 +14,6 @@ internal class Initializer : IInitializer
{
private readonly IFCCEngine fccEngine;
private readonly ILogger logger;
- private readonly ICoverageProjectFactory coverageProjectFactory;
private readonly IFirstTimeToolWindowOpener firstTimeToolWindowOpener;
public InitializeStatus InitializeStatus { get; set; } = InitializeStatus.Initializing;
@@ -25,7 +23,6 @@ internal class Initializer : IInitializer
public Initializer(
IFCCEngine fccEngine,
ILogger logger,
- ICoverageProjectFactory coverageProjectFactory,
IFirstTimeToolWindowOpener firstTimeToolWindowOpener,
[ImportMany]
IInitializable[] initializables
@@ -33,7 +30,6 @@ IInitializable[] initializables
{
this.fccEngine = fccEngine;
this.logger = logger;
- this.coverageProjectFactory = coverageProjectFactory;
this.firstTimeToolWindowOpener = firstTimeToolWindowOpener;
}
public async Task InitializeAsync(CancellationToken cancellationToken)
@@ -44,7 +40,6 @@ public async Task InitializeAsync(CancellationToken cancellationToken)
logger.Log($"Initializing");
cancellationToken.ThrowIfCancellationRequested();
- coverageProjectFactory.Initialize();
fccEngine.Initialize(cancellationToken);
diff --git a/SharedProject/Core/Model/CoverageProject.cs b/SharedProject/Core/Model/CoverageProject.cs
index d867bf58..cdc025b3 100644
--- a/SharedProject/Core/Model/CoverageProject.cs
+++ b/SharedProject/Core/Model/CoverageProject.cs
@@ -5,15 +5,10 @@
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;
using System.Xml.Linq;
-using System.Xml.XPath;
-using EnvDTE;
-using FineCodeCoverage.Core.Model;
using FineCodeCoverage.Core.Utilities;
using FineCodeCoverage.Engine.FileSynchronization;
using FineCodeCoverage.Options;
using Microsoft.VisualStudio.Shell;
-using Microsoft.CodeAnalysis.MSBuild;
-using EnvDTE80;
using System.Threading;
namespace FineCodeCoverage.Engine.Model
@@ -22,10 +17,8 @@ internal class CoverageProject : ICoverageProject
{
private readonly IAppOptionsProvider appOptionsProvider;
private readonly IFileSynchronizationUtil fileSynchronizationUtil;
- private readonly ILogger logger;
- private readonly DTE2 dte;
private readonly ICoverageProjectSettingsManager settingsManager;
- private readonly bool canUseMsBuildWorkspace;
+ private readonly IReferencedProjectsHelper referencedProjectsHelper;
private XElement projectFileXElement;
private IAppOptions settings;
private string targetFramework;
@@ -63,17 +56,13 @@ private string BuildOutputPath
public CoverageProject(
IAppOptionsProvider appOptionsProvider,
IFileSynchronizationUtil fileSynchronizationUtil,
- ILogger logger,
- DTE2 dte,
ICoverageProjectSettingsManager settingsManager,
- bool canUseMsBuildWorkspace)
+ IReferencedProjectsHelper referencedProjectsHelper)
{
this.appOptionsProvider = appOptionsProvider;
this.fileSynchronizationUtil = fileSynchronizationUtil;
- this.logger = logger;
- this.dte = dte;
this.settingsManager = settingsManager;
- this.canUseMsBuildWorkspace = canUseMsBuildWorkspace;
+ this.referencedProjectsHelper = referencedProjectsHelper;
}
public string FCCOutputFolder => Path.Combine(ProjectOutputFolder, fccFolderName);
@@ -164,8 +153,8 @@ public XElement ProjectFileXElement
}
}
- public List ExcludedReferencedProjects { get; } = new List();
- public List IncludedReferencedProjects { get; set; } = new List();
+ public List ExcludedReferencedProjects { get; } = new List();
+ public List IncludedReferencedProjects { get; set; } = new List();
public bool Is64Bit { get; set; }
public string RunSettingsFile { get; set; }
public bool IsDotNetFramework { get; private set; }
@@ -234,180 +223,30 @@ public async Task PrepareForCoverageA
private async Task SetIncludedExcludedReferencedProjectsAsync()
{
- List referencedProjects = await GetReferencedProjectsAsync();
+ var referencedProjects = await referencedProjectsHelper.GetReferencedProjectsAsync(ProjectFile,() => ProjectFileXElement);
SetExcludedReferencedProjects(referencedProjects);
SetIncludedReferencedProjects(referencedProjects);
}
- private void SetIncludedReferencedProjects(List referencedProjects)
+ private void SetIncludedReferencedProjects(List referencedProjects)
{
if (Settings.IncludeReferencedProjects)
{
- IncludedReferencedProjects = referencedProjects.Select(referencedProject => referencedProject.AssemblyName).ToList();
+ IncludedReferencedProjects = new List(referencedProjects);
}
}
- private void SetExcludedReferencedProjects(List referencedProjects)
+ private void SetExcludedReferencedProjects(List referencedProjects)
{
foreach (var referencedProject in referencedProjects)
{
if (referencedProject.ExcludeFromCodeCoverage)
{
- ExcludedReferencedProjects.Add(referencedProject.AssemblyName);
+ ExcludedReferencedProjects.Add(referencedProject);
}
}
}
- private async Task> GetReferencedProjectsAsync()
- {
- List referencedProjects = await SafeGetReferencedProjectsFromDteAsync() ?? await GetReferencedProjectsFromProjectFileAsync();
- return referencedProjects;
- }
-
- private async Task> SafeGetReferencedProjectsFromDteAsync()
- {
- try
- {
- return await GetReferencedProjectsFromDteAsync();
- }
- catch (Exception) { }
- return null;
- }
-
- private async Task GetProjectAsync()
- {
- await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
- var project = dte.Solution.Projects.Cast().FirstOrDefault(p =>
- {
- ThreadHelper.ThrowIfNotOnUIThread();
- //have to try here as unloaded projects will throw
- var projectFullName = "";
- try
- {
- projectFullName = p.FullName;
- }
- catch { }
- return projectFullName == ProjectFile;
- });
-
- if (project == null)
- {
- return null;
- }
-
- return project.Object as VSLangProj.VSProject;
- }
-
- private IEnumerable GetReferencedSourceProjects(VSLangProj.VSProject vsproject)
- {
- return vsproject.References.Cast().Where(r => r.SourceProject != null)
- .Select(r => r.SourceProject);
- }
-
- private async Task GetAssemblyNameAsync(Project project)
- {
- await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
- var assNameProperty = project.Properties.Cast().FirstOrDefault(p =>
- {
-#pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread
- return p.Name == "AssemblyName";
-#pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread
- });
- return assNameProperty?.Value.ToString() ?? project.Name;
- }
- private async Task GetReferencedProjectAsync(Project project)
- {
- await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
- var assemblyName = await GetAssemblyNameAsync(project);
- return new ReferencedProject(project.FullName, assemblyName);
- }
-
- private async Task> GetReferencedProjectsFromDteAsync()
- {
- var vsproject = await GetProjectAsync();
-
- if (vsproject == null)
- {
- return null;
- }
- return (await Task.WhenAll(GetReferencedSourceProjects(vsproject).Select(GetReferencedProjectAsync))).ToList();
-
- }
-
- private async Task> SafeGetReferencedProjectsWithDesignTimeBuildAsync()
- {
- try
- {
- return await GetReferencedProjectsWithDesignTimeBuildWorkerAsync();
- }
- catch (Exception exception)
- {
- logger.Log("Unable to get referenced projects with design time build", exception);
- }
- return new List();
- }
-
- private async Task> GetReferencedProjectsWithDesignTimeBuildWorkerAsync()
- {
- var msBuildWorkspace = MSBuildWorkspace.Create();
- var project = await msBuildWorkspace.OpenProjectAsync(ProjectFile);
- var solution = msBuildWorkspace.CurrentSolution;
- return project.ProjectReferences.Select(
- pr => solution.Projects.First(p => p.Id == pr.ProjectId).FilePath)
- .Where(path => path != null)
- .Select(path => new ReferencedProject(path)).ToList();
- }
-
- private async Task> GetReferencedProjectsFromProjectFileAsync()
- {
- /*
-
-
-
-
- */
-
-
- var xprojectReferences = ProjectFileXElement.XPathSelectElements($"/ItemGroup/ProjectReference[@Include]");
- var requiresDesignTimeBuild = false;
- List referencedProjectFiles = new List();
- foreach (var xprojectReference in xprojectReferences)
- {
- var referencedProjectProjectFile = xprojectReference.Attribute("Include").Value;
- if (referencedProjectProjectFile.Contains("$("))
- {
- if (canUseMsBuildWorkspace)
- {
- requiresDesignTimeBuild = true;
- break;
- }
- else
- {
- logger.Log($"Cannot exclude referenced project {referencedProjectProjectFile} of {ProjectFile} with {ReferencedProject.excludeFromCodeCoveragePropertyName}. Cannot use MSBuildWorkspace");
- }
-
- }
- else
- {
- if (!Path.IsPathRooted(referencedProjectProjectFile))
- {
- referencedProjectProjectFile = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(ProjectFile), referencedProjectProjectFile));
- }
- referencedProjectFiles.Add(referencedProjectProjectFile);
- }
-
- }
-
- if (requiresDesignTimeBuild)
- {
- var referencedProjects = await SafeGetReferencedProjectsWithDesignTimeBuildAsync();
- return referencedProjects;
-
- }
-
- return referencedProjectFiles.Select(referencedProjectProjectFile => new ReferencedProject(referencedProjectProjectFile)).ToList();
- }
-
private void EnsureDirectories()
{
EnsureFccDirectory();
diff --git a/SharedProject/Core/Model/CoverageProjectFactory.cs b/SharedProject/Core/Model/CoverageProjectFactory.cs
index 6d958cdd..f0b1eb77 100644
--- a/SharedProject/Core/Model/CoverageProjectFactory.cs
+++ b/SharedProject/Core/Model/CoverageProjectFactory.cs
@@ -1,13 +1,6 @@
-using System;
-using System.ComponentModel.Composition;
-using System.Threading.Tasks;
-using EnvDTE;
-using EnvDTE80;
+using System.ComponentModel.Composition;
using FineCodeCoverage.Engine.FileSynchronization;
using FineCodeCoverage.Options;
-using Microsoft.Build.Locator;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Threading;
namespace FineCodeCoverage.Engine.Model
{
@@ -16,54 +9,30 @@ internal class CoverageProjectFactory : ICoverageProjectFactory
{
private readonly IAppOptionsProvider appOptionsProvider;
private readonly IFileSynchronizationUtil fileSynchronizationUtil;
- private readonly ILogger logger;
private readonly ICoverageProjectSettingsManager coverageProjectSettingsManager;
- private bool canUseMsBuildWorkspace = true;
- private readonly AsyncLazy lazyDTE2;
+ private readonly IReferencedProjectsHelper referencedProjectsHelper;
[ImportingConstructor]
public CoverageProjectFactory(
IAppOptionsProvider appOptionsProvider,
IFileSynchronizationUtil fileSynchronizationUtil,
- ILogger logger,
ICoverageProjectSettingsManager coverageProjectSettingsManager,
- [Import(typeof(SVsServiceProvider))]
- IServiceProvider serviceProvider)
+ IReferencedProjectsHelper referencedProjectsHelper
+ )
{
this.appOptionsProvider = appOptionsProvider;
this.fileSynchronizationUtil = fileSynchronizationUtil;
- this.logger = logger;
this.coverageProjectSettingsManager = coverageProjectSettingsManager;
-
- lazyDTE2 = new AsyncLazy(async () =>
- {
- await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
- return (DTE2)serviceProvider.GetService(typeof(DTE));
- },ThreadHelper.JoinableTaskFactory);
+ this.referencedProjectsHelper = referencedProjectsHelper;
}
- public void Initialize()
- {
- try
- {
- MSBuildLocator.RegisterDefaults();
- }
- catch
- {
- canUseMsBuildWorkspace = false;
- }
- }
- public async Task CreateAsync()
+ public ICoverageProject Create()
{
- var dte2 = await lazyDTE2.GetValueAsync();
-
return new CoverageProject(
appOptionsProvider,
fileSynchronizationUtil,
- logger,
- dte2,
coverageProjectSettingsManager,
- canUseMsBuildWorkspace);
+ referencedProjectsHelper);
}
}
}
diff --git a/SharedProject/Core/Model/ICoverageProject.cs b/SharedProject/Core/Model/ICoverageProject.cs
index 67bad4cc..01821f3d 100644
--- a/SharedProject/Core/Model/ICoverageProject.cs
+++ b/SharedProject/Core/Model/ICoverageProject.cs
@@ -12,8 +12,8 @@ internal interface ICoverageProject
string CoverageOutputFile { get; }
string CoverageOutputFolder { get; set; }
string DefaultCoverageOutputFolder { get; }
- List ExcludedReferencedProjects { get; }
- List IncludedReferencedProjects { get; }
+ List ExcludedReferencedProjects { get; }
+ List IncludedReferencedProjects { get; }
string FailureDescription { get; set; }
string FailureStage { get; set; }
bool HasFailed { get; }
diff --git a/SharedProject/Core/Model/ICoverageProjectFactory.cs b/SharedProject/Core/Model/ICoverageProjectFactory.cs
index ef54b62c..a9328ccb 100644
--- a/SharedProject/Core/Model/ICoverageProjectFactory.cs
+++ b/SharedProject/Core/Model/ICoverageProjectFactory.cs
@@ -1,10 +1,7 @@
-using System.Threading.Tasks;
-
-namespace FineCodeCoverage.Engine.Model
+namespace FineCodeCoverage.Engine.Model
{
internal interface ICoverageProjectFactory
{
- Task CreateAsync();
- void Initialize();
+ ICoverageProject Create();
}
}
diff --git a/SharedProject/Core/Model/ReferencedProjects/CPPReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/CPPReferencedProjectsHelper.cs
new file mode 100644
index 00000000..35ea4f7d
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/CPPReferencedProjectsHelper.cs
@@ -0,0 +1,73 @@
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.VCProjectEngine;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ [Export(typeof(ICPPReferencedProjectsHelper))]
+ internal class CPPReferencedProjectsHelper : ICPPReferencedProjectsHelper
+ {
+ private VCProject GetReferencedVCProject(VCProjectReference projectReference)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return projectReference.ReferencedProject as VCProject
+ ?? (projectReference.ReferencedProject as EnvDTE.Project)?.Object as VCProject;
+ }
+
+ private bool? IsDll(VCProject vcProject)
+ {
+ if (!(vcProject.Configurations is IEnumerable configurations))
+ return null;
+
+ var configuration = configurations.Cast().FirstOrDefault();
+ if (configuration == null)
+ return null;
+
+ bool isDll = configuration.ConfigurationType == ConfigurationTypes.typeDynamicLibrary;
+ bool isApplication = configuration.ConfigurationType == ConfigurationTypes.typeApplication;
+ if (!isDll && !isApplication)
+ return null;
+ return isDll;
+ }
+
+ private string GetCPPProjectReferenceProjectFilePath(VCProjectReference reference)
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ var vsReference = reference.Reference as VSLangProj.Reference;
+ var sourceProject = vsReference.SourceProject;
+ return sourceProject.FileName;
+ }
+
+ public async Task> GetInstrumentableReferencedProjectsAsync(VCProject cppProject)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+
+ if (!(cppProject.VCReferences is IEnumerable vcReferences))
+ return null;
+
+ return vcReferences
+ .OfType()
+ .Select(reference =>
+ {
+ var referencedProject = GetReferencedVCProject(reference);
+
+ var isDll = IsDll(referencedProject);
+ return isDll.HasValue ?(IExcludableReferencedProject) new ReferencedProject(
+ GetCPPProjectReferenceProjectFilePath(reference),
+ Path.GetFileNameWithoutExtension(reference.FullPath),
+ isDll.Value
+ )
+ : null;
+ })
+ .Where(p => p != null)
+ .ToList();
+ }
+
+ }
+
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/DotNetReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/DotNetReferencedProjectsHelper.cs
new file mode 100644
index 00000000..18933374
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/DotNetReferencedProjectsHelper.cs
@@ -0,0 +1,52 @@
+using EnvDTE;
+using Microsoft.VisualStudio.Shell;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Threading.Tasks;
+using VSLangProj;
+using VSLangProj80;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ [Export(typeof(IDotNetReferencedProjectsHelper))]
+ internal class DotNetReferencedProjectsHelper : IDotNetReferencedProjectsHelper
+ {
+ public async Task> GetReferencedProjectsAsync(VSProject vsProject)
+ {
+ var referencedProjects = (await System.Threading.Tasks.Task.WhenAll(GetReferencedSourceProjects(vsProject).Select(GetReferencedProjectAsync))).ToList();
+ return new List(referencedProjects);
+ }
+
+ private IEnumerable GetReferencedSourceProjects(VSProject vsproject)
+ {
+ return vsproject.References.Cast().Where(r => r.SourceProject != null)
+ .Select(r => r.SourceProject);
+ }
+
+ private async Task GetReferencedProjectAsync(Project project)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ var (assemblyName, isDll) = await GetAssemblyNameIsDllAsync(project);
+ return new ReferencedProject(project.FullName, assemblyName, isDll);
+ }
+
+ private async Task<(string, bool)> GetAssemblyNameIsDllAsync(Project project)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ var assemblyNameProperty = project.Properties.Item(nameof(ProjectProperties3.AssemblyName));
+ var assemblyName = assemblyNameProperty?.Value.ToString() ?? project.Name;
+ var outputTypeProperty = project.Properties.Item(nameof(ProjectProperties3.OutputType));
+ var isDll = true;
+ if (outputTypeProperty != null)
+ {
+ prjOutputType po = (prjOutputType)Enum.Parse(typeof(prjOutputType), outputTypeProperty.Value.ToString());
+ isDll = po == prjOutputType.prjOutputTypeLibrary;
+ }
+
+ return (assemblyName, isDll);
+ }
+ }
+
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/ICPPReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/ICPPReferencedProjectsHelper.cs
new file mode 100644
index 00000000..d2020811
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/ICPPReferencedProjectsHelper.cs
@@ -0,0 +1,12 @@
+using Microsoft.VisualStudio.VCProjectEngine;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ internal interface ICPPReferencedProjectsHelper
+ {
+ Task> GetInstrumentableReferencedProjectsAsync(VCProject cppProject);
+ }
+
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/IDotNetReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/IDotNetReferencedProjectsHelper.cs
new file mode 100644
index 00000000..fe7e57af
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/IDotNetReferencedProjectsHelper.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using VSLangProj;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ internal interface IDotNetReferencedProjectsHelper
+ {
+ Task> GetReferencedProjectsAsync(VSProject vsProject);
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/IExcludableReferencedProject.cs b/SharedProject/Core/Model/ReferencedProjects/IExcludableReferencedProject.cs
new file mode 100644
index 00000000..6bd33618
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/IExcludableReferencedProject.cs
@@ -0,0 +1,7 @@
+namespace FineCodeCoverage.Engine.Model
+{
+ interface IExcludableReferencedProject : IReferencedProject
+ {
+ bool ExcludeFromCodeCoverage { get; }
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/IProjectFileReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/IProjectFileReferencedProjectsHelper.cs
new file mode 100644
index 00000000..068d4c84
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/IProjectFileReferencedProjectsHelper.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using System.Xml.Linq;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ interface IProjectFileReferencedProjectsHelper
+ {
+ List GetReferencedProjects(string projectFile, XElement projectFileXElement);
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/IReferencedProject.cs b/SharedProject/Core/Model/ReferencedProjects/IReferencedProject.cs
new file mode 100644
index 00000000..42172682
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/IReferencedProject.cs
@@ -0,0 +1,8 @@
+namespace FineCodeCoverage.Engine.Model
+{
+ internal interface IReferencedProject
+ {
+ string AssemblyName { get; }
+ bool IsDll { get; }
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/IReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/IReferencedProjectsHelper.cs
new file mode 100644
index 00000000..446b6902
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/IReferencedProjectsHelper.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ internal interface IReferencedProjectsHelper
+ {
+
+ // todo - should not need ms build workspaces or parsing the project file
+ Task> GetReferencedProjectsAsync(
+ string projectFile, Func projectFileXElementProvider);
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/IVsApiReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/IVsApiReferencedProjectsHelper.cs
new file mode 100644
index 00000000..5f894195
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/IVsApiReferencedProjectsHelper.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ internal interface IVsApiReferencedProjectsHelper
+ {
+ Task> GetReferencedProjectsAsync(string projectFile);
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/ProjectFileReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/ProjectFileReferencedProjectsHelper.cs
new file mode 100644
index 00000000..567a3082
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/ProjectFileReferencedProjectsHelper.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using System.Xml.XPath;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ // todo - remove this ? Should not be necessary
+ [Export(typeof(IProjectFileReferencedProjectsHelper))]
+ internal class ProjectFileReferencedProjectsHelper : IProjectFileReferencedProjectsHelper
+
+ {
+ private readonly ILogger logger;
+
+ [ImportingConstructor]
+ public ProjectFileReferencedProjectsHelper(ILogger logger)
+ {
+ this.logger = logger;
+ }
+
+ public List GetReferencedProjects(
+ string projectFile, XElement projectFileXElement
+ )
+ {
+ /*
+
+
+
+
+ */
+
+ var xprojectReferences = projectFileXElement.XPathSelectElements($"/ItemGroup/ProjectReference[@Include]");
+ var requiresDesignTimeBuild = false;
+ List referencedProjectFiles = new List();
+ foreach (var xprojectReference in xprojectReferences)
+ {
+ var referencedProjectProjectFile = xprojectReference.Attribute("Include").Value;
+ if (referencedProjectProjectFile.Contains("$("))
+ {
+ logger.Log($"Cannot exclude referenced project {referencedProjectProjectFile} of {projectFile} with {ReferencedProject.excludeFromCodeCoveragePropertyName}. Cannot use MSBuildWorkspace");
+ }
+ else
+ {
+ if (!Path.IsPathRooted(referencedProjectProjectFile))
+ {
+ referencedProjectProjectFile = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectFile), referencedProjectProjectFile));
+ }
+ referencedProjectFiles.Add(referencedProjectProjectFile);
+ }
+
+ }
+
+ if (requiresDesignTimeBuild)
+ {
+ return new List();
+
+ }
+
+ return referencedProjectFiles.Select(referencedProjectProjectFile => (IExcludableReferencedProject)new ReferencedProject(referencedProjectProjectFile)).ToList();
+ }
+ }
+}
diff --git a/SharedProject/Core/Model/ReferencedProject.cs b/SharedProject/Core/Model/ReferencedProjects/ReferencedProject.cs
similarity index 68%
rename from SharedProject/Core/Model/ReferencedProject.cs
rename to SharedProject/Core/Model/ReferencedProjects/ReferencedProject.cs
index 882e3010..32eaeb74 100644
--- a/SharedProject/Core/Model/ReferencedProject.cs
+++ b/SharedProject/Core/Model/ReferencedProjects/ReferencedProject.cs
@@ -3,18 +3,21 @@
using System.Xml.XPath;
using FineCodeCoverage.Core.Utilities;
-namespace FineCodeCoverage.Core.Model
+namespace FineCodeCoverage.Engine.Model
{
- internal class ReferencedProject
- {
+ internal class ReferencedProject : IExcludableReferencedProject
+ {
internal const string excludeFromCodeCoveragePropertyName = "FCCExcludeFromCodeCoverage";
private readonly string projectPath;
+
- public ReferencedProject(string projectPath,string assemblyName)
+ public ReferencedProject(string projectPath,string assemblyName,bool isDll)
{
- AssemblyName = assemblyName;
this.projectPath = projectPath;
+ AssemblyName = assemblyName;
+ IsDll = isDll;
}
+
public ReferencedProject(string projectPath)
{
this.projectPath = projectPath;
@@ -43,8 +46,17 @@ private string GetAssemblyName(XElement projectFileXElement, string fallbackName
return result;
}
- public string AssemblyName { get; private set; }
- public bool ExcludeFromCodeCoverage
+ public string AssemblyName { get; }
+
+ public bool IsDll { get; } = true;
+
+ /*
+ Annoyingly by allowing and not true
+ it is not possible to use IVsBuildPropertyStorage.
+ Todo - consider breaking change to true
+ Given that purpose is for dotnet framework.....
+ */
+ public bool ExcludeFromCodeCoverage
{
get
{
diff --git a/SharedProject/Core/Model/ReferencedProjects/ReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/ReferencedProjectsHelper.cs
new file mode 100644
index 00000000..134fa97d
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/ReferencedProjectsHelper.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace FineCodeCoverage.Engine.Model
+{
+ [Export(typeof(IReferencedProjectsHelper))]
+ internal class ReferencedProjectsHelper : IReferencedProjectsHelper
+ {
+ private readonly IVsApiReferencedProjectsHelper vsApiReferencedProjectsHelper;
+ private readonly IProjectFileReferencedProjectsHelper projectFileReferencedProjectsHelper;
+ private string projectFile { get; set; }
+ private Func projectFileXElementProvider;
+
+ [ImportingConstructor]
+ public ReferencedProjectsHelper(
+ IVsApiReferencedProjectsHelper vsApiReferencedProjectsHelper,
+ IProjectFileReferencedProjectsHelper projectFileReferencedProjectsHelper
+ )
+ {
+ this.vsApiReferencedProjectsHelper = vsApiReferencedProjectsHelper;
+ this.projectFileReferencedProjectsHelper = projectFileReferencedProjectsHelper;
+ }
+
+ public async Task> GetReferencedProjectsAsync(string projectFile, Func projectFileXElementProvider)
+ {
+ this.projectFileXElementProvider = projectFileXElementProvider;
+ this.projectFile = projectFile;
+ var referencedProjects = await GetReferencedProjectsAsync();
+ return new List(referencedProjects);
+ }
+
+ private async Task> GetReferencedProjectsAsync()
+ {
+ return await SafeGetReferencedProjectsFromVSApiAsync() ?? projectFileReferencedProjectsHelper.GetReferencedProjects(projectFile, projectFileXElementProvider());
+ }
+
+ private async Task> SafeGetReferencedProjectsFromVSApiAsync()
+ {
+ try
+ {
+ return await vsApiReferencedProjectsHelper.GetReferencedProjectsAsync(projectFile);
+ }
+ catch (Exception) { }
+ return null;
+ }
+ }
+
+}
diff --git a/SharedProject/Core/Model/ReferencedProjects/VsApiReferencedProjectsHelper.cs b/SharedProject/Core/Model/ReferencedProjects/VsApiReferencedProjectsHelper.cs
new file mode 100644
index 00000000..f0991049
--- /dev/null
+++ b/SharedProject/Core/Model/ReferencedProjects/VsApiReferencedProjectsHelper.cs
@@ -0,0 +1,84 @@
+using EnvDTE;
+using EnvDTE80;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Threading;
+using Microsoft.VisualStudio.VCProjectEngine;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Threading.Tasks;
+using VSLangProj;
+
+namespace FineCodeCoverage.Engine.Model
+{
+
+ [Export(typeof(IVsApiReferencedProjectsHelper))]
+ internal class VsApiReferencedProjectsHelper : IVsApiReferencedProjectsHelper
+ {
+ private readonly ICPPReferencedProjectsHelper cppReferencedProjectsHelper;
+ private readonly IDotNetReferencedProjectsHelper dotNetReferencedProjectsHelper;
+ private AsyncLazy lazyDTE2;
+
+ [ImportingConstructor]
+ public VsApiReferencedProjectsHelper(
+ [Import(typeof(SVsServiceProvider))]
+ IServiceProvider serviceProvider,
+ ICPPReferencedProjectsHelper cppReferencedProjectsHelper,
+ IDotNetReferencedProjectsHelper dotNetReferencedProjectsHelper
+ )
+ {
+ lazyDTE2 = new AsyncLazy(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ return (DTE2)serviceProvider.GetService(typeof(DTE));
+ }, ThreadHelper.JoinableTaskFactory);
+ this.cppReferencedProjectsHelper = cppReferencedProjectsHelper;
+ this.dotNetReferencedProjectsHelper = dotNetReferencedProjectsHelper;
+ }
+ public async Task> GetReferencedProjectsAsync(string projectFile)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ var project = await GetProjectAsync(projectFile);
+
+ if (project == null)
+ {
+ return null;
+ }
+
+ var cppProject = project.Object as VCProject;
+ if (cppProject != null)
+ {
+ return await cppReferencedProjectsHelper.GetInstrumentableReferencedProjectsAsync(cppProject);
+ }
+
+ var vsProject = project.Object as VSProject;
+ if (vsProject != null)
+ {
+ return await dotNetReferencedProjectsHelper.GetReferencedProjectsAsync(vsProject);
+ }
+
+ return null;
+ }
+
+ private async Task GetProjectAsync(string projectFile)
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ var dte2 = await lazyDTE2.GetValueAsync();
+ // note that cannot do dte.Solution.Projects.Item(ProjectFile) - fails when dots in path
+ return dte2.Solution.Projects.Cast().FirstOrDefault(p =>
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ //have to try here as unloaded projects will throw
+ var projectFullName = "";
+ try
+ {
+ projectFullName = p.FullName;
+ }
+ catch { }
+ return projectFullName == projectFile;
+ });
+ }
+ }
+
+}
diff --git a/SharedProject/Core/MsTestPlatform/CodeCoverage/IUserRunSettingsProjectDetails.cs b/SharedProject/Core/MsTestPlatform/CodeCoverage/IUserRunSettingsProjectDetails.cs
index a4df082e..a39925b1 100644
--- a/SharedProject/Core/MsTestPlatform/CodeCoverage/IUserRunSettingsProjectDetails.cs
+++ b/SharedProject/Core/MsTestPlatform/CodeCoverage/IUserRunSettingsProjectDetails.cs
@@ -1,12 +1,13 @@
-using FineCodeCoverage.Options;
+using FineCodeCoverage.Engine.Model;
+using FineCodeCoverage.Options;
using System.Collections.Generic;
namespace FineCodeCoverage.Engine.MsTestPlatform.CodeCoverage
{
internal interface IUserRunSettingsProjectDetails
{
- List ExcludedReferencedProjects { get; set; }
- List IncludedReferencedProjects { get; set; }
+ List ExcludedReferencedProjects { get; set; }
+ List IncludedReferencedProjects { get; set; }
string CoverageOutputFolder { get; set; }
IMsCodeCoverageOptions Settings { get; set; }
string TestDllFile { get; set; }
diff --git a/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRegex.cs b/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRegex.cs
index 2301c13c..41c44ae0 100644
--- a/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRegex.cs
+++ b/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRegex.cs
@@ -7,9 +7,15 @@ public static string RegexEscapePath(string path)
return path.Replace(@"\", @"\\");
}
- public static string RegexModuleName(string moduleName)
+ public static string RegexModuleName(string moduleName, bool isDll)
+ {
+ var extensionMatch = isDll ? "dll" : "(dll|exe)";
+ return $".*\\\\{EscapeDots(moduleName)}\\.{extensionMatch}$";
+ }
+
+ private static string EscapeDots(string moduleName)
{
- return $".*\\\\{moduleName}.dll$";
+ return moduleName.Replace(".", @"\.");
}
}
diff --git a/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRunSettingsService.cs b/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRunSettingsService.cs
index cf137bce..5729169b 100644
--- a/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRunSettingsService.cs
+++ b/SharedProject/Core/MsTestPlatform/CodeCoverage/MsCodeCoverageRunSettingsService.cs
@@ -29,8 +29,8 @@ private class UserRunSettingsProjectDetails : IUserRunSettingsProjectDetails
public IMsCodeCoverageOptions Settings { get; set; }
public string CoverageOutputFolder { get; set; }
public string TestDllFile { get; set; }
- public List ExcludedReferencedProjects { get; set; }
- public List IncludedReferencedProjects { get; set; }
+ public List ExcludedReferencedProjects { get; set; }
+ public List IncludedReferencedProjects { get; set; }
}
private class CoverageProjectsByType
{
diff --git a/SharedProject/Core/MsTestPlatform/CodeCoverage/RunSettingsTemplateReplacementsFactory.cs b/SharedProject/Core/MsTestPlatform/CodeCoverage/RunSettingsTemplateReplacementsFactory.cs
index 30bf0633..84aecedf 100644
--- a/SharedProject/Core/MsTestPlatform/CodeCoverage/RunSettingsTemplateReplacementsFactory.cs
+++ b/SharedProject/Core/MsTestPlatform/CodeCoverage/RunSettingsTemplateReplacementsFactory.cs
@@ -1,5 +1,4 @@
-using FineCodeCoverage.Core.Model;
-using FineCodeCoverage.Engine.Model;
+using FineCodeCoverage.Engine.Model;
using FineCodeCoverage.Options;
using Microsoft.VisualStudio.TestWindow.Extensibility;
using System;
@@ -160,14 +159,14 @@ public IRunSettingsTemplateReplacements Create(
}
private IEnumerable GetAdditionalModulePaths(
- IEnumerable referencedProjects,
+ IEnumerable referencedProjects,
string testDllFile,
bool includeTestAssembly,
bool isInclude
)
{
var additionalReferenced = referencedProjects.Select(
- rp => MsCodeCoverageRegex.RegexModuleName(rp));
+ rp => MsCodeCoverageRegex.RegexModuleName(rp.AssemblyName,rp.IsDll));
if(includeTestAssembly == isInclude)
{
additionalReferenced = additionalReferenced.Append(MsCodeCoverageRegex.RegexEscapePath(testDllFile));
diff --git a/SharedProject/Core/MsTestPlatform/TestingPlatform/DisableTestingPlatformServerCapabilityGlobalPropertiesProvider.cs b/SharedProject/Core/MsTestPlatform/TestingPlatform/DisableTestingPlatformServerCapabilityGlobalPropertiesProvider.cs
index 32aedfdf..1c74e4a1 100644
--- a/SharedProject/Core/MsTestPlatform/TestingPlatform/DisableTestingPlatformServerCapabilityGlobalPropertiesProvider.cs
+++ b/SharedProject/Core/MsTestPlatform/TestingPlatform/DisableTestingPlatformServerCapabilityGlobalPropertiesProvider.cs
@@ -55,7 +55,7 @@ ICoverageProjectSettingsManager coverageProjectSettingsManager
{
// todo - ICoverageProjectSettingsManager.GetSettingsAsync parameter
// to change to what it actually needs
- coverageProject = new CoverageProject(appOptionsProvider, null, null, null, coverageProjectSettingsManager, false)
+ coverageProject = new CoverageProject(appOptionsProvider, null, coverageProjectSettingsManager, null)
{
Id = projectGuid,
ProjectFile = unconfiguredProject.FullPath
diff --git a/SharedProject/Core/OpenCover/OpenCoverExeArgumentsProvider.cs b/SharedProject/Core/OpenCover/OpenCoverExeArgumentsProvider.cs
index 55a06918..785e2531 100644
--- a/SharedProject/Core/OpenCover/OpenCoverExeArgumentsProvider.cs
+++ b/SharedProject/Core/OpenCover/OpenCoverExeArgumentsProvider.cs
@@ -25,13 +25,13 @@ internal class OpenCoverExeArgumentsProvider : IOpenCoverExeArgumentsProvider
private enum Delimiter { Semicolon, Space}
private void AddFilter(ICoverageProject project, List opencoverSettings)
{
- var includedModules = project.IncludedReferencedProjects.ToList();
+ var includedModules = project.IncludedReferencedProjects.Select(rp => rp.AssemblyName).ToList();
if (project.Settings.IncludeTestAssembly)
{
includedModules.Add(project.ProjectName);
}
var includeFilters = GetExcludesOrIncludes(project.Settings.Include, includedModules, true);
- var excludeFilters = GetExcludesOrIncludes(project.Settings.Exclude, project.ExcludedReferencedProjects,false);
+ var excludeFilters = GetExcludesOrIncludes(project.Settings.Exclude, project.ExcludedReferencedProjects.Select(rp => rp.AssemblyName), false);
AddIncludeAllIfExcludingWithoutIncludes();
var filters = includeFilters.Concat(excludeFilters).ToList();
SafeAddToSettingsDelimitedIfAny(opencoverSettings, "filter", filters, Delimiter.Space);
diff --git a/SharedProject/Impl/TestContainerDiscovery/TestOperation.cs b/SharedProject/Impl/TestContainerDiscovery/TestOperation.cs
index 3a16d71b..3b061be8 100644
--- a/SharedProject/Impl/TestContainerDiscovery/TestOperation.cs
+++ b/SharedProject/Impl/TestContainerDiscovery/TestOperation.cs
@@ -34,7 +34,7 @@ private async Task> GetCoverageProjectsAsync(TestConfigur
List coverageProjects = new List();
foreach (var container in testContainers)
{
- var project = await coverageProjectFactory.CreateAsync();
+ var project = coverageProjectFactory.Create();
coverageProjects.Add(project);
project.ProjectName = container.ProjectName;
project.TestDllFile = container.Source;
diff --git a/SharedProject/Output/Directory.Build.props b/SharedProject/Output/Directory.Build.props
deleted file mode 100644
index 2df4bf32..00000000
--- a/SharedProject/Output/Directory.Build.props
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/SharedProject/SharedProject.projitems b/SharedProject/SharedProject.projitems
index 582ce406..99505aa7 100644
--- a/SharedProject/SharedProject.projitems
+++ b/SharedProject/SharedProject.projitems
@@ -79,18 +79,30 @@
+
+
+
+
+
+
+
+
+
+
-
+
+
+
@@ -443,10 +455,10 @@
-
+