fix(cli): resolve CLI-008..013 — format validation, exit-code semantics, debug-stream cancellation/disposal, test coverage
This commit is contained in:
88
tests/ScadaLink.CLI.Tests/CommandTreeTests.cs
Normal file
88
tests/ScadaLink.CLI.Tests/CommandTreeTests.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System.CommandLine;
|
||||
using ScadaLink.CLI.Commands;
|
||||
using ScadaLink.Commons.Messages.Management;
|
||||
|
||||
namespace ScadaLink.CLI.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Regression tests for CLI-013 — the command-tree wiring was untested. These tests
|
||||
/// build every command group and assert the tree is well-formed (every leaf has an
|
||||
/// action, no group is empty), and that every management command record the CLI sends
|
||||
/// resolves via <see cref="ManagementCommandRegistry"/> (so command-name derivation
|
||||
/// never throws at runtime).
|
||||
/// </summary>
|
||||
public class CommandTreeTests
|
||||
{
|
||||
private static readonly Option<string> Url = new("--url") { Recursive = true };
|
||||
private static readonly Option<string> Username = new("--username") { Recursive = true };
|
||||
private static readonly Option<string> Password = new("--password") { Recursive = true };
|
||||
private static readonly Option<string> Format = CliOptions.CreateFormatOption();
|
||||
|
||||
private static IEnumerable<Command> AllCommandGroups() => new[]
|
||||
{
|
||||
TemplateCommands.Build(Url, Format, Username, Password),
|
||||
InstanceCommands.Build(Url, Format, Username, Password),
|
||||
SiteCommands.Build(Url, Format, Username, Password),
|
||||
DeployCommands.Build(Url, Format, Username, Password),
|
||||
DataConnectionCommands.Build(Url, Format, Username, Password),
|
||||
ExternalSystemCommands.Build(Url, Format, Username, Password),
|
||||
NotificationCommands.Build(Url, Format, Username, Password),
|
||||
SecurityCommands.Build(Url, Format, Username, Password),
|
||||
AuditLogCommands.Build(Url, Format, Username, Password),
|
||||
HealthCommands.Build(Url, Format, Username, Password),
|
||||
DebugCommands.Build(Url, Format, Username, Password),
|
||||
SharedScriptCommands.Build(Url, Format, Username, Password),
|
||||
DbConnectionCommands.Build(Url, Format, Username, Password),
|
||||
ApiMethodCommands.Build(Url, Format, Username, Password),
|
||||
};
|
||||
|
||||
private static IEnumerable<Command> LeafCommands(Command command)
|
||||
{
|
||||
if (command.Subcommands.Count == 0)
|
||||
{
|
||||
yield return command;
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var sub in command.Subcommands)
|
||||
foreach (var leaf in LeafCommands(sub))
|
||||
yield return leaf;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllCommandGroups_Build_WithoutThrowing()
|
||||
{
|
||||
var groups = AllCommandGroups().ToList();
|
||||
Assert.Equal(14, groups.Count);
|
||||
Assert.All(groups, g => Assert.False(string.IsNullOrWhiteSpace(g.Name)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EveryLeafCommand_HasAnAction()
|
||||
{
|
||||
// A leaf command with no action is dead wiring — invoking it would do nothing.
|
||||
var leaves = AllCommandGroups().SelectMany(LeafCommands).ToList();
|
||||
|
||||
Assert.NotEmpty(leaves);
|
||||
Assert.All(leaves, leaf =>
|
||||
Assert.True(leaf.Action != null, $"Leaf command '{leaf.Name}' has no action."));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(GetInstanceCommand))]
|
||||
[InlineData(typeof(ListSitesCommand))]
|
||||
[InlineData(typeof(CreateTemplateCommand))]
|
||||
[InlineData(typeof(SetConnectionBindingsCommand))]
|
||||
[InlineData(typeof(SetInstanceOverridesCommand))]
|
||||
[InlineData(typeof(DebugSnapshotCommand))]
|
||||
[InlineData(typeof(MgmtDeployInstanceCommand))]
|
||||
[InlineData(typeof(QueryAuditLogCommand))]
|
||||
public void CommandPayloadTypes_ResolveViaRegistry(Type commandType)
|
||||
{
|
||||
// GetCommandName throws ArgumentException for an unregistered type — the CLI
|
||||
// calls it for every command it sends, so each must round-trip.
|
||||
var name = ManagementCommandRegistry.GetCommandName(commandType);
|
||||
Assert.False(string.IsNullOrWhiteSpace(name));
|
||||
Assert.Equal(commandType, ManagementCommandRegistry.Resolve(name));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user