Skip to content

Commit 9c605ab

Browse files
authored
GH4627: Add explicit path type support for .NET 10+ compatibility (#4633)
(GH-4627) Add explicit path type support for .NET 10+ compatibility Adds DotNetTestPathType enum and PathType property to DotNetTestSettings to support explicit --project and --solution parameters required by .NET 10+. Changes: - Add DotNetTestPathType enum with None, Auto, Project, and Solution values - Add PathType property to DotNetTestSettings (defaults to None for backward compatibility) - Update DotNetTester to handle path type logic with switch expressions - Add comprehensive unit tests covering all path type scenarios - Support auto-detection based on file extensions (.sln, .csproj, .vbproj, .fsproj, .vcxproj) Resolves #4627
1 parent 0a23893 commit 9c605ab

File tree

4 files changed

+213
-0
lines changed

4 files changed

+213
-0
lines changed

src/Cake.Common.Tests/Unit/Tools/DotNet/Test/DotNetTesterTests.cs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using Cake.Common.Tests.Fixtures.Tools.DotNet.Test;
6+
using Cake.Common.Tools.DotNet.Test;
67
using Cake.Core;
78
using Cake.Testing;
89
using Xunit;
@@ -160,6 +161,132 @@ public void Should_Add_Host_Arguments()
160161
// Then
161162
Assert.Equal("--diagnostics test", result.Args);
162163
}
164+
165+
[Fact]
166+
public void Should_Add_Project_Path_With_Explicit_Project_Type()
167+
{
168+
// Given
169+
var fixture = new DotNetTesterFixture();
170+
fixture.Project = "./test/Project.Tests.csproj";
171+
fixture.Settings.PathType = DotNetTestPathType.Project;
172+
173+
// When
174+
var result = fixture.Run();
175+
176+
// Then
177+
Assert.Equal("test --project \"./test/Project.Tests.csproj\"", result.Args);
178+
}
179+
180+
[Fact]
181+
public void Should_Add_Solution_Path_With_Explicit_Solution_Type()
182+
{
183+
// Given
184+
var fixture = new DotNetTesterFixture();
185+
fixture.Project = "./test/TestSolution.sln";
186+
fixture.Settings.PathType = DotNetTestPathType.Solution;
187+
188+
// When
189+
var result = fixture.Run();
190+
191+
// Then
192+
Assert.Equal("test --solution \"./test/TestSolution.sln\"", result.Args);
193+
}
194+
195+
[Theory]
196+
[InlineData("./test/Project.csproj", "test --project \"./test/Project.csproj\"")]
197+
[InlineData("./test/Project.vbproj", "test --project \"./test/Project.vbproj\"")]
198+
[InlineData("./test/Project.fsproj", "test --project \"./test/Project.fsproj\"")]
199+
[InlineData("./test/Project.vcxproj", "test --project \"./test/Project.vcxproj\"")]
200+
public void Should_Auto_Detect_Project_Files(string projectPath, string expected)
201+
{
202+
// Given
203+
var fixture = new DotNetTesterFixture();
204+
fixture.Project = projectPath;
205+
fixture.Settings.PathType = DotNetTestPathType.Auto;
206+
207+
// When
208+
var result = fixture.Run();
209+
210+
// Then
211+
Assert.Equal(expected, result.Args);
212+
}
213+
214+
[Fact]
215+
public void Should_Auto_Detect_Solution_Files()
216+
{
217+
// Given
218+
var fixture = new DotNetTesterFixture();
219+
fixture.Project = "./test/TestSolution.sln";
220+
fixture.Settings.PathType = DotNetTestPathType.Auto;
221+
222+
// When
223+
var result = fixture.Run();
224+
225+
// Then
226+
Assert.Equal("test --solution \"./test/TestSolution.sln\"", result.Args);
227+
}
228+
229+
[Fact]
230+
public void Should_Use_Legacy_Behavior_For_Unknown_Extensions_With_Auto()
231+
{
232+
// Given
233+
var fixture = new DotNetTesterFixture();
234+
fixture.Project = "./test/UnknownFile.xyz";
235+
fixture.Settings.PathType = DotNetTestPathType.Auto;
236+
237+
// When
238+
var result = fixture.Run();
239+
240+
// Then
241+
Assert.Equal("test \"./test/UnknownFile.xyz\"", result.Args);
242+
}
243+
244+
[Fact]
245+
public void Should_Use_Legacy_Behavior_When_PathType_Is_None()
246+
{
247+
// Given
248+
var fixture = new DotNetTesterFixture();
249+
fixture.Project = "./test/Project.csproj";
250+
fixture.Settings.PathType = DotNetTestPathType.None;
251+
252+
// When
253+
var result = fixture.Run();
254+
255+
// Then
256+
Assert.Equal("test \"./test/Project.csproj\"", result.Args);
257+
}
258+
259+
[Fact]
260+
public void Should_Use_Legacy_Behavior_When_PathType_Is_Default()
261+
{
262+
// Given
263+
var fixture = new DotNetTesterFixture();
264+
fixture.Project = "./test/Project.csproj";
265+
// PathType defaults to None
266+
267+
// When
268+
var result = fixture.Run();
269+
270+
// Then
271+
Assert.Equal("test \"./test/Project.csproj\"", result.Args);
272+
}
273+
274+
[Fact]
275+
public void Should_Combine_PathType_With_Other_Settings()
276+
{
277+
// Given
278+
var fixture = new DotNetTesterFixture();
279+
fixture.Project = "./test/Project.csproj";
280+
fixture.Settings.PathType = DotNetTestPathType.Project;
281+
fixture.Settings.NoBuild = true;
282+
fixture.Settings.Configuration = "Release";
283+
284+
// When
285+
var result = fixture.Run();
286+
287+
// Then
288+
Assert.Equal("test --project \"./test/Project.csproj\" --configuration Release --no-build", result.Args);
289+
}
163290
}
164291
}
165292
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace Cake.Common.Tools.DotNet.Test
6+
{
7+
/// <summary>
8+
/// Represents the path type for .NET test command.
9+
/// </summary>
10+
public enum DotNetTestPathType
11+
{
12+
/// <summary>
13+
/// No explicit path type specified (default behavior).
14+
/// </summary>
15+
None,
16+
17+
/// <summary>
18+
/// Automatically detect the path type based on the file extension.
19+
/// </summary>
20+
Auto,
21+
22+
/// <summary>
23+
/// Explicitly specify the path as a project file.
24+
/// </summary>
25+
Project,
26+
27+
/// <summary>
28+
/// Explicitly specify the path as a solution file.
29+
/// </summary>
30+
Solution
31+
}
32+
}

