Skip to content

Commit 93563ad

Browse files
committed
Add test for default verb with no properties
Introduces a new unit test to cover a customer scenario where a default command's options object has no properties, but parameters are still passed to the app. This ensures the default command correctly runs and receives an instance of its options type despite the lack of defined properties.
1 parent a5df819 commit 93563ad

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

Neolution.DotNet.Console.UnitTests/DotNetConsoleGrammarTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,26 @@ public async Task GivenBuiltConsoleApp_WhenCallingDefaultVerbWithParametersWithV
160160
options.TenantId.ShouldBe("1234");
161161
}
162162

163+
/// <summary>
164+
/// When calling the console app with parameters but without specifying the default verb, and the default options have no properties, it should still run the default command.
165+
/// This reproduces a customer scenario where they defined isDefault but parse arguments manually in the command.
166+
/// </summary>
167+
/// <returns>The <see cref="Task"/>.</returns>
168+
[Fact]
169+
public async Task GivenBuiltConsoleAppWithDefaultVerbWithoutProperties_WhenCallingWithParametersWithoutVerb_ThenShouldRunDefaultVerb()
170+
{
171+
// Arrange
172+
const string args = "--option=Queue --tenantId=1234";
173+
var logger = new UnitTestLogger();
174+
var console = CreateConsoleAppWithLoggerForDefaultWithoutProperties(args, logger);
175+
176+
// Act
177+
await console.RunAsync();
178+
179+
// Assert
180+
logger.LoggedObjects["options"].ShouldBeOfType<DefaultOptionsWithoutProperties>();
181+
}
182+
163183
/// <summary>
164184
/// Creates the console application with logger.
165185
/// </summary>
@@ -174,5 +194,22 @@ private static IDotNetConsole CreateConsoleAppWithLogger(string args, IUnitTestL
174194

175195
return builder.Build();
176196
}
197+
198+
/// <summary>
199+
/// Creates the console application with logger for default command without properties.
200+
/// </summary>
201+
/// <param name="args">The arguments.</param>
202+
/// <param name="tracker">The logger.</param>
203+
/// <returns>A built console app ready to run.</returns>
204+
private static IDotNetConsole CreateConsoleAppWithLoggerForDefaultWithoutProperties(string args, IUnitTestLogger tracker)
205+
{
206+
var servicesAssembly = Assembly.GetAssembly(typeof(DefaultCommandWithoutProperties))!;
207+
var verbTypes = new[] { typeof(DefaultOptionsWithoutProperties) };
208+
var builder = DotNetConsole.CreateBuilderWithReference(servicesAssembly, verbTypes, args.Split(" "));
209+
210+
builder.Services.Replace(new ServiceDescriptor(typeof(IUnitTestLogger), tracker));
211+
212+
return builder.Build();
213+
}
177214
}
178215
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
namespace Neolution.DotNet.Console.UnitTests.Fakes
2+
{
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Microsoft.Extensions.Hosting;
6+
using Neolution.DotNet.Console.Abstractions;
7+
using Neolution.DotNet.Console.UnitTests.Spies;
8+
9+
/// <summary>
10+
/// The command for the default verb without properties - simulates customer scenario where they parse args manually.
11+
/// </summary>
12+
/// <seealso cref="IDotNetConsoleCommand{TOptions}" />
13+
public class DefaultCommandWithoutProperties : IDotNetConsoleCommand<DefaultOptionsWithoutProperties>
14+
{
15+
/// <summary>
16+
/// The logger
17+
/// </summary>
18+
private readonly IUnitTestLogger logger;
19+
20+
/// <summary>
21+
/// The environment
22+
/// </summary>
23+
private readonly IHostEnvironment environment;
24+
25+
/// <summary>
26+
/// Initializes a new instance of the <see cref="DefaultCommandWithoutProperties" /> class.
27+
/// </summary>
28+
/// <param name="logger">The logger.</param>
29+
/// <param name="environment">The environment.</param>
30+
public DefaultCommandWithoutProperties(IUnitTestLogger logger, IHostEnvironment environment)
31+
{
32+
this.logger = logger;
33+
this.environment = environment;
34+
}
35+
36+
/// <inheritdoc />
37+
public async Task RunAsync(DefaultOptionsWithoutProperties options, CancellationToken cancellationToken)
38+
{
39+
this.logger.Log("options", options);
40+
this.logger.Log("environment", this.environment);
41+
42+
// In real scenario, customers would manually parse Environment.GetCommandLineArgs() here
43+
await Task.CompletedTask;
44+
}
45+
}
46+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Neolution.DotNet.Console.UnitTests.Fakes
2+
{
3+
using CommandLine;
4+
5+
/// <summary>
6+
/// The options stub for the <see cref="DefaultCommandWithoutProperties"/> - simulates customer scenario where options have no properties
7+
/// </summary>
8+
[Verb("default-no-props", isDefault: true)]
9+
public class DefaultOptionsWithoutProperties
10+
{
11+
// No properties defined - customers parse manually in the command
12+
}
13+
}

0 commit comments

Comments
 (0)