diff --git a/src/Cake.Cli.Tests/VerifyConfig.cs b/src/Cake.Cli.Tests/VerifyConfig.cs index a28a9cb467..9946ee2346 100644 --- a/src/Cake.Cli.Tests/VerifyConfig.cs +++ b/src/Cake.Cli.Tests/VerifyConfig.cs @@ -14,7 +14,10 @@ public static class VerifyConfig [ModuleInitializer] public static void Init() { - DerivePathInfo(Expectations.Initialize); - VerifyDiffPlex.Initialize(OutputType.Compact); + if (!VerifyDiffPlex.Initialized) + { + VerifyDiffPlex.Initialize(OutputType.Compact); + DerivePathInfo(Expectations.Initialize); + } } } \ No newline at end of file diff --git a/src/Cake.Common.Tests/Cake.Common.Tests.csproj b/src/Cake.Common.Tests/Cake.Common.Tests.csproj index 495523babc..84c82340e6 100644 --- a/src/Cake.Common.Tests/Cake.Common.Tests.csproj +++ b/src/Cake.Common.Tests/Cake.Common.Tests.csproj @@ -3,6 +3,7 @@ Cake.Common.Tests true true + enable @@ -17,6 +18,9 @@ + + + all @@ -48,4 +52,8 @@ + + + + \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Folders.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Folders.verified.txt new file mode 100644 index 0000000000..06946dbfe5 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Folders.verified.txt @@ -0,0 +1,72 @@ +{ + Version: Format Version 12.00, + VisualStudioVersion: 14.0.25123.0, + MinimumVisualStudioVersion: 10.0.40219.1, + Projects: [ + { + Items: [ + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2 + } + ], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + }, + { + Items: [ + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2 + } + ], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + }, + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_7, + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_2, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects.verified.txt new file mode 100644 index 0000000000..06946dbfe5 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects.verified.txt @@ -0,0 +1,72 @@ +{ + Version: Format Version 12.00, + VisualStudioVersion: 14.0.25123.0, + MinimumVisualStudioVersion: 10.0.40219.1, + Projects: [ + { + Items: [ + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2 + } + ], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + }, + { + Items: [ + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2 + } + ], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + }, + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_7, + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_2, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects_With_Absolute_Path.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects_With_Absolute_Path.verified.txt new file mode 100644 index 0000000000..68e19a45fc --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects_With_Absolute_Path.verified.txt @@ -0,0 +1,14 @@ +{ + Version: Format Version 12.00, + VisualStudioVersion: 16.0.31702.278, + MinimumVisualStudioVersion: 10.0.40219.1, + Projects: [ + { + Id: Guid_1, + Name: dummy, + Path: C:/project/dummy/src/dummy/dummy.csproj, + Type: Guid_2, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects_With_Empty_Lines.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects_With_Empty_Lines.verified.txt new file mode 100644 index 0000000000..06946dbfe5 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Projects_With_Empty_Lines.verified.txt @@ -0,0 +1,72 @@ +{ + Version: Format Version 12.00, + VisualStudioVersion: 14.0.25123.0, + MinimumVisualStudioVersion: 10.0.40219.1, + Projects: [ + { + Items: [ + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2 + } + ], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + }, + { + Items: [ + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2 + } + ], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + }, + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_7, + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_2, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Relation_Between_Project_And_Folder.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Relation_Between_Project_And_Folder.verified.txt new file mode 100644 index 0000000000..06946dbfe5 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSln.Should_Properly_Parse_Relation_Between_Project_And_Folder.verified.txt @@ -0,0 +1,72 @@ +{ + Version: Format Version 12.00, + VisualStudioVersion: 14.0.25123.0, + MinimumVisualStudioVersion: 10.0.40219.1, + Projects: [ + { + Items: [ + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2 + } + ], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + }, + { + Items: [ + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2 + } + ], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + }, + { + Id: Guid_1, + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_3, + Name: src, + Path: /Working/src, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_5, + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: Guid_6, + Name: test, + Path: /Working/test, + Type: Guid_4, + Parent: null + } + }, + { + Id: Guid_7, + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_2, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Folders.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Folders.verified.txt new file mode 100644 index 0000000000..53421f1f50 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Folders.verified.txt @@ -0,0 +1,72 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Items: [ + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1 + } + ], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + } + }, + { + Items: [ + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1 + } + ], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + } + }, + { + Id: , + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_1, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects.verified.txt new file mode 100644 index 0000000000..53421f1f50 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects.verified.txt @@ -0,0 +1,72 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Items: [ + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1 + } + ], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + } + }, + { + Items: [ + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1 + } + ], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + } + }, + { + Id: , + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_1, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Absolute_Path.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Absolute_Path.verified.txt new file mode 100644 index 0000000000..1c24bdfc2f --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Absolute_Path.verified.txt @@ -0,0 +1,14 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Id: , + Name: dummy, + Path: C:/project/dummy/src/dummy/dummy.csproj, + Type: Guid_1, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Different_Type_Id.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Different_Type_Id.verified.txt new file mode 100644 index 0000000000..d5050fbcdd --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Different_Type_Id.verified.txt @@ -0,0 +1,14 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Id: , + Name: WebApplication, + Path: /Working/WebApplication/WebApplication.csproj, + Type: Guid_1, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Empty_Lines.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Empty_Lines.verified.txt new file mode 100644 index 0000000000..53421f1f50 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Projects_With_Empty_Lines.verified.txt @@ -0,0 +1,72 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Items: [ + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1 + } + ], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + } + }, + { + Items: [ + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1 + } + ], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + } + }, + { + Id: , + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_1, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Relation_Between_Project_And_Folder.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Relation_Between_Project_And_Folder.verified.txt new file mode 100644 index 0000000000..53421f1f50 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Relation_Between_Project_And_Folder.verified.txt @@ -0,0 +1,72 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Items: [ + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1 + } + ], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy, + Path: /Working/src/dummy/dummy.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: src, + Path: /Working/src, + Type: Guid_2, + Parent: null + } + }, + { + Items: [ + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1 + } + ], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + }, + { + Id: , + Name: dummy.Tests, + Path: /Working/test/dummy.Tests/dummy.Tests.csproj, + Type: Guid_1, + Parent: { + Items: [], + Id: , + Name: test, + Path: /Working/test, + Type: Guid_2, + Parent: null + } + }, + { + Id: , + Name: executable, + Path: /Working/executable/executable.csproj, + Type: Guid_1, + Parent: null + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Solution_With_Nested_Solution_Folders.verified.txt b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Solution_With_Nested_Solution_Folders.verified.txt new file mode 100644 index 0000000000..bdd23783d5 --- /dev/null +++ b/src/Cake.Common.Tests/Expectations/SolutionParserTests.TheParseMethodForSlnx.Should_Properly_Parse_Solution_With_Nested_Solution_Folders.verified.txt @@ -0,0 +1,44 @@ +{ + Version: , + VisualStudioVersion: , + MinimumVisualStudioVersion: , + Projects: [ + { + Items: [], + Id: , + Name: SolutionFolder1, + Path: /Working/SolutionFolder1, + Type: Guid_1, + Parent: null + }, + { + Items: [ + { + Id: , + Name: ClassLibraryNestedSolutionFolder, + Path: /Working/ClassLibraryNestedSolutionFolder/ClassLibraryNestedSolutionFolder.csproj, + Type: Guid_2 + } + ], + Id: , + Name: NestedSolutionFolder, + Path: /Working/SolutionFolder1/NestedSolutionFolder, + Type: Guid_1, + Parent: null + }, + { + Id: , + Name: ClassLibraryNestedSolutionFolder, + Path: /Working/ClassLibraryNestedSolutionFolder/ClassLibraryNestedSolutionFolder.csproj, + Type: Guid_2, + Parent: { + Items: [], + Id: , + Name: NestedSolutionFolder, + Path: /Working/SolutionFolder1/NestedSolutionFolder, + Type: Guid_1, + Parent: null + } + } + ] +} \ No newline at end of file diff --git a/src/Cake.Common.Tests/Fixtures/Solution/SolutionParserFixture.cs b/src/Cake.Common.Tests/Fixtures/Solution/SolutionParserFixture.cs index cc8a0b265f..b42294d100 100644 --- a/src/Cake.Common.Tests/Fixtures/Solution/SolutionParserFixture.cs +++ b/src/Cake.Common.Tests/Fixtures/Solution/SolutionParserFixture.cs @@ -26,5 +26,11 @@ public FilePath WithSolutionFile(string slnContent) var file = FileSystem.CreateFile("/Working/dummySolution.sln").SetContent(slnContent); return file.Path; } + + public FilePath WithXmlSolutionFile(string slnxContent) + { + var file = FileSystem.CreateFile("/Working/dummySolution.slnx").SetContent(slnxContent); + return file.Path; + } } } \ No newline at end of file diff --git a/src/Cake.Common.Tests/Properties/Resources.Designer.cs b/src/Cake.Common.Tests/Properties/Resources.Designer.cs index c82f75cde0..6c66f8bfc9 100644 --- a/src/Cake.Common.Tests/Properties/Resources.Designer.cs +++ b/src/Cake.Common.Tests/Properties/Resources.Designer.cs @@ -1,7 +1,6 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -216,14 +215,14 @@ public static string DupFinderReportWithDuplicates { /// /// Looks up a localized string similar to //------------------------------------------------------------------------------ - ///// <auto-generated> - ///// This code was generated by a tool. - ///// Runtime Version:4.0.30319.42000 - ///// - ///// Changes to this file may cause incorrect behavior and will be lost if - ///// the code is regenerated. - ///// </auto-generated> - /////------------------------------------------------------------------------------ + /// // <auto-generated> + /// // This code was generated by a tool. + /// // Runtime Version:4.0.30319.42000 + /// // + /// // Changes to this file may cause incorrect behavior and will be lost if + /// // the code is regenerated. + /// // </auto-generated> + /// //------------------------------------------------------------------------------ /// ///using System; ///using System.Reflection; @@ -283,8 +282,8 @@ public static string InspectCodeReportWithViolations { /// Looks up a localized string similar to using System.Reflection; ///using System.Runtime.CompilerServices; /// - ///// Information about this assembly is defined by the following attributes. - ///// Change them to the values specific to your project. + /// // Information about this assembly is defined by the following attributes. + /// // Change them to the values specific to your project. /// ///[assembly: AssemblyTitle ("MonoDevelopAssemblyTitle")] ///[assembly: AssemblyDescription ("MonoDevelopAssemblyDescription")] @@ -328,7 +327,7 @@ public static string Nuspec_ContentFiles { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_FrameworkAssemblies { get { @@ -347,7 +346,7 @@ public static string Nuspec_FrameworkAssemblies { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_License { get { @@ -366,7 +365,7 @@ public static string Nuspec_License { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_Metadata { get { @@ -405,7 +404,7 @@ public static string Nuspec_Metadata_PackWithTargetFrameworkDependencies { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_Metadata_WithDependencies { get { @@ -424,10 +423,10 @@ public static string Nuspec_Metadata_WithDependencies { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> + /// <icon>images\icon.png</icon> /// <iconUrl>https://icon.com</iconUrl> /// <requireLicenseAcceptance>true</requireLicenseAcceptance> - /// <developmentDependency>true</developmentDependency> - /// <descriptio [rest of string was truncated]";. + /// <developmentDependency>true</devel [rest of string was truncated]";. /// public static string Nuspec_Metadata_WithoutNamespaces { get { @@ -446,10 +445,10 @@ public static string Nuspec_Metadata_WithoutNamespaces { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> + /// <icon>images\icon.png</icon> /// <iconUrl>https://icon.com</iconUrl> /// <requireLicenseAcceptance>true</requireLicenseAcceptance> - /// <developmentDependency>true</developmentDependency> - /// <descriptio [rest of string was truncated]";. + /// <developmentDependency>true</devel [rest of string was truncated]";. /// public static string Nuspec_Metadata_WithoutNamespaces_WithDependencies { get { @@ -468,10 +467,10 @@ public static string Nuspec_Metadata_WithoutNamespaces_WithDependencies { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> + /// <icon>images\icon.png</icon> /// <iconUrl>https://icon.com</iconUrl> /// <requireLicenseAcceptance>true</requireLicenseAcceptance> - /// <developmentDependency>true</developmentDependency> - /// <descriptio [rest of string was truncated]";. + /// <developmentDependency>true</devel [rest of string was truncated]";. /// public static string Nuspec_Metadata_WithoutNamespaces_WithTargetFramworkDependencies { get { @@ -490,7 +489,7 @@ public static string Nuspec_Metadata_WithoutNamespaces_WithTargetFramworkDepende /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_Metadata_WithTargetFrameworkDependencies { get { @@ -562,7 +561,7 @@ public static string Nuspec_NoMetadataValues_WithoutNamespaces { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_PackageTypes { get { @@ -598,7 +597,7 @@ public static string Nuspec_ProjectFile { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_References { get { @@ -617,7 +616,7 @@ public static string Nuspec_References { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_References_WithTargetFramework { get { @@ -636,7 +635,7 @@ public static string Nuspec_References_WithTargetFramework { /// <owners>Owner #1,Owner #2</owners> /// <licenseUrl>https://license.com</licenseUrl> /// <projectUrl>https://project.com</projectUrl> - /// <iconUr [rest of string was truncated]";. + /// <icon>i [rest of string was truncated]";. /// public static string Nuspec_Repository { get { @@ -660,7 +659,7 @@ public static string Solution_WithProjectsAndFolders { return ResourceManager.GetString("Solution_WithProjectsAndFolders", resourceCulture); } } - + /// /// Looks up a localized string similar to Microsoft Visual Studio Solution File, Format Version 12.00 ///# Visual Studio 14 @@ -698,6 +697,94 @@ public static string Solution_WithProjectUsingAbsolutePath { } } + /// + /// Looks up a localized string similar to <Solution> + /// <Folder Name="/SolutionFolder1/"> + /// </Folder> + /// <Folder Name="/SolutionFolder1/NestedSolutionFolder/"> + /// <Project Path="ClassLibraryNestedSolutionFolder/ClassLibraryNestedSolutionFolder.csproj" /> + /// </Folder> + ///</Solution> + ///. + /// + public static string SolutionXml_WithNestedSolutionFolders { + get { + return ResourceManager.GetString("SolutionXml_WithNestedSolutionFolders", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <Solution> + /// <Folder Name="/src/"> + /// <Project Path="src/dummy/dummy.csproj" /> + /// </Folder> + /// <Folder Name="/test/"> + /// <Project Path="test/dummy.Tests/dummy.Tests.csproj" /> + /// </Folder> + /// <Project Path="executable/executable.csproj" /> + ///</Solution> + ///. + /// + public static string SolutionXml_WithProjectsAndFolders { + get { + return ResourceManager.GetString("SolutionXml_WithProjectsAndFolders", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <Solution> + /// <Folder Name="/src/"> + /// <Project Path="src/dummy/dummy.csproj" /> + /// </Folder> + /// + /// + /// + /// <Folder Name="/test/"> + /// <Project Path="test/dummy.Tests/dummy.Tests.csproj" /> + /// </Folder> + /// + /// + /// + /// <Project Path="executable/executable.csproj" /> + /// + /// + /// + /// + ///</Solution> + ///. + /// + public static string SolutionXml_WithProjectsAndFoldersAndAdditionalLines { + get { + return ResourceManager.GetString("SolutionXml_WithProjectsAndFoldersAndAdditionalLines", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <Solution> + /// <Project Path="C:/project/dummy/src/dummy/dummy.csproj" /> + ///</Solution> + ///. + /// + public static string SolutionXml_WithProjectUsingAbsolutePath { + get { + return ResourceManager.GetString("SolutionXml_WithProjectUsingAbsolutePath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <Solution> + /// <Project Path="WebApplication/WebApplication.csproj" Type="e6fdf86b-f3d1-11d4-8576-0002a516ece8"> + /// <Platform Project="AnyCPU" /> + /// </Project> + ///</Solution> + ///. + /// + public static string SolutionXml_WithProjectWithDifferentTypeId { + get { + return ResourceManager.GetString("SolutionXml_WithProjectWithDifferentTypeId", resourceCulture); + } + } + /// /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" standalone="no"?> ///<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> @@ -750,8 +837,8 @@ public static string TeamCity_Runner_Properties_Xml { /// Looks up a localized string similar to using System.Reflection; ///using System.Runtime.CompilerServices; /// - ///// Information about this assembly is defined by the following attributes. - ///// Change them to the values specific to your project. + /// // Information about this assembly is defined by the following attributes. + /// // Change them to the values specific to your project. /// ///[assembly: AssemblyTitle("VisualStudioAssemblyTitle")] ///[assembly: AssemblyDescription("VisualStudioAssemblyDescription")] diff --git a/src/Cake.Common.Tests/Properties/Resources.resx b/src/Cake.Common.Tests/Properties/Resources.resx index 69d086648b..730da8f4a0 100644 --- a/src/Cake.Common.Tests/Properties/Resources.resx +++ b/src/Cake.Common.Tests/Properties/Resources.resx @@ -1501,4 +1501,62 @@ EndGlobal </xsl:template> </xsl:stylesheet> + + <Solution> + <Folder Name="/src/"> + <Project Path="src/dummy/dummy.csproj" /> + </Folder> + <Folder Name="/test/"> + <Project Path="test/dummy.Tests/dummy.Tests.csproj" /> + </Folder> + <Project Path="executable/executable.csproj" /> +</Solution> + + + + <Solution> + <Folder Name="/src/"> + <Project Path="src/dummy/dummy.csproj" /> + </Folder> + + + + <Folder Name="/test/"> + <Project Path="test/dummy.Tests/dummy.Tests.csproj" /> + </Folder> + + + + <Project Path="executable/executable.csproj" /> + + + + +</Solution> + + + + <Solution> + <Project Path="C:/project/dummy/src/dummy/dummy.csproj" /> +</Solution> + + + + <Solution> + <Project Path="WebApplication/WebApplication.csproj" Type="e6fdf86b-f3d1-11d4-8576-0002a516ece8"> + <Platform Project="AnyCPU" /> + </Project> +</Solution> + + + + <Solution> + <Folder Name="/SolutionFolder1/"> + </Folder> + <Folder Name="/SolutionFolder1/NestedSolutionFolder/"> + <Project Path="ClassLibraryNestedSolutionFolder/ClassLibraryNestedSolutionFolder.csproj" /> + </Folder> +</Solution> + + \ No newline at end of file diff --git a/src/Cake.Common.Tests/Unit/Solution/SolutionParserTests.cs b/src/Cake.Common.Tests/Unit/Solution/SolutionParserTests.cs index ab18f8bc71..0197b469f2 100644 --- a/src/Cake.Common.Tests/Unit/Solution/SolutionParserTests.cs +++ b/src/Cake.Common.Tests/Unit/Solution/SolutionParserTests.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Linq; using Cake.Common.Solution; using Cake.Common.Tests.Fixtures.Solution; using Cake.Common.Tests.Properties; -using Xunit; namespace Cake.Common.Tests.Unit.Solution { @@ -37,7 +35,8 @@ public void Should_Throw_If_Environment_Is_Null() AssertEx.IsArgumentNullException(result, "environment"); } } - public sealed class TheParseMethod + + public sealed class TheParseMethodForSln { [Fact] public void Should_Throw_If_SolutionPath_Is_Null() @@ -54,7 +53,7 @@ public void Should_Throw_If_SolutionPath_Is_Null() } [Fact] - public void Should_Properly_Parse_Projects() + public async Task Should_Properly_Parse_Projects() { // Given var fixture = new SolutionParserFixture(); @@ -65,15 +64,11 @@ public void Should_Properly_Parse_Projects() var result = solutionParser.Parse(slnFilePath); // Then - Assert.NotNull(result); - Assert.NotNull(result.Projects); - Assert.Equal(5, result.Projects.Count); - var onlyProjects = result.Projects.Where(x => !(x is SolutionFolder)).ToList(); - Assert.Equal(3, onlyProjects.Count); + await Verify(result); } [Fact] - public void Should_Properly_Parse_Folders() + public async Task Should_Properly_Parse_Folders() { // Given var fixture = new SolutionParserFixture(); @@ -84,14 +79,11 @@ public void Should_Properly_Parse_Folders() var result = solutionParser.Parse(slnFilePath); // Then - Assert.NotNull(result); - Assert.NotNull(result.Projects); - var folders = result.Projects.OfType().ToList(); - Assert.Equal(2, folders.Count); + await Verify(result); } [Fact] - public void Should_Properly_Parse_Relation_Between_Project_And_Folder() + public async Task Should_Properly_Parse_Relation_Between_Project_And_Folder() { // Given var fixture = new SolutionParserFixture(); @@ -102,18 +94,11 @@ public void Should_Properly_Parse_Relation_Between_Project_And_Folder() var result = solutionParser.Parse(slnFilePath); // Then - Assert.NotNull(result); - Assert.NotNull(result.Projects); - var folders = result.Projects.OfType().ToList(); - var srcFolder = folders.First(x => x.Name == "src"); - Assert.Single(srcFolder.Items); - var dummyProject = result.Projects.First(x => x.Name == "dummy"); - Assert.Contains(dummyProject, srcFolder.Items); - Assert.Equal(srcFolder, dummyProject.Parent); + await Verify(result); } [Fact] - public void Should_Properly_Parse_Projects_With_Empty_Lines() + public async Task Should_Properly_Parse_Projects_With_Empty_Lines() { // Given var fixture = new SolutionParserFixture(); @@ -124,15 +109,11 @@ public void Should_Properly_Parse_Projects_With_Empty_Lines() var result = solutionParser.Parse(slnFilePath); // Then - Assert.NotNull(result); - Assert.NotNull(result.Projects); - Assert.Equal(5, result.Projects.Count); - var onlyProjects = result.Projects.Where(x => !(x is SolutionFolder)).ToList(); - Assert.Equal(3, onlyProjects.Count); + await Verify(result); } [Fact] - public void Should_Properly_Parse_Projects_With_Absolute_Path() + public async Task Should_Properly_Parse_Projects_With_Absolute_Path() { // Given var fixture = new SolutionParserFixture(); @@ -143,11 +124,115 @@ public void Should_Properly_Parse_Projects_With_Absolute_Path() var result = solutionParser.Parse(slnFilePath); // Then - Assert.NotNull(result); - Assert.NotNull(result.Projects); - Assert.Single(result.Projects); - var onlyProjects = result.Projects.Where(x => !(x is SolutionFolder)).ToList(); - Assert.Single(onlyProjects); + await Verify(result); + } + } + + public sealed class TheParseMethodForSlnx + { + [Fact] + public async Task Should_Properly_Parse_Projects() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithProjectsAndFolders); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); + } + + [Fact] + public async Task Should_Properly_Parse_Folders() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithProjectsAndFolders); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); + } + + [Fact] + public async Task Should_Properly_Parse_Relation_Between_Project_And_Folder() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithProjectsAndFolders); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); + } + + [Fact] + public async Task Should_Properly_Parse_Projects_With_Empty_Lines() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithProjectsAndFoldersAndAdditionalLines); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); + } + + [Fact] + public async Task Should_Properly_Parse_Projects_With_Absolute_Path() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithProjectUsingAbsolutePath); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); + } + + [Fact] + public async Task Should_Properly_Parse_Projects_With_Different_Type_Id() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithProjectWithDifferentTypeId); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); + } + + [Fact] + public async Task Should_Properly_Parse_Solution_With_Nested_Solution_Folders() + { + // Given + var fixture = new SolutionParserFixture(); + var slnFilePath = fixture.WithXmlSolutionFile(Resources.SolutionXml_WithNestedSolutionFolders); + var solutionParser = new SolutionParser(fixture.FileSystem, fixture.Environment); + + // When + var result = solutionParser.Parse(slnFilePath); + + // Then + await Verify(result); } } } diff --git a/src/Cake.Common.Tests/VerifyConfig.cs b/src/Cake.Common.Tests/VerifyConfig.cs new file mode 100644 index 0000000000..a67b3c9ea6 --- /dev/null +++ b/src/Cake.Common.Tests/VerifyConfig.cs @@ -0,0 +1,25 @@ +using System.Runtime.CompilerServices; +using Argon; +using VerifyTests.DiffPlex; + +namespace Cake.Common.Tests; + +public static class VerifyConfig +{ + [ModuleInitializer] + public static void Init() + { + EmptyFiles.FileExtensions.AddTextExtension("cake"); + + if (!VerifyDiffPlex.Initialized) + { + VerifyDiffPlex.Initialize(OutputType.Compact); + DerivePathInfo(Expectations.Initialize); + } + + VerifierSettings.DontScrubDateTimes(); + VerifierSettings.DontIgnoreEmptyCollections(); + VerifierSettings.AddExtraSettings(settings => settings.DefaultValueHandling = DefaultValueHandling.Include); + VerifierSettings.IgnoreStackTrace(); + } +} diff --git a/src/Cake.Common/Solution/SolutionParser.cs b/src/Cake.Common/Solution/SolutionParser.cs index e2f2dcf2c4..4606273e4e 100644 --- a/src/Cake.Common/Solution/SolutionParser.cs +++ b/src/Cake.Common/Solution/SolutionParser.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.Linq; using System.Text; +using System.Xml; using Cake.Core; using Cake.Core.IO; @@ -46,7 +47,7 @@ public SolutionParserResult Parse(FilePath solutionPath) solutionPath = solutionPath.MakeAbsolute(_environment); } - // Get the release notes file. + // Get solution file. var file = _fileSystem.GetFile(solutionPath); if (!file.Exists) { @@ -55,6 +56,18 @@ public SolutionParserResult Parse(FilePath solutionPath) throw new CakeException(message); } + var fileExtension = file.Path.GetExtension().ToLowerInvariant(); + + return fileExtension switch + { + ".sln" => ParseSlnSolution(file), + ".slnx" => ParseSlnxSolution(file), + _ => throw new CakeException($"Unknown file extension {fileExtension} for solution file '{solutionPath.FullPath}'."), + }; + } + + private static SolutionParserResult ParseSlnSolution(IFile file) + { string version = null, visualStudioVersion = null, @@ -182,5 +195,114 @@ private static void ParseNestedProjectLine(List projects, strin parent.Items.Add(child); child.Parent = parent; } + + private static SolutionParserResult ParseSlnxSolution(IFile file) + { + var xmlReaderSettings = new XmlReaderSettings + { + DtdProcessing = DtdProcessing.Prohibit, // Prevent XXE + XmlResolver = null, // Disable external entity resolution + }; + using var xmlContentStream = file.OpenRead(); + var xmlDocument = new XmlDocument(); + + using var xmlReader = XmlReader.Create(xmlContentStream, xmlReaderSettings); + xmlDocument.Load(xmlReader); + + var root = xmlDocument.DocumentElement; + if (root == null) + { + throw new CakeException($"Solution file '{file.Path.FullPath}' does not contain a root element."); + } + + var projects = new List(); + foreach (var xmlElement in root.ChildNodes.OfType()) + { + var projectsFromElement = ParseSlnxElement(xmlElement, file); + projects.AddRange(projectsFromElement); + } + + // the new SLNX has no information about the file format version, VS version and minimal VS version, so it's omitted. + return new SolutionParserResult(string.Empty, string.Empty, string.Empty, projects.AsReadOnly()); + } + + private static List ParseSlnxElement(XmlElement xmlElement, IFile solutionFile) + { + return xmlElement.Name switch + { + "Folder" => ParseSlnxFolder(xmlElement, solutionFile), + "Project" => ParseSlnxProject(xmlElement, solutionFile), + _ =>[], + }; + } + + private static List ParseSlnxFolder(XmlElement xmlElement, IFile solutionFile) + { + var folderName = xmlElement.GetAttribute("Name"); + if (string.IsNullOrWhiteSpace(folderName)) + { + throw new CakeException($"Could not find solution folder name attribute in solution file '{solutionFile.Path.FullPath}'."); + } + + // the name of the folder is also its path. And it always has a starting and trailing "/", which break the check if its relative, so they are removed. + var folderPath = new FilePath(folderName.Trim('/')); + var folderFullPath = folderPath.IsRelative ? + solutionFile.Path.GetDirectory().CombineWithFilePath(folderPath) : + folderPath; + + var actualFolderName = folderName.Split('/', StringSplitOptions.RemoveEmptyEntries).Last(); + + // elements in the SLNX file don't have any IDs anymore, so it's omitted. + var solutionFolder = new SolutionFolder(string.Empty, actualFolderName, folderFullPath); + var projects = new List + { + solutionFolder, + }; + + foreach (var childElement in xmlElement.ChildNodes.OfType()) + { + var childProjects = ParseSlnxElement(childElement, solutionFile); + foreach (var childProject in childProjects) + { + childProject.Parent = solutionFolder; + solutionFolder.Items.Add(childProject); + projects.Add(childProject); + } + } + + return projects; + } + + private static List ParseSlnxProject(XmlElement xmlElement, IFile solutionFile) + { + const string defaultProjectTypeId = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; + + var projectPath = xmlElement.GetAttribute("Path"); + if (string.IsNullOrWhiteSpace(projectPath)) + { + throw new CakeException($"Could not find solution project path attribute in solution file '{solutionFile.Path.FullPath}'."); + } + + var projectTypeId = xmlElement.GetAttribute("Type"); + projectTypeId = string.IsNullOrWhiteSpace(projectTypeId) + ? defaultProjectTypeId + // the new project type id notation does not quite fit the known format, so it is adjusted. + : $"{{{projectTypeId.ToUpper()}}}"; + + var projectFilePath = new FilePath(projectPath); + var projectFileFullPath = projectFilePath.IsRelative ? + solutionFile.Path.GetDirectory().CombineWithFilePath(projectFilePath) : + projectFilePath; + + // the project name is part of its path. + var actualProjectName = projectFilePath.GetFilenameWithoutExtension().FullPath; + + // elements in the SLNX file don't have any IDs anymore, so it's omitted. + var solutionProject = new SolutionProject(string.Empty, actualProjectName, projectFileFullPath, projectTypeId); + return + [ + solutionProject, + ]; + } } } \ No newline at end of file diff --git a/src/Cake.Core.Tests/VerifyConfig.cs b/src/Cake.Core.Tests/VerifyConfig.cs index 7118e6a57f..79981e8aaf 100644 --- a/src/Cake.Core.Tests/VerifyConfig.cs +++ b/src/Cake.Core.Tests/VerifyConfig.cs @@ -12,8 +12,12 @@ public static class VerifyConfig public static void Init() { EmptyFiles.FileExtensions.AddTextExtension(Extensions.Cake); - DerivePathInfo(Expectations.Initialize); - VerifyDiffPlex.Initialize(OutputType.Compact); + + if (!VerifyDiffPlex.Initialized) + { + VerifyDiffPlex.Initialize(OutputType.Compact); + DerivePathInfo(Expectations.Initialize); + } } public static class Extensions diff --git a/src/Cake.Testing.Tests/VerifyConfig.cs b/src/Cake.Testing.Tests/VerifyConfig.cs index dc5f79e454..1c74af1d37 100644 --- a/src/Cake.Testing.Tests/VerifyConfig.cs +++ b/src/Cake.Testing.Tests/VerifyConfig.cs @@ -9,9 +9,14 @@ public static class VerifyConfig [ModuleInitializer] public static void Init() { - DerivePathInfo(Expectations.Initialize); EmptyFiles.FileExtensions.AddTextExtension("cake"); - VerifyDiffPlex.Initialize(OutputType.Compact); + + if (!VerifyDiffPlex.Initialized) + { + VerifyDiffPlex.Initialize(OutputType.Compact); + DerivePathInfo(Expectations.Initialize); + } + VerifierSettings.DontScrubDateTimes(); VerifierSettings.IgnoreMember(x => x.Content); VerifierSettings.IgnoreMember("LastWriteTime"); diff --git a/tests/integration/Cake.Common/Solution/SolutionAliases.cake b/tests/integration/Cake.Common/Solution/SolutionAliases.cake index e4621a3cd6..a28b693e10 100644 --- a/tests/integration/Cake.Common/Solution/SolutionAliases.cake +++ b/tests/integration/Cake.Common/Solution/SolutionAliases.cake @@ -13,7 +13,7 @@ Task("Cake.Common.Solution.SolutionAliases.ParseSolution") version: "Format Version 12.00", visualStudioVersion: "14.0.25420.1", minimumVisualStudioVersion: "10.0.40219.1", - projects: new System.Collections.ObjectModel.ReadOnlyCollection(new [] { + projects: new System.Collections.ObjectModel.ReadOnlyCollection(new[] { new SolutionProject( id: "{4147F50A-8743-4393-A414-EFC707D4BA2C}", name: "Project", @@ -38,6 +38,78 @@ Task("Cake.Common.Solution.SolutionAliases.ParseSolution") Assert.Equal(expect, result, SolutionParserResultEqualityComparer.Comparer); }); +Task("Cake.Common.Solution.SolutionAliases.ParseXmlSolution") + .Does(() => +{ + // Given + var path = Paths.Resources.Combine("./Cake.Common/Solution"); + var file = path.CombineWithFilePath("./XmlSolution.slnx"); + var expect = new SolutionParserResult( + version: string.Empty, + visualStudioVersion: string.Empty, + minimumVisualStudioVersion: string.Empty, + projects: new System.Collections.ObjectModel.ReadOnlyCollection(new[] { + new SolutionProject( + id: string.Empty, + name: "Project", + path: path.CombineWithFilePath("Project/Project.csproj"), + type: "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" + ), + new SolutionProject( + id: string.Empty, + name: "ReferenceProject", + path: path.CombineWithFilePath("ReferenceProject/ReferenceProject.csproj"), + type: "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" + ) + }) + ); + + // When + var result = ParseSolution(file); + + // Then + Assert.NotNull(result); + Assert.Equal(expect.Projects, result.Projects, SolutionProjectEqualityComparer.Comparer); + Assert.Equal(expect, result, SolutionParserResultEqualityComparer.Comparer); +}); + +Task("Cake.Common.Solution.SolutionAliases.ParseXmlSolutionWithProjectWithTypeId") + .Does(() => +{ + // Given + var path = Paths.Resources.Combine("./Cake.Common/Solution"); + var file = path.CombineWithFilePath("./XmlSolutionWithProjectWithTypeId.slnx"); + var expect = new SolutionParserResult( + version: string.Empty, + visualStudioVersion: string.Empty, + minimumVisualStudioVersion: string.Empty, + projects: new System.Collections.ObjectModel.ReadOnlyCollection(new[] { + new SolutionProject( + id: string.Empty, + name: "Project", + path: path.CombineWithFilePath("Project/Project.csproj"), + type: "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" + ), + new SolutionProject( + id: string.Empty, + name: "ReferenceProject", + path: path.CombineWithFilePath("ReferenceProject/ReferenceProject.csproj"), + type: "{E6FDF86B-F3D1-11D4-8576-0002A516ECE8}" + ) + }) + ); + + // When + var result = ParseSolution(file); + + // Then + Assert.NotNull(result); + Assert.Equal(expect.Projects, result.Projects, SolutionProjectEqualityComparer.Comparer); + Assert.Equal(expect, result, SolutionParserResultEqualityComparer.Comparer); +}); + Task("Cake.Common.Solution.SolutionAliases") - .IsDependentOn("Cake.Common.Solution.SolutionAliases.ParseSolution"); \ No newline at end of file + .IsDependentOn("Cake.Common.Solution.SolutionAliases.ParseSolution") + .IsDependentOn("Cake.Common.Solution.SolutionAliases.ParseXmlSolution") + .IsDependentOn("Cake.Common.Solution.SolutionAliases.ParseXmlSolutionWithProjectWithTypeId"); \ No newline at end of file diff --git a/tests/integration/resources/Cake.Common/Solution/XmlSolution.slnx b/tests/integration/resources/Cake.Common/Solution/XmlSolution.slnx new file mode 100644 index 0000000000..431e54bb9e --- /dev/null +++ b/tests/integration/resources/Cake.Common/Solution/XmlSolution.slnx @@ -0,0 +1,4 @@ + + + + diff --git a/tests/integration/resources/Cake.Common/Solution/XmlSolutionWithProjectWithTypeId.slnx b/tests/integration/resources/Cake.Common/Solution/XmlSolutionWithProjectWithTypeId.slnx new file mode 100644 index 0000000000..cced27e425 --- /dev/null +++ b/tests/integration/resources/Cake.Common/Solution/XmlSolutionWithProjectWithTypeId.slnx @@ -0,0 +1,4 @@ + + + +