From 1dc5283fa49f1e5f443055b278eec0b36da3335a Mon Sep 17 00:00:00 2001 From: Simon Ensslen Date: Thu, 15 Aug 2024 13:12:29 +0200 Subject: [PATCH] Improve packagereference vs pacakges.config distinction detection --- NuGetUtility.sln | 21 +++ .../Extensions/ProjectExtensions.cs | 20 +-- .../ReferencedPackageReader.cs | 37 +++-- .../Wrapper/MsBuildWrapper/IProject.cs | 10 +- .../MsBuildWrapper/MsBuildAbstraction.cs | 15 +- .../Wrapper/MsBuildWrapper/ProjectWrapper.cs | 30 ++-- .../Extensions/ProjectExtensionsTest.cs | 93 ++---------- .../ReferencedPackageReaderTest.cs | 19 ++- ...ReferencedPackagesReaderIntegrationTest.cs | 39 ++++- .../EmptyCppProject/EmptyCppProject.vcxproj | 138 ++++++++++++++++++ .../EmptyCppProject.vcxproj.filters | 17 +++ 11 files changed, 282 insertions(+), 157 deletions(-) create mode 100644 tests/targets/EmptyCppProject/EmptyCppProject.vcxproj create mode 100644 tests/targets/EmptyCppProject/EmptyCppProject.vcxproj.filters diff --git a/NuGetUtility.sln b/NuGetUtility.sln index c49ef5ba..deeab385 100644 --- a/NuGetUtility.sln +++ b/NuGetUtility.sln @@ -40,6 +40,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integration", "integration" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectWithReferenceContainingLicenseExpression", "integration\ProjectWithReferenceContainingLicenseExpression\ProjectWithReferenceContainingLicenseExpression.csproj", "{01704839-219A-4CE2-93F4-DB3CB8773DCE}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmptyCppProject", "tests\targets\EmptyCppProject\EmptyCppProject.vcxproj", "{9B107A91-87F9-420C-ADF8-732C77DAFB93}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -247,6 +249,24 @@ Global {01704839-219A-4CE2-93F4-DB3CB8773DCE}.TestWindows|x64.Build.0 = TestWindows|Any CPU {01704839-219A-4CE2-93F4-DB3CB8773DCE}.TestWindows|x86.ActiveCfg = TestWindows|Any CPU {01704839-219A-4CE2-93F4-DB3CB8773DCE}.TestWindows|x86.Build.0 = TestWindows|Any CPU + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Debug|Any CPU.ActiveCfg = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Debug|Any CPU.Build.0 = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Debug|x64.ActiveCfg = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Debug|x64.Build.0 = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Debug|x86.ActiveCfg = Debug|Win32 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Debug|x86.Build.0 = Debug|Win32 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Release|Any CPU.ActiveCfg = Release|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Release|Any CPU.Build.0 = Release|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Release|x64.ActiveCfg = Release|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Release|x64.Build.0 = Release|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Release|x86.ActiveCfg = Release|Win32 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.Release|x86.Build.0 = Release|Win32 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.TestWindows|Any CPU.ActiveCfg = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.TestWindows|Any CPU.Build.0 = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.TestWindows|x64.ActiveCfg = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.TestWindows|x64.Build.0 = Debug|x64 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.TestWindows|x86.ActiveCfg = Debug|Win32 + {9B107A91-87F9-420C-ADF8-732C77DAFB93}.TestWindows|x86.Build.0 = Debug|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -264,6 +284,7 @@ Global {FBA6622A-C9E3-4250-AB79-35F02CAD2419} = {D2AB2D00-1F48-487D-BFE0-99FDB4E071CC} {DE079B9C-B6BA-4D53-8B83-03D3CBD4027F} = {D2AB2D00-1F48-487D-BFE0-99FDB4E071CC} {01704839-219A-4CE2-93F4-DB3CB8773DCE} = {FFB2826C-17A3-4C18-8FFE-A34AB51592F7} + {9B107A91-87F9-420C-ADF8-732C77DAFB93} = {FA92392F-D895-4D1E-A5ED-E6DC3C08223E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {70887D40-0182-4C32-BFA1-B5A02E405F11} diff --git a/src/NuGetUtility/Extensions/ProjectExtensions.cs b/src/NuGetUtility/Extensions/ProjectExtensions.cs index 38b18e93..6904e70c 100644 --- a/src/NuGetUtility/Extensions/ProjectExtensions.cs +++ b/src/NuGetUtility/Extensions/ProjectExtensions.cs @@ -7,34 +7,16 @@ namespace NuGetUtility.Extensions { public static class ProjectExtensions { - private const string PackageReferenceValue = "PackageReference"; private const string PackagesConfigFileName = "packages.config"; - public static bool HasNuGetPackagesReferenced(this IProject project) - { - return (project.GetPackageReferenceCount() > 0) || project.HasPackagesConfigFile(); - } - - public static bool IsPackageReferenceProject(this IProject project) - { - return TargetIsEqualIfSet(project.GetNuGetStyleTag(), PackageReferenceValue) && - TargetIsEqualIfSet(project.GetRestoreStyleTag(), PackageReferenceValue) && - !project.HasPackagesConfigFile(); - } - public static string GetPackagesConfigPath(this IProject project) { return Path.Combine(Path.GetDirectoryName(project.FullPath) ?? string.Empty, PackagesConfigFileName); } - private static bool HasPackagesConfigFile(this IProject project) + public static bool HasPackagesConfigFile(this IProject project) { return project.GetEvaluatedIncludes().Any(include => include?.Equals(PackagesConfigFileName) ?? false); } - - private static bool TargetIsEqualIfSet(string source, string target) - { - return string.IsNullOrEmpty(source) || source.Equals(target); - } } } diff --git a/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs b/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs index 6bf147ed..e71ca6bf 100644 --- a/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs +++ b/src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs @@ -1,6 +1,7 @@ // Licensed to the projects contributors. // The license conditions are provided in the LICENSE file located in the project root +using System.Diagnostics.CodeAnalysis; using NuGetUtility.Extensions; using NuGetUtility.Wrapper.MsBuildWrapper; using NuGetUtility.Wrapper.NuGetWrapper.Packaging.Core; @@ -28,23 +29,28 @@ public IEnumerable GetInstalledPackages(string projectPath, boo { IProject project = _msBuild.GetProject(projectPath); - if (!project.HasNuGetPackagesReferenced() && !includeTransitive) + if (TryGetInstalledPackagesFromAssetsFile(includeTransitive, project, out IEnumerable? dependencies)) { - return Enumerable.Empty(); + return dependencies; } - if (project.IsPackageReferenceProject()) + if (project.HasPackagesConfigFile()) { - return GetInstalledPackagesFromAssetsFile(includeTransitive, project); + return _packagesConfigReader.GetPackages(project); } - return _packagesConfigReader.GetPackages(project); + return Array.Empty(); } - private IEnumerable GetInstalledPackagesFromAssetsFile(bool includeTransitive, - IProject project) + private bool TryGetInstalledPackagesFromAssetsFile(bool includeTransitive, + IProject project, + [NotNullWhen(true)] out IEnumerable? installedPackages) { - ILockFile assetsFile = LoadAssetsFile(project); + installedPackages = null; + if (!TryLoadAssetsFile(project, out ILockFile? assetsFile)) + { + return false; + } var referencedLibraries = new HashSet(); @@ -55,7 +61,8 @@ private IEnumerable GetInstalledPackagesFromAssetsFile(bool inc referencedLibraries.AddRange(referencedLibrariesForTarget); } - return referencedLibraries.Select(r => new PackageIdentity(r.Name, r.Version)); + installedPackages = referencedLibraries.Select(r => new PackageIdentity(r.Name, r.Version)); + return true; } private IEnumerable GetReferencedLibrariesForTarget(IProject project, @@ -102,10 +109,14 @@ private static ITargetFrameworkInformation GetTargetFrameworkInformation(ILockFi } } - private ILockFile LoadAssetsFile(IProject project) + private bool TryLoadAssetsFile(IProject project, [NotNullWhen(true)] out ILockFile? assetsFile) { - string assetsPath = project.GetAssetsPath(); - ILockFile assetsFile = _lockFileFactory.GetFromFile(assetsPath); + if (!project.TryGetAssetsPath(out string assetsPath)) + { + assetsFile = null; + return false; + } + assetsFile = _lockFileFactory.GetFromFile(assetsPath); if (!assetsFile.PackageSpec.IsValid() || !(assetsFile.Targets?.Any() ?? false)) { @@ -113,7 +124,7 @@ private ILockFile LoadAssetsFile(IProject project) $"Failed to validate project assets for project {project.FullPath}"); } - return assetsFile; + return true; } } } diff --git a/src/NuGetUtility/Wrapper/MsBuildWrapper/IProject.cs b/src/NuGetUtility/Wrapper/MsBuildWrapper/IProject.cs index 32bba45e..7f3dbdf1 100644 --- a/src/NuGetUtility/Wrapper/MsBuildWrapper/IProject.cs +++ b/src/NuGetUtility/Wrapper/MsBuildWrapper/IProject.cs @@ -1,19 +1,15 @@ // Licensed to the projects contributors. // The license conditions are provided in the LICENSE file located in the project root +using System.Diagnostics.CodeAnalysis; + namespace NuGetUtility.Wrapper.MsBuildWrapper { public interface IProject { public string FullPath { get; } - string GetAssetsPath(); - - string GetRestoreStyleTag(); - - string GetNuGetStyleTag(); - - int GetPackageReferenceCount(); + bool TryGetAssetsPath([NotNullWhen(true)] out string assetsFile); IEnumerable GetEvaluatedIncludes(); } diff --git a/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs b/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs index e38e20de..1e24eb8e 100644 --- a/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs +++ b/src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs @@ -14,7 +14,9 @@ namespace NuGetUtility.Wrapper.MsBuildWrapper public class MsBuildAbstraction : IMsBuildAbstraction { private const string CollectPackageReferences = "CollectPackageReferences"; - private readonly Dictionary _globalProjectProperties = new(); + private readonly ProjectCollection? _projects; + + private ProjectCollection Projects => _projects ?? InitializeProjectCollection(); public MsBuildAbstraction() { @@ -48,9 +50,7 @@ public IProject GetProject(string projectPath) } #endif - ProjectRootElement rootElement = TryGetProjectRootElement(projectPath); - - var project = new Project(rootElement, _globalProjectProperties, null); + Project project = Projects.LoadProject(projectPath); return new ProjectWrapper(project); } @@ -82,6 +82,11 @@ private static ProjectRootElement TryGetProjectRootElement(string projectPath) } } - protected void AddGlobalProjectProperty(string name, string value) => _globalProjectProperties.Add(name, value); + private static ProjectCollection InitializeProjectCollection() + { + ProjectCollection collection = ProjectCollection.GlobalProjectCollection; + collection.UnloadAllProjects(); + return collection; + } } } diff --git a/src/NuGetUtility/Wrapper/MsBuildWrapper/ProjectWrapper.cs b/src/NuGetUtility/Wrapper/MsBuildWrapper/ProjectWrapper.cs index aa435ff8..e8be3b50 100644 --- a/src/NuGetUtility/Wrapper/MsBuildWrapper/ProjectWrapper.cs +++ b/src/NuGetUtility/Wrapper/MsBuildWrapper/ProjectWrapper.cs @@ -1,16 +1,14 @@ // Licensed to the projects contributors. // The license conditions are provided in the LICENSE file located in the project root +using System.Diagnostics.CodeAnalysis; using Microsoft.Build.Evaluation; namespace NuGetUtility.Wrapper.MsBuildWrapper { internal class ProjectWrapper : IProject { - private const string PackageReferenceTypeTag = "PackageReference"; private const string ProjectAssetsFile = "ProjectAssetsFile"; - private const string RestoreStyleTag = "RestoreProjectStyle"; - private const string NugetStyleTag = "NuGetProjectStyle"; private readonly Project _project; @@ -19,31 +17,21 @@ public ProjectWrapper(Project project) _project = project; } - public string GetAssetsPath() + public bool TryGetAssetsPath([NotNullWhen(true)] out string assetsFile) { - string assetsFile = _project.GetPropertyValue(ProjectAssetsFile); + assetsFile = _project.GetPropertyValue(ProjectAssetsFile); + if (string.IsNullOrEmpty(assetsFile)) + { + return false; + } + if (!File.Exists(assetsFile)) { throw new MsBuildAbstractionException( $"Failed to get the project assets file for project {_project.FullPath} ({assetsFile})"); } - return assetsFile; - } - - public string GetRestoreStyleTag() - { - return _project.GetPropertyValue(RestoreStyleTag); - } - - public string GetNuGetStyleTag() - { - return _project.GetPropertyValue(NugetStyleTag); - } - - public int GetPackageReferenceCount() - { - return _project.GetItems(PackageReferenceTypeTag).Count; + return true; } public IEnumerable GetEvaluatedIncludes() diff --git a/tests/NuGetUtility.Test/Extensions/ProjectExtensionsTest.cs b/tests/NuGetUtility.Test/Extensions/ProjectExtensionsTest.cs index bbe7197e..60f5b4d6 100644 --- a/tests/NuGetUtility.Test/Extensions/ProjectExtensionsTest.cs +++ b/tests/NuGetUtility.Test/Extensions/ProjectExtensionsTest.cs @@ -18,83 +18,7 @@ public void SetUp() private IProject _project = null!; - [Test] - public void HasNugetPackagesReferenced_Should_ReturnTrue_If_PackageReferenceCountIsMoreThanZero( - [Values(1, 50, 999)] int referenceCount) - { - _project.GetPackageReferenceCount().Returns(referenceCount); - - bool result = _project.HasNuGetPackagesReferenced(); - - Assert.That(result, Is.True); - } - - [Test] - public void HasNugetPackagesReferences_Should_ReturnTrue_If_ProjectHasPackagesConfigFileReferenced() - { - _project.GetPackageReferenceCount().Returns(0); - _project.GetEvaluatedIncludes().Returns(new List { "packages.config" }); - - bool result = _project!.HasNuGetPackagesReferenced(); - - Assert.That(result, Is.True); - } - - [Test] - public void - HasNugetPackagesReferenced_Should_ReturnFalse_If_PackageReferenceCountIsZeroOrLess_And_ProjectHasNoPackagesConfigFileReferenced( - [Values(-9999, -50, 0)] int referenceCount) - { - _project.GetPackageReferenceCount().Returns(referenceCount); - _project.GetEvaluatedIncludes().Returns(Enumerable.Empty()); - - bool result = _project!.HasNuGetPackagesReferenced(); - - Assert.That(result, Is.False); - } - - [TestCase(null, null)] - [TestCase("", "")] - [TestCase(null, "PackageReference")] - [TestCase("", "PackageReference")] - [TestCase("PackageReference", null)] - [TestCase("PackageReference", "")] - [TestCase("PackageReference", "PackageReference")] - public void IsPackageReferenceProject_Should_ReturnTrue_If_ProjectIsPackageReferenceProject( - string nugetStyleTag, - string restoreStyleTag) - { - _project.GetNuGetStyleTag().Returns(nugetStyleTag); - _project.GetRestoreStyleTag().Returns(restoreStyleTag); - _project.GetEvaluatedIncludes().Returns(new List { "not-packages.config" }); - - bool result = _project.IsPackageReferenceProject(); - - Assert.That(result, Is.True); - } - - [TestCase("InvalidTag", "InvalidTag", "packages.config")] - [TestCase("InvalidTag", "PackageReference", "packages.config")] - [TestCase("InvalidTag", "InvalidTag", "not-packages.config")] - [TestCase("InvalidTag", "PackageReference", "not-packages.config")] - [TestCase("PackageReference", "InvalidTag", "packages.config")] - [TestCase("PackageReference", "PackageReference", "packages.config")] - [TestCase("PackageReference", "InvalidTag", "not-packages.config")] - public void IsPackageReferenceProject_Should_ReturnFalse_If_ProjectIsNotPackageReferenceProject( - string nugetStyleTag, - string restoreStyleTag, - string evaluatedInclude) - { - _project.GetNuGetStyleTag().Returns(nugetStyleTag); - _project.GetRestoreStyleTag().Returns(restoreStyleTag); - _project.GetEvaluatedIncludes().Returns(new List { evaluatedInclude }); - - bool result = _project.IsPackageReferenceProject(); - - Assert.That(result, Is.False); - } - - [TestCase()] + [TestCase] public void GetPackagesConfigPath_Should_Return_CorrectPath() { string path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString()); @@ -104,5 +28,20 @@ public void GetPackagesConfigPath_Should_Return_CorrectPath() Assert.That(result, Is.EqualTo(Path.Combine(Path.GetDirectoryName(path)!, "packages.config"))); } + + [TestCase(new string?[] { }, false)] + [TestCase(new string?[] { null }, false)] + [TestCase(new string?[] { null, "not-packages.config" }, false)] + [TestCase(new string?[] { "not-packages.config" }, false)] + [TestCase(new string?[] { "packages.config" }, true)] + [TestCase(new string?[] { null, "packages.config" }, true)] + [TestCase(new string?[] { "not-packages.config", "packages.config" }, true)] + [TestCase(new string?[] { null, "not-packages.config", "packages.config" }, true)] + public void HasPackagesConfigFile_Should_Return_Correct_Result(IEnumerable evaluatedIncludes, bool expectation) + { + _project.GetEvaluatedIncludes().Returns(evaluatedIncludes); + + Assert.That(_project.HasPackagesConfigFile(), Is.EqualTo(expectation)); + } } } diff --git a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs index 38cdeee3..1fca7751 100644 --- a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs +++ b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs @@ -37,8 +37,11 @@ public void SetUp() _packageReferencesFromProjectForFramework = new Dictionary(); _msBuild.GetProject(_projectPath).Returns(_projectMock); - _projectMock.GetPackageReferenceCount().Returns(1); - _projectMock.GetAssetsPath().Returns(_assetsFilePath); + _projectMock.TryGetAssetsPath(out Arg.Any()).Returns(args => + { + args[0] = _assetsFilePath; + return true; + }); _projectMock.FullPath.Returns(_projectPath); _lockFileFactory.GetFromFile(_assetsFilePath).Returns(_lockFileMock); _lockFileMock.PackageSpec.Returns(_packageSpecMock); @@ -185,10 +188,10 @@ public void GetInstalledPackages_Should_GetProjectFromPath([Values] bool include } [Test] - public void GetInstalledPackages_Should_LoadAssetsFileFromProject([Values] bool includeTransitive) + public void GetInstalledPackages_Should_TryLoadAssetsFileFromProject([Values] bool includeTransitive) { _uut.GetInstalledPackages(_projectPath, includeTransitive); - _projectMock.Received(1).GetAssetsPath(); + _projectMock.Received(1).TryGetAssetsPath(out Arg.Any()); _lockFileFactory.Received(1).GetFromFile(Arg.Any()); _lockFileFactory.Received(1).GetFromFile(_assetsFilePath); } @@ -223,9 +226,9 @@ public void GetInstalledPackages_Should_ReturnCorrectValues_If_NotIncludingTrans [Test] public void - GetInstalledPackages_Should_ReturnEmptyCollection_When_ProjectHasNoPackageReferences_And_IsNotTransitive() + GetInstalledPackages_Should_ReturnEmptyCollection_If_Cannot_Get_Asset_File_Path_And_Has_No_Packages_Config() { - _projectMock.GetPackageReferenceCount().Returns(0); + _projectMock.TryGetAssetsPath(out Arg.Any()).Returns(false); _projectMock.GetEvaluatedIncludes().Returns(Enumerable.Empty()); IEnumerable result = _uut.GetInstalledPackages(_projectPath, false); @@ -236,7 +239,7 @@ public void public void GetInstalledPackages_Should_Use_PackageGonfigReader_If_ProjectIsPackageConfigProject( [Values] bool includeTransitive) { - _packageSpecMock.IsValid().Returns(false); + _projectMock.TryGetAssetsPath(out Arg.Any()).Returns(false); _projectMock.FullPath.Returns(_projectPath); _projectMock.GetEvaluatedIncludes().Returns(new List { "packages.config" }); @@ -250,7 +253,7 @@ public void GetInstalledPackages_Should_Use_PackageGonfigReader_If_ProjectIsPack public void GetInstalledPackages_Should_ReturnPackagesReturnedBy_PackageGonfigReader_If_ProjectIsPackageConfigProject( [Values] bool includeTransitive) { - _packageSpecMock.IsValid().Returns(false); + _projectMock.TryGetAssetsPath(out Arg.Any()).Returns(false); _projectMock.FullPath.Returns(_projectPath); _projectMock.GetEvaluatedIncludes().Returns(new List { "packages.config" }); PackageIdentity[] expectedPackages = _packageReferencesFromProjectForFramework.First().Value.Select(l => new PackageIdentity(l.PackageName, l.Version!)).ToArray(); diff --git a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs index 0e4be0d3..c4234b71 100644 --- a/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs +++ b/tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackagesReaderIntegrationTest.cs @@ -8,7 +8,7 @@ namespace NuGetUtility.Test.ReferencedPackagesReader { - [TestFixture] + [TestFixture, FixtureLifeCycle(LifeCycle.InstancePerTestCase)] public class ReferencedPackagesReaderIntegrationTest { [SetUp] @@ -94,22 +94,47 @@ public void GetInstalledPackagesShould_ThrowError_PackagesConfigProject() } #if NETFRAMEWORK - [Test] - public void GetInstalledPackagesShould_ReturnPackages_For_NativeCppProject() + [TestCase(true)] + [TestCase(false)] + public void GetInstalledPackagesShould_ReturnPackages_For_NativeCppProject_With_References(bool includeTransitive) { string path = Path.GetFullPath("../../../../targets/SimpleCppProject/SimpleCppProject.vcxproj"); - IEnumerable result = _uut!.GetInstalledPackages(path, false); + IEnumerable result = _uut!.GetInstalledPackages(path, includeTransitive); Assert.That(result.Count, Is.EqualTo(2)); } #else - [Test] - public void GetInstalledPackagesShould_ThrowError_For_PackagesForNativeCppProject() + [TestCase(true)] + [TestCase(false)] + public void GetInstalledPackagesShould_ThrowError_For_PackagesForNativeCppProject_With_References(bool includeTransitive) { string path = Path.GetFullPath("../../../../targets/SimpleCppProject/SimpleCppProject.vcxproj"); - MsBuildAbstractionException? exception = Assert.Throws(() => _uut!.GetInstalledPackages(path, false)); + MsBuildAbstractionException? exception = Assert.Throws(() => _uut!.GetInstalledPackages(path, includeTransitive)); + Assert.That(exception?.Message, Is.EqualTo($"Please use the .net Framework version to analyze c++ projects (Project: {path})")); + } +#endif + +#if NETFRAMEWORK + [TestCase(true)] + [TestCase(false)] + public void GetInstalledPackagesShould_ReturnPackages_For_NativeCppProject_Without_References(bool includeTransitive) + { + string path = Path.GetFullPath("../../../../targets/EmptyCppProject/EmptyCppProject.vcxproj"); + + IEnumerable result = _uut!.GetInstalledPackages(path, includeTransitive); + + Assert.That(result.Count, Is.EqualTo(0)); + } +#else + [TestCase(true)] + [TestCase(false)] + public void GetInstalledPackagesShould_ThrowError_For_PackagesForNativeCppProject_Without_References(bool includeTransitive) + { + string path = Path.GetFullPath("../../../../targets/EmptyCppProject/EmptyCppProject.vcxproj"); + + MsBuildAbstractionException? exception = Assert.Throws(() => _uut!.GetInstalledPackages(path, includeTransitive)); Assert.That(exception?.Message, Is.EqualTo($"Please use the .net Framework version to analyze c++ projects (Project: {path})")); } #endif diff --git a/tests/targets/EmptyCppProject/EmptyCppProject.vcxproj b/tests/targets/EmptyCppProject/EmptyCppProject.vcxproj new file mode 100644 index 00000000..871bfbfa --- /dev/null +++ b/tests/targets/EmptyCppProject/EmptyCppProject.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + 17.0 + Win32Proj + {9b107a91-87f9-420c-adf8-732c77dafb93} + EmptyCppProject + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + diff --git a/tests/targets/EmptyCppProject/EmptyCppProject.vcxproj.filters b/tests/targets/EmptyCppProject/EmptyCppProject.vcxproj.filters new file mode 100644 index 00000000..a8a65633 --- /dev/null +++ b/tests/targets/EmptyCppProject/EmptyCppProject.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + \ No newline at end of file