mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
@@ -166,5 +166,17 @@ namespace CliFx.Tests
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
}
|
||||
|
||||
[Command]
|
||||
private class NoParameterCommand : ICommand
|
||||
{
|
||||
[CommandOption(nameof(OptionA))]
|
||||
public string? OptionA { get; set; }
|
||||
|
||||
[CommandOption(nameof(OptionB))]
|
||||
public string? OptionB { get; set; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1018,5 +1018,37 @@ namespace CliFx.Tests
|
||||
// Act & assert
|
||||
Assert.Throws<CliFxException>(() => schema.InitializeEntryPoint(input));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void All_provided_option_arguments_must_be_bound_to_corresponding_properties()
|
||||
{
|
||||
// Arrange
|
||||
var schema = ApplicationSchema.Resolve(new[] {typeof(AllSupportedTypesCommand)});
|
||||
|
||||
var input = new CommandLineInputBuilder()
|
||||
.AddOption("not-a-real-option", "boom")
|
||||
.AddOption("fake-option", "poof")
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
Assert.Throws<CliFxException>(() => schema.InitializeEntryPoint(input));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void All_provided_parameter_arguments_must_be_bound_to_corresponding_properties()
|
||||
{
|
||||
// Arrange
|
||||
var schema = ApplicationSchema.Resolve(new[] {typeof(NoParameterCommand)});
|
||||
|
||||
var input = new CommandLineInputBuilder()
|
||||
.AddUnboundArgument("boom")
|
||||
.AddUnboundArgument("poof")
|
||||
.AddOption(nameof(NoParameterCommand.OptionA), "foo")
|
||||
.AddOption(nameof(NoParameterCommand.OptionB), "bar")
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
Assert.Throws<CliFxException>(() => schema.InitializeEntryPoint(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,9 @@ namespace CliFx.Domain
|
||||
|
||||
private void InjectParameters(ICommand command, IReadOnlyList<string> parameterInputs)
|
||||
{
|
||||
// All inputs must be bound
|
||||
var remainingParameterInputs = parameterInputs.ToList();
|
||||
|
||||
// Scalar parameters
|
||||
var scalarParameters = Parameters
|
||||
.OrderBy(p => p.Order)
|
||||
@@ -57,6 +60,7 @@ namespace CliFx.Domain
|
||||
: throw new CliFxException($"Missing value for parameter <{scalarParameter.DisplayName}>.");
|
||||
|
||||
scalarParameter.Inject(command, scalarParameterInput);
|
||||
remainingParameterInputs.Remove(scalarParameterInput);
|
||||
}
|
||||
|
||||
// Non-scalar parameter (only one is allowed)
|
||||
@@ -68,6 +72,16 @@ namespace CliFx.Domain
|
||||
{
|
||||
var nonScalarParameterInputs = parameterInputs.Skip(scalarParameters.Length).ToArray();
|
||||
nonScalarParameter.Inject(command, nonScalarParameterInputs);
|
||||
remainingParameterInputs.Clear();
|
||||
}
|
||||
|
||||
// Ensure all inputs were bound
|
||||
if (remainingParameterInputs.Any())
|
||||
{
|
||||
throw new CliFxException(new StringBuilder()
|
||||
.AppendLine("Unrecognized parameters provided:")
|
||||
.AppendBulletList(remainingParameterInputs)
|
||||
.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +90,9 @@ namespace CliFx.Domain
|
||||
IReadOnlyList<CommandOptionInput> optionInputs,
|
||||
IReadOnlyDictionary<string, string> environmentVariables)
|
||||
{
|
||||
// All inputs must be bound
|
||||
var remainingOptionInputs = optionInputs.ToList();
|
||||
|
||||
// Keep track of required options so that we can raise an error if any of them are not set
|
||||
var unsetRequiredOptions = Options.Where(o => o.IsRequired).ToList();
|
||||
|
||||
@@ -103,10 +120,12 @@ namespace CliFx.Domain
|
||||
if (option != null)
|
||||
{
|
||||
option.Inject(command, optionInput.Values);
|
||||
remainingOptionInputs.Remove(optionInput);
|
||||
unsetRequiredOptions.Remove(option);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure all required options were set
|
||||
if (unsetRequiredOptions.Any())
|
||||
{
|
||||
throw new CliFxException(new StringBuilder()
|
||||
@@ -114,6 +133,15 @@ namespace CliFx.Domain
|
||||
.AppendBulletList(unsetRequiredOptions.Select(o => o.DisplayName))
|
||||
.ToString());
|
||||
}
|
||||
|
||||
// Ensure all inputs were bound
|
||||
if (remainingOptionInputs.Any())
|
||||
{
|
||||
throw new CliFxException(new StringBuilder()
|
||||
.AppendLine("Unrecognized options provided:")
|
||||
.AppendBulletList(remainingOptionInputs.Select(o => o.Alias))
|
||||
.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand CreateInstance(
|
||||
|
||||
Reference in New Issue
Block a user