Skip to content

Commit cf253c1

Browse files
committed
Changed the way multi-valued options are specified so that each value needs to be preceded by the same prefix key. Revamped testing classes to focus on property being tested rather.
1 parent 49d556f commit cf253c1

31 files changed

+589
-887
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using FluentAssertions;
3+
using J4JSoftware.CommandLine;
4+
using Xunit;
5+
6+
namespace J4JCommandLine.Tests
7+
{
8+
public class ArrayPropertyTest
9+
{
10+
[Theory]
11+
[InlineData("-z 32 33", true, MappingResults.MissingRequired, new int[] { }, new int[] {33 })]
12+
[InlineData("-x 32 33", true, MappingResults.Success, new int[] { 32 }, new int[] { 33 })]
13+
[InlineData("-z 32 33", false, MappingResults.Success, new int[] { }, new int[] {33 })]
14+
[InlineData("-x 32 -x 33", true, MappingResults.Success, new int[] { 32, 33 }, new int[] { })]
15+
public void root_properties(
16+
string cmdLine,
17+
bool required,
18+
MappingResults result,
19+
int[] optValue,
20+
int[] unkeyedValues)
21+
{
22+
var target = ServiceProvider.GetBindingTarget<TestProperties>(false);
23+
var option = target!.Bind(x => x.IntArray, "x");
24+
var unkeyed = target!.BindUnkeyed(x => x.Unkeyed);
25+
26+
ProcessTest(cmdLine, required, target, option, unkeyed, result, () => target.Value, optValue,
27+
unkeyedValues);
28+
}
29+
30+
[Theory]
31+
[InlineData("-z 32 33", true, MappingResults.MissingRequired, new int[] { }, new int[] { 33})]
32+
[InlineData("-x 32 33", true, MappingResults.Success, new int[] { 32 }, new int[] { 33 })]
33+
[InlineData("-z 32 33", false, MappingResults.Success, new int[] { }, new int[] {33 })]
34+
[InlineData("-x 32 -x 33", true, MappingResults.Success, new int[] { 32, 33 }, new int[] { })]
35+
public void parameterless_properties(
36+
string cmdLine,
37+
bool required,
38+
MappingResults result,
39+
int[] optValue,
40+
int[] unkeyedValues)
41+
{
42+
var target = ServiceProvider.GetBindingTarget<ParameterlessConstructorParent>(false);
43+
var option = target!.Bind(x => x.TestProperties.IntArray, "x");
44+
var unkeyed = target!.BindUnkeyed(x => x.TestProperties.Unkeyed);
45+
46+
ProcessTest(cmdLine, required, target, option, unkeyed, result, () => target.Value.TestProperties, optValue,
47+
unkeyedValues);
48+
}
49+
50+
[Theory]
51+
[InlineData("-z 32 33", true, MappingResults.MissingRequired, new int[] { }, new int[] { 33})]
52+
[InlineData("-x 32 33", true, MappingResults.Success, new int[] { 32 }, new int[] { 33 })]
53+
[InlineData("-z 32 33", false, MappingResults.Success, new int[] { }, new int[] {33 })]
54+
[InlineData("-x 32 -x 33", true, MappingResults.Success, new int[] { 32, 33 }, new int[] { })]
55+
public void parametered_properties(
56+
string cmdLine,
57+
bool required,
58+
MappingResults result,
59+
int[] optValue,
60+
int[] unkeyedValues)
61+
{
62+
var target =
63+
ServiceProvider.GetBindingTarget<ParameteredConstructorParent>(
64+
false,
65+
new ParameteredConstructorParent(52));
66+
67+
var option = target!.Bind(x => x.TestProperties.IntArray, "x");
68+
var unkeyed = target!.BindUnkeyed(x => x.TestProperties.Unkeyed);
69+
70+
ProcessTest(cmdLine, required, target, option, unkeyed, result, () => target.Value.TestProperties, optValue,
71+
unkeyedValues);
72+
}
73+
74+
private void ProcessTest<T>(
75+
string cmdLine,
76+
bool required,
77+
BindingTarget<T> target,
78+
Option option,
79+
Option unkeyed,
80+
MappingResults desiredParseResults,
81+
Func<TestProperties> results,
82+
int[] optValue,
83+
int[] unkeyedValues)
84+
where T : class
85+
{
86+
target.Should().NotBeNull();
87+
88+
option.Should().BeAssignableTo<MappableOption>();
89+
unkeyed.Should().BeAssignableTo<MappableOption>();
90+
91+
if (required)
92+
option.Required();
93+
94+
var parseResults = target.Parse(new string[] { cmdLine });
95+
parseResults.Should().Be(desiredParseResults);
96+
97+
results().IntArray.Should().BeEquivalentTo(optValue);
98+
results().Unkeyed.Should().BeEquivalentTo(unkeyedValues);
99+
}
100+
}
101+
}

