From 038f48b78e6a38fa54846ad3603b5f10e8263c70 Mon Sep 17 00:00:00 2001 From: Robert Dailey Date: Thu, 8 Apr 2021 12:51:17 -0500 Subject: [PATCH] Show choices on non-scalar enum parameters and options (#102) --- CliFx.Tests/HelpTextSpecs.cs | 47 +++++++++++++++++++++- CliFx/Schema/BindablePropertyDescriptor.cs | 14 ++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CliFx.Tests/HelpTextSpecs.cs b/CliFx.Tests/HelpTextSpecs.cs index 3fcba11..8a1e08f 100644 --- a/CliFx.Tests/HelpTextSpecs.cs +++ b/CliFx.Tests/HelpTextSpecs.cs @@ -577,6 +577,51 @@ public class Command : ICommand ); } + [Fact] + public async Task Help_text_shows_all_valid_values_for_non_scalar_enum_parameters_and_options() + { + // Arrange + var commandType = DynamicCommandBuilder.Compile( + // language=cs + @" +public enum CustomEnum { One, Two, Three } + +[Command] +public class Command : ICommand +{ + [CommandParameter(0)] + public List Foo { get; set; } + + [CommandOption(""bar"")] + public List Bar { get; set; } + + public ValueTask ExecuteAsync(IConsole console) => default; +} +"); + + var application = new CliApplicationBuilder() + .AddCommand(commandType) + .UseConsole(FakeConsole) + .Build(); + + // Act + var exitCode = await application.RunAsync( + new[] {"--help"}, + new Dictionary() + ); + + var stdOut = FakeConsole.ReadOutputString(); + + // Assert + exitCode.Should().Be(0); + stdOut.Should().ContainAllInOrder( + "PARAMETERS", + "foo", "Choices:", "One", "Two", "Three", + "OPTIONS", + "--bar", "Choices:", "One", "Two", "Three" + ); + } + [Fact] public async Task Help_text_shows_environment_variables_for_options_that_have_them_configured_as_fallback() { @@ -875,4 +920,4 @@ public class SecondCommandSecondChildCommand : ICommand stdOut.Trim().Should().Be("v6.9"); } } -} \ No newline at end of file +} diff --git a/CliFx/Schema/BindablePropertyDescriptor.cs b/CliFx/Schema/BindablePropertyDescriptor.cs index 289e99f..0f9b804 100644 --- a/CliFx/Schema/BindablePropertyDescriptor.cs +++ b/CliFx/Schema/BindablePropertyDescriptor.cs @@ -21,7 +21,17 @@ namespace CliFx.Schema public IReadOnlyList GetValidValues() { - var underlyingType = Type.TryGetNullableUnderlyingType() ?? Type; + Type typeToCheck = Type; + foreach (var inf in typeToCheck.GetInterfaces()) + { + if (inf.IsGenericType && inf.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + typeToCheck = inf.GenericTypeArguments[0]; + break; + } + } + + var underlyingType = typeToCheck.TryGetNullableUnderlyingType() ?? typeToCheck; // We can only get valid values for enums if (underlyingType.IsEnum) @@ -30,4 +40,4 @@ namespace CliFx.Schema return Array.Empty(); } } -} \ No newline at end of file +}