Skip to content

Commit fe63e41

Browse files
committed
integrate the new validator and remove the old dead code.
1 parent 1350384 commit fe63e41

File tree

6 files changed

+42
-52
lines changed

6 files changed

+42
-52
lines changed

FluentCommandLineParser.Tests/FluentCommandLineParser/when_setting_up_a_new_option/with_a_long_name/with_a_long_name_that_is_already_used_but_differs_by_case.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ public class with_a_long_name_that_is_already_used_but_differs_by_case : Setting
5353
SetupOptionWith(valid_short_name, existingLongName.ToLower());
5454
};
5555

56-
It should_throw_an_error = () => error.ShouldBeOfType(typeof(OptionAlreadyExistsException));
57-
It should_not_have_setup_an_option = () => sut.Options.ShouldContainOnly(existingOption);
56+
It should_not_throw_an_error = () => error.ShouldBeNull();
57+
It should_not_have_setup_an_option = () => sut.Options.ShouldContainOnly(new[] { existingOption, option });
5858
}
5959
}
6060
}

FluentCommandLineParser.Tests/FluentCommandLineParser/when_setting_up_a_new_option/with_a_short_name/with_a_short_name_that_is_already_used_but_differs_by_case.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ public class with_a_short_name_that_is_already_used_but_differs_by_case : Settin
5454
SetupOptionWith(existingShortNameLower);
5555
};
5656

57-
It should_throw_an_error = () => error.ShouldBeOfType(typeof(OptionAlreadyExistsException));
58-
It should_not_have_setup_an_option = () => sut.Options.ShouldContainOnly(existingOption);
57+
It should_not_throw_an_error = () => error.ShouldBeNull();
58+
It should_have_setup_an_option = () => sut.Options.ShouldContainOnly(new[] { existingOption, option });
5959
}
6060
}
6161
}

FluentCommandLineParser.Tests/Internals/Validators/CommandLineOptionNameValidatorTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#endregion
2424

2525
using System;
26+
using System.Globalization;
2627
using Fclp.Internals;
2728
using Fclp.Internals.Validators;
2829
using Machine.Specifications;
@@ -103,6 +104,14 @@ class when_the_short_name_is_empty : ValidateTestContext
103104
It should_not_throw_an_error = () => error.ShouldBeNull();
104105
}
105106

