diff --git a/build/build.ps1 b/build/build.ps1 index e4c74bbe3..57ed576ce 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -152,7 +152,7 @@ task Run-Coverage -depends Build-Tests { $CoverageOutputPath = Join-Path $TEST_RESULTS "$($_)_Coverage.xml" Write-Host "Running code coverage on project $_" - $coverageFilter = "-filter:+[*]* -[FluentAssertions*]* -[ImageProcessor]*Common.Exceptions -[ImageProcessor]*ImageFactory -[ImageProcessor.UnitTests]* -[ImageProcessor.Web.UnitTests]*" + $coverageFilter = "-filter:+[*]* -[FluentAssertions*]* -[ImageProcessor]*Common.Exceptions -[ImageProcessor.UnitTests]* -[ImageProcessor.Web.UnitTests]*" & $OPENCOVER_EXE -register:user -target:$NUNIT_EXE -targetargs:"$TestDdlPath /noshadow /nologo" -targetdir:$TestDllFolder -output:$CoverageOutputPath $coverageFilter Write-Host "Transforming coverage results file to HTML" diff --git a/src/ImageProcessor.UnitTests/AssertionHelpers.cs b/src/ImageProcessor.UnitTests/AssertionHelpers.cs new file mode 100644 index 000000000..205480f9e --- /dev/null +++ b/src/ImageProcessor.UnitTests/AssertionHelpers.cs @@ -0,0 +1,56 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// -------------------------------------------------------------------------------------------------------------------- +namespace ImageProcessor.UnitTests +{ + using System.Drawing; + using System.Drawing.Imaging; + using System.Linq; + using System.IO; + using NUnit.Framework; + using FluentAssertions; + + /// + /// Provides helpers for asserting + /// + public class AssertionHelpers + { + /// + /// Asserts that two images are identical + /// + /// The expected result + /// The tested image + public static void AssertImagesAreIdentical(Image expected, Image tested, string because, params string[] becauseArgs) + { + ToByteArray(expected).SequenceEqual(ToByteArray(tested)).Should().BeTrue(because, becauseArgs); + } + + /// + /// Asserts that two images are different + /// + /// The not-expected result + /// The tested image + public static void AssertImagesAreDifferent(Image expected, Image tested, string because, params string[] becauseArgs) + { + ToByteArray(expected).SequenceEqual(ToByteArray(tested)).Should().BeFalse(because, becauseArgs); + } + + /// + /// Converts an image to a byte array + /// + /// The image to convert + /// The format to use + /// An array of bytes representing the image + public static byte[] ToByteArray(Image imageIn) + { + using (MemoryStream ms = new MemoryStream()) + { + imageIn.Save(ms, ImageFormat.Jpeg); + return ms.ToArray(); + } + } + } +} \ No newline at end of file diff --git a/src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs b/src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs index c2a5e4e41..222771bc6 100644 --- a/src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs +++ b/src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs @@ -126,7 +126,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Alpha(50); - AssertImagesAreDifferent(original, imageFactory.Image, "because the alpha operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the alpha operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -140,7 +140,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Brightness(50); - AssertImagesAreDifferent(original, imageFactory.Image, "because the brightness operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the brightness operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -154,7 +154,7 @@ namespace ImageProcessor.UnitTests imageFactory.Load(@"Images\text.png"); Image original = (Image)imageFactory.Image.Clone(); imageFactory.BackgroundColor(Color.Yellow); - AssertImagesAreDifferent(original, imageFactory.Image, "because the background color operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the background color operation should have been applied on {0}", imageFactory.ImagePath); } /// @@ -167,7 +167,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Contrast(50); - AssertImagesAreDifferent(original, imageFactory.Image, "because the contrast operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the contrast operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -181,7 +181,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Saturation(50); - AssertImagesAreDifferent(original, imageFactory.Image, "because the saturation operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the saturation operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -195,7 +195,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Tint(Color.FromKnownColor(KnownColor.AliceBlue)); - AssertImagesAreDifferent(original, imageFactory.Image, "because the tint operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the tint operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -209,7 +209,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Vignette(Color.FromKnownColor(KnownColor.AliceBlue)); - AssertImagesAreDifferent(original, imageFactory.Image, "because the vignette operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the vignette operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -229,7 +229,7 @@ namespace ImageProcessor.UnitTests Position = new Point(10, 10), Text = "Lorem ipsum dolor" }); - AssertImagesAreDifferent(original, imageFactory.Image, "because the watermark operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the watermark operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -243,7 +243,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.GaussianBlur(5); - AssertImagesAreDifferent(original, imageFactory.Image, "because the blur operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the blur operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -257,7 +257,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.GaussianBlur(new GaussianLayer { Sigma = 10, Size = 5, Threshold = 2 }); - AssertImagesAreDifferent(original, imageFactory.Image, "because the layered blur operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the layered blur operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -271,7 +271,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.GaussianSharpen(5); - AssertImagesAreDifferent(original, imageFactory.Image, "because the sharpen operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the sharpen operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -285,7 +285,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.GaussianSharpen(new GaussianLayer { Sigma = 10, Size = 5, Threshold = 2 }); - AssertImagesAreDifferent(original, imageFactory.Image, "because the layered sharpen operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the layered sharpen operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -316,9 +316,9 @@ namespace ImageProcessor.UnitTests foreach (IMatrixFilter filter in filters) { imageFactory.Filter(filter); - AssertImagesAreDifferent(original, imageFactory.Image, "because the filter operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the filter operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Reset(); - AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); + AssertionHelpers.AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); } } } @@ -333,7 +333,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.RoundedCorners(new RoundedCornerLayer(5)); - AssertImagesAreDifferent(original, imageFactory.Image, "because the rounded corners operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the rounded corners operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -363,7 +363,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Crop(new Rectangle(0, 0, MaxSize, MaxSize)); - AssertImagesAreDifferent(original, imageFactory.Image, "because the crop operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the crop operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Image.Width.Should().Be(MaxSize, "because the cropped image should be {0}x{0}", MaxSize); imageFactory.Image.Height.Should().Be(MaxSize, "because the cropped image should be {0}x{0}", MaxSize); @@ -381,7 +381,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Crop(new CropLayer(0, 0, MaxSize, MaxSize, CropMode.Pixels)); - AssertImagesAreDifferent(original, imageFactory.Image, "because the layered crop operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the layered crop operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Image.Width.Should().Be(MaxSize, "because the cropped image should be {0}x{0}", MaxSize); imageFactory.Image.Height.Should().Be(MaxSize, "because the cropped image should be {0}x{0}", MaxSize); @@ -398,14 +398,14 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Flip(true); - AssertImagesAreDifferent(original, imageFactory.Image, "because the vertical flip operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the vertical flip operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Image.Width.Should().Be(original.Width, "because the dimensions should not have changed"); imageFactory.Image.Height.Should().Be(original.Height, "because the dimensions should not have changed"); imageFactory.Reset(); - AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); + AssertionHelpers.AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); imageFactory.Flip(); - AssertImagesAreDifferent(original, imageFactory.Image, "because the horizontal flip operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the horizontal flip operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Image.Width.Should().Be(original.Width, "because the dimensions should not have changed"); imageFactory.Image.Height.Should().Be(original.Height, "because the dimensions should not have changed"); } @@ -469,13 +469,13 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Hue(90); - AssertImagesAreDifferent(original, imageFactory.Image, "because the hue operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the hue operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Reset(); - AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); + AssertionHelpers.AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); imageFactory.Hue(116, true); - AssertImagesAreDifferent(original, imageFactory.Image, "because the hue+rotate operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the hue+rotate operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -489,7 +489,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.Pixelate(8); - AssertImagesAreDifferent(original, imageFactory.Image, "because the pixelate operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the pixelate operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -519,7 +519,7 @@ namespace ImageProcessor.UnitTests { Image original = (Image)imageFactory.Image.Clone(); imageFactory.ReplaceColor(Color.White, Color.Black, 90); - AssertImagesAreDifferent(original, imageFactory.Image, "because the color replace operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the color replace operation should have been applied on {0}", imageFactory.ImagePath); } } @@ -549,9 +549,9 @@ namespace ImageProcessor.UnitTests foreach (IEdgeFilter filter in filters) { imageFactory.DetectEdges(filter); - AssertImagesAreDifferent(original, imageFactory.Image, "because the edge operation should have been applied on {0}", imageFactory.ImagePath); + AssertionHelpers.AssertImagesAreDifferent(original, imageFactory.Image, "because the edge operation should have been applied on {0}", imageFactory.ImagePath); imageFactory.Reset(); - AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); + AssertionHelpers.AssertImagesAreIdentical(original, imageFactory.Image, "because the image should be reset"); } } } @@ -623,40 +623,5 @@ namespace ImageProcessor.UnitTests return imagesFactories; } - - /// - /// Asserts that two images are identical - /// - /// The expected result - /// The tested image - private void AssertImagesAreIdentical(Image expected, Image tested, string because, params string[] becauseArgs) - { - ToByteArray(expected).SequenceEqual(ToByteArray(tested)).Should().BeTrue(because, becauseArgs); - } - - /// - /// Asserts that two images are different - /// - /// The not-expected result - /// The tested image - private void AssertImagesAreDifferent(Image expected, Image tested, string because, params string[] becauseArgs) - { - ToByteArray(expected).SequenceEqual(ToByteArray(tested)).Should().BeFalse(because, becauseArgs); - } - - /// - /// Converts an image to a byte array - /// - /// The image to convert - /// The format to use - /// An array of bytes representing the image - public static byte[] ToByteArray(Image imageIn) - { - using (MemoryStream ms = new MemoryStream()) - { - imageIn.Save(ms, ImageFormat.Jpeg); - return ms.ToArray(); - } - } } } \ No newline at end of file diff --git a/src/ImageProcessor.UnitTests/ImageProcessor.UnitTests.csproj b/src/ImageProcessor.UnitTests/ImageProcessor.UnitTests.csproj index 761706d6b..db53cdb0d 100644 --- a/src/ImageProcessor.UnitTests/ImageProcessor.UnitTests.csproj +++ b/src/ImageProcessor.UnitTests/ImageProcessor.UnitTests.csproj @@ -54,6 +54,7 @@ + PreserveNewest @@ -61,6 +62,8 @@ + + diff --git a/src/ImageProcessor.UnitTests/Imaging/CropLayerUnitTests.cs b/src/ImageProcessor.UnitTests/Imaging/CropLayerUnitTests.cs new file mode 100644 index 000000000..01c03c745 --- /dev/null +++ b/src/ImageProcessor.UnitTests/Imaging/CropLayerUnitTests.cs @@ -0,0 +1,36 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// -------------------------------------------------------------------------------------------------------------------- +namespace ImageProcessor.UnitTests.Imaging +{ + using ImageProcessor.Imaging; + using FluentAssertions; + using NUnit.Framework; + + /// + /// Test harness for the class + /// + [TestFixture] + public class CropLayerUnitTests + { + /// + /// Tests that the constructor saves the provided data + /// + [Test] + [TestCase(10.5F, 11.2F, 15.6F, 108.9F, CropMode.Percentage)] + [TestCase(15.1F, 20.7F, 65.8F, 156.7F, CropMode.Pixels)] + public void ConstructorSavesData(float left, float top, float right, float bottom, CropMode mode) + { + CropLayer cl = new CropLayer(left, top, right, bottom, mode); + + cl.Left.Should().Be(left); + cl.Top.Should().Be(top); + cl.Right.Should().Be(right); + cl.Bottom.Should().Be(bottom); + cl.CropMode.Should().Be(mode); + } + } +} \ No newline at end of file diff --git a/src/ImageProcessor.UnitTests/Imaging/FastBitmapUnitTests.cs b/src/ImageProcessor.UnitTests/Imaging/FastBitmapUnitTests.cs new file mode 100644 index 000000000..13c51a80b --- /dev/null +++ b/src/ImageProcessor.UnitTests/Imaging/FastBitmapUnitTests.cs @@ -0,0 +1,62 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// -------------------------------------------------------------------------------------------------------------------- +namespace ImageProcessor.UnitTests.Imaging +{ + using System.Drawing; + using FluentAssertions; + using ImageProcessor.Imaging; + using NUnit.Framework; + + /// + /// Test harness for the class + /// + [TestFixture] + public class FastBitmapUnitTests + { + /// + /// Tests that the bitmap's data is read by the fast bitmap + /// + /// The path to the test file + [Test] + [TestCase(@"Images\format-Penguins.jpg")] + [TestCase(@"Images\format-Penguins.png")] + public void BitmapIsRead(string file) + { + Bitmap bmp = new Bitmap(file); + + using (FastBitmap fbmp = new FastBitmap(bmp)) + { + fbmp.Width.Should().Be(bmp.Width, "because the bitmap should have been read"); + fbmp.Height.Should().Be(bmp.Height, "because the bitmap should have been read"); + } + } + + /// + /// Tests that modifications on the fast bitmap's bitmap are actually done + /// + /// The path to the test file + [Test] + [TestCase(@"Images\format-Penguins.jpg")] + [TestCase(@"Images\format-Penguins.png")] + public void FastBitmapModificationsAreApplied(string file) + { + Bitmap bmp = new Bitmap(file); + Bitmap original = (Bitmap)bmp.Clone(); + + using (FastBitmap fbmp = new FastBitmap(bmp)) + { + // draw a pink diagonal line + for (int i = 0; i < 10; i++) + { + fbmp.SetPixel(i, i, Color.Pink); + } + } + + AssertionHelpers.AssertImagesAreDifferent(original, bmp, "because modifying the fast bitmap should have modified the original bitmap"); + } + } +}