J4JCommandLine.Tests/CommandLineParsing.cs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,37 @@ public CommandLineParsing()
3131
}
3232

3333
[ Theory ]
34-
[ InlineData( new string[] { "-x", "hello" }, "x", new string[] { "hello" } ) ]
35-
[ InlineData( new string[] { "-x", "hello", "goodbye" }, "x", new string[] { "hello", "goodbye" } ) ]
36-
[ InlineData( new string[] { "-x" }, "x", new string[] { "true" } ) ]
37-
[ InlineData( new string[] { "-x:abc" }, "x", new string[] { "abc" } ) ]
38-
[ InlineData( new string[] { "-x:\"abc\"" }, "x", new string[] { "\"abc\"" } ) ]
39-
public void parse_one_item( string[] toParse, string key, string[] args )
34+
[ InlineData( "-x hello", new string[] { "hello" }, new string[] { } ) ]
35+
[ InlineData( "-x hello goodbye", new string[] { "hello" }, new string[] { "goodbye" } ) ]
36+
[ InlineData( "-x", new string[] { }, new string[] { } ) ]
37+
[ InlineData( "-x:abc", new string[] { "abc" }, new string[] { } ) ]
38+
[ InlineData( "-x:\"abc\"", new string[] { "\"abc\"" }, new string[] { } ) ]
39+
public void parse_one_item( string cmdLine, string[] optValue, string[] unkeyedValue )
4040
{
41-
var parsed = _cmdLineParser.Parse( toParse );
41+
var parsed = _cmdLineParser.Parse( cmdLine );
4242

4343
parsed.Count.Should().Be( 1 );
44-
parsed.Contains( key ).Should().BeTrue();
44+
parsed.Contains( "x" ).Should().BeTrue();
4545

46-
parsed[ key ].Parameters.Should().BeEquivalentTo( args );
46+
parsed[ "x" ].Parameters.Should().BeEquivalentTo( optValue );
47+
parsed.Unkeyed.Parameters.Should().BeEquivalentTo( unkeyedValue );
4748
}
4849

