Browse Source

[SL.Core] harmonize Guard + DebugGuard code and tests

af/octree-no-pixelmap
Anton Firszov 7 years ago
parent
commit
2ca0a42301
  1. 42
      src/SixLabors.Core/Helpers/DebugGuard.cs
  2. 119
      tests/SixLabors.Core.Tests/Helpers/DebugGuardTests.cs
  3. 40
      tests/SixLabors.Core.Tests/Helpers/GuardTests.cs

42
src/SixLabors.Core/Helpers/DebugGuard.cs

@ -13,7 +13,7 @@ namespace SixLabors
[DebuggerStepThrough]
internal static class DebugGuard
{
/// <summary>
/// <summary>
/// Ensures that the value is not null.
/// </summary>
/// <param name="value">The target object, which cannot be null.</param>
@ -225,6 +225,26 @@ namespace SixLabors
}
}
/// <summary>
/// Verifies, that the `source` span has the length of 'minLength', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans.</typeparam>
/// <param name="source">The target span.</param>
/// <param name="minLength">The minimum length.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="source"/> has less than <paramref name="minLength"/> items.
/// </exception>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public static void MustBeSizedAtLeast<T>(Span<T> source, int minLength, string parameterName)
{
if (source.Length < minLength)
{
ThrowArgumentException($"The size must be at least {minLength}.", parameterName);
}
}
/// <summary>
/// Verifies that the 'destination' span is not shorter than 'source'.
/// </summary>
@ -267,26 +287,6 @@ namespace SixLabors
}
}
/// <summary>
/// Verifies, that the `source` span has the length of 'minLength', or longer.
/// </summary>
/// <typeparam name="T">The element type of the spans.</typeparam>
/// <param name="source">The target span.</param>
/// <param name="minLength">The minimum length.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentException">
/// <paramref name="source"/> has less than <paramref name="minLength"/> items.
/// </exception>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public static void MustBeSizedAtLeast<T>(Span<T> 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)
{

119
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<ArgumentNullException>(() => 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<ArgumentNullException>(() =>
if (shouldThrow)
{
DebugGuard.NotNull((object)null, "myParamName");
});
Assert.ThrowsAny<ArgumentException>(() => 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<ArgumentException>(() => 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<ArgumentException>(() => Guard.IsFalse(value, nameof(value), "Boo!"));
}
else
{
Guard.IsFalse(value, nameof(value), "Boo.");
}
}
public static readonly TheoryData<int, int, bool> SizeCheckData = new TheoryData<int, int, bool>
{
{ 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<ArgumentException>(() => Guard.MustBeSizedAtLeast((Span<int>)data, minLength, nameof(data)));
Assert.Throws<ArgumentException>(() => Guard.MustBeSizedAtLeast((ReadOnlySpan<int>)data, minLength, nameof(data)));
}
else
{
Guard.MustBeSizedAtLeast((Span<int>)data, minLength, nameof(data));
Guard.MustBeSizedAtLeast((ReadOnlySpan<int>)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<ArgumentException>(() => Guard.DestinationShouldNotBeTooShort((Span<int>)source, (Span<int>)dest, nameof(dest)));
Assert.Throws<ArgumentException>(() => Guard.DestinationShouldNotBeTooShort((ReadOnlySpan<int>)source, (Span<int>)dest, nameof(dest)));
}
else
{
Guard.DestinationShouldNotBeTooShort((Span<int>)source, (Span<int>)dest, nameof(dest));
Guard.DestinationShouldNotBeTooShort((ReadOnlySpan<int>)source, (Span<int>)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]

40
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<int, int, bool> SizeCheckData = new TheoryData<int, int, bool>
{
{ 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<ArgumentException>(() => Guard.DestinationShouldNotBeTooShort((Span<int>)source, (Span<int>)dest, nameof(dest)));
Assert.Throws<ArgumentException>(() => Guard.DestinationShouldNotBeTooShort((ReadOnlySpan<int>)source, (Span<int>)dest, nameof(dest)));
}
else
{
Guard.DestinationShouldNotBeTooShort((Span<int>)source, (Span<int>)dest, nameof(dest));
Guard.DestinationShouldNotBeTooShort((ReadOnlySpan<int>)source, (Span<int>)dest, nameof(dest));
}
}
[Fact]
public void MustBeLessThan_IsLess_ThrowsNoException()
{

Loading…
Cancel
Save