From 732557b0776133878d25cdca1463a21521ea40c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Wed, 10 Nov 2021 11:59:02 +0100 Subject: [PATCH] Fix type conversion in the default pair deconstructor implementation The code using the TypeConverter was written backwards (using `ConvertTo` instead of `ConvertFrom` and would thus throw an exception. For example, when converting an enum: > System.NotSupportedException: 'EnumConverter' is unable to convert 'System.String' to 'System.DayOfWeek'. A test covering conversion of enums was added: `Should_Map_Pairs_With_Enum_Value_To_Pair_Deconstructable_Collection_Using_Default_Deconstructor` --- .../Cli/Internal/DefaultPairDeconstructor.cs | 12 +++---- .../Unit/Cli/CommandAppTests.Pairs.cs | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Spectre.Console/Cli/Internal/DefaultPairDeconstructor.cs b/src/Spectre.Console/Cli/Internal/DefaultPairDeconstructor.cs index ed7279ae0..86b8f4878 100644 --- a/src/Spectre.Console/Cli/Internal/DefaultPairDeconstructor.cs +++ b/src/Spectre.Console/Cli/Internal/DefaultPairDeconstructor.cs @@ -19,9 +19,6 @@ internal sealed class DefaultPairDeconstructor : IPairDeconstructor throw new ArgumentNullException(nameof(value)); } - var keyConverter = GetConverter(keyType); - var valueConverter = GetConverter(valueType); - var parts = value.Split(new[] { '=' }, StringSplitOptions.None); if (parts.Length < 1 || parts.Length > 2) { @@ -47,15 +44,16 @@ internal sealed class DefaultPairDeconstructor : IPairDeconstructor } } - return (Parse(keyConverter, keyType, stringkey), - Parse(valueConverter, valueType, stringValue)); + return (Parse(stringkey, keyType), + Parse(stringValue, valueType)); } - private static object Parse(TypeConverter converter, Type type, string value) + private static object? Parse(string value, Type targetType) { try { - return converter.ConvertTo(value, type); + var converter = GetConverter(targetType); + return converter.ConvertFrom(value); } catch { diff --git a/test/Spectre.Console.Tests/Unit/Cli/CommandAppTests.Pairs.cs b/test/Spectre.Console.Tests/Unit/Cli/CommandAppTests.Pairs.cs index ea1565d66..df429caad 100644 --- a/test/Spectre.Console.Tests/Unit/Cli/CommandAppTests.Pairs.cs +++ b/test/Spectre.Console.Tests/Unit/Cli/CommandAppTests.Pairs.cs @@ -35,6 +35,12 @@ public sealed class DefaultPairDeconstructorSettings : CommandSettings public IDictionary Values { get; set; } } + public sealed class DefaultPairDeconstructorEnumValueSettings : CommandSettings + { + [CommandOption("--var ")] + public IDictionary Values { get; set; } + } + public sealed class LookupSettings : CommandSettings { [CommandOption("--var ")] @@ -153,6 +159,35 @@ public void Should_Map_Pairs_To_Pair_Deconstructable_Collection_Using_Default_De }); } + [Fact] + public void Should_Map_Pairs_With_Enum_Value_To_Pair_Deconstructable_Collection_Using_Default_Deconstructor() + { + // Given + var app = new CommandAppTester(); + app.SetDefaultCommand>(); + app.Configure(config => + { + config.PropagateExceptions(); + }); + + // When + var result = app.Run(new[] + { + "--var", "foo=Monday", + "--var", "bar=Tuesday", + }); + + // Then + result.ExitCode.ShouldBe(0); + result.Settings.ShouldBeOfType().And(pair => + { + pair.Values.ShouldNotBeNull(); + pair.Values.Count.ShouldBe(2); + pair.Values["foo"].ShouldBe(DayOfWeek.Monday); + pair.Values["bar"].ShouldBe(DayOfWeek.Tuesday); + }); + } + [Theory] [InlineData("foo=1=2", "Error: The value 'foo=1=2' is not in a correct format")] [InlineData("foo=1=2=3", "Error: The value 'foo=1=2=3' is not in a correct format")]