From 9db729459db59717335eb9f08b667233b604aa33 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 24 Sep 2015 21:48:40 +1000 Subject: [PATCH] Add Guard tests Former-commit-id: f55de41ddb9ea4ee387ceb462b4786af7df5cacb Former-commit-id: 636f57e4157a3f388ca28ee1e9e83cd11615f301 Former-commit-id: ea4683211d00a728dffab492db02b5537b9d38d4 --- .../Common/Extensions/ByteExtensions.cs | 2 +- src/ImageProcessor/Common/Helpers/Guard.cs | 15 +- src/ImageProcessor/Formats/Gif/LzwDecoder.cs | 2 +- .../Formats/Gif/Quantizer/OctreeQuantizer.cs | 4 +- .../Formats/Gif/Quantizer/QuantizedImage.cs | 4 +- .../Formats/Jpg/LibJpeg/BitStream.cs | 10 +- src/ImageProcessor/ImageBase.cs | 4 +- src/ImageProcessor/Properties/AssemblyInfo.cs | 3 + .../Helpers/GuardTests.cs | 209 ++++++++++++++++++ .../ImageProcessor.Tests.csproj | 3 +- 10 files changed, 235 insertions(+), 21 deletions(-) create mode 100644 tests/ImageProcessor.Tests/Helpers/GuardTests.cs diff --git a/src/ImageProcessor/Common/Extensions/ByteExtensions.cs b/src/ImageProcessor/Common/Extensions/ByteExtensions.cs index 958326f176..d11132801f 100644 --- a/src/ImageProcessor/Common/Extensions/ByteExtensions.cs +++ b/src/ImageProcessor/Common/Extensions/ByteExtensions.cs @@ -29,7 +29,7 @@ namespace ImageProcessor public static byte[] ToArrayByBitsLength(this byte[] bytes, int bits) { Guard.NotNull(bytes, "bytes"); - Guard.GreaterThan(bits, 0, "bits"); + Guard.MustBeGreaterThan(bits, 0, "bits"); byte[] result; diff --git a/src/ImageProcessor/Common/Helpers/Guard.cs b/src/ImageProcessor/Common/Helpers/Guard.cs index 438831fa0a..d832e1b82c 100644 --- a/src/ImageProcessor/Common/Helpers/Guard.cs +++ b/src/ImageProcessor/Common/Helpers/Guard.cs @@ -11,11 +11,12 @@ namespace ImageProcessor { using System; - using System.Globalization; + using System.Diagnostics; /// /// Provides methods to protect against invalid parameters. /// + [DebuggerStepThrough] internal static class Guard { /// @@ -70,7 +71,7 @@ namespace ImageProcessor if (string.IsNullOrWhiteSpace(target)) { - throw new ArgumentException("String parameter cannot be null or empty and cannot contain only blanks.", parameterName); + throw new ArgumentException("Value cannot be null or empty and cannot contain only blanks.", parameterName); } } @@ -85,7 +86,7 @@ namespace ImageProcessor /// /// is greater than the maximum value. /// - public static void LessThan(TValue value, TValue max, string parameterName) where TValue : IComparable + public static void MustBeLessThan(TValue value, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(max) >= 0) { @@ -106,7 +107,7 @@ namespace ImageProcessor /// /// is greater than the maximum value. /// - public static void LessEquals(TValue value, TValue max, string parameterName) where TValue : IComparable + public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(max) > 0) { @@ -127,7 +128,7 @@ namespace ImageProcessor /// /// is less than the minimum value. /// - public static void GreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable + public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { if (value.CompareTo(min) <= 0) { @@ -148,7 +149,7 @@ namespace ImageProcessor /// /// is less than the minimum value. /// - public static void GreaterEquals(TValue value, TValue min, string parameterName) where TValue : IComparable + public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { if (value.CompareTo(min) < 0) { @@ -170,7 +171,7 @@ namespace ImageProcessor /// /// is less than the minimum value of greater than the maximum value. /// - public static void BetweenEquals(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable + public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) { diff --git a/src/ImageProcessor/Formats/Gif/LzwDecoder.cs b/src/ImageProcessor/Formats/Gif/LzwDecoder.cs index 1c3d5d28ba..4d6cfd4fb9 100644 --- a/src/ImageProcessor/Formats/Gif/LzwDecoder.cs +++ b/src/ImageProcessor/Formats/Gif/LzwDecoder.cs @@ -56,7 +56,7 @@ namespace ImageProcessor.Formats /// The decoded and uncompressed array. public byte[] DecodePixels(int width, int height, int dataSize) { - Guard.LessThan(dataSize, int.MaxValue, nameof(dataSize)); + Guard.MustBeLessThan(dataSize, int.MaxValue, nameof(dataSize)); // The resulting index table. byte[] pixels = new byte[width * height]; diff --git a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs index 5844e3d878..a7ebe8ec3b 100644 --- a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs +++ b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs @@ -57,8 +57,8 @@ namespace ImageProcessor.Formats public OctreeQuantizer(int maxColors, int maxColorBits) : base(false) { - Guard.LessEquals(maxColors, 255, "maxColors"); - Guard.BetweenEquals(maxColorBits, 1, 8, "maxColorBits"); + Guard.MustBeLessThanOrEqualTo(maxColors, 255, "maxColors"); + Guard.MustBeBetweenOrEqualTo(maxColorBits, 1, 8, "maxColorBits"); // Construct the Octree this.octree = new Octree(maxColorBits); diff --git a/src/ImageProcessor/Formats/Gif/Quantizer/QuantizedImage.cs b/src/ImageProcessor/Formats/Gif/Quantizer/QuantizedImage.cs index 627eee2acd..5738f9e887 100644 --- a/src/ImageProcessor/Formats/Gif/Quantizer/QuantizedImage.cs +++ b/src/ImageProcessor/Formats/Gif/Quantizer/QuantizedImage.cs @@ -42,8 +42,8 @@ namespace ImageProcessor.Formats /// public QuantizedImage(int width, int height, Bgra[] palette, byte[] pixels) { - Guard.GreaterThan(width, 0, nameof(width)); - Guard.GreaterThan(height, 0, nameof(height)); + Guard.MustBeGreaterThan(width, 0, nameof(width)); + Guard.MustBeGreaterThan(height, 0, nameof(height)); Guard.NotNull(palette, nameof(palette)); Guard.NotNull(pixels, nameof(pixels)); diff --git a/src/ImageProcessor/Formats/Jpg/LibJpeg/BitStream.cs b/src/ImageProcessor/Formats/Jpg/LibJpeg/BitStream.cs index 2bdaae68c2..9c2128bcd9 100644 --- a/src/ImageProcessor/Formats/Jpg/LibJpeg/BitStream.cs +++ b/src/ImageProcessor/Formats/Jpg/LibJpeg/BitStream.cs @@ -129,7 +129,7 @@ namespace ImageProcessor.Formats /// public virtual int Read(int bitCount) { - Guard.LessEquals(this.Tell() + bitCount, this.BitsAllocated(), "bitCount"); + Guard.MustBeLessThanOrEqualTo(this.Tell() + bitCount, this.BitsAllocated(), "bitCount"); return this.ReadBits(bitCount); } @@ -150,7 +150,7 @@ namespace ImageProcessor.Formats const int MaxBitsInStorage = sizeof(int) * BitsInByte; - Guard.LessEquals(bitCount, MaxBitsInStorage, "bitCount"); + Guard.MustBeLessThanOrEqualTo(bitCount, MaxBitsInStorage, "bitCount"); for (int i = 0; i < bitCount; ++i) { @@ -251,7 +251,7 @@ namespace ImageProcessor.Formats // This stream is then divided into 8-bit bytes, high-order bit first. // Thus, codes can straddle byte boundaries arbitrarily. After the EOD marker (code value 257), // any leftover bits in the final byte are set to 0. - Guard.BetweenEquals(bitsCount, 0, 32, "bitsCount"); + Guard.MustBeBetweenOrEqualTo(bitsCount, 0, 32, "bitsCount"); if (bitsCount == 0) { @@ -338,7 +338,7 @@ namespace ImageProcessor.Formats /// private void SeekSet(int position) { - Guard.GreaterEquals(position, 0, "position"); + Guard.MustBeGreaterThanOrEqualTo(position, 0, "position"); int byteDisplacement = position / BitsInByte; this.stream.Seek(byteDisplacement, SeekOrigin.Begin); @@ -356,7 +356,7 @@ namespace ImageProcessor.Formats private void SeekCurrent(int position) { int result = this.Tell() + position; - Guard.BetweenEquals(position, 0, this.BitsAllocated(), "position"); + Guard.MustBeBetweenOrEqualTo(position, 0, this.BitsAllocated(), "position"); this.SeekSet(result); } diff --git a/src/ImageProcessor/ImageBase.cs b/src/ImageProcessor/ImageBase.cs index 517ac184f8..0773d63e85 100644 --- a/src/ImageProcessor/ImageBase.cs +++ b/src/ImageProcessor/ImageBase.cs @@ -40,8 +40,8 @@ namespace ImageProcessor /// protected ImageBase(int width, int height) { - Guard.GreaterThan(width, 0, "width"); - Guard.GreaterThan(height, 0, "height"); + Guard.MustBeGreaterThan(width, 0, "width"); + Guard.MustBeGreaterThan(height, 0, "height"); this.Width = width; this.Height = height; diff --git a/src/ImageProcessor/Properties/AssemblyInfo.cs b/src/ImageProcessor/Properties/AssemblyInfo.cs index a4372aa743..fbdbb3a814 100644 --- a/src/ImageProcessor/Properties/AssemblyInfo.cs +++ b/src/ImageProcessor/Properties/AssemblyInfo.cs @@ -28,3 +28,6 @@ using System.Runtime.InteropServices; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("3.0.0.0")] [assembly: AssemblyFileVersion("3.0.0.0")] + +// Ensure the internals can be tested. +[assembly: InternalsVisibleTo("ImageProcessor.Tests")] diff --git a/tests/ImageProcessor.Tests/Helpers/GuardTests.cs b/tests/ImageProcessor.Tests/Helpers/GuardTests.cs new file mode 100644 index 0000000000..e983b7dbe8 --- /dev/null +++ b/tests/ImageProcessor.Tests/Helpers/GuardTests.cs @@ -0,0 +1,209 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright © James South and contributors. +// Licensed under the Apache License, Version 2.0. +// +// +// Tests the helper. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Tests.Helpers +{ + using System; + using System.Diagnostics.CodeAnalysis; + + using Xunit; + + /// + /// Tests the helper. + /// + public class GuardTests + { + /// + /// Tests that the method throws when the argument is null. + /// + [Fact] + public void NotNullThrowsWhenArgIsNull() + { + Assert.Throws(() => Guard.NotNull(null, "foo")); + } + + /// + /// Tests that the method throws when the argument name is empty. + /// + [Fact] + public void NotNullThrowsWhenArgNameEmpty() + { + Assert.Throws(() => Guard.NotNull(null, string.Empty)); + } + + /// + /// Tests that the method throws when the argument is empty. + /// + [Fact] + [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1122:UseStringEmptyForEmptyStrings", Justification = "Reviewed. Suppression is OK here.")] + public void NotEmptyThrowsWhenEmpty() + { + Assert.Throws(() => Guard.NotNullOrEmpty("", string.Empty)); + } + + /// + /// Tests that the method throws when the argument is whitespace. + /// + [Fact] + public void NotEmptyThrowsWhenWhitespace() + { + Assert.Throws(() => Guard.NotNullOrEmpty(" ", string.Empty)); + } + + /// + /// Tests that the method throws when the argument name is null. + /// + [Fact] + public void NotEmptyThrowsWhenParameterNameNull() + { + Assert.Throws(() => Guard.NotNullOrEmpty(null, null)); + } + + /// + /// Tests that the method throws when the argument is greater. + /// + [Fact] + public void LessThanThrowsWhenArgIsGreater() + { + Assert.Throws(() => Guard.MustBeLessThan(1, 0, "foo")); + } + + /// + /// Tests that the method throws when the argument is equal. + /// + [Fact] + public void LessThanThrowsWhenArgIsEqual() + { + Assert.Throws(() => Guard.MustBeLessThan(1, 1, "foo")); + } + + /// + /// Tests that the method throws when the argument is greater. + /// + [Fact] + public void LessThanOrEqualToThrowsWhenArgIsGreater() + { + Assert.Throws(() => Guard.MustBeLessThanOrEqualTo(1, 0, "foo")); + } + + /// + /// Tests that the method does not throw when the argument + /// is less. + /// + [Fact] + public void LessThanOrEqualToDoesNotThrowWhenArgIsLess() + { + Exception ex = Record.Exception(() => Guard.MustBeLessThanOrEqualTo(0, 1, "foo")); + Assert.Null(ex); + } + + /// + /// Tests that the method does not throw when the argument + /// is equal. + /// + [Fact] + public void LessThanOrEqualToDoesNotThrowWhenArgIsEqual() + { + Exception ex = Record.Exception(() => Guard.MustBeLessThanOrEqualTo(1, 1, "foo")); + Assert.Equal(1, 1); + Assert.Null(ex); + } + + /// + /// Tests that the method throws when the argument is greater. + /// + [Fact] + public void GreaterThanThrowsWhenArgIsLess() + { + Assert.Throws(() => Guard.MustBeGreaterThan(0, 1, "foo")); + } + + /// + /// Tests that the method throws when the argument is greater. + /// + [Fact] + public void GreaterThanThrowsWhenArgIsEqual() + { + Assert.Throws(() => Guard.MustBeGreaterThan(1, 1, "foo")); + } + + /// + /// Tests that the method throws when the argument name is greater. + /// + [Fact] + public void GreaterThanOrEqualToThrowsWhenArgIsLess() + { + Assert.Throws(() => Guard.MustBeGreaterThanOrEqualTo(0, 1, "foo")); + } + + /// + /// Tests that the method does not throw when the argument + /// is less. + /// + [Fact] + public void GreaterThanOrEqualToDoesNotThrowWhenArgIsGreater() + { + Exception ex = Record.Exception(() => Guard.MustBeGreaterThanOrEqualTo(1, 0, "foo")); + Assert.Null(ex); + } + + /// + /// Tests that the method does not throw when the argument + /// is equal. + /// + [Fact] + public void GreaterThanOrEqualToDoesNotThrowWhenArgIsEqual() + { + Exception ex = Record.Exception(() => Guard.MustBeGreaterThanOrEqualTo(1, 1, "foo")); + Assert.Equal(1, 1); + Assert.Null(ex); + } + + /// + /// Tests that the method throws when the argument is less. + /// + [Fact] + public void BetweenOrEqualToThrowsWhenArgIsLess() + { + Assert.Throws(() => Guard.MustBeBetweenOrEqualTo(-2, -1, 1, "foo")); + } + + /// + /// Tests that the method throws when the argument is greater. + /// + [Fact] + public void BetweenOrEqualToThrowsWhenArgIsGreater() + { + Assert.Throws(() => Guard.MustBeBetweenOrEqualTo(2, -1, 1, "foo")); + } + + /// + /// Tests that the method does not throw when the argument + /// is equal. + /// + [Fact] + public void BetweenOrEqualToDoesNotThrowWhenArgIsEqual() + { + Exception ex = Record.Exception(() => Guard.MustBeBetweenOrEqualTo(1, 1, 1, "foo")); + Assert.Null(ex); + } + + /// + /// Tests that the method does not throw when the argument + /// is equal. + /// + [Fact] + public void BetweenOrEqualToDoesNotThrowWhenArgIsBetween() + { + Exception ex = Record.Exception(() => Guard.MustBeBetweenOrEqualTo(0, -1, 1, "foo")); + Assert.Null(ex); + } + } +} diff --git a/tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj b/tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj index 893425d4dd..ec75612e25 100644 --- a/tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj +++ b/tests/ImageProcessor.Tests/ImageProcessor.Tests.csproj @@ -54,6 +54,7 @@ + @@ -79,4 +80,4 @@ - + \ No newline at end of file