4950
[ Theory ]
50-
[ InlineData( new string[] { "-x", "hello", "-y", "goodbye" }, new string[] { "x", "y" },
51-
new string[] { "hello" }, new string[] { "goodbye" } ) ]
52-
[InlineData(new string[] { "-x", "hello", "-y" }, new string[] { "x", "y" },
53-
new string[] { "hello" }, new string[] { "true" })]
54-
[InlineData(new string[] { "-x", "hello", "goodbye", "-y" }, new string[] { "x", "y" },
55-
new string[] { "hello", "goodbye" }, new string[] { "true" })]
56-
[InlineData(new string[] { "-x", "hello", "-x", "goodbye" }, new string[] { "x" },
57-
new string[] { "hello", "goodbye" }, new string[] {})]
58-
public void parse_two_items( string[] toParse, string[] keys, string[] results1, string[] results2 )
51+
[ InlineData( "-x hello -y goodbye", new string[] { "x", "y" }, new string[] { "hello" },
52+
new string[] { "goodbye" }, new string[] { } ) ]
53+
[ InlineData( "-x hello -y", new string[] { "x", "y" }, new string[] { "hello" }, new string[] { },
54+
new string[] { } ) ]
55+
[ InlineData( "-x hello goodbye -y", new string[] { "x", "y" },
56+
new string[] { "hello" }, new string[] { }, new string[] { "goodbye" } ) ]
57+
[ InlineData( "-x hello -x goodbye", new string[] { "x" }, new string[] { "hello", "goodbye" },
58+
new string[] { }, new string[] { } ) ]
59+
public void parse_two_items( string cmdLine, string[] keys, string[] results1, string[] results2,
60+
string[] unkeyedResults )
5961
{
6062
var results = new string[][] { results1, results2 };
6163

62-
var parsed = _cmdLineParser.Parse( toParse );
64+
var parsed = _cmdLineParser.Parse( cmdLine );
6365

6466
parsed.Count.Should().Be( keys.Length );
6567

@@ -68,6 +70,8 @@ public void parse_two_items( string[] toParse, string[] keys, string[] results1,
6870
parsed.Contains( keys[ idx ] ).Should().BeTrue();
6971
parsed[ keys[ idx ] ].Parameters.Should().BeEquivalentTo( results[ idx ] );
7072
}
73+
74+
parsed.Unkeyed.Parameters.Should().BeEquivalentTo(unkeyedResults);
7175
}
7276
}
7377
}

