Skip to content

Commit

Permalink
Merge branch 'master' into feature/upgrade-to-net8
Browse files Browse the repository at this point in the history
  • Loading branch information
mayuki committed Jan 3, 2024
2 parents f0b9f60 + c2bfb6d commit c16cb1f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/Cocona.Core/Command/Binder/CoconaParameterBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ private object CreateParameterSetWithMembers(CommandParameterSetDescriptor param
{
return Validate(option, _valueConverter.ConvertTo(type, value));
}
catch (Exception ex) when (!(ex is ParameterBinderException))
catch (Exception ex) when (ex is not ParameterBinderException)
{
throw new ParameterBinderException(ParameterBinderResult.TypeNotSupported, $"Option '{option.Name}' requires {type.Name} value. '{value}' cannot be converted to {type.Name} value.", option: option, innerException: ex);
}
Expand All @@ -256,7 +256,7 @@ private object CreateParameterSetWithMembers(CommandParameterSetDescriptor param
{
return Validate(argument, _valueConverter.ConvertTo(type, value));
}
catch (Exception ex) when (!(ex is ParameterBinderException))
catch (Exception ex) when (ex is not ParameterBinderException)
{
throw new ParameterBinderException(ParameterBinderResult.TypeNotSupported, $"Argument '{argument.Name}' requires {type.Name} value. '{value}' cannot be converted to {type.Name} value.", argument: argument, innerException: ex);
}
Expand All @@ -267,7 +267,7 @@ private object CreateParameterSetWithMembers(CommandParameterSetDescriptor param
if (DynamicListHelper.TryCreateArrayOrEnumerableLike(valueType, values, _valueConverter, out var arrayOrEnumerableLike))
{
// T[] or List<T> (IEnumerable<T>, IList<T>)
return arrayOrEnumerableLike;
return option is not null ? Validate(option, arrayOrEnumerableLike) : Validate(argument!, arrayOrEnumerableLike);
}
else if (!DynamicListHelper.IsArrayOrEnumerableLike(valueType))
{
Expand All @@ -280,4 +280,4 @@ private object CreateParameterSetWithMembers(CommandParameterSetDescriptor param

throw new ParameterBinderException(ParameterBinderResult.TypeNotSupported, $"Cannot create a instance of type '{valueType.FullName}'", option, argument);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ private CommandDescriptor CreateCommand(ICommandParameterDescriptor[] parameterD
null
);
}

private static CoconaParameterBinder CreateCoconaParameterBinder()
{
return new CoconaParameterBinder(new ServiceCollection().BuildServiceProvider(), new CoconaValueConverter(), new DataAnnotationsParameterValidatorProvider());
Expand All @@ -48,7 +49,7 @@ public void Bind_Option_DataAnnotationsParameterValidator_Empty()
[Fact]
public void Bind_Option_DataAnnotationsParameterValidator_Single()
{
var command = CreateCommand(new []
var command = CreateCommand(new[]
{
new CommandOptionDescriptor(typeof(int), "arg0", Array.Empty<char>(), "", CoconaDefaultValue.None, null, CommandOptionFlags.None, new [] { new RangeAttribute(0, 100) } )
});
Expand Down Expand Up @@ -111,6 +112,7 @@ public void Bind_Argument_DataAnnotationsParameterValidator_Single()
result.Should().HaveCount(1);
}


[Fact]
public void Bind_Argument_DataAnnotationsParameterValidator_Error()
{
Expand All @@ -123,6 +125,36 @@ public void Bind_Argument_DataAnnotationsParameterValidator_Error()
var ex = Assert.Throws<ParameterBinderException>(() => binder.Bind(command, Array.Empty<CommandOption>(), new[] { new CommandArgument("123", 0) }));
ex.Result.Should().Be(ParameterBinderResult.ValidationFailed);
}

[Fact]
public void Bind_Enumerable_Argument_DataAnnotationsParameterValidator_Single()
{
var command = CreateCommand(new[] { new CommandArgumentDescriptor(typeof(List<int>), "arg0", 0, "", CoconaDefaultValue.None, new[] { new IsEvenEnumerableAttribute() }) });

var binder = CreateCoconaParameterBinder();
var result = binder.Bind(command, Array.Empty<CommandOption>(), new[]
{
new CommandArgument("10", 0),
new CommandArgument("20", 1),
new CommandArgument("30", 2),
new CommandArgument("40", 3),
});
result.Should().HaveCount(1);
}

[Fact]
public void Bind_Enumerable_Argument_DataAnnotationsParameterValidator_Error()
{
var command = CreateCommand(new[] { new CommandArgumentDescriptor(typeof(List<int>), "arg0", 0, "", CoconaDefaultValue.None, new[] { new IsEvenEnumerableAttribute() }) });

var binder = CreateCoconaParameterBinder();
var act = () => binder.Bind(
command,
Array.Empty<CommandOption>(),
new[] { new CommandArgument("10", 0), new CommandArgument("15", 1), new CommandArgument("20", 2), new CommandArgument("25", 3), });

act.Should().Throw<ParameterBinderException>().And.Result.Should().Be(ParameterBinderResult.ValidationFailed);
}

[Fact]
public void Bind_Argument_DataAnnotationsParameterValidator_UnknownAttribute()
Expand All @@ -138,10 +170,27 @@ public void Bind_Argument_DataAnnotationsParameterValidator_UnknownAttribute()
}


class MyAttribute : Attribute { }
class MyAttribute : Attribute
{
}

class IsEvenEnumerableAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
if (value is not IEnumerable<int> numbers)
{
return new ValidationResult($"Could not validate collection, values's type is {value?.GetType()}");
}

return numbers.All(x => x % 2 == 0)
? ValidationResult.Success
: new ValidationResult("List contains uneven numbers.");
}
}

class CommandParameterValidationTest
{
public void Dummy() { }
}
}
}

0 comments on commit c16cb1f

Please sign in to comment.