Skip to content

Commit

Permalink
Merge pull request #28 from joncloud/enum-help
Browse files Browse the repository at this point in the history
Implements better support for enum options
  • Loading branch information
joncloud authored Aug 12, 2020
2 parents 4e2987d + a15bc65 commit bd09219
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 11 deletions.
16 changes: 14 additions & 2 deletions src/ThorNet/Option.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
using System.Linq;

namespace ThorNet
{
internal class Option
{
readonly string[] _possibleValues;

public Option(OptionAttribute attribute)
: this(attribute.Alias, attribute.Name)
: this(attribute.Alias, attribute.Name, attribute.GetPossibleValues())
{
AllowFlag = attribute.Flag;
}

public Option(string alias, string name = null)
public Option(string alias, string name = null, string[] possibleValues = null)
{
Alias = alias;
Name = name ?? alias;
_possibleValues = possibleValues;
}

public string Alias { get; }
public bool AllowFlag { get; set; }
public string Name { get; }
public string Value { get; set; }

internal bool ShouldUseValue(string value)
{
if (_possibleValues is null) return true;

return _possibleValues.Contains(value);
}
}
}
27 changes: 27 additions & 0 deletions src/ThorNet/OptionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,32 @@ public OptionAttribute(string name, string alias, string description)
/// Gets the name of the option.
/// </summary>
public string Name { get; }

Type _enumType;
/// <summary>
/// Gets or sets the enum type used to help describe information in help.
/// </summary>
public Type EnumType
{
get => _enumType;
set
{
if (!(value is null) && !value.IsEnum)
{
throw new ArgumentException("value must be an enum type", nameof(value));
}
_enumType = value;
}
}

internal string[] GetPossibleValues()
{
if (!(EnumType is null))
{
return Enum.GetNames(EnumType);
}

return null;
}
}
}
12 changes: 6 additions & 6 deletions src/ThorNet/OptionSubstitutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ private bool TrySubstituteOption(
option = null;
return false;
}
option.Value = textValue;
return true;
}
else
{
return false;

if (option.ShouldUseValue(textValue))
{
option.Value = textValue;
return true;
}
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/ThorNet/Thor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,29 @@ int PrintCommandHelp(string commandName, string[] subcommandNames)

Terminal.WriteLine(message.ToString());
message.Clear();

// Print possible values
var possibleValues = option.GetPossibleValues();
if (!(possibleValues is null))
{
message.Append(' ', max);
message.Append(" # Possible values: ");

bool appendComma = false;
foreach (var possibleValue in possibleValues)
{
if (appendComma)
{
message.Append(", ");
}
message.Append(possibleValue);
appendComma = true;
}

Terminal.Truncate(message);
Terminal.WriteLine(message.ToString());
message.Clear();
}
}
Terminal.WriteLine();
}
Expand Down
35 changes: 32 additions & 3 deletions tests/ThorNet.UnitTests/OptionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ namespace ThorNet.UnitTests
{
public class OptionTests
{
[InlineData("Test,--class=A,--classDefault=B,--method=C,--methodDefault=D", "A,B,C,D")]
[InlineData("Test,-cA,-dB,-mC,-nD", "A,B,C,D")]
[InlineData("Test,--class=A,--classDefault=B,--method=Foo,--methodDefault=D", "A,B,Foo,D")]
[InlineData("Test,-cA,-dB,-mFoo,-nD", "A,B,Foo,D")]
[Theory]
public async Task Option_Tests(string args, string values)
{
Expand Down Expand Up @@ -50,6 +50,28 @@ public async Task Help_ShouldIncludeHyphen_GivenAliasWithHyphen()
Assert.Equal(expected, actual);
}

[Fact]
public async Task Help_ShouldIncludePossibleValues_GivenOptionEnumType()
{
var lines = (await GetHelpAsync()).ToArray();

int i;
for (i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith(" -m"))
{
break;
}
}

Assert.NotEqual(i, lines.Length - 1);

var actual = lines[i + 1];

var expected = " # Possible values: Foo, Bar, FooBar";
Assert.Equal(expected, actual);
}

static async Task<IEnumerable<string>> GetHelpAsync()
{
var terminal = new MockTerminal(100);
Expand Down Expand Up @@ -88,7 +110,7 @@ public Target(ITerminal terminal)

public static Options OptionValues { get; set; }

[Option("method", "m", "")]
[Option("method", "m", "", EnumType = typeof(PossibleValues))]
[Option("methodDefault", "-n", "method default help", DefaultValue = "MethodDefault")]
public void Test()
{
Expand All @@ -98,5 +120,12 @@ public void Test()
OptionValues.MethodDefault = Option("methodDefault");
}
}

public enum PossibleValues
{
Foo,
Bar,
FooBar
}
}
}

0 comments on commit bd09219

Please sign in to comment.