Skip to content

Commit 648160a

Browse files
committed
Implemented AllocationResult class. Fixed problem in test caused by MasterTextCollection being a single instance.
1 parent 7599642 commit 648160a

File tree

9 files changed

+141
-73
lines changed

9 files changed

+141
-73
lines changed

Binder.Tests/CompositionRoot.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,14 @@ private void ConfigureDependencyInjection( HostBuilderContext context, Container
5151
.AsSelf();
5252

5353
builder.RegisterType<MasterTextCollection>()
54-
.OnActivated( x =>
54+
.OnActivating( x =>
5555
{
5656
x.Instance.Initialize( StringComparison.OrdinalIgnoreCase );
5757
x.Instance.AddRange( TextUsageType.Prefix, "-", "--" );
5858
x.Instance.AddRange( TextUsageType.Quote, "\"", "'" );
5959
x.Instance.AddRange( TextUsageType.ValueEncloser, "=" );
6060
} )
61-
.AsSelf()
62-
.SingleInstance();
61+
.AsSelf();
6362

6463
builder.RegisterType<DefaultTypeInitializer>()
6564
.AsImplementedInterfaces();

Binder.Tests/SwitchTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Binder.Tests;
9+
using FluentAssertions;
10+
using J4JSoftware.CommandLine;
11+
using Xunit;
12+
13+
namespace J4JSoftware.Binder.Tests
14+
{
15+
public class SwitchTests : BaseTest
16+
{
17+
[Theory]
18+
[InlineData("ASwitch", "x", "-x", OptionStyle.Switch, true, true, 0, 0)]
19+
[InlineData("ASwitch", "x", "-z", OptionStyle.Switch, false, false, 1, 0)]
20+
public void ByContextDefinition(
21+
string contextKey,
22+
string cmdLineKey,
23+
string cmdLine,
24+
OptionStyle style,
25+
bool allocResult,
26+
bool valueAssigned,
27+
int unknownKeys,
28+
int unkeyedParams )
29+
{
30+
var options = CompositionRoot.Default.Options;
31+
32+
var option = options.Add( new SimpleContextKey( contextKey ) );
33+
34+
option.AddCommandLineKey( cmdLineKey )
35+
.SetStyle( style );
36+
37+
var allocator = CompositionRoot.Default.Allocator;
38+
39+
var result = allocator.AllocateCommandLine( cmdLine, options );
40+
41+
( (bool) result ).Should().Be( allocResult );
42+
43+
option.WasAssignedValue.Should().Be( valueAssigned );
44+
45+
result.UnknownKeys.Count.Should().Be( unknownKeys );
46+
result.UnkeyedParameters.Count.Should().Be( unkeyedParams );
47+
}
48+
}
49+
}

Binder.Tests/TestOne.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
3+
namespace J4JSoftware.CommandLine
4+
{
5+
public class AllocationResult
6+
{
7+
public static implicit operator bool( AllocationResult result ) => result.UnknownKeys.Count <= 0;
8+
9+
public List<string> UnkeyedParameters { get; } = new List<string>();
10+
public List<string> UnknownKeys { get; } = new List<string>();
11+
}
12+
}

Binder/allocating/Allocator.cs

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
43
using System.Runtime.CompilerServices;
54
using System.Runtime.InteropServices.ComTypes;
65
using System.Text;
76
using J4JSoftware.Logging;
7+
using Microsoft.VisualBasic;
88

99
#pragma warning disable 8618
1010

@@ -29,23 +29,13 @@ IJ4JLogger logger
2929
_logger.SetLoggedType( GetType() );
3030
}
3131

32-
public bool AllocateCommandLine( string[] args, Options options, out List<string>? unkeyed )
33-
{
34-
unkeyed = null;
35-
36-
if( !AllocateCommandLine( string.Join( " ", args ), options, out var temp ) )
37-
return false;
32+
public AllocationResult AllocateCommandLine( string[] args, Options options ) =>
33+
AllocateCommandLine( string.Join( " ", args ), options );
3834

39-
unkeyed = temp;
40-
41-
return true;
42-
}
43-
44-
public bool AllocateCommandLine( string cmdLine, Options options, out List<string>? unkeyed )
35+
public AllocationResult AllocateCommandLine( string cmdLine, Options options )
4536
{
46-
unkeyed = null;
47-
var unkeyedInternal = new List<string>();
48-
37+
var retVal = new AllocationResult();
38+
4939
var accumulator = new StringBuilder();
5040
Option? curOption = null;
5141
var charsProcessed = 0;
@@ -78,23 +68,24 @@ public bool AllocateCommandLine( string cmdLine, Options options, out List<strin
7868

7969
// if the key (contained in element) isn't among the keys defined
8070
// in the options collection we have a problem
81-
if( !options.UsesCommandLineKey( element ) )
71+
if( options.UsesCommandLineKey( element ) )
8272
{
83-
_logger.Error<string>( "Unknown key '{0}'", element );
84-
return false;
85-
}
73+
curOption = options[element];
74+
curOption!.CommandLineKeyProvided = element;
8675

87-
curOption = options[ element ];
88-
89-
curOption!.CommandLineKeyUsed = element;
90-
91-
lastElementWasKey = true;
76+
lastElementWasKey = true;
77+
}
78+
else
79+
{
80+
retVal.UnknownKeys.Add( element );
81+
_logger.Error<string>("Unknown key '{0}'", element);
82+
}
9283
}
9384
else
9485
{
9586
// element is parameter value
9687
if( curOption == null || !lastElementWasKey )
97-
unkeyedInternal.Add( element );
88+
retVal.UnkeyedParameters.Add( element );
9889
else curOption.AddAllocatedValue( element );
9990

10091
lastElementWasKey = false;
@@ -104,9 +95,7 @@ public bool AllocateCommandLine( string cmdLine, Options options, out List<strin
10495
accumulator.Clear();
10596
}
10697

107-
unkeyed = unkeyedInternal;
108-
109-
return true;
98+
return retVal;
11099
}
111100
}
112101
}

