diff --git a/src/SixLabors.Core/Helpers/DebugGuard.cs b/src/SixLabors.Core/Helpers/DebugGuard.cs index c7fb796b3..31d7d23f2 100644 --- a/src/SixLabors.Core/Helpers/DebugGuard.cs +++ b/src/SixLabors.Core/Helpers/DebugGuard.cs @@ -13,7 +13,7 @@ namespace SixLabors [DebuggerStepThrough] internal static class DebugGuard { - /// + /// /// Ensures that the value is not null. /// /// The target object, which cannot be null. @@ -225,6 +225,26 @@ namespace SixLabors } } + /// + /// Verifies, that the `source` span has the length of 'minLength', or longer. + /// + /// The element type of the spans. + /// The target span. + /// The minimum length. + /// The name of the parameter that is to be checked. + /// + /// has less than items. + /// + [Conditional("DEBUG")] + [DebuggerStepThrough] + public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) + { + if (source.Length < minLength) + { + ThrowArgumentException($"The size must be at least {minLength}.", parameterName); + } + } + /// /// Verifies that the 'destination' span is not shorter than 'source'. /// @@ -267,26 +287,6 @@ namespace SixLabors } } - /// - /// Verifies, that the `source` span has the length of 'minLength', or longer. - /// - /// The element type of the spans. - /// The target span. - /// The minimum length. - /// The name of the parameter that is to be checked. - /// - /// has less than items. - /// - [Conditional("DEBUG")] - [DebuggerStepThrough] - public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) - { - if (source.Length < minLength) - { - ThrowArgumentException($"Span-s must be at least of length {minLength}!", parameterName); - } - } - [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowArgumentException(string message, string parameterName) { diff --git a/tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs b/tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs index 9b14fc8ca..3db5642d1 100644 --- a/tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs +++ b/tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs @@ -14,6 +14,10 @@ namespace SixLabors.Helpers.Tests { public class DebugGuardTests { + private class Foo + { + } + [Fact] public void AllStaticMethodsOnOnDebugGuardHaveDEBUGConditional() { @@ -28,18 +32,113 @@ namespace SixLabors.Helpers.Tests } [Fact] - public void NotNull_TargetNotNull_ThrowsNoException() + public void NotNull_WhenNull_Throws() { - DebugGuard.NotNull("test", "myParamName"); + Foo foo = null; + Assert.Throws(() => Guard.NotNull(foo, nameof(foo))); } [Fact] - public void NotNull_TargetNull_ThrowsException() + public void NotNull_WhenNotNull() + { + Foo foo = new Foo(); + Guard.NotNull(foo, nameof(foo)); + } + + [Theory] + [InlineData(null, true)] + [InlineData("", true)] + [InlineData(" ", true)] + [InlineData("$", false)] + [InlineData("lol", false)] + public void NotNullOrWhiteSpace(string str, bool shouldThrow) { - Assert.Throws(() => + if (shouldThrow) { - DebugGuard.NotNull((object)null, "myParamName"); - }); + Assert.ThrowsAny(() => Guard.NotNullOrWhiteSpace(str, nameof(str))); + } + else + { + Guard.NotNullOrWhiteSpace(str, nameof(str)); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void IsTrue(bool value) + { + if (!value) + { + Assert.Throws(() => Guard.IsTrue(value, nameof(value), "Boo!")); + } + else + { + Guard.IsTrue(value, nameof(value), "Boo."); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void IsFalse(bool value) + { + if (value) + { + Assert.Throws(() => Guard.IsFalse(value, nameof(value), "Boo!")); + } + else + { + Guard.IsFalse(value, nameof(value), "Boo."); + } + } + + public static readonly TheoryData SizeCheckData = new TheoryData + { + { 0, 0, false }, + { 1, 1, false }, + { 1, 0, false }, + { 13, 13, false }, + { 20, 13, false }, + { 12, 13, true }, + { 0, 1, true }, + }; + + [Theory] + [MemberData(nameof(SizeCheckData))] + public void MustBeSizedAtLeast(int length, int minLength, bool shouldThrow) + { + int[] data = new int[length]; + + if (shouldThrow) + { + Assert.Throws(() => Guard.MustBeSizedAtLeast((Span)data, minLength, nameof(data))); + Assert.Throws(() => Guard.MustBeSizedAtLeast((ReadOnlySpan)data, minLength, nameof(data))); + } + else + { + Guard.MustBeSizedAtLeast((Span)data, minLength, nameof(data)); + Guard.MustBeSizedAtLeast((ReadOnlySpan)data, minLength, nameof(data)); + } + } + + [Theory] + [MemberData(nameof(SizeCheckData))] + public void DestinationShouldNotBeTooShort(int destLength, int sourceLength, bool shouldThrow) + { + int[] dest = new int[destLength]; + int[] source = new int[sourceLength]; + + if (shouldThrow) + { + Assert.Throws(() => Guard.DestinationShouldNotBeTooShort((Span)source, (Span)dest, nameof(dest))); + Assert.Throws(() => Guard.DestinationShouldNotBeTooShort((ReadOnlySpan)source, (Span)dest, nameof(dest))); + } + else + { + Guard.DestinationShouldNotBeTooShort((Span)source, (Span)dest, nameof(dest)); + Guard.DestinationShouldNotBeTooShort((ReadOnlySpan)source, (Span)dest, nameof(dest)); + } } [Fact] @@ -59,7 +158,7 @@ namespace SixLabors.Helpers.Tests }); Assert.Equal("myParamName", exception.ParamName); - Assert.Contains($"Value must be less than {max}.", exception.Message); + Assert.Contains($"Value {value} must be less than {max}.", exception.Message); } [Theory] @@ -79,7 +178,7 @@ namespace SixLabors.Helpers.Tests }); Assert.Equal("myParamName", exception.ParamName); - Assert.Contains($"Value must be less than or equal to 1.", exception.Message); + Assert.Contains($"Value 2 must be less than or equal to 1.", exception.Message); } [Fact] @@ -99,7 +198,7 @@ namespace SixLabors.Helpers.Tests }); Assert.Equal("myParamName", exception.ParamName); - Assert.Contains($"Value must be greater than {min}.", exception.Message); + Assert.Contains($"Value {value} must be greater than {min}.", exception.Message); } [Theory] @@ -119,7 +218,7 @@ namespace SixLabors.Helpers.Tests }); Assert.Equal("myParamName", exception.ParamName); - Assert.Contains($"Value must be greater than or equal to 2.", exception.Message); + Assert.Contains($"Value 1 must be greater than or equal to 2.", exception.Message); } [Theory] diff --git a/tests/SixLabors.Core.Tests/Helpers/GuardTests.cs b/tests/SixLabors.Core.Tests/Helpers/GuardTests.cs index bed743767..a35668c38 100644 --- a/tests/SixLabors.Core.Tests/Helpers/GuardTests.cs +++ b/tests/SixLabors.Core.Tests/Helpers/GuardTests.cs @@ -20,7 +20,7 @@ namespace SixLabors.Helpers.Tests } [Fact] - public void NotNull_NotNull() + public void NotNull_WhenNotNull() { Foo foo = new Foo(); Guard.NotNull(foo, nameof(foo)); @@ -74,14 +74,19 @@ namespace SixLabors.Helpers.Tests } } + public static readonly TheoryData SizeCheckData = new TheoryData + { + { 0, 0, false }, + { 1, 1, false }, + { 1, 0, false }, + { 13, 13, false }, + { 20, 13, false }, + { 12, 13, true }, + { 0, 1, true }, + }; + [Theory] - [InlineData(0, 0, false)] - [InlineData(1, 1, false)] - [InlineData(1, 0, false)] - [InlineData(13, 13, false)] - [InlineData(20, 13, false)] - [InlineData(12, 13, true)] - [InlineData(0, 1, true)] + [MemberData(nameof(SizeCheckData))] public void MustBeSizedAtLeast(int length, int minLength, bool shouldThrow) { int[] data = new int[length]; @@ -98,6 +103,25 @@ namespace SixLabors.Helpers.Tests } } + [Theory] + [MemberData(nameof(SizeCheckData))] + public void DestinationShouldNotBeTooShort(int destLength, int sourceLength, bool shouldThrow) + { + int[] dest = new int[destLength]; + int[] source = new int[sourceLength]; + + if (shouldThrow) + { + Assert.Throws(() => Guard.DestinationShouldNotBeTooShort((Span)source, (Span)dest, nameof(dest))); + Assert.Throws(() => Guard.DestinationShouldNotBeTooShort((ReadOnlySpan)source, (Span)dest, nameof(dest))); + } + else + { + Guard.DestinationShouldNotBeTooShort((Span)source, (Span)dest, nameof(dest)); + Guard.DestinationShouldNotBeTooShort((ReadOnlySpan)source, (Span)dest, nameof(dest)); + } + } + [Fact] public void MustBeLessThan_IsLess_ThrowsNoException() {