From 15ff40eabea934e47883a05688f832204f76f337 Mon Sep 17 00:00:00 2001 From: Hamid Reza Ashkiyan Date: Sun, 24 Dec 2023 13:39:51 +0330 Subject: [PATCH 1/3] feat: add string length out of range. --- .../GuardAgainstOutOfRangeExtensions.cs | 48 +++++++++++++++++ .../GuardAgainstStringOutOfRange.cs | 51 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs diff --git a/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs b/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs index 6621e35..addd654 100644 --- a/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs +++ b/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs @@ -9,6 +9,54 @@ namespace Ardalis.GuardClauses; public static partial class GuardClauseExtensions { + /// + /// Throws an if string length is out of range. + /// + /// + /// + /// + /// + /// + /// Optional. Custom error message + /// if the value is not negative. + /// +#if NETFRAMEWORK || NETSTANDARD2_0 + public static string LengthOutOfRange(this IGuardClause guardClause, + string input, + int minLength, + int maxLength, + string parameterName, + string? message = null) +#else + public static string LengthOutOfRange(this IGuardClause guardClause, + string input, + int minLength, + int maxLength, + [CallerArgumentExpression("input")] string? parameterName = null, + string? message = null) +#endif + { + Guard.Against.NegativeOrZero(minLength, nameof(minLength)); + if (input.Length < minLength) + { + throw new ArgumentException( + message ?? + $"Input {parameterName} with length {input.Length} is too short. Minimum length is {minLength}.", + parameterName); + } + + Guard.Against.NegativeOrZero(maxLength, nameof(maxLength)); + if (input.Length > maxLength) + { + throw new ArgumentException( + message ?? + $"Input {parameterName} with length {input.Length} is too long. Maxmimum length is {maxLength}.", + parameterName); + } + + return input; + } + /// /// Throws an if is not a valid enum value. /// diff --git a/test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs b/test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs new file mode 100644 index 0000000..cde44b3 --- /dev/null +++ b/test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs @@ -0,0 +1,51 @@ +using System; +using Ardalis.GuardClauses; +using Xunit; + +namespace GuardClauses.UnitTests; + +public class GuardAgainstStringOutOfRange +{ + [Fact] + public void DoesNothingGivenNonEmptyString() + { + Guard.Against.LengthOutOfRange("a", 1, 4, "string"); + Guard.Against.LengthOutOfRange("abc", 1, 4, "string"); + Guard.Against.LengthOutOfRange("a", 1, 4, "string"); + Guard.Against.LengthOutOfRange("a", 1, 4, "string"); + Guard.Against.LengthOutOfRange("a", 1, 4, "string"); + } + + [Fact] + public void ThrowsGivenEmptyString() + { + Assert.Throws(() => Guard.Against.LengthOutOfRange("", 1, 2, "string")); + } + + [Fact] + public void ThrowsGivenNonPositiveMinLength() + { + Assert.Throws(() => Guard.Against.LengthOutOfRange("", 0, 0, "string")); + Assert.Throws(() => Guard.Against.LengthOutOfRange("", -1, -1, "string")); + } + + [Fact] + public void ThrowsGivenStringShorterThanMinLength() + { + Assert.Throws(() => Guard.Against.LengthOutOfRange("a", 2, 2, "string")); + } + + [Fact] + public void ThrowsGivenStringLongerThanMaxLength() + { + Assert.Throws(() => Guard.Against.LengthOutOfRange("abcd", 2, 2, "string")); + } + + [Fact] + public void ReturnsExpectedValueWhenGivenLongerString() + { + var expected = "abc"; + var actual = Guard.Against.LengthOutOfRange("abc", 2, 5, "string"); + Assert.Equal(expected, actual); + } +} From 409fb6a1cf638e319e0f783cbac620aebfa53460 Mon Sep 17 00:00:00 2001 From: Hamid Reza Ashkiyan Date: Sun, 24 Dec 2023 13:48:54 +0330 Subject: [PATCH 2/3] feat: Add min and max check. --- src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs | 8 ++++++++ ...utOfRange.cs => GuardAgainstStringLengthOutOfRange.cs} | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) rename test/GuardClauses.UnitTests/{GuardAgainstStringOutOfRange.cs => GuardAgainstStringLengthOutOfRange.cs} (87%) diff --git a/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs b/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs index addd654..6d2cfd5 100644 --- a/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs +++ b/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs @@ -36,6 +36,14 @@ public static string LengthOutOfRange(this IGuardClause guardClause, string? message = null) #endif { + if (maxLength < minLength) + { + throw new ArgumentException( + message ?? + $"Min length must be equal or less than max length.", + parameterName); + } + Guard.Against.NegativeOrZero(minLength, nameof(minLength)); if (input.Length < minLength) { diff --git a/test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs b/test/GuardClauses.UnitTests/GuardAgainstStringLengthOutOfRange.cs similarity index 87% rename from test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs rename to test/GuardClauses.UnitTests/GuardAgainstStringLengthOutOfRange.cs index cde44b3..3dceae0 100644 --- a/test/GuardClauses.UnitTests/GuardAgainstStringOutOfRange.cs +++ b/test/GuardClauses.UnitTests/GuardAgainstStringLengthOutOfRange.cs @@ -4,7 +4,7 @@ namespace GuardClauses.UnitTests; -public class GuardAgainstStringOutOfRange +public class GuardAgainstStringLengthOutOfRange { [Fact] public void DoesNothingGivenNonEmptyString() @@ -41,6 +41,12 @@ public void ThrowsGivenStringLongerThanMaxLength() Assert.Throws(() => Guard.Against.LengthOutOfRange("abcd", 2, 2, "string")); } + [Fact] + public void ThrowsWhenMinIsBiggerThanMax() + { + Assert.Throws(() => Guard.Against.LengthOutOfRange("asd", 4, 2, "string")); + } + [Fact] public void ReturnsExpectedValueWhenGivenLongerString() { From 967e717bb88fa0ee0b87d054ca255934105e0f7e Mon Sep 17 00:00:00 2001 From: Hamid Reza Ashkiyan Date: Mon, 25 Dec 2023 10:53:31 +0330 Subject: [PATCH 3/3] Refactor LengthOutOfRange. --- .../GuardAgainstOutOfRangeExtensions.cs | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs b/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs index 6d2cfd5..06da4e2 100644 --- a/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs +++ b/src/GuardClauses/GuardAgainstOutOfRangeExtensions.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; +using GuardClauses; namespace Ardalis.GuardClauses; @@ -36,31 +37,10 @@ public static string LengthOutOfRange(this IGuardClause guardClause, string? message = null) #endif { - if (maxLength < minLength) - { - throw new ArgumentException( - message ?? - $"Min length must be equal or less than max length.", - parameterName); - } - - Guard.Against.NegativeOrZero(minLength, nameof(minLength)); - if (input.Length < minLength) - { - throw new ArgumentException( - message ?? - $"Input {parameterName} with length {input.Length} is too short. Minimum length is {minLength}.", - parameterName); - } - - Guard.Against.NegativeOrZero(maxLength, nameof(maxLength)); - if (input.Length > maxLength) - { - throw new ArgumentException( - message ?? - $"Input {parameterName} with length {input.Length} is too long. Maxmimum length is {maxLength}.", - parameterName); - } + Guard.Against.Negative(maxLength - minLength, parameterName: "min or max length", + message: "Min length must be equal or less than max length."); + Guard.Against.StringTooShort(input, minLength, nameof(minLength)); + Guard.Against.StringTooLong(input, maxLength, nameof(maxLength)); return input; }