Skip to content

Commit

Permalink
Merge branch 'fix/MakeInternalHelperClassesStatic_39'
Browse files Browse the repository at this point in the history
  • Loading branch information
akamsteeg committed Jun 9, 2018
2 parents e10246d + 0b16cbf commit ea88442
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,46 @@ namespace AtleX.CommandLineArguments.Tests.Parsers.Helpers
{
public class ArgumentPropertiesHelperTests
{
[Fact]
public void Ctor_WithNullTypeParsers_Throws()
{
Assert.Throws<ArgumentNullException>(() => new ArgumentPropertiesHelper(null));
}

[Fact]
public void Ctor_WithTypeParsers_DoesNotThrow()
{
new ArgumentPropertiesHelper(Enumerable.Empty<TypeParser>());
}

[Fact]
public void FillProperty_WithNullArgumentParameter_Throws()
{
var helper = new ArgumentPropertiesHelper(Enumerable.Empty<TypeParser>());
var property = typeof(TestArguments).GetTypeInfo().DeclaredProperties.First(a => a.Name == "RequiredString");

Assert.Throws<ArgumentNullException>(() => helper.FillProperty<TestArguments>(null, property, "value"));
Assert.Throws<ArgumentNullException>(() =>
ArgumentPropertiesHelper.FillProperty<TestArguments>(null, property, "value", Enumerable.Empty<TypeParser>())
);
}

[Fact]
public void FillProperty_WithNullPropertyParameter_Throws()
{
var helper = new ArgumentPropertiesHelper(Enumerable.Empty<TypeParser>());

Assert.Throws<ArgumentNullException>(() => helper.FillProperty(new TestArguments(), null, "value"));
Assert.Throws<ArgumentNullException>(() =>
ArgumentPropertiesHelper.FillProperty(new TestArguments(), null, "value", Enumerable.Empty<TypeParser>())
);
}

[Fact]
public void FillProperty_WithNullPropertyValueParameter_DoesNotThrow()
{
var helper = new ArgumentPropertiesHelper(Enumerable.Empty<TypeParser>());
var property = typeof(TestArguments).GetTypeInfo().DeclaredProperties.First(a => a.Name == "RequiredString");

helper.FillProperty(new TestArguments(), property, null);
ArgumentPropertiesHelper.FillProperty(new TestArguments(), property, null, Enumerable.Empty<TypeParser>());
}

[Fact]
public void FillProperty_WithEmptyPropertyValueParameter_DoesNotThrow()
{
var helper = new ArgumentPropertiesHelper(Enumerable.Empty<TypeParser>());
var property = typeof(TestArguments).GetTypeInfo().DeclaredProperties.First(a => a.Name == "RequiredString");

helper.FillProperty(new TestArguments(), property, "");
ArgumentPropertiesHelper.FillProperty(new TestArguments(), property, "", Enumerable.Empty<TypeParser>());
}

[Fact]
public void FillProperty_WithNullTypeParsersParameter_Throws()
{
Assert.Throws<ArgumentNullException>(() =>
ArgumentPropertiesHelper.FillProperty(new TestArguments(), null, "value", null)
);
}

[Fact]
Expand All @@ -67,11 +62,11 @@ public void FillProperty_StringProperty_IsParsedCorrectly()
{
new StringTypeParser()
};
var helper = new ArgumentPropertiesHelper(typeParsers);

var property = typeof(TestArguments).GetTypeInfo().DeclaredProperties.First(a => a.Name == "RequiredString");
var arguments = new TestArguments();
helper.FillProperty(arguments, property, testValue);

ArgumentPropertiesHelper.FillProperty(arguments, property, testValue, typeParsers);

Assert.Equal(testValue, arguments.RequiredString);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AtleX.CommandLineArguments.Parsers.Helpers;
using AtleX.CommandLineArguments.Tests.Mocks;
using AtleX.CommandLineArguments.Validators;
using Xunit;

Expand All @@ -12,23 +11,32 @@ namespace AtleX.CommandLineArguments.Tests.Parsers.Helpers
public class ValidationHelperTests
{
[Fact]
public void Ctor_WithNullValidatorsToRun_Throws()
public void TryValidate_WithNullValidatorsArgument_Throws()
{
Assert.Throws<ArgumentNullException>(() => new ValidationHelper(null));
Assert.Throws<ArgumentNullException>(() =>
ValidationHelper.TryValidate(null, null, true, "", out _)
);
}

[Fact]
public void Ctor_WithValidatorsToRun_DoesNotThrow()
public void TryValidate_WithNullPropertyInfoArgument_Throws()
{
new ValidationHelper(Enumerable.Empty<ArgumentValidator>());
Assert.Throws<ArgumentNullException>(() =>
ValidationHelper.TryValidate(Enumerable.Empty<ArgumentValidator>(), null, true, "", out _)
);
}

[Fact]
public void TryValidate_WithNullPropertyInfo_Throws()
public void TryValidate_WithValidArguments_Succeeds()
{
var helper = new ValidationHelper(Enumerable.Empty<ArgumentValidator>());
var validators = new List<ArgumentValidator>()
{
new RequiredArgumentValidator(),
};

Assert.Throws<ArgumentNullException>(() => helper.TryValidate(null, true, "", out _));
var propertyInfo = typeof(TestArguments).GetProperties().First();

ValidationHelper.TryValidate(validators, propertyInfo, true, "", out _);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,19 @@ public ParseResult<T> Parse<T>(string[] arguments, IEnumerable<ArgumentValidator
var allValidationErrors = new List<ValidationError>();

var properties = typeof(T).GetTypeInfo().DeclaredProperties;
var argumentPropertiesHelper = new ArgumentPropertiesHelper(typeParsers);
var validationHelper = new ValidationHelper(validators);

foreach (var currentProperty in properties)
{
var argumentIsSpecified = this.TryFindRawArgumentValue(arguments, currentProperty.Name, out var argumentValue);

if (argumentIsSpecified)
{
argumentPropertiesHelper.FillProperty(argumentsObject, currentProperty, argumentValue);
ArgumentPropertiesHelper.FillProperty(argumentsObject, currentProperty, argumentValue, typeParsers);
}

var isValid = validationHelper.TryValidate(currentProperty,
var isValid = ValidationHelper.TryValidate(
validators,
currentProperty,
argumentIsSpecified,
argumentValue,
out var validationErrors);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using AtleX.CommandLineArguments.Parsers.TypeParsers;

namespace AtleX.CommandLineArguments.Parsers.Helpers
{
/// <summary>
/// Represents a helper for setting property values in the <see cref="Arguments"/>
/// </summary>
internal sealed class ArgumentPropertiesHelper
internal static class ArgumentPropertiesHelper
{
/// <summary>
/// Gets the collection of <see cref="TypeParser"/> to parse the argument values with
/// </summary>
private readonly IEnumerable<TypeParser> typeParsers;

/// <summary>
/// Initializes a new instance of <see cref="ArgumentPropertiesHelper"/>
/// </summary>
/// <param name="typeParsers">
/// The <see cref="IEnumerable{T}"/> of <see cref="TypeParser"/> to parse the argument values with
/// </param>
public ArgumentPropertiesHelper(IEnumerable<TypeParser> typeParsers)
{
this.typeParsers = typeParsers ?? throw new ArgumentNullException(nameof(typeParsers));
}

/// <summary>
/// Set the value of the property with the specified name in the <see
/// cref="Arguments"/> to the specified value
Expand All @@ -42,14 +27,19 @@ public ArgumentPropertiesHelper(IEnumerable<TypeParser> typeParsers)
/// <param name="propertyValue">
/// The value of the property to set
/// </param>
public void FillProperty<T>(T arguments, PropertyInfo propertyInfo, string propertyValue)
/// <param name="typeParsers">
/// The <see cref="IEnumerable{T}"/> of <see cref="TypeParser"/> to parse the
/// argument values with
/// </param>
public static void FillProperty<T>(T arguments, PropertyInfo propertyInfo, string propertyValue, IEnumerable<TypeParser> typeParsers)
where T: Arguments
{
_ = arguments ?? throw new ArgumentNullException(nameof(arguments));
_ = propertyInfo ?? throw new ArgumentNullException(nameof(propertyInfo));
_ = typeParsers ?? throw new ArgumentNullException(nameof(typeParsers));

if (
(this.TryFillCustomType(arguments, propertyInfo, propertyValue))
(TryFillCustomType(arguments, propertyInfo, propertyValue, typeParsers))
||
(propertyInfo.PropertyType.GetTypeInfo().IsEnum && TryFillEnum(arguments, propertyInfo, propertyValue))
)
Expand All @@ -76,7 +66,7 @@ public void FillProperty<T>(T arguments, PropertyInfo propertyInfo, string prope
/// <returns>
/// True when the property value could be set, false otherwise
/// </returns>
private bool TryFillEnum<T>(T arguments, PropertyInfo property, string value)
private static bool TryFillEnum<T>(T arguments, PropertyInfo property, string value)
where T: Arguments
{
var result = false;
Expand Down Expand Up @@ -109,15 +99,19 @@ private bool TryFillEnum<T>(T arguments, PropertyInfo property, string value)
/// <param name="value">
/// The value to set
/// </param>
/// <param name="typeParsers">
/// The <see cref="IEnumerable{T}"/> of <see cref="TypeParser"/> to parse the
/// argument values with
/// </param>
/// <returns>
/// True when the property value could be set, false otherwise
/// </returns>
private bool TryFillCustomType<T>(T arguments, PropertyInfo property, string value)
private static bool TryFillCustomType<T>(T arguments, PropertyInfo property, string value, IEnumerable<TypeParser> typeParsers)
where T: Arguments
{
var result = false;

foreach (var currentTypeParser in this.typeParsers)
foreach (var currentTypeParser in typeParsers)
{
if (currentTypeParser.Type == property.PropertyType)
{
Expand Down
34 changes: 13 additions & 21 deletions src/AtleX.CommandLineArguments/Parsers/Helpers/ValidationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,15 @@ namespace AtleX.CommandLineArguments.Parsers.Helpers
/// <summary>
/// Represents a helper for validation of command line arguments
/// </summary>
internal sealed class ValidationHelper
internal static class ValidationHelper
{
/// <summary>
/// Gets the <see cref="IEnumerable{T}"/> of <see cref="ArgumentValidator"/> to validate the arguments with
/// </summary>
private readonly IEnumerable<ArgumentValidator> argumentValidators;

/// <summary>
/// Initializes a new instance of <see cref="ValidationHelper"/> with the
/// specified <see cref="IEnumerable{T}"/> of <see cref="ArgumentValidator"/>
/// </summary>
/// <param name="validatorsToRun">
/// The <see cref="IEnumerable{T}"/> of <see cref="ArgumentValidator"/> to validate with
/// </param>
public ValidationHelper(IEnumerable<ArgumentValidator> validatorsToRun)
{
this.argumentValidators = validatorsToRun ?? throw new ArgumentNullException(nameof(validatorsToRun));
}

/// <summary>
/// Try validating the argument with all argument validators
/// </summary>
/// <param name="argumentValidators">
/// The <see cref="IEnumerable{T}"/> of <see cref="ArgumentValidator"/> to
/// validate with
/// </param>
/// <param name="parsedPropertyToValidate">
/// The <see cref="PropertyInfo"/> of the argument to validate
/// </param>
Expand All @@ -48,17 +35,22 @@ public ValidationHelper(IEnumerable<ArgumentValidator> validatorsToRun)
/// <returns>
/// True when the argument is valid, false otherwise
/// </returns>
public bool TryValidate(PropertyInfo parsedPropertyToValidate, bool isSpecified, string originalValue, out IEnumerable<ValidationError> validationErrors)
public static bool TryValidate(IEnumerable<ArgumentValidator> argumentValidators,
PropertyInfo parsedPropertyToValidate,
bool isSpecified,
string originalValue,
out IEnumerable<ValidationError> validationErrors)
{
_ = argumentValidators ?? throw new ArgumentNullException(nameof(argumentValidators));
_ = parsedPropertyToValidate ?? throw new ArgumentNullException(nameof(parsedPropertyToValidate));

var result = true;

List<ValidationError> currentValidationErrors = null; // PERF Only set the collection of validation errors when there's actually one or more

foreach (var currentValidator in this.argumentValidators)
foreach (var currentValidator in argumentValidators)
{
var isValid = currentValidator.TryValidate(parsedPropertyToValidate, isSpecified, originalValue, out ValidationError validationError);
var isValid = currentValidator.TryValidate(parsedPropertyToValidate, isSpecified, originalValue, out var validationError);

if (!isValid)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace AtleX.CommandLineArguments.Validators
internal sealed class RequiredArgumentValidator
: ArgumentValidator
{

/// <summary>
/// Initializes a new instance of <see cref="RequiredArgumentValidator"/>
/// </summary>
Expand Down

0 comments on commit ea88442

Please sign in to comment.