mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Cleanup
This commit is contained in:
@@ -134,11 +134,17 @@ namespace CliFx.Tests
|
||||
[Command]
|
||||
private class RequiredOptionCommand : ICommand
|
||||
{
|
||||
[CommandOption(nameof(OptionA))]
|
||||
public string? OptionA { get; set; }
|
||||
[CommandOption(nameof(Option), IsRequired = true)]
|
||||
public string? Option { get; set; }
|
||||
|
||||
[CommandOption(nameof(OptionB), IsRequired = true)]
|
||||
public string? OptionB { get; set; }
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
}
|
||||
|
||||
[Command]
|
||||
private class RequiredArrayOptionCommand : ICommand
|
||||
{
|
||||
[CommandOption(nameof(Option), IsRequired = true)]
|
||||
public IReadOnlyList<string>? Option { get; set; }
|
||||
|
||||
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||
}
|
||||
|
||||
@@ -825,113 +825,6 @@ namespace CliFx.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_an_option_can_be_bound_from_multiple_values_even_if_the_inputs_use_mixed_naming()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddOption("option", "foo")
|
||||
.AddOption("o", "bar")
|
||||
.AddOption("option", "baz")
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var instance = CommandHelper.ResolveCommand<ArrayOptionCommand>(input);
|
||||
|
||||
// Assert
|
||||
instance.Should().BeEquivalentTo(new ArrayOptionCommand
|
||||
{
|
||||
Option = new[] {"foo", "bar", "baz"}
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_a_required_option_must_always_be_set()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddOption(nameof(RequiredOptionCommand.OptionA), "foo")
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<RequiredOptionCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_a_required_option_must_always_be_bound_to_some_value()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddOption(nameof(RequiredOptionCommand.OptionB))
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<RequiredOptionCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_parameter_is_bound_directly_from_argument_value_according_to_the_order()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddParameter("foo")
|
||||
.AddParameter("bar")
|
||||
.AddParameter("hello")
|
||||
.AddParameter("world")
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var instance = CommandHelper.ResolveCommand<ParametersCommand>(input);
|
||||
|
||||
// Assert
|
||||
instance.Should().BeEquivalentTo(new ParametersCommand
|
||||
{
|
||||
ParameterA = "foo",
|
||||
ParameterB = "bar",
|
||||
ParameterC = new[] {"hello", "world"}
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Scalar_properties_annotated_as_parameter_requires_input()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<ParametersCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NonScalar_properties_annotated_as_parameter_requires_input()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddParameter("foo")
|
||||
.AddParameter("bar")
|
||||
.Build();
|
||||
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<ParametersCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_parameter_must_always_be_bound_to_some_value()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddParameter("foo")
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<ParametersCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_of_custom_type_that_implements_IEnumerable_can_only_be_bound_if_that_type_has_a_constructor_accepting_an_array()
|
||||
{
|
||||
@@ -984,6 +877,114 @@ namespace CliFx.Tests
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_an_option_can_be_bound_from_multiple_values_even_if_the_inputs_use_mixed_naming()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddOption("option", "foo")
|
||||
.AddOption("o", "bar")
|
||||
.AddOption("option", "baz")
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var instance = CommandHelper.ResolveCommand<ArrayOptionCommand>(input);
|
||||
|
||||
// Assert
|
||||
instance.Should().BeEquivalentTo(new ArrayOptionCommand
|
||||
{
|
||||
Option = new[] {"foo", "bar", "baz"}
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_a_required_option_must_always_be_set()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<RequiredOptionCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_a_required_option_must_always_be_bound_to_some_value()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddOption(nameof(RequiredOptionCommand.Option))
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<RequiredOptionCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_a_required_option_must_always_be_bound_to_at_least_one_value_if_it_expects_multiple_values()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddOption(nameof(RequiredOptionCommand.Option))
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<RequiredArrayOptionCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_parameter_is_bound_directly_from_argument_value_according_to_the_order()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddParameter("foo")
|
||||
.AddParameter("bar")
|
||||
.AddParameter("hello")
|
||||
.AddParameter("world")
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var instance = CommandHelper.ResolveCommand<ParametersCommand>(input);
|
||||
|
||||
// Assert
|
||||
instance.Should().BeEquivalentTo(new ParametersCommand
|
||||
{
|
||||
ParameterA = "foo",
|
||||
ParameterB = "bar",
|
||||
ParameterC = new[] {"hello", "world"}
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_parameter_must_always_be_bound_to_some_value()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddParameter("foo")
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<ParametersCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Property_annotated_as_parameter_must_always_be_bound_to_at_least_one_value_if_it_expects_multiple_values()
|
||||
{
|
||||
// Arrange
|
||||
var input = new CommandInputBuilder()
|
||||
.AddParameter("foo")
|
||||
.AddParameter("bar")
|
||||
.Build();
|
||||
|
||||
// Act & assert
|
||||
var ex = Assert.Throws<CliFxException>(() => CommandHelper.ResolveCommand<ParametersCommand>(input));
|
||||
_output.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void All_provided_option_arguments_must_be_bound_to_corresponding_properties()
|
||||
{
|
||||
|
||||
@@ -103,15 +103,16 @@ namespace CliFx.Domain
|
||||
|
||||
if (nonScalarParameter != null)
|
||||
{
|
||||
// Verify that we have at least one value
|
||||
if(!parameterInputs.Skip(scalarParameters.Length).Any())
|
||||
throw CliFxException.ParameterNotSet(nonScalarParameter);
|
||||
|
||||
var nonScalarValues = parameterInputs
|
||||
.Skip(scalarParameters.Length)
|
||||
.Select(p => p.Value)
|
||||
.ToArray();
|
||||
|
||||
// Parameters are required by default and so a non-scalar parameter must
|
||||
// be bound to at least one value
|
||||
if(!nonScalarValues.Any())
|
||||
throw CliFxException.ParameterNotSet(nonScalarParameter);
|
||||
|
||||
nonScalarParameter.BindOn(instance, nonScalarValues);
|
||||
remainingParameterInputs.Clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user