From 16a239fa578c212190ad0b89b69b13e57a627976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Fri, 26 Apr 2024 23:11:20 +0200 Subject: [PATCH 1/2] feat: Added `ThrowIfNullOrEmpty(IEnumerable`1)` --- .../Argument_ThrowArgumentException.cs | 4 +- .../Argument_ThrowArgumentNullException.cs | 4 +- .../Argument_ThrowIfNullOrEmpty.cs | 21 ++++++ .../ArgumentTests_ThrowIfNullOrEmpty.cs | 72 +++++++++++++++++++ 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/NetEvolve.Arguments/Argument_ThrowArgumentException.cs b/src/NetEvolve.Arguments/Argument_ThrowArgumentException.cs index bc6f02f..d146d78 100644 --- a/src/NetEvolve.Arguments/Argument_ThrowArgumentException.cs +++ b/src/NetEvolve.Arguments/Argument_ThrowArgumentException.cs @@ -1,5 +1,4 @@ -#if !NET8_0_OR_GREATER -namespace NetEvolve.Arguments; +namespace NetEvolve.Arguments; using System; using System.Diagnostics; @@ -17,4 +16,3 @@ private static void ThrowArgumentException(string? paramName, string? message = throw new ArgumentException(message, paramName); } } -#endif diff --git a/src/NetEvolve.Arguments/Argument_ThrowArgumentNullException.cs b/src/NetEvolve.Arguments/Argument_ThrowArgumentNullException.cs index d2f2fb8..51e959d 100644 --- a/src/NetEvolve.Arguments/Argument_ThrowArgumentNullException.cs +++ b/src/NetEvolve.Arguments/Argument_ThrowArgumentNullException.cs @@ -1,5 +1,4 @@ -#if !NET8_0_OR_GREATER -namespace NetEvolve.Arguments; +namespace NetEvolve.Arguments; using System; using System.Diagnostics; @@ -17,4 +16,3 @@ private static void ThrowArgumentNullException(string? paramName, string? messag throw new ArgumentNullException(paramName, message); } } -#endif diff --git a/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs b/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs index 8b661d0..a1d660f 100644 --- a/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs +++ b/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs @@ -1,8 +1,10 @@ namespace NetEvolve.Arguments; using System; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Runtime.CompilerServices; public static partial class Argument @@ -38,4 +40,23 @@ public static void ThrowIfNullOrEmpty( } #endif } + + [DebuggerStepThrough] + [StackTraceHidden] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowIfNullOrEmpty( + [NotNull] IEnumerable argument, + [CallerArgumentExpression(nameof(argument))] string? paramName = null + ) + { + if (argument is null) + { + ThrowArgumentNullException(paramName); + } + + if (argument.TryGetNonEnumeratedCount(out var count) && count == 0) + { + ThrowArgumentException(paramName); + } + } } diff --git a/tests/NetEvolve.Arguments.Tests.Unit/ArgumentTests_ThrowIfNullOrEmpty.cs b/tests/NetEvolve.Arguments.Tests.Unit/ArgumentTests_ThrowIfNullOrEmpty.cs index 205f645..369a46f 100644 --- a/tests/NetEvolve.Arguments.Tests.Unit/ArgumentTests_ThrowIfNullOrEmpty.cs +++ b/tests/NetEvolve.Arguments.Tests.Unit/ArgumentTests_ThrowIfNullOrEmpty.cs @@ -1,6 +1,7 @@ namespace NetEvolve.Arguments.Tests.Unit; using System; +using System.Collections.Generic; using Xunit; public sealed partial class ArgumentTests @@ -43,4 +44,75 @@ public void ThrowIfNullOrEmpty_WhenArgumentIsNotEmpty_ReturnsArgument() // Assert Assert.True(true); } + + [Fact] + public void ThrowIfNullOrEmpty_WhenIEnumerableNull_ThrowsArgumentNullException() + { + // Arrange + IEnumerable? argument = null; + + // Act + void Act() => Argument.ThrowIfNullOrEmpty(argument); + + // Assert + _ = Assert.Throws(nameof(argument), Act); + } + + [Theory] + [MemberData(nameof(ThrowIfNullOrEmptyEnumerableData))] + public void ThrowIfNullOrEmpty_WhenIEnumerableIsEmpty_ThrowsArgumentException( + IEnumerable argument + ) + { + // Act + void Act() => Argument.ThrowIfNullOrEmpty(argument); + + // Assert + _ = Assert.Throws(nameof(argument), Act); + } + + [Theory] + [MemberData(nameof(ThrowIfNullOrEmptyEnumerableWithData))] + public void ThrowIfNullOrEmpty_WhenIEnumerableIsNotEmpty_ReturnsArgument( + IEnumerable argument + ) + { + // Act + Argument.ThrowIfNullOrEmpty(argument); + + // Assert + Assert.True(true); + } + + public static TheoryData> ThrowIfNullOrEmptyEnumerableData + { + get + { + var data = new TheoryData> + { + Array.Empty(), + new List(), + new HashSet() + }; + + return data; + } + } + + public static TheoryData> ThrowIfNullOrEmptyEnumerableWithData + { + get + { + var data = new TheoryData> + { +#pragma warning disable CA1861 // Avoid constant arrays as arguments + new[] { "argument" }, +#pragma warning restore CA1861 // Avoid constant arrays as arguments + new List { "argument" }, + new HashSet { "argument" } + }; + + return data; + } + } } From c647217ebe2269c71917d7e1d80d53967bca289f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Fri, 26 Apr 2024 23:15:41 +0200 Subject: [PATCH 2/2] docs: Added XML Summary to ThrowIfNullOrEmpty method --- src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs b/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs index a1d660f..3462339 100644 --- a/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs +++ b/src/NetEvolve.Arguments/Argument_ThrowIfNullOrEmpty.cs @@ -41,6 +41,11 @@ public static void ThrowIfNullOrEmpty( #endif } + /// Throws an exception if is null or empty. + /// The string argument to validate as non-null and non-empty. + /// The name of the parameter with which corresponds. + /// is null. + /// is empty. [DebuggerStepThrough] [StackTraceHidden] [MethodImpl(MethodImplOptions.NoInlining)]