J4JCommandLine.Tests/EnumTests.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ namespace J4JCommandLine.Tests
77
{
88
public class EnumTests
99
{
10-
protected class RootProperties
11-
{
12-
public PlainEnum Plain { get; set; }
13-
public FlagsEnum Flags { get; set; }
14-
public UnconvertibleEnum Unconvertible { get; set; }
15-
}
16-
1710
[ Theory ]
1811
[ InlineData( "z", "B", true, MappingResults.MissingRequired, PlainEnum.A ) ]
1912
[ InlineData( "x", "B", true, MappingResults.Success, PlainEnum.B ) ]
@@ -25,7 +18,7 @@ public void Plain_enum(
2518
MappingResults result,
2619
PlainEnum desiredValue )
2720
{
28-
var target = ServiceProvider.GetBindingTarget<RootProperties>( true );
21+
var target = ServiceProvider.GetBindingTarget<EnumProperties>( true );
2922
target.Should().NotBeNull();
3023

3124
var option = target!.Bind( x => x.Plain, "x" );
@@ -55,7 +48,7 @@ public void Flags_enum(
5548
MappingResults result,
5649
FlagsEnum desiredValue)
5750
{
58-
var target = ServiceProvider.GetBindingTarget<RootProperties>(true);
51+
var target = ServiceProvider.GetBindingTarget<EnumProperties>(true);
5952
target.Should().NotBeNull();
6053

6154
var option = target!.Bind(x => x.Flags, "x");
@@ -85,7 +78,7 @@ public void Unconvertible_enum(
8578
MappingResults result,
8679
UnconvertibleEnum desiredValue)
8780
{
88-
var target = ServiceProvider.GetBindingTarget<RootProperties>(true);
81+
var target = ServiceProvider.GetBindingTarget<EnumProperties>(true);
8982
target.Should().NotBeNull();
9083

9184
var option = target!.Bind(x => x.Unconvertible, "x");

J4JCommandLine.Tests/HelpErrorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void No_help_keys()
4141
.Description("a test program for exercising J4JCommandLine")
4242
.ProgramName($"{this.GetType()}");
4343

44-
builder.Build<RootProperties>(null, out var target);
44+
var target = builder.Build<RootProperties>( null );
4545

4646
target.Should().BeNull();
4747
}
@@ -57,7 +57,7 @@ public void Duplicate_help_keys()
5757
.Description("a test program for exercising J4JCommandLine")
5858
.ProgramName($"{this.GetType()}");
5959

60-
builder.Build<RootProperties>(null, out var target);
60+
var target = builder.Build<RootProperties>(null);
6161

6262
target.Should().NotBeNull();
6363
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using FluentAssertions;
3+
using J4JSoftware.CommandLine;
4+
using Xunit;
5+
6+
namespace J4JCommandLine.Tests
7+
{
8+
public class ListPropertyTest
9+
{
10+
[Theory]
11+
[InlineData("-z 32 33", true, MappingResults.MissingRequired, new int[] { }, new int[] { 33 })]
12+
[InlineData("-x 32 33", true, MappingResults.Success, new int[] { 32 }, new int[] { 33 })]
13+
[InlineData("-z 32 33", false, MappingResults.Success, new int[] { }, new int[] { 33 })]
14+
[InlineData("-x 32 -x 33", true, MappingResults.Success, new int[] { 32, 33 }, new int[] { })]
15+
public void root_properties(
16+
string cmdLine,
17+
bool required,
18+
MappingResults result,
19+
int[] optValue,
20+
int[] unkeyedValues)
21+
{
22+
var target = ServiceProvider.GetBindingTarget<TestProperties>(false);
23+
var option = target!.Bind(x => x.IntList, "x");
24+
var unkeyed = target!.BindUnkeyed(x => x.Unkeyed);
25+
26+
ProcessTest(cmdLine, required, target, option, unkeyed, result, () => target.Value, optValue,
27+
unkeyedValues);
28+
}
29+
30+
[Theory]
31+
[InlineData("-z 32 33", true, MappingResults.MissingRequired, new int[] { }, new int[] { 33 })]
32+
[InlineData("-x 32 33", true, MappingResults.Success, new int[] { 32 }, new int[] { 33 })]
33+
[InlineData("-z 32 33", false, MappingResults.Success, new int[] { }, new int[] { 33 })]
34+
[InlineData("-x 32 -x 33", true, MappingResults.Success, new int[] { 32, 33 }, new int[] { })]
35+
public void parameterless_properties(
36+
string cmdLine,
37+
bool required,
38+
MappingResults result,
39+
int[] optValue,
40+
int[] unkeyedValues)
41+
{
42+
var target = ServiceProvider.GetBindingTarget<ParameterlessConstructorParent>(false);
43+
var option = target!.Bind(x => x.TestProperties.IntList, "x");
44+
var unkeyed = target!.BindUnkeyed(x => x.TestProperties.Unkeyed);
45+
46+
ProcessTest(cmdLine, required, target, option, unkeyed, result, () => target.Value.TestProperties, optValue,
47+
unkeyedValues);
48+
}
49+
50+
[Theory]
51+
[InlineData("-z 32 33", true, MappingResults.MissingRequired, new int[] { }, new int[] { 33 })]
52+
[InlineData("-x 32 33", true, MappingResults.Success, new int[] { 32 }, new int[] { 33 })]
53+
[InlineData("-z 32 33", false, MappingResults.Success, new int[] { }, new int[] { 33 })]
54+
[InlineData("-x 32 -x 33", true, MappingResults.Success, new int[] { 32, 33 }, new int[] { })]
55+
public void parametered_properties(
56+
string cmdLine,
57+
bool required,
58+
MappingResults result,
59+
int[] optValue,
60+
int[] unkeyedValues)
61+
{
62+
var target =
63+
ServiceProvider.GetBindingTarget<ParameteredConstructorParent>(
64+
false,
65+
new ParameteredConstructorParent(52));
66+
67+
var option = target!.Bind(x => x.TestProperties.IntList, "x");
68+
var unkeyed = target!.BindUnkeyed(x => x.TestProperties.Unkeyed);
69+
70+
ProcessTest(cmdLine, required, target, option, unkeyed, result, () => target.Value.TestProperties, optValue,
71+
unkeyedValues);
72+
}
73+
74+
private void ProcessTest<T>(
75+
string cmdLine,
76+
bool required,
77+
BindingTarget<T> target,
78+
Option option,
79+
Option unkeyed,
80+
MappingResults desiredParseResults,
81+
Func<TestProperties> results,
82+
int[] optValue,
83+
int[] unkeyedValues)
84+
where T : class
85+
{
86+
target.Should().NotBeNull();
87+
88+
option.Should().BeAssignableTo<MappableOption>();
89+
unkeyed.Should().BeAssignableTo<MappableOption>();
90+
91+
if (required)
92+
option.Required();
93+
94+
var parseResults = target.Parse(new string[] { cmdLine });
95+
parseResults.Should().Be(desiredParseResults);
96+
97+
results().IntList.Should().BeEquivalentTo(optValue);
98+
results().Unkeyed.Should().BeEquivalentTo(unkeyedValues);
99+
}
100+
}
101+
}

J4JCommandLine.Tests/ParsingTests.cs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public ParsingTests()
3434
}
3535

3636
[ Theory ]
37-
[ InlineData( "x", new string[] { "-x" }, new string[] { "true" } ) ]
37+
[ InlineData( "x", new string[] { "-x" }, new string[] { } ) ]
3838
[ InlineData( "x", new string[] { "-x 7" }, new string[] { "7" } ) ]
3939
[ InlineData( "x", new string[] { "-x -7" }, new string[] { "-7" } ) ]
4040
[ InlineData( "", new string[] { "value" }, null ) ]
@@ -58,28 +58,19 @@ public void Single_parameter( string key, string[] input, string[] output )
5858
}
5959

6060
[Theory]
61-
[InlineData(new string[] {"x", "y", "z"}, "-x -y 7 -z -12", new int[] {1,1,1}, new string[] { "true", "7", "-12" })]
62-
[InlineData(new string[] { "x", "y", "z" }, "-x -y 7 8 -z -12", new int[] { 1, 2, 1 }, new string[] { "true", "7", "8", "-12" })]
63-
public void Command_line_string(string[] keys, string cmdLine, int[] rowLengths, string[] output)
61+
[InlineData("-x -y 7 -z -12", 3, new string[] { "7", "-12" }, new string[]{})]
62+
[InlineData("-x -y 7 8 -z -12", 3, new string[] { "7", "-12" }, new string[]{"8"})]
63+
[InlineData("abc -x -y 7 8 -z -12", 3, new string[] { "7", "-12" }, new string[] { "abc", "8" })]
64+
public void Command_line_string(string cmdLine, int numKeys, string[] keyedOutput, string[] unkeyedOutput )
6465
{
65-
if( keys.Length != rowLengths.Length)
66-
throw new ArgumentException("Mismatch between keys and output row lengths");
67-
6866
var results = _cmdLineParser.Parse(cmdLine);
6967

70-
results.Count.Should().Be(keys.Length);
71-
72-
for( var idx = 0; idx < results.Count; idx++ )
73-
{
74-
results[idx].Key.Should().Be(keys[idx]);
75-
results[ idx ].NumParameters.Should().Be( rowLengths[ idx ] );
68+
results.Count.Should().Be(numKeys);
7669

77-
var rowLength = rowLengths[ idx ];
78-
var rowOffset = rowLengths.Where( ( rl, i ) => i < idx ).Select( rl => rl ).Sum();
79-
var rowOutput = output[ rowOffset..( rowOffset + rowLength ) ];
70+
var consolidatedOutput = results.SelectMany( r => r.Parameters ).ToArray();
71+
consolidatedOutput.Should().BeEquivalentTo( keyedOutput );
8072

81-
results[ idx ].Parameters.Should().BeEquivalentTo( rowOutput );
82-
}
73+
results.Unkeyed.Parameters.Should().BeEquivalentTo(unkeyedOutput);
8374
}
8475
}
8576
}

0 commit comments

Comments
 (0)