Improve conversion error messages

When a conversion to an enum fails, list all the valid enum values in the error message.

Message before this commit:
> Error: heimday is not a valid value for DayOfWeek.

Message after this commit:
> Error: Failed to convert 'heimday' to DayOfWeek. Valid values are 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
This commit is contained in:
Cédric Luthi
2023-01-24 19:38:03 +01:00
parent 7b9553dd22
commit de847b90e4
8 changed files with 83 additions and 10 deletions

View File

@ -1,9 +1,9 @@
namespace Spectre.Console.Tests.Data;
[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);
return 0;

View File

@ -0,0 +1,7 @@
namespace Spectre.Console.Tests.Data;
public class HorseSettings : MammalSettings
{
[CommandOption("-d|--day")]
public DayOfWeek Day { get; set; }
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Model>
<!--ANIMAL-->
<Command Name="animal" IsBranch="true" Settings="Spectre.Console.Tests.Data.AnimalSettings">
@ -27,9 +27,9 @@
</Parameters>
</Command>
<!--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>
<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>
</Command>
</Command>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Model>
<!--ANIMAL-->
<Command Name="animal" IsBranch="true" Settings="Spectre.Console.Tests.Data.AnimalSettings">
@ -23,8 +23,9 @@
</Parameters>
</Command>
<!--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>
<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" />
</Parameters>
</Command>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Model>
<!--DEFAULT COMMAND-->
<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>
</Command>
<!--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>
<Argument Name="LEGS" Position="0" Required="false" Kind="scalar" ClrType="System.Int32">
<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">
<Description>Indicates whether or not the animal is alive.</Description>
</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" />
</Parameters>
</Command>

View File

@ -29,5 +29,52 @@ public sealed partial class CommandAppTests
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));
}
}
}