mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-16 08:52:50 +08:00
Merge pull request #1141 from 0xced/better-conversion-errors
This commit is contained in:
commit
beca0b2419
@ -42,6 +42,13 @@ public class CommandRuntimeException : CommandAppException
|
|||||||
return new CommandRuntimeException($"Could not find converter for type '{parameter.ParameterType.FullName}'.");
|
return new CommandRuntimeException($"Could not find converter for type '{parameter.ParameterType.FullName}'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static CommandRuntimeException ConversionFailed(MappedCommandParameter parameter, TypeConverter typeConverter, Exception exception)
|
||||||
|
{
|
||||||
|
var standardValues = typeConverter.GetStandardValuesSupported() ? typeConverter.GetStandardValues() : null;
|
||||||
|
var validValues = standardValues == null ? string.Empty : $" Valid values are '{string.Join("', '", standardValues.Cast<object>().Select(Convert.ToString))}'";
|
||||||
|
return new CommandRuntimeException($"Failed to convert '{parameter.Value}' to {parameter.Parameter.ParameterType.Name}.{validValues}", exception);
|
||||||
|
}
|
||||||
|
|
||||||
internal static CommandRuntimeException ValidationFailed(ValidationResult result)
|
internal static CommandRuntimeException ValidationFailed(ValidationResult result)
|
||||||
{
|
{
|
||||||
return new CommandRuntimeException(result.Message ?? "Unknown validation error.");
|
return new CommandRuntimeException(result.Message ?? "Unknown validation error.");
|
||||||
|
@ -84,8 +84,18 @@ internal static class CommandValueResolver
|
|||||||
throw CommandRuntimeException.NoConverterFound(mapped.Parameter);
|
throw CommandRuntimeException.NoConverterFound(mapped.Parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object? value;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = converter.ConvertFromInvariantString(mapped.Value ?? string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
throw CommandRuntimeException.ConversionFailed(mapped, converter, exception);
|
||||||
|
}
|
||||||
|
|
||||||
// Assign the value to the parameter.
|
// Assign the value to the parameter.
|
||||||
binder.Bind(mapped.Parameter, resolver, converter.ConvertFromInvariantString(mapped.Value ?? string.Empty));
|
binder.Bind(mapped.Parameter, resolver, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
namespace Spectre.Console.Tests.Data;
|
namespace Spectre.Console.Tests.Data;
|
||||||
|
|
||||||
[Description("The horse command.")]
|
[Description("The horse command.")]
|
||||||
public class HorseCommand : AnimalCommand<MammalSettings>
|
public class HorseCommand : AnimalCommand<HorseSettings>
|
||||||
{
|
{
|
||||||
public override int Execute(CommandContext context, MammalSettings settings)
|
public override int Execute(CommandContext context, HorseSettings settings)
|
||||||
{
|
{
|
||||||
DumpSettings(context, settings);
|
DumpSettings(context, settings);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace Spectre.Console.Tests.Data;
|
||||||
|
|
||||||
|
public class HorseSettings : MammalSettings
|
||||||
|
{
|
||||||
|
[CommandOption("-d|--day")]
|
||||||
|
public DayOfWeek Day { get; set; }
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Model>
|
<Model>
|
||||||
<!--ANIMAL-->
|
<!--ANIMAL-->
|
||||||
<Command Name="animal" IsBranch="true" Settings="Spectre.Console.Tests.Data.AnimalSettings">
|
<Command Name="animal" IsBranch="true" Settings="Spectre.Console.Tests.Data.AnimalSettings">
|
||||||
@ -27,9 +27,9 @@
|
|||||||
</Parameters>
|
</Parameters>
|
||||||
</Command>
|
</Command>
|
||||||
<!--HORSE-->
|
<!--HORSE-->
|
||||||
<Command Name="horse" IsBranch="false" ClrType="Spectre.Console.Tests.Data.HorseCommand" Settings="Spectre.Console.Tests.Data.MammalSettings">
|
<Command Name="horse" IsBranch="false" ClrType="Spectre.Console.Tests.Data.HorseCommand" Settings="Spectre.Console.Tests.Data.HorseSettings">
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Option Shadowed="true" Short="n,p" Long="name,pet-name" Value="VALUE" Required="false" Kind="scalar" ClrType="System.String" />
|
<Option Short="d" Long="day" Value="NULL" Required="false" Kind="scalar" ClrType="System.DayOfWeek" />
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</Command>
|
</Command>
|
||||||
</Command>
|
</Command>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Model>
|
<Model>
|
||||||
<!--ANIMAL-->
|
<!--ANIMAL-->
|
||||||
<Command Name="animal" IsBranch="true" Settings="Spectre.Console.Tests.Data.AnimalSettings">
|
<Command Name="animal" IsBranch="true" Settings="Spectre.Console.Tests.Data.AnimalSettings">
|
||||||
@ -23,8 +23,9 @@
|
|||||||
</Parameters>
|
</Parameters>
|
||||||
</Command>
|
</Command>
|
||||||
<!--HORSE-->
|
<!--HORSE-->
|
||||||
<Command Name="horse" IsBranch="false" ClrType="Spectre.Console.Tests.Data.HorseCommand" Settings="Spectre.Console.Tests.Data.MammalSettings">
|
<Command Name="horse" IsBranch="false" ClrType="Spectre.Console.Tests.Data.HorseCommand" Settings="Spectre.Console.Tests.Data.HorseSettings">
|
||||||
<Parameters>
|
<Parameters>
|
||||||
|
<Option Short="d" Long="day" Value="NULL" Required="false" Kind="scalar" ClrType="System.DayOfWeek" />
|
||||||
<Option Short="n,p" Long="name,pet-name" Value="VALUE" Required="false" Kind="scalar" ClrType="System.String" />
|
<Option Short="n,p" Long="name,pet-name" Value="VALUE" Required="false" Kind="scalar" ClrType="System.String" />
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</Command>
|
</Command>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Model>
|
<Model>
|
||||||
<!--DEFAULT COMMAND-->
|
<!--DEFAULT COMMAND-->
|
||||||
<Command Name="__default_command" IsBranch="false" IsDefault="true" ClrType="Spectre.Console.Tests.Data.DogCommand" Settings="Spectre.Console.Tests.Data.DogSettings">
|
<Command Name="__default_command" IsBranch="false" IsDefault="true" ClrType="Spectre.Console.Tests.Data.DogCommand" Settings="Spectre.Console.Tests.Data.DogSettings">
|
||||||
@ -19,7 +19,7 @@
|
|||||||
</Parameters>
|
</Parameters>
|
||||||
</Command>
|
</Command>
|
||||||
<!--HORSE-->
|
<!--HORSE-->
|
||||||
<Command Name="horse" IsBranch="false" ClrType="Spectre.Console.Tests.Data.HorseCommand" Settings="Spectre.Console.Tests.Data.MammalSettings">
|
<Command Name="horse" IsBranch="false" ClrType="Spectre.Console.Tests.Data.HorseCommand" Settings="Spectre.Console.Tests.Data.HorseSettings">
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Argument Name="LEGS" Position="0" Required="false" Kind="scalar" ClrType="System.Int32">
|
<Argument Name="LEGS" Position="0" Required="false" Kind="scalar" ClrType="System.Int32">
|
||||||
<Description>The number of legs.</Description>
|
<Description>The number of legs.</Description>
|
||||||
@ -31,6 +31,7 @@
|
|||||||
<Option Short="a" Long="alive,not-dead" Value="NULL" Required="false" Kind="flag" ClrType="System.Boolean">
|
<Option Short="a" Long="alive,not-dead" Value="NULL" Required="false" Kind="flag" ClrType="System.Boolean">
|
||||||
<Description>Indicates whether or not the animal is alive.</Description>
|
<Description>Indicates whether or not the animal is alive.</Description>
|
||||||
</Option>
|
</Option>
|
||||||
|
<Option Short="d" Long="day" Value="NULL" Required="false" Kind="scalar" ClrType="System.DayOfWeek" />
|
||||||
<Option Short="n,p" Long="name,pet-name" Value="VALUE" Required="false" Kind="scalar" ClrType="System.String" />
|
<Option Short="n,p" Long="name,pet-name" Value="VALUE" Required="false" Kind="scalar" ClrType="System.String" />
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</Command>
|
</Command>
|
||||||
|
@ -29,5 +29,52 @@ public sealed partial class CommandAppTests
|
|||||||
cat.Agility.ShouldBe(6);
|
cat.Agility.ShouldBe(6);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Convert_Enum_Ignoring_Case()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var app = new CommandAppTester();
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.AddCommand<HorseCommand>("horse");
|
||||||
|
});
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = app.Run(new[] { "horse", "--day", "friday" });
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ExitCode.ShouldBe(0);
|
||||||
|
result.Settings.ShouldBeOfType<HorseSettings>().And(horse =>
|
||||||
|
{
|
||||||
|
horse.Day.ShouldBe(DayOfWeek.Friday);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_List_All_Valid_Enum_Values_On_Conversion_Error()
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
var app = new CommandAppTester();
|
||||||
|
app.Configure(config =>
|
||||||
|
{
|
||||||
|
config.AddCommand<HorseCommand>("horse");
|
||||||
|
});
|
||||||
|
|
||||||
|
// When
|
||||||
|
var result = app.Run(new[] { "horse", "--day", "heimday" });
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result.ExitCode.ShouldBe(-1);
|
||||||
|
result.Output.ShouldStartWith("Error");
|
||||||
|
result.Output.ShouldContain("heimday");
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Sunday));
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Monday));
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Tuesday));
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Wednesday));
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Thursday));
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Friday));
|
||||||
|
result.Output.ShouldContain(nameof(DayOfWeek.Saturday));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user