Validate option name length

Closes #40
This commit is contained in:
Alexey Golub
2020-04-16 16:51:51 +03:00
parent 8c3b8d1f49
commit 7d3ba612c4
4 changed files with 69 additions and 2 deletions

View File

@@ -76,6 +76,24 @@ namespace CliFx.Tests
public ValueTask ExecuteAsync(IConsole console) => default;
}
[Command]
private class EmptyOptionNameCommand : ICommand
{
[CommandOption("")]
public string? Apples { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default;
}
[Command]
private class SingleCharacterOptionNameCommand : ICommand
{
[CommandOption("a")]
public string? Apples { get; set; }
public ValueTask ExecuteAsync(IConsole console) => default;
}
[Command]
private class DuplicateOptionNamesCommand : ICommand
{

View File

@@ -125,6 +125,26 @@ namespace CliFx.Tests
Assert.Throws<CliFxException>(() => ApplicationSchema.Resolve(commandTypes));
}
[Fact]
public void Command_options_must_have_names_that_are_not_empty()
{
// Arrange
var commandTypes = new[] {typeof(EmptyOptionNameCommand)};
// Act & assert
Assert.Throws<CliFxException>(() => ApplicationSchema.Resolve(commandTypes));
}
[Fact]
public void Command_options_must_have_names_that_are_longer_than_one_character()
{
// Arrange
var commandTypes = new[] {typeof(SingleCharacterOptionNameCommand)};
// Act & assert
Assert.Throws<CliFxException>(() => ApplicationSchema.Resolve(commandTypes));
}
[Fact]
public void Command_options_must_have_unique_names()
{

View File

@@ -9,14 +9,14 @@ namespace CliFx.Attributes
public class CommandOptionAttribute : Attribute
{
/// <summary>
/// Option name.
/// Option name (must be longer than a single character).
/// Either <see cref="Name"/> or <see cref="ShortName"/> must be set.
/// All options in a command must have different names (comparison is not case-sensitive).
/// </summary>
public string? Name { get; }
/// <summary>
/// Option short name.
/// Option short name (single character).
/// Either <see cref="Name"/> or <see cref="ShortName"/> must be set.
/// All options in a command must have different short names (comparison is case-sensitive).
/// </summary>

View File

@@ -163,6 +163,35 @@ namespace CliFx.Domain
private static void ValidateOptions(CommandSchema command)
{
var emptyNameGroup = command.Options
.Where(o => o.ShortName == null && string.IsNullOrWhiteSpace(o.Name))
.ToArray();
if (emptyNameGroup.Any())
{
throw new CliFxException(new StringBuilder()
.AppendLine($"Command {command.Type.FullName} contains one or more options that have empty names:")
.AppendBulletList(emptyNameGroup.Select(o => o.Property.Name))
.AppendLine()
.Append("Options in a command must all have at least a name or a short name.")
.ToString());
}
var invalidNameGroup = command.Options
.Where(o => !string.IsNullOrWhiteSpace(o.Name))
.Where(o => o.Name.Length <= 1)
.ToArray();
if (invalidNameGroup.Any())
{
throw new CliFxException(new StringBuilder()
.AppendLine($"Command {command.Type.FullName} contains one or more options that have names that are too short:")
.AppendBulletList(invalidNameGroup.Select(o => o.Property.Name))
.AppendLine()
.Append("Options in a command must all have names that are longer than a single character.")
.ToString());
}
var duplicateNameGroup = command.Options
.Where(o => !string.IsNullOrWhiteSpace(o.Name))
.GroupBy(o => o.Name, StringComparer.OrdinalIgnoreCase)