Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions ZySharp.Validation.Tests/Test.Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,56 @@ public void NotNullOrEmptyVal<T>(ValTestCase<T> test)
}

#endregion NotNullOrEmpty

#region MutuallyExclusive

public static IEnumerable<object[]> DataMutuallyExclusiveRef => new List<object[]>
{
new object[] { new RefTestCaseWithParam<object, object >(null , null , false) },
new object[] { new RefTestCaseWithParam<TestConstants.Obj, TestConstants.Obj>(TestConstants.Obj.A, TestConstants.Obj.A , true ) },
new object[] { new RefTestCaseWithParam<TestConstants.Obj, TestConstants.Obj>(TestConstants.Obj.A, TestConstants.Obj.B , true ) },
new object[] { new RefTestCaseWithParam<TestConstants.Obj, TestConstants.Obj>(TestConstants.Obj.A, null , false) },
new object[] { new RefTestCaseWithParam<TestConstants.Obj, TestConstants.Obj>(null , TestConstants.Obj.B , false) },
new object[] { new RefTestCaseWithParam<string, string >("A" , "A" , true ) },
new object[] { new RefTestCaseWithParam<string, string >("A" , "B" , true ) },
new object[] { new RefTestCaseWithParam<string, string >("A" , null , false) },
new object[] { new RefTestCaseWithParam<string, string >(null , "B" , false) }
};

[Theory]
[MemberData(nameof(DataMutuallyExclusiveRef))]
public void MutuallyExclusiveRef<T>(RefTestCaseWithParam<T, T> test)
where T : class
{
TestExtensions.TestValidation(test, v => v.MutuallyExclusive(ArgumentReference.For(test.Parameter, "param")));
}

public static IEnumerable<object[]> DataMutuallyExclusiveVal => new List<object[]>
{
new object[] { new ValTestCaseWithValParam<int , int >(null , null , false) },
new object[] { new ValTestCaseWithValParam<int , int >(0 , 0 , true ) },
new object[] { new ValTestCaseWithValParam<int , int >(0 , 1 , true ) },
new object[] { new ValTestCaseWithValParam<int , int >(0 , null , false) },
new object[] { new ValTestCaseWithValParam<int , int >(null , 1 , false) },
new object[] { new ValTestCaseWithValParam<Guid , Guid >(null , null , false) },
new object[] { new ValTestCaseWithValParam<Guid , Guid >(TestConstants.GuidA , TestConstants.GuidA , true ) },
new object[] { new ValTestCaseWithValParam<Guid , Guid >(TestConstants.GuidA , TestConstants.GuidB , true ) },
new object[] { new ValTestCaseWithValParam<Guid , Guid >(TestConstants.GuidA , null , false) },
new object[] { new ValTestCaseWithValParam<Guid , Guid >(null , TestConstants.GuidB , false) },
new object[] { new ValTestCaseWithValParam<TimeSpan, TimeSpan>(null , null , false) },
new object[] { new ValTestCaseWithValParam<TimeSpan, TimeSpan>(TestConstants.TimeSpanA, TestConstants.TimeSpanA, true ) },
new object[] { new ValTestCaseWithValParam<TimeSpan, TimeSpan>(TestConstants.TimeSpanA, TestConstants.TimeSpanB, true ) },
new object[] { new ValTestCaseWithValParam<TimeSpan, TimeSpan>(TestConstants.TimeSpanA, null , false) },
new object[] { new ValTestCaseWithValParam<TimeSpan, TimeSpan>(null , TestConstants.TimeSpanB, false) }
};

[Theory]
[MemberData(nameof(DataMutuallyExclusiveVal))]
public void MutuallyExclusiveVal<T>(ValTestCaseWithValParam<T, T> test)
where T : struct
{
TestExtensions.TestValidation(test, v => v.MutuallyExclusive(ArgumentReference.For(test.Parameter, "param")));
}

#endregion MutuallyExclusive
}
15 changes: 15 additions & 0 deletions ZySharp.Validation.Tests/TestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,18 @@ public ValTestCaseWithParam(TValue? value, TParam? parameter, bool expectThrow,
Parameter = parameter;
}
}

[ExcludeFromCodeCoverage]
public class ValTestCaseWithValParam<TValue, TParam> :
ValTestCase<TValue>
where TValue : struct
where TParam : struct
{
public TParam? Parameter { get; }

public ValTestCaseWithValParam(TValue? value, TParam? parameter, bool expectThrow, Type? exceptionType = null) :
base(value, expectThrow, exceptionType)
{
Parameter = parameter;
}
}
9 changes: 9 additions & 0 deletions ZySharp.Validation/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ZySharp.Validation/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@
<data name="ArgumentMustBeLessThanReference" xml:space="preserve">
<value>The value of argument '{0}' must be less than the value of argument `{1}`. Values: '{0}' = '{2}', '{1}' = '{3}'</value>
</data>
<data name="ArgumentMustBeMutuallyExclusive" xml:space="preserve">
<value>The argument '{0}' must be used mutually exclusive to the argument '{1}'.</value>
</data>
<data name="ArgumentMustBeOfType" xml:space="preserve">
<value>The type of argument '{0}' must be '{1}'.</value>
</data>
Expand Down
28 changes: 28 additions & 0 deletions ZySharp.Validation/ValidateArgument.Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,32 @@ public static IValidatorContext<T> NotEmpty<T>(this IValidatorContext<T> validat
}

#endregion NotNullOrEmpty

#region MutuallyExclusive

/// <summary>
/// Throws if both, the current value and the <paramref name="reference"/> value is not <c>null</c>.
/// </summary>
/// <typeparam name="T">The type of the current value.</typeparam>
/// <param name="validator">The current validator context.</param>
/// <param name="reference">A reference to the other value.</param>
/// <returns>The unmodified validator context.</returns>
public static IValidatorContext<T?> MutuallyExclusive<T>(this IValidatorContext<T?> validator,
IArgumentReference<T?> reference)
{
ValidationInternals.ValidateNotNull(reference, nameof(reference));

return validator.Perform(() =>
{
if ((validator.Value is not null) && (reference.Value is not null))
{
validator.SetArgumentException(
string.Format(CultureInfo.InvariantCulture, Resources.ArgumentMustBeMutuallyExclusive,
ValidationInternals.FormatName(validator.Path, null),
ValidationInternals.FormatName(reference.Path, null)));
}
}, false);
}

#endregion
}
2 changes: 1 addition & 1 deletion ZySharp.Validation/ValidateArgument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static partial class ValidateArgument
/// <param name="name">The name of the argument to validate.</param>
/// <param name="action">The action to perform for the selected parameter.</param>
/// <returns>The value of the validated argument.</returns>
[return: NotNullIfNotNull("value")]
[return: NotNullIfNotNull(nameof(value))]
public static T? For<T>([ValidatedNotNull][NoEnumeration] T? value, string name, Action<IValidatorContext<T?>> action)
{
ValidationInternals.ValidateNotNull(name, nameof(name));
Expand Down