107+
class when_the_short_name_is_a_control_char : ValidateTestContext
108+
{
109+
Establish context = () =>
110+
SetupOptionWith(shortName: ((char)7).ToString(CultureInfo.InvariantCulture));
111+
112+
It should_throw_an_error = () => error.ShouldBeOfType<ArgumentOutOfRangeException>();
113+
}
114+
106115
class when_the_short_name_is_longer_than_one_char : ValidateTestContext
107116
{
108117
Establish context = () =>

FluentCommandLineParser/FluentCommandLineParser.cs

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
using Fclp.Internals;
3030
using Fclp.Internals.Errors;
3131
using Fclp.Internals.Extensions;
32+
using Fclp.Internals.Validators;
3233

3334
namespace Fclp
3435
{
@@ -44,6 +45,7 @@ public class FluentCommandLineParser : IFluentCommandLineParser
4445
ICommandLineOptionFormatter _optionFormatter;
4546
IHelpCommandLineOption _helpOption;
4647
ICommandLineParserErrorFormatter _errorFormatter;
48+
ICommandLineOptionValidator _optionValidator;
4749

4850
///// <summary>
4951
///// Gets or sets whether the parser is case-sensitive. E.g. If <c>true</c> then <c>/a</c> will be treated as identical to <c>/A</c>.
@@ -95,6 +97,15 @@ public ICommandLineOptionFactory OptionFactory
9597
set { _optionFactory = value; }
9698
}
9799

100+
/// <summary>
101+
/// Gets or sets the <see cref="ICommandLineOptionValidator"/> used to validate each setup Option.
102+
/// </summary>
103+
public ICommandLineOptionValidator OptionValidator
104+
{
105+
get { return _optionValidator ?? (_optionValidator = new CommandLineOptionValidator(this)); }
106+
set { _optionValidator = value; }
107+
}
108+
98109
/// <summary>
99110
/// Gets or sets the <see cref="ICommandLineParserEngine"/> to use for parsing the command line args.
100111
/// </summary>
@@ -122,58 +133,23 @@ internal IHelpCommandLineOption HelpOption
122133
/// </exception>
123134
public ICommandLineOptionFluent<T> Setup<T>(char shortOption, string longOption)
124135
{
125-
EnsureIsValidShortName(shortOption);
126-
EnsureIsValidLongName(longOption);
127-
//EnsureHasShortNameOrLongName(shortOption, longOption);
128-
129136
return SetupInternal<T>(shortOption.ToString(CultureInfo.InvariantCulture), longOption);
130137
}
131138

132139
private ICommandLineOptionFluent<T> SetupInternal<T>(string shortOption, string longOption)
133140
{
134-
foreach (var option in this.Options)
135-
{
136-
if (shortOption != null && shortOption.Equals(option.ShortName, this.StringComparison))
137-
throw new OptionAlreadyExistsException(shortOption);
138-
139-
if (longOption != null && longOption.Equals(option.LongName, this.StringComparison))
140-
throw new OptionAlreadyExistsException(longOption);
141-
}
142-
143141
var argOption = this.OptionFactory.CreateOption<T>(shortOption, longOption);
144142

145143
if (argOption == null)
146144
throw new InvalidOperationException("OptionFactory is producing unexpected results.");
147145

146+
OptionValidator.Validate(argOption);
147+
148148
this.Options.Add(argOption);
149149

150150
return argOption;
151151
}
152152

153-
private static void EnsureIsValidShortName(char value)
154-
{
155-
if (char.IsWhiteSpace(value) || char.IsControl(value) || value == ':' || value == '=')
156-
throw new ArgumentOutOfRangeException("value");
157-
}
158-
159-
private static void EnsureIsValidLongName(string value)
160-
{
161-
if (string.IsNullOrEmpty(value)) return;
162-
163-
if (value.Trim().Length < 2)
164-
throw new ArgumentOutOfRangeException("value");
165-
166-
var invalidChars = SpecialCharacters.ValueAssignments.Union(new[] { SpecialCharacters.Whitespace });
167-
if (invalidChars.Any(value.Contains))
168-
throw new ArgumentOutOfRangeException("value");
169-
}
170-
171-
private static void EnsureHasShortNameOrLongName(char shortOption, string longOption)
172-
{
173-
if (char.IsWhiteSpace(shortOption) && longOption.IsNullOrWhiteSpace())
174-
throw new ArgumentOutOfRangeException("shortOption", "Either shortOption or longOption must be specified");
175-
}
176-
177153
/// <summary>
178154
/// Setup a new <see cref="ICommandLineOptionFluent{T}"/> using the specified short Option name.
179155
/// </summary>
@@ -184,7 +160,6 @@ private static void EnsureHasShortNameOrLongName(char shortOption, string longOp
184160
/// </exception>
185161
public ICommandLineOptionFluent<T> Setup<T>(char shortOption)
186162
{
187-
EnsureIsValidShortName(shortOption);
188163
return SetupInternal<T>(shortOption.ToString(CultureInfo.InvariantCulture), null);
189164
}
190165

@@ -198,7 +173,6 @@ public ICommandLineOptionFluent<T> Setup<T>(char shortOption)
198173
/// </exception>
199174
public ICommandLineOptionFluent<T> Setup<T>(string longOption)
200175
{
201-
EnsureIsValidLongName(longOption);
202176
return SetupInternal<T>(null, longOption);
203177
}
204178

@@ -242,10 +216,10 @@ public ICommandLineParserResult Parse(string[] args)
242216
{
243217
option.Bind(match);
244218
}
245-
catch(OptionSyntaxException)
219+
catch (OptionSyntaxException)
246220
{
247221
result.Errors.Add(new OptionSyntaxParseError(option, match));
248-
if(option.HasDefault)
222+
if (option.HasDefault)
249223
option.BindDefault();
250224
}
251225

FluentCommandLineParser/Internals/Validators/NoDuplicateOptionValidator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ public void Validate(ICommandLineOption commandLineOption)
5151
{
5252
foreach (var option in _parser.Options)
5353
{
54-
if (commandLineOption.HasShortName)
54+
if (string.IsNullOrEmpty(commandLineOption.ShortName) == false)
5555
{
5656
ValuesAreEqual(commandLineOption.ShortName, option.ShortName);
5757
}
5858

59-
if (commandLineOption.HasLongName)
59+
if (string.IsNullOrEmpty(commandLineOption.LongName) == false)
6060
{
6161
ValuesAreEqual(commandLineOption.LongName, option.LongName);
6262
}

FluentCommandLineParser/Internals/Validators/OptionNameValidator.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ private static void ValidateShortAndLongName(string shortName, string longName)
5959

6060
private static void ValidateLongName(string longName)
6161
{
62-
if (longName != null
63-
&& longName.Length == 1)
62+
if (string.IsNullOrEmpty(longName)) return;
63+
64+
if (longName.Length == 1)
6465
{
6566
throw new ArgumentOutOfRangeException();
6667
}
@@ -73,8 +74,9 @@ private static void ValidateLongName(string longName)
7374

7475
private static void ValidateShortName(string shortName)
7576
{
76-
if (shortName != null
77-
&& shortName.Length > 1)
77+
if (string.IsNullOrEmpty(shortName)) return;
78+
79+
if (shortName.Length > 1)
7880
{
7981
throw new ArgumentOutOfRangeException();
8082
}
@@ -83,9 +85,14 @@ private static void ValidateShortName(string shortName)
8385
{
8486
throw new ArgumentOutOfRangeException();
8587
}
88+
89+
if (char.IsControl(shortName, 0))
90+
{
91+
throw new ArgumentOutOfRangeException();
92+
}
8693
}
8794

88-
private static bool ContainsReserved(string value)
95+
private static bool ContainsReserved(string value)
8996
{
9097
return value != null
9198
&& ReservedChars.Any(value.Contains);

0 commit comments

Comments
 (0)