diff --git a/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionParameterAttribute.cs b/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionParameterAttribute.cs index fc8ec0a3..011eb8bd 100644 --- a/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionParameterAttribute.cs +++ b/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionParameterAttribute.cs @@ -1,4 +1,5 @@ using System; +using CreativeCoders.Core; using JetBrains.Annotations; namespace CreativeCoders.SysConsole.Cli.Parsing; @@ -7,23 +8,29 @@ namespace CreativeCoders.SysConsole.Cli.Parsing; [AttributeUsage(AttributeTargets.Property)] public sealed class OptionParameterAttribute : OptionBaseAttribute { + public OptionParameterAttribute(string shortName, string longName) + { + ShortName = Ensure.IsNotNullOrWhitespace(shortName); + LongName = Ensure.IsNotNullOrWhitespace(longName); + } + public OptionParameterAttribute(char shortName, string longName) { - ShortName = shortName; - LongName = longName; + ShortName = shortName.ToString(); + LongName = Ensure.IsNotNullOrWhitespace(longName); } public OptionParameterAttribute(char shortName) { - ShortName = shortName; + ShortName = shortName.ToString(); } public OptionParameterAttribute(string longName) { - LongName = longName; + LongName = Ensure.IsNotNullOrWhitespace(longName); } - public char? ShortName { get; } + public string? ShortName { get; } public string? LongName { get; } } diff --git a/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionProperties/OptionParameterProperty.cs b/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionProperties/OptionParameterProperty.cs index 1207460f..0b1607e1 100644 --- a/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionProperties/OptionParameterProperty.cs +++ b/source/SysConsole/CreativeCoders.SysConsole.Cli.Parsing/OptionProperties/OptionParameterProperty.cs @@ -1,26 +1,24 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using CreativeCoders.Core; namespace CreativeCoders.SysConsole.Cli.Parsing.OptionProperties; -public class OptionParameterProperty : OptionPropertyBase +public class OptionParameterProperty( + PropertyInfo propertyInfo, + OptionParameterAttribute optionParameterAttribute) + : OptionPropertyBase(propertyInfo, optionParameterAttribute) { - private readonly OptionParameterAttribute _optionParameterAttribute; - - public OptionParameterProperty(PropertyInfo propertyInfo, - OptionParameterAttribute optionParameterAttribute) - : base(propertyInfo, optionParameterAttribute) - { - _optionParameterAttribute = optionParameterAttribute; - } + private readonly OptionParameterAttribute _optionParameterAttribute = + Ensure.NotNull(optionParameterAttribute); public override bool Read(IEnumerable optionArguments, object optionObject) { var optionArgument = optionArguments .FirstOrDefault(x => (x.Kind == OptionArgumentKind.ShortName - && x.OptionName == _optionParameterAttribute.ShortName.ToString()) || + && x.OptionName == _optionParameterAttribute.ShortName) || (x.Kind == OptionArgumentKind.LongName && x.OptionName == _optionParameterAttribute.LongName)); diff --git a/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/OptionParserTests.cs b/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/OptionParserTests.cs index 9351812e..39208c10 100644 --- a/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/OptionParserTests.cs +++ b/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/OptionParserTests.cs @@ -24,7 +24,7 @@ public void Parse_ValueAndParameterWithLongName_PropertiesAreSetCorrect() .Should() .NotBeNull(); - option!.HelloWorld + option.HelloWorld .Should() .Be("hello"); @@ -48,7 +48,7 @@ public void Parse_ValueAndParameterWithShortName_PropertiesAreSetCorrect() .Should() .NotBeNull(); - option!.HelloWorld + option.HelloWorld .Should() .Be("hello"); @@ -57,6 +57,54 @@ public void Parse_ValueAndParameterWithShortName_PropertiesAreSetCorrect() .Be("TestText"); } + [Fact] + public void Parse_ValueAndParameterWithMultiCharShortName_PropertiesAreSetCorrect() + { + var args = new[] { "hello", "-te", "TestText" }; + + var parser = new OptionParser(typeof(TestOptionForParser)); + + // Act + var option = parser.Parse(args) as TestOptionForParser; + + // Assert + option + .Should() + .NotBeNull(); + + option.HelloWorld + .Should() + .Be("hello"); + + option.TextValueMultiCharShortName + .Should() + .Be("TestText"); + } + + [Fact] + public void Parse_ValueAndParameterWithMultiCharShortNameAndSingleChar_PropertiesAreSetCorrect() + { + var args = new[] { "hello", "-te", "TestText", "-t", "ShotText" }; + + var parser = new OptionParser(typeof(TestOptionForParser)); + + // Act + var option = parser.Parse(args) as TestOptionForParser; + + // Assert + option + .Should().NotBeNull(); + + option.HelloWorld + .Should().Be("hello"); + + option.TextValue + .Should().Be("ShotText"); + + option.TextValueMultiCharShortName + .Should().Be("TestText"); + } + [Fact] public void Parse_IntValueAndParameterWithLongName_PropertiesAreSetCorrect() { @@ -76,7 +124,7 @@ public void Parse_IntValueAndParameterWithLongName_PropertiesAreSetCorrect() .Should() .NotBeNull(); - option!.IntValue + option.IntValue .Should() .Be(expectedValue0); @@ -103,7 +151,7 @@ public void Parse_IntValueAndParameterWithShortName_PropertiesAreSetCorrect() .Should() .NotBeNull(); - option!.IntValue + option.IntValue .Should() .Be(expectedValue0); @@ -158,7 +206,7 @@ public void Parse_BoolValues_PropertiesAreSetCorrect() .Should() .NotBeNull(); - option!.Verbose + option.Verbose .Should() .BeTrue(); @@ -182,7 +230,7 @@ public void Parse_BoolValuesInvalidFormat_PropertyIsSetFalse() .Should() .NotBeNull(); - option!.Verbose + option.Verbose .Should() .BeTrue(); @@ -232,7 +280,7 @@ public void Parse_ValueDefaultValue_DefaultValueIsSet() .Should() .NotBeNull(); - options!.FirstValue + options.FirstValue .Should() .Be(null); @@ -307,7 +355,7 @@ public void Parse_EnumValue_PropertyIsSetCorrect(string argValue, TestEnum enumV .Should() .NotBeNull(); - option!.EnumValue + option.EnumValue .Should() .Be(enumValue); } @@ -331,7 +379,7 @@ public void Parse_PropertyWithConverter_PropertyIsSetCorrect(string argValue, st .Should() .NotBeNull(); - option!.Text + option.Text .Should() .Be(propertyValue); } @@ -355,7 +403,7 @@ public void Parse_PropertyIsIEnumerableOfInt_PropertyIsSetCorrect(string argValu .Should() .NotBeNull(); - option!.IntValues + option.IntValues .Should() .ContainInOrder(intValues); } @@ -379,7 +427,7 @@ public void Parse_PropertyIsEnumWithFlags_EnumFlagsAreSetCorrect(string argValue .Should() .NotBeNull(); - option!.EnumValue + option.EnumValue .Should() .Be(enumWithFlags); } @@ -406,7 +454,7 @@ public void Parse_NotAllArgsMatch_ThrowsException(params string[] args) .Should() .HaveCount(1) .And - .BeEquivalentTo(new[] { new OptionArgument { Kind = OptionArgumentKind.Value, Value = "test" } }); + .BeEquivalentTo([new OptionArgument { Kind = OptionArgumentKind.Value, Value = "test" }]); } [Theory] diff --git a/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/TestData/TestOptionForParser.cs b/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/TestData/TestOptionForParser.cs index 6e83b8c8..f2a6bda3 100644 --- a/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/TestData/TestOptionForParser.cs +++ b/tests/CreativeCoders.SysConsole.Cli.Parsing.UnitTests/TestData/TestOptionForParser.cs @@ -7,4 +7,6 @@ public class TestOptionForParser [OptionValue(0)] public string? HelloWorld { get; [UsedImplicitly] set; } [OptionParameter('t', "text")] public string? TextValue { get; [UsedImplicitly] set; } + + [OptionParameter("te", "text2")] public string? TextValueMultiCharShortName { get; [UsedImplicitly] set; } }