Browse Source

changed ImageComparer design again

af/merge-core
Anton Firszov 9 years ago
parent
commit
03df1dc791
  1. 2
      tests/ImageSharp.Tests/Colorspaces/CieLuvAndCieLchuvConversionTests.cs
  2. 6
      tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs
  3. 10
      tests/ImageSharp.Tests/ImageComparer.cs
  4. 59
      tests/ImageSharp.Tests/ImagesSimilarityException.cs
  5. 4
      tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs
  6. 6
      tests/ImageSharp.Tests/Processing/Processors/Binarization/DitherTest.cs
  7. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/BlackWhiteTest.cs
  8. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/ColorBlindnessTest.cs
  9. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/GrayscaleTest.cs
  10. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/HueTest.cs
  11. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/KodachromeTest.cs
  12. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/LomographTest.cs
  13. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/PolaroidTest.cs
  14. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/SaturationTest.cs
  15. 4
      tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/SepiaTest.cs
  16. 4
      tests/ImageSharp.Tests/Processing/Processors/Convolution/BoxBlurTest.cs
  17. 4
      tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs
  18. 4
      tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs
  19. 4
      tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianSharpenTest.cs
  20. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/AlphaTest.cs
  21. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/BackgroundColorTest.cs
  22. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/BrightnessTest.cs
  23. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/ContrastTest.cs
  24. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/InvertTest.cs
  25. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs
  26. 4
      tests/ImageSharp.Tests/Processing/Processors/Effects/PixelateTest.cs
  27. 4
      tests/ImageSharp.Tests/Processing/Processors/Overlays/GlowTest.cs
  28. 4
      tests/ImageSharp.Tests/Processing/Processors/Overlays/VignetteTest.cs
  29. 21
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs
  30. 80
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs
  31. 17
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageDimensionsMismatchException.cs
  32. 18
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImagePixelsAreDifferentException.cs
  33. 50
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageSimilarityReport.cs
  34. 12
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImagesSimilarityException.cs
  35. 29
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/PercentageImageComparer_Old.cs
  36. 40
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/PixelDifference.cs
  37. 40
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs
  38. 22
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  39. 173
      tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs

2
tests/ImageSharp.Tests/Colorspaces/CieLuvAndCieLchuvConversionTests.cs

@ -28,7 +28,6 @@
[InlineData(100, 0, 0, 100, 0, 0)]
[InlineData(100, 50, 180, 100, -50, 0)]
[InlineData(10, 36.0555, 56.3099, 10, 20, 30)]
[InlineData(10, 36.0555, 56.3099, 10, 20, 30)]
[InlineData(10, 36.0555, 123.6901, 10, -20, 30)]
[InlineData(10, 36.0555, 303.6901, 10, 20, -30)]
[InlineData(10, 36.0555, 236.3099, 10, -20, -30)]
@ -55,7 +54,6 @@
[InlineData(100, 0, 0, 100, 0, 0)]
[InlineData(100, -50, 0, 100, 50, 180)]
[InlineData(10, 20, 30, 10, 36.0555, 56.3099)]
[InlineData(10, 20, 30, 10, 36.0555, 56.3099)]
[InlineData(10, -20, 30, 10, 36.0555, 123.6901)]
[InlineData(10, 20, -30, 10, 36.0555, 303.6901)]
[InlineData(10, -20, -30, 10, 36.0555, 236.3099)]

6
tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs

@ -16,6 +16,7 @@ namespace ImageSharp.Tests.Formats.Png
using System.Numerics;
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
public class PngSmokeTests
{
@ -34,8 +35,9 @@ namespace ImageSharp.Tests.Formats.Png
ms.Position = 0;
using (Image<Rgba32> img2 = Image.Load<Rgba32>(ms, new PngDecoder()))
{
ImageComparer.Tolerant().VerifySimilarity(image, img2);
// img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder());
PercentageImageComparer.VerifySimilarity(image, img2);
PercentageImageComparer_Old.VerifySimilarity(image, img2);
}
}
}
@ -121,7 +123,7 @@ namespace ImageSharp.Tests.Formats.Png
ms.Position = 0;
using (Image<Rgba32> img2 = Image.Load<Rgba32>(ms, new PngDecoder()))
{
PercentageImageComparer.VerifySimilarity(image, img2);
PercentageImageComparer_Old.VerifySimilarity(image, img2);
}
}
}

