Skip to content

Commit 52e2c38

Browse files
authored
Split key on postfix value if needed (#43)
* Split key on postfix value if needed * Allow arguments to be split on postfix * Fix codefactor
1 parent 080a86d commit 52e2c38

13 files changed

+229
-17
lines changed

CommandLineParser.Tests/CommandLineParserTests.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,24 @@ public override void OnConfigure(ICommandConfigurationBuilder<object> builder)
2929
}
3030
}
3131

32+
[Theory]
33+
[InlineData(true)]
34+
[InlineData(false)]
35+
public void CommandLineParserParsesCorrectOptionsWithPostfix(bool useShort)
36+
{
37+
var query = $"{(useShort ? "-" : "--")}p=some text";
38+
39+
var parser = new CommandLineParser<AddOption>();
40+
41+
parser.Configure(p => p.Message).Name("p", "p").Required();
42+
43+
var result = parser.Parse(new string[] { query });
44+
45+
result.AssertNoErrors();
46+
47+
Assert.Equal("some text", result.Result.Message);
48+
}
49+
3250
[Fact]
3351
public void CommandLineParserUsesCorrectOptions()
3452
{
@@ -174,7 +192,7 @@ public void ParseTests()
174192

175193
[Theory]
176194
[InlineData(new[] { "app.exe", "-e", "Opt1" }, false, EnumOption.Opt1)]
177-
[InlineData(new[] { "app.exe", "-e", "opt1" }, false, EnumOption.Opt1)]
195+
[InlineData(new[] { "app.exe", "-e=opt1" }, false, EnumOption.Opt1)]
178196
[InlineData(new[] { "app.exe", "-e", "Opt2" }, false, EnumOption.Opt2)]
179197
[InlineData(new[] { "app.exe", "-e", "bla" }, true, default(EnumOption))]
180198
[InlineData(new[] { "app.exe", "-e" }, true, default(EnumOption))]
@@ -195,11 +213,11 @@ public void ParseEnumInArguments(string[] args, bool hasErrors, EnumOption enumO
195213

196214
[Theory]
197215
// string
198-
[InlineData(typeof(string), new[] { "-1", "message1", "-2", "-3" }, "default", "message1", "default", "default")]
216+
[InlineData(typeof(string), new[] { "-1=message1", "-2", "-3" }, "default", "message1", "default", "default")]
199217
[InlineData(typeof(string), new[] { "-1", "-2", "message2", "-3" }, "default", "default", "message2", "default")]
200218
[InlineData(typeof(string), new[] { "-1", "-2", "-3" }, "default", "default", "default", "default")]
201219
// bool
202-
[InlineData(typeof(bool), new[] { "-1", "false", "-2", "-3" }, false, false, true, true)]
220+
[InlineData(typeof(bool), new[] { "-1=false", "-2", "-3" }, false, false, true, true)]
203221
[InlineData(typeof(bool), new[] { "-1", "-2", "false", "-3" }, false, true, false, true)]
204222
[InlineData(typeof(bool), new[] { "-1", "-2", "-3" }, false, true, true, true)]
205223
//// int
@@ -316,7 +334,7 @@ public void ParseWithCommandTests()
316334
.Name("m", "message")
317335
.Required();
318336

319-
var parsed = parser.Parse(new string[] { "app.exe", "-o", "test", "add", "-m", "my message" });
337+
var parsed = parser.Parse(new string[] { "app.exe", "-o", "test", "add", "-m=my message" });
320338

321339
parsed.AssertNoErrors();
322340

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Xunit;
2+
using MatthiWare.CommandLine.Core.Utils;
3+
using System.Linq;
4+
using Moq;
5+
using MatthiWare.CommandLine.Abstractions;
6+
7+
namespace MatthiWare.CommandLine.Tests.Utils
8+
{
9+
public class ExtensionMethodsTest
10+
{
11+
[Fact]
12+
public void TestSplitOnPostFixWorksCorrectly()
13+
{
14+
var settings = new CommandLineParserOptions();
15+
16+
var mockTestOption1 = CreateMock(settings, "test").Object;
17+
var mockTestOption2 = CreateMock(settings, "test2", "test2").Object;
18+
var mockTestOption3 = CreateMock(settings, "test3").Object;
19+
var mockTestOption4 = CreateMock(settings, "blabla", "blabla").Object;
20+
21+
var options = new[]
22+
{
23+
mockTestOption1,
24+
mockTestOption2,
25+
mockTestOption3,
26+
mockTestOption4
27+
};
28+
29+
var input = new[] { "--test=1", "-test2=\"some value\"", "--test3=some value", "-blabla", "third" };
30+
var output = input.SplitOnPostfix(settings, options).ToArray();
31+
32+
Assert.Equal("--test", output[0]);
33+
Assert.Equal("1", output[1]);
34+
Assert.Equal("-test2", output[2]);
35+
Assert.Equal("\"some value\"", output[3]);
36+
Assert.Equal("--test3", output[4]);
37+
Assert.Equal("some value", output[5]);
38+
Assert.Equal("-blabla", output[6]);
39+
Assert.Equal("third", output[7]);
40+
}
41+
42+
[Fact]
43+
public void TestSplitOnPostFixWorksCorrectly_2()
44+
{
45+
var settings = new CommandLineParserOptions();
46+
47+
var testOption = CreateMock(settings, "test").Object;
48+
49+
var options = new[]
50+
{
51+
testOption,
52+
};
53+
54+
var input = new[] { "--test", "some=value" };
55+
56+
var output = input.SplitOnPostfix(settings, options).ToArray();
57+
58+
Assert.Equal("--test", output[0]);
59+
Assert.Equal("some=value", output[1]);
60+
}
61+
62+
private Mock<ICommandLineOption> CreateMock(CommandLineParserOptions settings, string longName, string shortName = "")
63+
{
64+
var mock = new Mock<ICommandLineOption>();
65+
66+
mock.SetupGet(option => option.LongName).Returns($"{settings.PrefixLongOption}{longName}");
67+
mock.SetupGet(option => option.HasLongName).Returns(true);
68+
69+
if (!string.IsNullOrWhiteSpace(shortName))
70+
{
71+
mock.SetupGet(option => option.ShortName).Returns($"{settings.PrefixShortOption}{shortName}");
72+
mock.SetupGet(option => option.HasShortName).Returns(true);
73+
}
74+
75+
return mock;
76+
}
77+
}
78+
}

CommandLineParser/Abstractions/Command/Command.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
/// <summary>
44
/// Defines a command
55
/// </summary>
6-
/// <typeparam name="TOptions">Base options of the command</typeparam>
76
public abstract class Command
87
{
98
/// <summary>

CommandLineParser/Abstractions/Command/ICommandBuilder'.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace MatthiWare.CommandLine.Abstractions.Command
77
/// Configures commands using a fluent interface
88
/// </summary>
99
/// <typeparam name="TSource">Command options class</typeparam>
10+
/// <typeparam name="TOption">Base option</typeparam>
1011
public interface ICommandBuilder<TOption, TSource> : ICommandConfigurationBuilder, ICommandExecutor<TOption, TSource>
1112
where TOption : class
1213
where TSource : class, new()

CommandLineParser/Abstractions/Command/ICommandBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public interface ICommandBuilder<TOption>
2626
/// <summary>
2727
/// Describes the command, used in the usage output.
2828
/// </summary>
29-
/// <param name="desc">description of the command</param>
29+
/// <param name="description">description of the command</param>
3030
/// <returns><see cref="ICommandBuilder{TOption}"/></returns>
3131
ICommandBuilder<TOption> Description(string description);
3232

CommandLineParser/Abstractions/Command/ICommandConfigurationBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public interface ICommandConfigurationBuilder
1515
/// <summary>
1616
/// Configures the description text for the command
1717
/// </summary>
18-
/// <param name="required">True or false</param>
18+
/// <param name="description">Description</param>
1919
/// <returns><see cref="ICommandConfigurationBuilder"/></returns>
2020
ICommandConfigurationBuilder Description(string description);
2121

CommandLineParser/Abstractions/Command/ICommandLineCommand.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,24 @@
55
/// </summary>
66
public interface ICommandLineCommand : IArgument
77
{
8+
/// <summary>
9+
/// Name of the command
10+
/// </summary>
811
string Name { get; }
12+
13+
/// <summary>
14+
/// Indicates if the command is required or not
15+
/// </summary>
916
bool IsRequired { get; }
17+
18+
/// <summary>
19+
/// Description of the command
20+
/// </summary>
1021
string Description { get; }
22+
23+
/// <summary>
24+
/// Auto executes the command if set to true
25+
/// </summary>
1126
bool AutoExecute { get; }
1227
}
1328
}

CommandLineParser/Abstractions/ICommandLineOption.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,39 @@
55
/// </summary>
66
public interface ICommandLineOption : IArgument
77
{
8+
/// <summary>
9+
/// Short name of the option
10+
/// </summary>
811
string ShortName { get; }
12+
13+
/// <summary>
14+
/// Long name of the option
15+
/// </summary>
916
string LongName { get; }
17+
18+
/// <summary>
19+
/// Description of the option
20+
/// </summary>
1021
string Description { get; }
22+
23+
/// <summary>
24+
/// Indicates if the option is required
25+
/// </summary>
1126
bool IsRequired { get; }
27+
28+
/// <summary>
29+
/// Indicates if a short option name has been specified
30+
/// </summary>
1231
bool HasShortName { get; }
32+
33+
/// <summary>
34+
/// Indicates if a long option name has been specified
35+
/// </summary>
1336
bool HasLongName { get; }
37+
38+
/// <summary>
39+
/// Inidicates if a default value has been specified for this option
40+
/// </summary>
1441
bool HasDefault { get; }
1542
}
1643
}

CommandLineParser/CommandLineParser.xml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CommandLineParser/CommandLineParserOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public class CommandLineParserOptions
1414
/// </summary>
1515
public string PrefixLongOption { get; set; } = "--";
1616

17+
/// <summary>
18+
/// Postfix for the long option
19+
/// </summary>
20+
public string PostfixOption { get; set; } = "=";
21+
1722
/// <summary>
1823
/// Help option name.
1924
/// Accepts both formatted and unformatted help name.

0 commit comments

Comments
 (0)