Skip to content

Commit 2c50367

Browse files
authored
Merge pull request #14 from jpdillingham/dev
Improved operand parsing, changed regular expression to allow for a wider variety of characters in argument names
2 parents a25c12f + 813e84d commit 2c50367

File tree

4 files changed

+265
-38
lines changed

4 files changed

+265
-38
lines changed

Examples/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using Utility.CommandLine;
45

56
namespace Examples
@@ -20,6 +21,9 @@ internal class Program
2021
[Argument('i', "integer")]
2122
private static int Int { get; set; }
2223

24+
[Argument('l', "list")]
25+
private static List<int> List { get; set; }
26+
2327
[Operands]
2428
private static string[] Operands { get; set; }
2529

@@ -74,7 +78,7 @@ private static void Print(string commandLine)
7478
Console.WriteLine("\r\nArgument\tValue");
7579
Console.WriteLine("-------\t\t-------");
7680

77-
Dictionary<string, string> argumentDictionary = Arguments.Parse(commandLine).ArgumentDictionary;
81+
Dictionary<string, object> argumentDictionary = Arguments.Parse(commandLine).ArgumentDictionary;
7882

7983
foreach (string key in argumentDictionary.Keys)
8084
{
@@ -88,6 +92,7 @@ private static void Print(string commandLine)
8892
Console.WriteLine("Bool\t\t" + Bool);
8993
Console.WriteLine("Int\t\t" + Int);
9094
Console.WriteLine("Double\t\t" + Double);
95+
Console.WriteLine("List\t\t" + String.Join(",", List.Select(o => o.ToString()).ToArray()));
9196

9297
Console.WriteLine("\r\nOperands\n-------");
9398

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Operands
182182
## Parsing
183183

184184
Argument key-value pairs can be parsed from any string using the ```Parse(string)``` method. This method returns a
185-
```Dictionary<string, string>``` containing all argument-value pairs.
185+
```Dictionary<string, object>``` containing all argument-value pairs.
186186

187187
If the string parameter is omitted, the value of ```Environment.CommandLine``` is used.
188188

@@ -192,7 +192,7 @@ from property handling quoted strings. There are generally very few instance in
192192
#### Example
193193

194194
```c#
195-
Dictionary<string, string> args = Arguments.Parse("-ab --foo bar");
195+
Dictionary<string, object> args = Arguments.Parse("-ab --foo bar");
196196
```
197197

198198
The example above would result in a dictionary ```args``` containing:

Utility.CommandLine.Arguments.Tests/Arguments.cs

Lines changed: 150 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public void Indexer()
162162
[Fact]
163163
public void Parse()
164164
{
165-
Dictionary<string, string> test = CommandLine.Arguments.Parse().ArgumentDictionary;
165+
Dictionary<string, object> test = CommandLine.Arguments.Parse().ArgumentDictionary;
166166

167167
Assert.NotEmpty(test);
168168
}
@@ -174,7 +174,7 @@ public void Parse()
174174
[Fact]
175175
public void ParseCaseSensitive()
176176
{
177-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--TEST -aBc").ArgumentDictionary;
177+
Dictionary<string, object> test = CommandLine.Arguments.Parse("--TEST -aBc").ArgumentDictionary;
178178

179179
Assert.True(test.ContainsKey("TEST"));
180180
Assert.False(test.ContainsKey("test"));
@@ -219,7 +219,7 @@ public void ParseEmpty()
219219
[Fact]
220220
public void ParseInnerQuotedStrings()
221221
{
222-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--test1 \"test \'1\'\" --test2 \'test \"2\"\'").ArgumentDictionary;
222+
Dictionary<string, object> test = CommandLine.Arguments.Parse("--test1 \"test \'1\'\" --test2 \'test \"2\"\'").ArgumentDictionary;
223223

224224
Assert.Equal("test \'1\'", test["test1"]);
225225
Assert.Equal("test \"2\"", test["test2"]);
@@ -232,7 +232,7 @@ public void ParseInnerQuotedStrings()
232232
[Fact]
233233
public void ParseLongAndShortMix()
234234
{
235-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--one=1 -ab 2 /three:3 -4 4").ArgumentDictionary;
235+
Dictionary<string, object> test = CommandLine.Arguments.Parse("--one=1 -ab 2 /three:3 -4 4").ArgumentDictionary;
236236

237237
Assert.Equal("1", test["one"]);
238238
Assert.True(test.ContainsKey("a"));
@@ -262,7 +262,7 @@ public void ParseMixedArgumentsAndOperands()
262262
[Fact]
263263
public void ParseMultipleQuotes()
264264
{
265-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--test1 \"1\" --test2 \"2\" --test3 \'3\' --test4 \'4\'").ArgumentDictionary;
265+
Dictionary<string, object> test = CommandLine.Arguments.Parse("--test1 \"1\" --test2 \"2\" --test3 \'3\' --test4 \'4\'").ArgumentDictionary;
266266

267267
Assert.Equal("1", test["test1"]);
268268
Assert.Equal("2", test["test2"]);
@@ -328,7 +328,7 @@ public void ParseOperands()
328328
[Fact]
329329
public void ParseShorts()
330330
{
331-
Dictionary<string, string> test = CommandLine.Arguments.Parse("-abc 'hello world'").ArgumentDictionary;
331+
Dictionary<string, object> test = CommandLine.Arguments.Parse("-abc 'hello world'").ArgumentDictionary;
332332

333333
Assert.True(test.ContainsKey("a"));
334334
Assert.Equal(string.Empty, test["a"]);
@@ -340,6 +340,34 @@ public void ParseShorts()
340340
Assert.Equal("hello world", test["c"]);
341341
}
342342

343+
/// <summary>
344+
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with a a string containing only the
345+
/// strict operand delimiter.
346+
/// </summary>
347+
[Fact]
348+
public void ParseStrictOperandDelimiterOnly()
349+
{
350+
CommandLine.Arguments test = CommandLine.Arguments.Parse("--");
351+
352+
Assert.Equal(0, test.OperandList.Count);
353+
}
354+
355+
/// <summary>
356+
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with a a string containing multiple
357+
/// strict operand delimiters.
358+
/// </summary>
359+
[Fact]
360+
public void ParseStrictOperandMultipleDelimiter()
361+
{
362+
CommandLine.Arguments test = CommandLine.Arguments.Parse("one -- two -- three");
363+
364+
Assert.Equal(4, test.OperandList.Count);
365+
Assert.Equal("one", test.OperandList[0]);
366+
Assert.Equal("two", test.OperandList[1]);
367+
Assert.Equal("--", test.OperandList[2]);
368+
Assert.Equal("three", test.OperandList[3]);
369+
}
370+
343371
/// <summary>
344372
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an explicit operand delimiter.
345373
/// </summary>
@@ -365,20 +393,34 @@ public void ParseStrictOperands()
365393
[Fact]
366394
public void ParseStrictOperandsEmpty()
367395
{
368-
CommandLine.Arguments test = CommandLine.Arguments.Parse("--test one two -- ");
396+
CommandLine.Arguments test = CommandLine.Arguments.Parse("--test one two --");
369397

370398
Assert.Equal(1, test.OperandList.Count);
371399
Assert.Equal("two", test.OperandList[0]);
372400
}
373401

402+
/// <summary>
403+
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with a a string beginning with the
404+
/// explicit operand delimiter.
405+
/// </summary>
406+
[Fact]
407+
public void ParseStrictOperandsStart()
408+
{
409+
CommandLine.Arguments test = CommandLine.Arguments.Parse("-- one two");
410+
411+
Assert.Equal(2, test.OperandList.Count);
412+
Assert.Equal("one", test.OperandList[0]);
413+
Assert.Equal("two", test.OperandList[1]);
414+
}
415+
374416
/// <summary>
375417
/// Tests the <see cref="Utility.CommandLine.Arguments.Parse(string)"/> method with an explicit command line string
376418
/// containing only long parameters.
377419
/// </summary>
378420
[Fact]
379421
public void ParseStringOfLongs()
380422
{
381-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--one 1 --two=2 /three:3 --four \"4 4\" --five='5 5'").ArgumentDictionary;
423+
Dictionary<string, object> test = CommandLine.Arguments.Parse("--one 1 --two=2 /three:3 --four \"4 4\" --five='5 5'").ArgumentDictionary;
382424

383425
Assert.NotEmpty(test);
384426
Assert.Equal(5, test.Count);
@@ -396,7 +438,7 @@ public void ParseStringOfLongs()
396438
[Fact]
397439
public void ParseValueWithQuotedPeriod()
398440
{
399-
Dictionary<string, string> test = CommandLine.Arguments.Parse("--test \"test.test\" --test2 'test2.test2'").ArgumentDictionary;
441+
Dictionary<string, object> test = CommandLine.Arguments.Parse("--test \"test.test\" --test2 'test2.test2'").ArgumentDictionary;
400442

401443
Assert.Equal("test.test", test["test"]);
402444
Assert.Equal("test2.test2", test["test2"]);
@@ -435,7 +477,7 @@ public void PopulateCaseSensitive()
435477
[Fact]
436478
public void PopulateDictionary()
437479
{
438-
Dictionary<string, string> dict = new Dictionary<string, string>();
480+
Dictionary<string, object> dict = new Dictionary<string, object>();
439481
dict.Add("i", "1");
440482

441483
CommandLine.Arguments.Populate(dict);
@@ -642,6 +684,55 @@ public void PopulateOperands()
642684
#endregion Public Methods
643685
}
644686

687+
/// <summary>
688+
/// Unit tests for the <see cref="CommandLine.Arguments"/> class.
689+
/// </summary>
690+
/// <remarks>Used to facilitate testing of a class with an array property.</remarks>
691+
[Collection("Arguments")]
692+
public class TestClassWithArrayProperty
693+
{
694+
#region Private Properties
695+
696+
[CommandLine.Argument('a', "array")]
697+
private static string[] Array { get; set; }
698+
699+
#endregion Private Properties
700+
701+
#region Public Methods
702+
703+
/// <summary>
704+
/// Tests the <see cref="Utility.CommandLine.Arguments.Populate(Type, string)"/> method with an explicit string
705+
/// containing multiple instances of the same argument.
706+
/// </summary>
707+
[Fact]
708+
public void Populate()
709+
{
710+
Exception ex = Record.Exception(() => CommandLine.Arguments.Populate(GetType(), "-a one -a two -a three"));
711+
712+
Assert.Null(ex);
713+
Assert.Equal(3, Array.Length);
714+
Assert.Equal("one", Array[0]);
715+
Assert.Equal("two", Array[1]);
716+
Assert.Equal("three", Array[2]);
717+
}
718+
719+
/// <summary>
720+
/// Tests the <see cref="Utility.CommandLine.Arguments.Populate(Type, string)"/> method with an explicit string
721+
/// containing a single a single instance of an array-backed argument.
722+
/// </summary>
723+
[Fact]
724+
public void PopulateSingle()
725+
{
726+
Exception ex = Record.Exception(() => CommandLine.Arguments.Populate(GetType(), "-a one"));
727+
728+
Assert.Null(ex);
729+
Assert.Equal(1, Array.Length);
730+
Assert.Equal("one", Array[0]);
731+
}
732+
733+
#endregion Public Methods
734+
}
735+
645736
/// <summary>
646737
/// Unit tests for the <see cref="CommandLine.Arguments"/> class.
647738
/// </summary>
@@ -680,6 +771,55 @@ public void PopulateOperands()
680771
#endregion Public Methods
681772
}
682773

774+
/// <summary>
775+
/// Unit tests for the <see cref="CommandLine.Arguments"/> class.
776+
/// </summary>
777+
/// <remarks>Used to facilitate testing of a class with a List{T} property.</remarks>
778+
[Collection("Arguments")]
779+
public class TestClassWithListProperty
780+
{
781+
#region Private Properties
782+
783+
[CommandLine.Argument('l', "list")]
784+
private static List<string> List { get; set; }
785+
786+
#endregion Private Properties
787+
788+
#region Public Methods
789+
790+
/// <summary>
791+
/// Tests the <see cref="Utility.CommandLine.Arguments.Populate(Type, string)"/> method with an explicit string
792+
/// containing multiple instances of a list-backed argument.
793+
/// </summary>
794+
[Fact]
795+
public void Populate()
796+
{
797+
Exception ex = Record.Exception(() => CommandLine.Arguments.Populate(GetType(), "-l one -l two -l three"));
798+
799+
Assert.Null(ex);
800+
Assert.Equal(3, List.Count);
801+
Assert.Equal("one", List[0]);
802+
Assert.Equal("two", List[1]);
803+
Assert.Equal("three", List[2]);
804+
}
805+
806+
/// <summary>
807+
/// Tests the <see cref="Utility.CommandLine.Arguments.Populate(Type, string)"/> method with an explicit string
808+
/// containing a single a single instance of a list-backed argument.
809+
/// </summary>
810+
[Fact]
811+
public void PopulateSingle()
812+
{
813+
Exception ex = Record.Exception(() => CommandLine.Arguments.Populate(GetType(), "-l one"));
814+
815+
Assert.Null(ex);
816+
Assert.Equal(1, List.Count);
817+
Assert.Equal("one", List[0]);
818+
}
819+
820+
#endregion Public Methods
821+
}
822+
683823
/// <summary>
684824
/// Unit tests for the <see cref="CommandLine.Arguments"/> class.
685825
/// </summary>

0 commit comments

Comments
 (0)