src/Cake.Common/Tools/DotNet/Test/DotNetTestSettings.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,14 @@ public class DotNetTestSettings : DotNetSettings
116116
/// Gets or sets additional arguments to be passed to MSBuild.
117117
/// </summary>
118118
public DotNetMSBuildSettings MSBuildSettings { get; set; }
119+
120+
/// <summary>
121+
/// Gets or sets the path type for the test command.
122+
/// When set to <see cref="DotNetTestPathType.Auto"/>, the path type will be automatically detected based on the file extension.
123+
/// When set to <see cref="DotNetTestPathType.Project"/>, the path will be treated as a project file.
124+
/// When set to <see cref="DotNetTestPathType.Solution"/>, the path will be treated as a solution file.
125+
/// This is particularly useful for .NET 10+ where explicit --project or --solution parameters are required.
126+
/// </summary>
127+
public DotNetTestPathType PathType { get; set; } = DotNetTestPathType.None;
119128
}
120129
}

src/Cake.Common/Tools/DotNet/Test/DotNetTester.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ private ProcessArgumentBuilder GetArguments(string project, ProcessArgumentBuild
5555
// Specific path?
5656
if (project != null)
5757
{
58+
// Handle path type for .NET 10+ compatibility
59+
switch (DeterminePathType(project, settings.PathType))
60+
{
61+
case DotNetTestPathType.Project:
62+
builder.Append("--project");
63+
break;
64+
case DotNetTestPathType.Solution:
65+
builder.Append("--solution");
66+
break;
67+
}
68+
5869
builder.AppendQuoted(project);
5970
}
6071

@@ -191,5 +202,39 @@ private ProcessArgumentBuilder GetArguments(string project, ProcessArgumentBuild
191202

192203
return builder;
193204
}
205+
206+
/// <summary>
207+
/// Determines the path type based on the project path and settings.
208+
/// </summary>
209+
/// <param name="project">The project path.</param>
210+
/// <param name="pathType">The configured path type.</param>
211+
/// <returns>The determined path type.</returns>
212+
private static DotNetTestPathType DeterminePathType(string project, DotNetTestPathType pathType)
213+
{
214+
return pathType switch
215+
{
216+
DotNetTestPathType.None => DotNetTestPathType.None,
217+
DotNetTestPathType.Project => DotNetTestPathType.Project,
218+
DotNetTestPathType.Solution => DotNetTestPathType.Solution,
219+
DotNetTestPathType.Auto => AutoDetectPathType(project),
220+
_ => DotNetTestPathType.None
221+
};
222+
}
223+
224+
/// <summary>
225+
/// Auto-detects the path type based on file extension.
226+
/// </summary>
227+
/// <param name="project">The project path.</param>
228+
/// <returns>The detected path type.</returns>
229+
private static DotNetTestPathType AutoDetectPathType(string project)
230+
{
231+
var extension = FilePath.FromString(project).GetExtension().ToLowerInvariant();
232+
return extension switch
233+
{
234+
".sln" => DotNetTestPathType.Solution,
235+
".csproj" or ".vbproj" or ".fsproj" or ".vcxproj" => DotNetTestPathType.Project,
236+
_ => DotNetTestPathType.None // Default to legacy behavior for unknown extensions
237+
};
238+
}
194239
}
195240
}

0 commit comments

Comments
 (0)