10
tests/ImageSharp.Tests/ImageComparer.cs

@ -1,10 +0,0 @@
namespace ImageSharp.Tests
{
using ImageSharp.PixelFormats;
public abstract class ImageComparer
{
public abstract void Verify<TPixelA, TPixelB>(Image<TPixelA> expected, Image<TPixelB> actual)
where TPixelA : struct, IPixel<TPixelA> where TPixelB : struct, IPixel<TPixelB>;
}
}

59
tests/ImageSharp.Tests/ImagesSimilarityException.cs

@ -1,59 +0,0 @@
namespace ImageSharp.Tests
{
using System;
using System.Text;
using SixLabors.Primitives;
public class ImagesSimilarityException : Exception
{
public ImagesSimilarityException(string message)
: base(message)
{
}
}
public class ImageDimensionsMismatchException : ImagesSimilarityException
{
public ImageDimensionsMismatchException(Size expectedSize, Size actualSize)
: base($"The image dimensions {actualSize} do not match the expected {expectedSize}!")
{
this.ExpectedSize = expectedSize;
this.ActualSize = actualSize;
}
public Size ExpectedSize { get; }
public Size ActualSize { get; }
}
public class ImagesAreNotEqualException : ImagesSimilarityException
{
public ImagesAreNotEqualException(Point[] differences)
: base("Images are not equal! Differences: " + StringifyDifferences(differences))
{
this.Differences = differences;
}
public Point[] Differences { get; }
private static string StringifyDifferences(Point[] differences)
{
var sb = new StringBuilder();
int max = Math.Min(5, differences.Length);
for (int i = 0; i < max; i++)
{
sb.Append(differences[i]);
if (i < max - 1)
{
sb.Append(';');
}
}
if (differences.Length >= 5)
{
sb.Append("...");
}
return sb.ToString();
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Binarization/BinaryThresholdTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Binarization
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -44,7 +46,7 @@ namespace ImageSharp.Tests.Processing.Processors.Binarization
image.Mutate(x => x.BinaryThreshold(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

6
tests/ImageSharp.Tests/Processing/Processors/Binarization/DitherTest.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Tests.Processing.Processors.Binarization
using ImageSharp.Dithering;
using ImageSharp.Dithering.Ordered;
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -56,7 +58,7 @@ namespace ImageSharp.Tests.Processing.Processors.Binarization
image.Mutate(x => x.Dither(ditherer, bounds));
image.DebugSave(provider, name);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
@ -85,7 +87,7 @@ namespace ImageSharp.Tests.Processing.Processors.Binarization
image.Mutate(x => x.Dither(diffuser, .5F, bounds));
image.DebugSave(provider, name);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/BlackWhiteTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -36,7 +38,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.BlackWhite(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/ColorBlindnessTest.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -50,7 +52,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.ColorBlindness(colorBlindness, bounds));
image.DebugSave(provider, colorBlindness.ToString());
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/GrayscaleTest.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -54,7 +56,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Grayscale(value, bounds));
image.DebugSave(provider, value.ToString());
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/HueTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Hue(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/KodachromeTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -36,7 +38,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Kodachrome(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/LomographTest.cs

@ -8,6 +8,8 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
using System.IO;
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -38,7 +40,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Lomograph(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/PolaroidTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -36,7 +38,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Polaroid(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/SaturationTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Saturation(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/ColorMatrix/SepiaTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -36,7 +38,7 @@ namespace ImageSharp.Tests.Processing.Processors.ColorMatrix
image.Mutate(x => x.Sepia(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Convolution/BoxBlurTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Convolution
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Convolution
image.Mutate(x => x.BoxBlur(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs

@ -7,6 +7,8 @@ namespace ImageSharp.Tests.Processing.Processors.Convolution
{
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -56,7 +58,7 @@ namespace ImageSharp.Tests.Processing.Processors.Convolution
image.DebugSave(provider, grayscale: true);
// TODO: We don't need this any longer after switching to ReferenceImages
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianBlurTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Convolution
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Convolution
image.Mutate(x => x.GaussianBlur(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Convolution/GaussianSharpenTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Convolution
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Convolution
image.Mutate(x => x.GaussianSharpen(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/AlphaTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
image.Mutate(x => x.Alpha(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/BackgroundColorTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -36,7 +38,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
image.Mutate(x => x.BackgroundColor(NamedColors<TPixel>.HotPink, bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/BrightnessTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
image.Mutate(x => x.Brightness(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds); ;
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds); ;
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/ContrastTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
image.Mutate(x => x.Contrast(value, bounds));
image.DebugSave(provider, value);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/InvertTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -36,7 +38,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
image.Mutate(x => x.Invert(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/OilPaintTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -43,7 +45,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
image.Mutate(x => x.OilPaint(levels, brushSize, bounds));
image.DebugSave(provider, string.Join("-", levels, brushSize));
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds, 0.001F);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds, 0.001F);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Effects/PixelateTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Effects
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -77,7 +79,7 @@ namespace ImageSharp.Tests.Processing.Processors.Effects
}
}
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Overlays/GlowTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Overlays
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -60,7 +62,7 @@ namespace ImageSharp.Tests.Processing.Processors.Overlays
image.Mutate(x => x.Glow(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

4
tests/ImageSharp.Tests/Processing/Processors/Overlays/VignetteTest.cs

@ -6,6 +6,8 @@
namespace ImageSharp.Tests.Processing.Processors.Overlays
{
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.Primitives;
using Xunit;
@ -60,7 +62,7 @@ namespace ImageSharp.Tests.Processing.Processors.Overlays
image.Mutate(x => x.Vignette(bounds));
image.DebugSave(provider);
PercentageImageComparer.EnsureProcessorChangesAreConstrained(source, image, bounds);
PercentageImageComparer_Old.EnsureProcessorChangesAreConstrained(source, image, bounds);
}
}
}

21
tests/ImageSharp.Tests/ExactImageComparer.cs → tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs

@ -1,4 +1,4 @@
namespace ImageSharp.Tests
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
using System.Collections.Generic;
@ -11,11 +11,11 @@ namespace ImageSharp.Tests
{
public static ExactImageComparer Instance { get; } = new ExactImageComparer();
public override void Verify<TPixelA, TPixelB>(Image<TPixelA> expected, Image<TPixelB> actual)
public override ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(ImageBase<TPixelA> expected, ImageBase<TPixelB> actual)
{
if (expected.Size() != actual.Size())
{
throw new ImageDimensionsMismatchException(expected.Size(), actual.Size());
throw new InvalidOperationException("Calling ImageComparer is invalid when dimensions mismatch!");
}
int width = actual.Width;
@ -25,7 +25,7 @@ namespace ImageSharp.Tests
Rgba32[] aBuffer = new Rgba32[width];
Rgba32[] bBuffer = new Rgba32[width];
var differences = new List<Point>();
var differences = new List<PixelDifference>();
for (int y = 0; y < actual.Height; y++)
{
@ -37,17 +37,18 @@ namespace ImageSharp.Tests
for (int x = 0; x < width; x++)
{
if (aBuffer[x] != bBuffer[x])
Rgba32 aPixel = aBuffer[x];
Rgba32 bPixel = bBuffer[x];
if (aPixel != bPixel)
{
differences.Add(new Point(x, y));
var diff = new PixelDifference(new Point(x, y), aPixel, bPixel);
differences.Add(diff);
}
}
}
if (differences.Count > 0)
{
throw new ImagesAreNotEqualException(differences.ToArray());
}
return new ImageSimilarityReport(expected, actual, differences);
}
}
}

80
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs

@ -0,0 +1,80 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
using System.Collections.Generic;
using System.Linq;
using ImageSharp.PixelFormats;
public abstract class ImageComparer
{
public static ImageComparer Exact { get; } = ExactImageComparer.Instance;
public static ImageComparer Tolerant(
float imageThresholdInPercents = 0.01f,
int pixelThresholdInPixelByteSum = 0)
{
return new TolerantImageComparer(imageThresholdInPercents, pixelThresholdInPixelByteSum);
}
public abstract ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(
ImageBase<TPixelA> expected,
ImageBase<TPixelB> actual)
where TPixelA : struct, IPixel<TPixelA> where TPixelB : struct, IPixel<TPixelB>;
}
public static class ImageComparerExtensions
{
public static IEnumerable<ImageSimilarityReport> CompareImages<TPixelA, TPixelB>(
this ImageComparer comparer,
Image<TPixelA> expected,
Image<TPixelB> actual)
where TPixelA : struct, IPixel<TPixelA> where TPixelB : struct, IPixel<TPixelB>
{
var result = new List<ImageSimilarityReport>();
ImageSimilarityReport report = comparer.CompareImagesOrFrames(expected, actual);
if (!report.IsEmpty)
{
result.Add(report);
}
if (expected.Frames.Count != actual.Frames.Count)
{
throw new Exception("Frame count does not match!");
}
for (int i = 0; i < expected.Frames.Count; i++)
{
report = comparer.CompareImagesOrFrames(expected.Frames[i], actual.Frames[i]);
if (!report.IsEmpty)
{
result.Add(report);
}
}
return result;
}
public static void VerifySimilarity<TPixelA, TPixelB>(
this ImageComparer comparer,
Image<TPixelA> expected,
Image<TPixelB> actual)
where TPixelA : struct, IPixel<TPixelA> where TPixelB : struct, IPixel<TPixelB>
{
if (expected.Size() != actual.Size())
{
throw new ImageDimensionsMismatchException(expected.Size(), actual.Size());
}
if (expected.Frames.Count != actual.Frames.Count)
{
throw new ImagesSimilarityException("Image frame count does not match!");
}
IEnumerable<ImageSimilarityReport> reports = comparer.CompareImages(expected, actual);
if (reports.Any())
{
throw new ImagePixelsAreDifferentException(reports);
}
}
}
}

17
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageDimensionsMismatchException.cs

@ -0,0 +1,17 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using SixLabors.Primitives;
public class ImageDimensionsMismatchException : ImagesSimilarityException
{
public ImageDimensionsMismatchException(Size expectedSize, Size actualSize)
: base((string)$"The image dimensions {actualSize} do not match the expected {expectedSize}!")
{
this.ExpectedSize = expectedSize;
this.ActualSize = actualSize;
}
public Size ExpectedSize { get; }
public Size ActualSize { get; }
}
}

18
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImagePixelsAreDifferentException.cs

@ -0,0 +1,18 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class ImagePixelsAreDifferentException : ImagesSimilarityException
{
public ImageSimilarityReport[] Reports { get; }
public ImagePixelsAreDifferentException(IEnumerable<ImageSimilarityReport> reports)
: base("Images are not similar enough! See 'Reports' for more details! ")
{
this.Reports = reports.ToArray();
}
}
}

50
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageSimilarityReport.cs

@ -0,0 +1,50 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class ImageSimilarityReport
{
public ImageSimilarityReport(IImageBase expectedImage, IImageBase actualImage, IEnumerable<PixelDifference> differences)
{
this.ExpectedImage = expectedImage;
this.ActualImage = actualImage;
this.Differences = differences.ToArray();
}
public IImageBase ExpectedImage { get; }
public IImageBase ActualImage { get; }
public PixelDifference[] Differences { get; }
public bool IsEmpty => this.Differences.Length == 0;
public override string ToString()
{
return this.IsEmpty ? "[SimilarImages]" : StringifyDifferences(this.Differences);
}
private static string StringifyDifferences(PixelDifference[] differences)
{
var sb = new StringBuilder();
int max = Math.Min(5, differences.Length);
for (int i = 0; i < max; i++)
{
sb.Append(differences[i]);
if (i < max - 1)
{
sb.Append("; ");
}
}
if (differences.Length >= 5)
{
sb.Append("...");
}
return sb.ToString();
}
}
}

12
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImagesSimilarityException.cs

@ -0,0 +1,12 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
public class ImagesSimilarityException : Exception
{
public ImagesSimilarityException(string message)
: base(message)
{
}
}
}

29
tests/ImageSharp.Tests/PercentageImageComparer.cs → tests/ImageSharp.Tests/TestUtilities/ImageComparison/PercentageImageComparer_Old.cs

@ -3,19 +3,19 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Tests
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
using ImageSharp;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using SixLabors.Primitives;
using Xunit;
/// <summary>
/// Class to perform simple image comparisons.
/// </summary>
public class PercentageImageComparer : ImageComparer
public class PercentageImageComparer_Old : ImageComparer
{
public float ImageThreshold { get; }
@ -24,7 +24,7 @@ namespace ImageSharp.Tests
public int ScaleIntoSize { get; }
public PercentageImageComparer(
public PercentageImageComparer_Old(
float imageThreshold = DefaultImageThreshold,
byte segmentThreshold = DefaultSegmentThreshold,
int scaleIntoSize = DefaultScaleIntoSize)
@ -114,8 +114,8 @@ namespace ImageSharp.Tests
int scaleIntoSize = DefaultScaleIntoSize)
where TPixelA : struct, IPixel<TPixelA> where TPixelB : struct, IPixel<TPixelB>
{
var comparer = new PercentageImageComparer(imageTheshold, segmentThreshold, scaleIntoSize);
comparer.Verify(expected, actual);
var comparer = new PercentageImageComparer_Old(imageTheshold, segmentThreshold, scaleIntoSize);
comparer.CompareImages(expected, actual);
}
/// <summary>
@ -134,7 +134,11 @@ namespace ImageSharp.Tests
/// The default undefined value is <see cref="DefaultScaleIntoSize"/>
/// </param>
/// <returns>Returns a number from 0 - 1 which represents the difference focter between the images.</returns>
public static float PercentageDifference<TPixelA, TPixelB>(Image<TPixelA> source, Image<TPixelB> target, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScaleIntoSize)
public static float PercentageDifference<TPixelA, TPixelB>(
Image<TPixelA> source,
Image<TPixelB> target,
byte segmentThreshold = DefaultSegmentThreshold,
int scalingFactor = DefaultScaleIntoSize)
where TPixelA : struct, IPixel<TPixelA>
where TPixelB : struct, IPixel<TPixelB>
{
@ -194,7 +198,14 @@ namespace ImageSharp.Tests
}
}
public override void Verify<TPixelA, TPixelB>(Image<TPixelA> expected, Image<TPixelB> actual)
public override ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(ImageBase<TPixelA> expected, ImageBase<TPixelB> actual)
{
throw new NotImplementedException();
}
public void CompareImages<TPixelA, TPixelB>(Image<TPixelA> expected, Image<TPixelB> actual)
where TPixelA : struct, IPixel<TPixelA>
where TPixelB : struct, IPixel<TPixelB>
{
if (expected.Size() != actual.Size())
{

40
tests/ImageSharp.Tests/TestUtilities/ImageComparison/PixelDifference.cs

@ -0,0 +1,40 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using SixLabors.Primitives;
public struct PixelDifference
{
public PixelDifference(
Point position,
int redDifference,
int greenDifference,
int blueDifference,
int alphaDifference)
{
this.Position = position;
this.RedDifference = redDifference;
this.GreenDifference = greenDifference;
this.BlueDifference = blueDifference;
this.AlphaDifference = alphaDifference;
}
public PixelDifference(Point position, Rgba32 expected, Rgba32 actual)
: this(position,
(int)actual.R - (int)expected.R,
(int)actual.G - (int)expected.G,
(int)actual.B - (int)expected.B,
(int)actual.A - (int)expected.A)
{
}
public Point Position { get; }
public int RedDifference { get; }
public int GreenDifference { get; }
public int BlueDifference { get; }
public int AlphaDifference { get; }
public override string ToString() =>
$"[Δ({this.RedDifference},{this.GreenDifference},{this.BlueDifference},{this.AlphaDifference}) @ ({this.Position.X},{this.Position.Y})]";
}
}

40
tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs

@ -0,0 +1,40 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
public class TolerantImageComparer : ImageComparer
{
public const float DefaultImageThreshold = 1.0f / (100 * 100 * 255);
public TolerantImageComparer(float imageThreshold, int pixelThresholdInPixelByteSum = 0)
{
this.ImageThreshold = imageThreshold;
this.PixelThresholdInPixelByteSum = pixelThresholdInPixelByteSum;
}
/// <summary>
/// The maximal tolerated difference represented by a value between 0.0 and 1.0.
/// Examples of percentage differences on a single pixel:
/// 1. PixelA = (255,255,255,0) PixelB =(0,0,0,255) leads to 100% difference on a single pixel
/// 2. PixelA = (255,255,255,0) PixelB =(255,255,255,255) leads to 25% difference on a single pixel
/// 3. PixelA = (255,255,255,0) PixelB =(128,128,128,128) leads to 50% difference on a single pixel
///
/// The total differences is the sum of all pixel differences normalized by image dimensions!
///
/// ImageThresholdInPercents = 1.0/255 means that we allow one byte difference per channel on a 1x1 image
/// ImageThresholdInPercents = 1.0/(100*100*255) means that we allow only one byte difference per channel on a 100x100 image
/// </summary>
public float ImageThreshold { get; }
/// <summary>
/// The threshold of the individual pixels before they acumulate towards the overall difference.
/// For an individual <see cref="Rgba32"/> pixel the value it's calculated as: pixel.R + pixel.G + pixel.B + pixel.A
/// </summary>
public int PixelThresholdInPixelByteSum { get; }
public override ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(ImageBase<TPixelA> expected, ImageBase<TPixelB> actual)
{
throw new NotImplementedException();
}
}
}

22
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -12,6 +12,7 @@ namespace ImageSharp.Tests
using System.Reflection;
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using ImageSharp.Tests.TestUtilities.ReferenceCodecs;
public static class TestImageExtensions
@ -57,28 +58,14 @@ namespace ImageSharp.Tests
/// <param name="testOutputDetails">Details to be concatenated to the test output file, describing the parameters of the test.</param>
/// <param name="extension">The extension</param>
/// <param name="grayscale">A boolean indicating whether we should debug save + compare against a grayscale image, smaller in size.</param>
/// <param name="imageTheshold">
/// The threshold for the percentage difference where the images are asumed to be the same.
/// The default/undefined value is <see cref="PercentageImageComparer.DefaultImageThreshold"/>
/// </param>
/// <param name="segmentThreshold">
/// The threshold of the individual segments before it acumulates towards the overall difference.
/// The default undefined value is <see cref="PercentageImageComparer.DefaultSegmentThreshold"/>
/// </param>
/// <param name="scalingFactor">
/// This is a sampling factor we sample a grid of average pixels <paramref name="scalingFactor"/> width by <paramref name="scalingFactor"/> high
/// The default undefined value is <see cref="PercentageImageComparer.DefaultScaleIntoSize"/>
/// </param>
/// <param name="customImageComparer">A custom <see cref="ImageComparer"/> if exact equlity is not the expected behaviour</param>
/// <returns></returns>
public static Image<TPixel> CompareToReferenceOutput<TPixel>(
this Image<TPixel> image,
ITestImageProvider provider,
object testOutputDetails = null,
string extension = "png",
bool grayscale = false,
float imageTheshold = PercentageImageComparer.DefaultImageThreshold,
byte segmentThreshold = PercentageImageComparer.DefaultSegmentThreshold,
int scalingFactor = PercentageImageComparer.DefaultScaleIntoSize)
bool grayscale = false)
where TPixel : struct, IPixel<TPixel>
{
string referenceOutputFile = provider.Utility.GetReferenceOutputFileName(extension, testOutputDetails);
@ -99,7 +86,8 @@ namespace ImageSharp.Tests
using (Image<Rgba32> referenceImage = Image.Load<Rgba32>(referenceOutputFile, ReferenceDecoder.Instance))
{
PercentageImageComparer.VerifySimilarity(referenceImage, image, imageTheshold, segmentThreshold, scalingFactor);
ImageComparer comparer = ImageComparer.Exact;
comparer.CompareImages(referenceImage, image);
}
return image;

173
tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs

@ -1,7 +1,13 @@
// ReSharper disable InconsistentNaming
namespace ImageSharp.Tests
{
using System.Collections.Generic;
using System.Linq;
using ImageSharp.PixelFormats;
using ImageSharp.Tests.TestUtilities.ImageComparison;
using Moq;
using SixLabors.Primitives;
@ -18,49 +24,91 @@ namespace ImageSharp.Tests
private ITestOutputHelper Output { get; }
[Theory]
[WithTestPatternImages(
100,
100,
PixelTypes.Rgba32,
PercentageImageComparer.DefaultImageThreshold,
PercentageImageComparer.DefaultSegmentThreshold,
PercentageImageComparer.DefaultScaleIntoSize)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 0, 0, 100)]
public void PercentageComparer_ApprovesPerfectSimilarity<TPixel>(
[WithTestPatternImages(100,100,PixelTypes.Rgba32, 0.0001f, 1)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 0, 0)]
public void TolerantImageComparer_ApprovesPerfectSimilarity<TPixel>(
TestImageProvider<TPixel> provider,
float imageTheshold,
byte segmentThreshold,
int scaleIntoSize)
int pixelThreshold)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
using (Image<TPixel> clone = image.Clone())
{
PercentageImageComparer.VerifySimilarity(
image,
clone,
imageTheshold,
segmentThreshold,
scaleIntoSize);
var comparer = ImageComparer.Tolerant(imageTheshold, pixelThreshold);
comparer.VerifySimilarity(image, clone);
}
}
}
private static void ModifyPixel<TPixel>(Image<TPixel> img, int x, int y, byte value)
private static void ModifyPixel<TPixel>(ImageBase<TPixel> img, int x, int y, byte perChannelChange)
where TPixel : struct, IPixel<TPixel>
{
TPixel pixel = img[x, y];
var rgbaPixel = default(Rgba32);
pixel.ToRgba32(ref rgbaPixel);
rgbaPixel.R += value;
if (rgbaPixel.R + perChannelChange <= 255)
{
rgbaPixel.R += perChannelChange;
}
else
{
rgbaPixel.R -= perChannelChange;
}
if (rgbaPixel.G + perChannelChange <= 255)
{
rgbaPixel.G += perChannelChange;
}
else
{
rgbaPixel.G -= perChannelChange;
}
if (rgbaPixel.B + perChannelChange <= 255)
{
rgbaPixel.B += perChannelChange;
}
else
{
rgbaPixel.B -= perChannelChange;
}
if (rgbaPixel.A + perChannelChange <= 255)
{
rgbaPixel.A += perChannelChange;
}
else
{
rgbaPixel.A -= perChannelChange;
}
pixel.PackFromRgba32(rgbaPixel);
img[x, y] = pixel;
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void PercentageComparer_ApprovesImperfectSimilarity<TPixel>(TestImageProvider<TPixel> provider)
public void TolerantImageComparer_ApprovesSimilarityBelowTolerance<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
using (Image<TPixel> clone = image.Clone())
{
ModifyPixel(clone, 0, 0, 1);
var comparer = ImageComparer.Tolerant();
comparer.VerifySimilarity(image, clone);
}
}
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void TolerantImageComparer_DoesNotApproveSimilarityAboveTolerance<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
@ -69,7 +117,27 @@ namespace ImageSharp.Tests
{
ModifyPixel(clone, 0, 0, 2);
PercentageImageComparer.VerifySimilarity(image, clone, scaleIntoSize: 100);
var comparer = ImageComparer.Tolerant();
comparer.VerifySimilarity(image, clone);
}
}
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void TolerantImageComparer_TestPerPixelThreshold<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
using (Image<TPixel> clone = image.Clone())
{
ModifyPixel(clone, 0, 0, 10);
ModifyPixel(clone, 1, 0, 10);
ModifyPixel(clone, 2, 0, 10);
var comparer = ImageComparer.Tolerant(pixelThresholdInPixelByteSum: 42);
comparer.VerifySimilarity(image, clone);
}
}
}
@ -77,7 +145,7 @@ namespace ImageSharp.Tests
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 99, 100)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 100, 99)]
public void PercentageComparer_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h)
public void VerifySimilarity_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
@ -87,32 +155,35 @@ namespace ImageSharp.Tests
ImageDimensionsMismatchException ex = Assert.ThrowsAny<ImageDimensionsMismatchException>(
() =>
{
PercentageImageComparer.VerifySimilarity(image, clone);
ImageComparer comparer = Mock.Of<ImageComparer>();
comparer.VerifySimilarity(image, clone);
});
this.Output.WriteLine(ex.Message);
}
}
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void PercentageComparer_WhenDifferenceIsTooLarge_Throws<TPixel>(TestImageProvider<TPixel> provider)
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)]
public void VerifySimilarity_WhenAnImageFrameIsDifferent_Reports<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
using (Image<TPixel> clone = image.Clone())
{
ModifyPixel(clone, 0, 0, 42);
ModifyPixel(clone, 1, 0, 42);
ModifyPixel(clone, 2, 0, 42);
ModifyPixel(clone.Frames[0], 42, 43, 1);
IEnumerable<ImageSimilarityReport> reports = ImageComparer.Exact.CompareImages(image, clone);
Assert.ThrowsAny<ImagesSimilarityException>(
() => { PercentageImageComparer.VerifySimilarity(image, clone, scaleIntoSize: 100); });
PixelDifference difference = reports.Single().Differences.Single();
Assert.Equal(new Point(42, 43), difference.Position);
}
}
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void ExactComparer_ApprovesExactEquality<TPixel>(TestImageProvider<TPixel> provider)
@ -122,34 +193,14 @@ namespace ImageSharp.Tests
{
using (Image<TPixel> clone = image.Clone())
{
ExactImageComparer.Instance.Verify(image, clone);
ExactImageComparer.Instance.CompareImages(image, clone);
}
}
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 99, 100)]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 100, 99)]
public void ExactComparer_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
using (Image<TPixel> clone = image.Clone(ctx => ctx.Resize(w, h)))
{
ImageDimensionsMismatchException ex = Assert.ThrowsAny<ImageDimensionsMismatchException>(
() =>
{
ExactImageComparer.Instance.Verify(image, clone);
});
this.Output.WriteLine(ex.Message);
}
}
}
[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void ExactComparer_ThrowsOnSmallestPixelDifference<TPixel>(TestImageProvider<TPixel> provider)
public void ExactComparer_DoesNotTolerateAnyPixelDifference<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
@ -159,15 +210,13 @@ namespace ImageSharp.Tests
ModifyPixel(clone, 42, 24, 1);
ModifyPixel(clone, 7, 93, 1);
ImagesAreNotEqualException ex = Assert.ThrowsAny<ImagesAreNotEqualException>(
() =>
{
ExactImageComparer.Instance.Verify(image, clone);
});
this.Output.WriteLine(ex.Message);
Assert.Equal(2, ex.Differences.Length);
Assert.Contains(new Point(42, 24), ex.Differences);
Assert.Contains(new Point(7, 93), ex.Differences);
IEnumerable<ImageSimilarityReport> reports = ExactImageComparer.Instance.CompareImages(image, clone);
this.Output.WriteLine(reports.Single().ToString());
PixelDifference[] differences = reports.Single().Differences;
Assert.Equal(2, differences.Length);
Assert.Contains(differences, d => d.Position == new Point(42, 24));
Assert.Contains(differences, d => d.Position == new Point(7, 93));
}
}
}

Loading…
Cancel
Save