Binder/allocating/IAllocator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace J4JSoftware.CommandLine
66
// defines the interface for an object used to parse a command line
77
public interface IAllocator
88
{
9-
bool AllocateCommandLine(string[] args, Options options, out List<string>? unkeyed);
10-
bool AllocateCommandLine(string cmdLine, Options options, out List<string>? unkeyed);
9+
AllocationResult AllocateCommandLine( string[] args, Options options );
10+
AllocationResult AllocateCommandLine( string cmdLine, Options options );
1111
}
1212
}

Binder/options/Option.cs

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
4+
using System.ComponentModel;
45
using System.Linq;
56

67
namespace J4JSoftware.CommandLine
@@ -9,11 +10,19 @@ public class Option
910
{
1011
private readonly List<string> _cmdLineKeys = new List<string>();
1112
private readonly List<string> _allocatedValues = new List<string>();
13+
private readonly MasterTextCollection _masterText;
1214

13-
internal Option( Options container, IContextKey contextKey )
15+
private int _allowedNumValues;
16+
17+
internal Option(
18+
Options container,
19+
IContextKey contextKey,
20+
MasterTextCollection masterText
21+
)
1422
{
1523
Container = container;
1624
ContextKey = contextKey;
25+
_masterText = masterText;
1726

1827
if( Container.UsesContextPath( ContextPath! ) )
1928
throw new ArgumentException( $"Duplicate context key path '{ContextPath}'" );
@@ -52,19 +61,43 @@ public List<IContextKey>? ContextPath
5261
// but they must be unique within the scope of all Options)
5362
public string FirstKey => _cmdLineKeys.OrderBy( k => k ).First();
5463

55-
public string? CommandLineKeyUsed { get; set; }
64+
public string? CommandLineKeyProvided { get; set; }
65+
66+
public bool WasAssignedValue
67+
{
68+
get
69+
{
70+
if( string.IsNullOrEmpty( CommandLineKeyProvided ) )
71+
return false;
72+
73+
var numValuesAlloc = _allocatedValues.Count;
74+
75+
return Style switch
76+
{
77+
OptionStyle.Switch => numValuesAlloc == 0,
78+
OptionStyle.SingleValued => numValuesAlloc == 1,
79+
OptionStyle.Collection => numValuesAlloc > 0,
80+
_ => throw new InvalidEnumArgumentException($"Unsupported OptionStyle '{Style}'")
81+
};
82+
}
83+
}
84+
5685
public ReadOnlyCollection<string> CommandLineValues => _allocatedValues.AsReadOnly();
5786

58-
public int AllowedNumberOfValues { get; private set; }
87+
public OptionStyle Style { get; private set; }
88+
5989
public bool Required { get; private set; }
6090
public string? Description { get; private set; }
6191

6292
internal void AddAllocatedValue( string value ) => _allocatedValues.Add( value );
6393

6494
public Option AddCommandLineKey(string cmdLineKey)
6595
{
66-
if (!Container.UsesCommandLineKey(cmdLineKey))
96+
if( !Container.UsesCommandLineKey( cmdLineKey ) )
97+
{
6798
_cmdLineKeys.Add(cmdLineKey);
99+
_masterText.Add( TextUsageType.OptionKey, cmdLineKey );
100+
}
68101

69102
return this;
70103
}
@@ -79,21 +112,16 @@ public Option AddCommandLineKeys(params string[] cmdLineKeys)
79112
return this;
80113
}
81114

82-
public Option IsSwitch()
83-
{
84-
AllowedNumberOfValues = 0;
85-
return this;
86-
}
87-
88-
public Option IsCollection()
115+
public Option SetStyle( OptionStyle style )
89116
{
90-
AllowedNumberOfValues = Int32.MaxValue;
91-
return this;
92-
}
117+
_allowedNumValues = style switch
118+
{
119+
OptionStyle.Collection => Int32.MaxValue,
120+
OptionStyle.SingleValued => 1,
121+
OptionStyle.Switch => 0,
122+
_ => throw new InvalidEnumArgumentException( $"Unsupported OptionStyle '{style}'" )
123+
};
93124

94-
public Option IsSingleValue()
95-
{
96-
AllowedNumberOfValues = 1;
97125
return this;
98126
}
99127

Binder/options/Options.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public Option? this[ string key ]
6969

7070
public Option Add(IContextKey contextKey )
7171
{
72-
var retVal = new Option( this, contextKey );
72+
var retVal = new Option( this, contextKey, _masterText );
7373

7474
_options.Add(retVal);
7575

Binder/options/SimpleContextKey.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace J4JSoftware.CommandLine
2+
{
3+
public class SimpleContextKey : IContextKey
4+
{
5+
public SimpleContextKey( string contextKey )
6+
{
7+
Text = contextKey;
8+
}
9+
10+
public string Text { get; }
11+
}
12+
}

0 commit comments

Comments
 (0)