diff --git a/Argument.Tests/ArgumentTests.cs b/Argument.Tests/ArgumentTests.cs index 912b623..e71da71 100644 --- a/Argument.Tests/ArgumentTests.cs +++ b/Argument.Tests/ArgumentTests.cs @@ -104,13 +104,44 @@ public static IEnumerable OutOfRangeVariants { yield return SimpleDataRow(name => Argument.PositiveOrZero(name, -1)); yield return SimpleDataRow(name => Argument.PositiveOrZero(name, int.MinValue)); - yield return SimpleDataRow(name => Argument.PositiveNonZero(name, -1L)); yield return SimpleDataRow(name => Argument.PositiveNonZero(name, long.MinValue)); yield return SimpleDataRow(name => Argument.PositiveNonZero(name, 0L)); yield return SimpleDataRow(name => Argument.PositiveOrZero(name, -1L)); yield return SimpleDataRow(name => Argument.PositiveOrZero(name, long.MinValue)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, 0, 0)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, -1, 0)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, int.MinValue, 0)); + yield return SimpleDataRow(name => Argument.GreaterThanOrEqualTo(name, -1, 0)); + yield return SimpleDataRow(name => Argument.GreaterThanOrEqualTo(name, int.MinValue, 0)); + yield return SimpleDataRow(name => Argument.LessThan(name, 0, 0)); + yield return SimpleDataRow(name => Argument.LessThan(name, 1, 0)); + yield return SimpleDataRow(name => Argument.LessThan(name, int.MaxValue, 0)); + yield return SimpleDataRow(name => Argument.LessThanOrEqualTo(name, 1, 0)); + yield return SimpleDataRow(name => Argument.LessThanOrEqualTo(name, int.MaxValue, 0)); + + yield return SimpleDataRow(name => Argument.GreaterThan(name, 0.0, 0.0)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, -double.Epsilon, 0.0)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, double.MinValue, 0.0)); + yield return SimpleDataRow(name => Argument.GreaterThanOrEqualTo(name, -double.Epsilon, 0.0)); + yield return SimpleDataRow(name => Argument.GreaterThanOrEqualTo(name, double.MinValue, 0.0)); + yield return SimpleDataRow(name => Argument.LessThan(name, 0.0, 0.0)); + yield return SimpleDataRow(name => Argument.LessThan(name, double.Epsilon, 0.0)); + yield return SimpleDataRow(name => Argument.LessThan(name, double.MaxValue, 0.0)); + yield return SimpleDataRow(name => Argument.LessThanOrEqualTo(name, double.Epsilon, 0.0)); + yield return SimpleDataRow(name => Argument.LessThanOrEqualTo(name, double.MaxValue, 0.0)); + + yield return SimpleDataRow(name => Argument.GreaterThan(name, 0m, 0m)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, NegativeEpsilon, 0m)); + yield return SimpleDataRow(name => Argument.GreaterThan(name, decimal.MinValue, 0m)); + yield return SimpleDataRow(name => Argument.GreaterThanOrEqualTo(name, NegativeEpsilon, 0m)); + yield return SimpleDataRow(name => Argument.GreaterThanOrEqualTo(name, decimal.MinValue, 0m)); + yield return SimpleDataRow(name => Argument.LessThan(name, 0m, 0m)); + yield return SimpleDataRow(name => Argument.LessThan(name, PositiveEpsilon, 0m)); + yield return SimpleDataRow(name => Argument.LessThan(name, decimal.MaxValue, 0m)); + yield return SimpleDataRow(name => Argument.LessThanOrEqualTo(name, PositiveEpsilon, 0m)); + yield return SimpleDataRow(name => Argument.LessThanOrEqualTo(name, decimal.MaxValue, 0m)); } } @@ -136,6 +167,38 @@ public static IEnumerable SuccessVariants { yield return SuccessDataRow(long.MaxValue, value => Argument.PositiveOrZero("x", value)); yield return SuccessDataRow(0L, value => Argument.PositiveOrZero("x", value)); + yield return SuccessDataRow(1, value => Argument.GreaterThan("x", value, 0)); + yield return SuccessDataRow(int.MaxValue, value => Argument.GreaterThan("x", value, 0)); + yield return SuccessDataRow(0, value => Argument.GreaterThanOrEqualTo("x", value, 0)); + yield return SuccessDataRow(1, value => Argument.GreaterThanOrEqualTo("x", value, 0)); + yield return SuccessDataRow(int.MaxValue, value => Argument.GreaterThanOrEqualTo("x", value, 0)); + yield return SuccessDataRow(-1, value => Argument.LessThan("x", value, 0)); + yield return SuccessDataRow(int.MinValue, value => Argument.LessThan("x", value, 0)); + yield return SuccessDataRow(0, value => Argument.LessThanOrEqualTo("x", value, 0)); + yield return SuccessDataRow(-1, value => Argument.LessThanOrEqualTo("x", value, 0)); + yield return SuccessDataRow(int.MinValue, value => Argument.LessThanOrEqualTo("x", value, 0)); + + yield return SuccessDataRow(double.Epsilon, value => Argument.GreaterThan("x", value, 0.0)); + yield return SuccessDataRow(double.MaxValue, value => Argument.GreaterThan("x", value, 0.0)); + yield return SuccessDataRow(0.0, value => Argument.GreaterThanOrEqualTo("x", value, 0.0)); + yield return SuccessDataRow(double.Epsilon, value => Argument.GreaterThanOrEqualTo("x", value, 0.0)); + yield return SuccessDataRow(double.MaxValue, value => Argument.GreaterThanOrEqualTo("x", value, 0.0)); + yield return SuccessDataRow(-double.Epsilon, value => Argument.LessThan("x", value, 0.0)); + yield return SuccessDataRow(double.MinValue, value => Argument.LessThan("x", value, 0.0)); + yield return SuccessDataRow(0.0, value => Argument.LessThanOrEqualTo("x", value, 0.0)); + yield return SuccessDataRow(-double.Epsilon, value => Argument.LessThanOrEqualTo("x", value, 0.0)); + yield return SuccessDataRow(double.MinValue, value => Argument.LessThanOrEqualTo("x", value, 0.0)); + + yield return SuccessDataRow(PositiveEpsilon, value => Argument.GreaterThan("x", value, 0m)); + yield return SuccessDataRow(decimal.MaxValue, value => Argument.GreaterThan("x", value, 0m)); + yield return SuccessDataRow(0m, value => Argument.GreaterThanOrEqualTo("x", value, 0m)); + yield return SuccessDataRow(PositiveEpsilon, value => Argument.GreaterThanOrEqualTo("x", value, 0m)); + yield return SuccessDataRow(decimal.MaxValue, value => Argument.GreaterThanOrEqualTo("x", value, 0m)); + yield return SuccessDataRow(NegativeEpsilon, value => Argument.LessThan("x", value, 0m)); + yield return SuccessDataRow(decimal.MinValue, value => Argument.LessThan("x", value, 0m)); + yield return SuccessDataRow(0m, value => Argument.LessThanOrEqualTo("x", value, 0m)); + yield return SuccessDataRow(NegativeEpsilon, value => Argument.LessThanOrEqualTo("x", value, 0m)); + yield return SuccessDataRow(decimal.MinValue, value => Argument.LessThanOrEqualTo("x", value, 0m)); } } @@ -148,4 +211,14 @@ private static object[] SuccessDataRow(T argument, Expression> val { return new object[] { argument, validate }; } + + /// + /// Represents the smallest possible which is greater than zero. + /// + private static decimal PositiveEpsilon => new decimal(1, 0, 0, false, 28); + + /// + /// Represents the smallest possible which is less than zero. + /// + private static decimal NegativeEpsilon => new decimal(1, 0, 0, true, 28); } \ No newline at end of file diff --git a/Argument/Argument.cs b/Argument/Argument.cs index 81dfb5a..3afe0d8 100644 --- a/Argument/Argument.cs +++ b/Argument/Argument.cs @@ -280,6 +280,98 @@ public static long PositiveNonZero([NotNull, InvokerParameterName] string name, return value; } + /// + /// Verifies that a given argument value is greater than a given threshold and returns the value provided. + /// + /// The type of the value to be tested. + /// Argument name. + /// Argument value. + /// The value to test against. + /// if it is greater than . + [AssertionMethod] + [ContractArgumentValidator] + public static TValue GreaterThan( + [NotNull, InvokerParameterName] string name, + TValue value, + TValue threshold + ) + where TValue : struct, IComparable, IComparable + { + if (value.CompareTo(threshold) <= 0) + throw new ArgumentOutOfRangeException(name, value, $"Value cannot be less than or equal to {threshold}."); + + return value; + } + + /// + /// Verifies that a given argument value is greater than or equal to a given threshold and returns the value provided. + /// + /// The type of the value to be tested. + /// Argument name. + /// Argument value. + /// The value to test against. + /// if it is greater than or equal to . + [AssertionMethod] + [ContractArgumentValidator] + public static TValue GreaterThanOrEqualTo( + [NotNull, InvokerParameterName] string name, + TValue value, + TValue threshold + ) + where TValue : struct, IComparable, IComparable + { + if (value.CompareTo(threshold) < 0) + throw new ArgumentOutOfRangeException(name, value, $"Value cannot be less than {threshold}."); + + return value; + } + + /// + /// Verifies that a given argument value is less than a given threshold and returns the value provided. + /// + /// The type of the value to be tested. + /// Argument name. + /// Argument value. + /// The value to test against. + /// if it is less than . + [AssertionMethod] + [ContractArgumentValidator] + public static TValue LessThan( + [NotNull, InvokerParameterName] string name, + TValue value, + TValue threshold + ) + where TValue : struct, IComparable, IComparable + { + if (value.CompareTo(threshold) >= 0) + throw new ArgumentOutOfRangeException(name, value, $"Value cannot be greater than or equal to {threshold}."); + + return value; + } + + /// + /// Verifies that a given argument value is less than or equal to a given threshold and returns the value provided. + /// + /// The type of the value to be tested. + /// Argument name. + /// Argument value. + /// The value to test against. + /// if it is less than or equal to . + [AssertionMethod] + [ContractArgumentValidator] + public static TValue LessThanOrEqualTo( + [NotNull, InvokerParameterName] string name, + TValue value, + TValue threshold + ) + where TValue : struct, IComparable, IComparable + { + if (value.CompareTo(threshold) > 0) + throw new ArgumentOutOfRangeException(name, value, $"Value cannot be greater than {threshold}."); + + return value; + } + /// /// Provides an extensibility point that can be used by custom argument validation extension methods. ///