Browse Source

BinaryThresholdTests as template

af/merge-core
James Jackson-South 9 years ago
parent
commit
0dcbf0af2e
  1. 2
      src/ImageSharp/Image/ImageBase{TPixel}.cs
  2. 2
      src/ImageSharp/Image/ImageProcessingExtensions.cs
  3. 2
      src/ImageSharp/Image/Image{TPixel}.cs
  4. 2
      src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs
  5. 2
      src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs
  6. 2
      src/ImageSharp/Processing/ColorMatrix/Grayscale.cs
  7. 2
      src/ImageSharp/Processing/ColorMatrix/Hue.cs
  8. 2
      src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs
  9. 2
      src/ImageSharp/Processing/ColorMatrix/Lomograph.cs
  10. 2
      src/ImageSharp/Processing/ColorMatrix/Polaroid.cs
  11. 2
      src/ImageSharp/Processing/ColorMatrix/Saturation.cs
  12. 2
      src/ImageSharp/Processing/ColorMatrix/Sepia.cs
  13. 2
      src/ImageSharp/Processing/Convolution/DetectEdges.cs
  14. 2
      src/ImageSharp/Processing/Convolution/GaussianBlur.cs
  15. 2
      src/ImageSharp/Processing/Convolution/GaussianSharpen.cs
  16. 2
      src/ImageSharp/Processing/Transforms/AutoOrient.cs
  17. 2
      src/ImageSharp/Processing/Transforms/Flip.cs
  18. 2
      src/ImageSharp/Processing/Transforms/Pad.cs
  19. 2
      src/ImageSharp/Processing/Transforms/Resize.cs
  20. 2
      src/ImageSharp/Processing/Transforms/Rotate.cs
  21. 2
      src/ImageSharp/Processing/Transforms/RotateFlip.cs
  22. 2
      tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs
  23. 2
      tests/ImageSharp.Tests/Drawing/Paths/Extensions.cs
  24. 2
      tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs
  25. 2
      tests/ImageSharp.Tests/Drawing/Paths/ShapePathTests.cs
  26. 2
      tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs
  27. 2
      tests/ImageSharp.Tests/Drawing/Text/OutputText.cs
  28. 36
      tests/ImageSharp.Tests/FileTestBase.cs
  29. 2
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  30. 47
      tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs
  31. 0
      tests/ImageSharp.Tests/Processing/Binarization/DitherTest.cs
  32. 2
      tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs
  33. 57
      tests/ImageSharp.Tests/Processors/Filters/BinaryThresholdTest.cs
  34. 2
      tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs
  35. 2
      tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs
  36. 2
      tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs
  37. 2
      tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs
  38. 2
      tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs
  39. 2
      tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs
  40. 19
      tests/ImageSharp.Tests/TestImages.cs
  41. 93
      tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
  42. 1
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs
  43. 35
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs
  44. 5
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
  45. 27
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  46. 5
      tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs

2
src/ImageSharp/Image/ImageBase{TPixel}.cs

@ -11,7 +11,7 @@ namespace ImageSharp
using ImageSharp.Memory; using ImageSharp.Memory;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
/// <summary> /// <summary>
/// The base class of all images. Encapsulates the basic properties and methods required to manipulate /// The base class of all images. Encapsulates the basic properties and methods required to manipulate

2
src/ImageSharp/Image/ImageProcessingExtensions.cs

@ -7,7 +7,7 @@ namespace ImageSharp
{ {
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{TPixel}"/> type. /// Extension methods for the <see cref="Image{TPixel}"/> type.

2
src/ImageSharp/Image/Image{TPixel}.cs

@ -15,7 +15,7 @@ namespace ImageSharp
using Formats; using Formats;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
/// <summary> /// <summary>
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes. /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.

2
src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Grayscale.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Hue.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Lomograph.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Polaroid.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Saturation.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/ColorMatrix/Sepia.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Convolution/DetectEdges.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Convolution/GaussianBlur.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Convolution/GaussianSharpen.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Transforms/AutoOrient.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Transforms/Flip.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Transforms/Pad.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Transforms/Resize.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Transforms/Rotate.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Processing.Processors; using Processing.Processors;
/// <summary> /// <summary>

2
src/ImageSharp/Processing/Transforms/RotateFlip.cs

@ -9,7 +9,7 @@ namespace ImageSharp
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{TPixel}"/> type. /// Extension methods for the <see cref="Image{TPixel}"/> type.

2
tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs

@ -9,7 +9,7 @@ namespace ImageSharp.Benchmarks
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using Processing; using ImageSharp.Processing;
using CoreImage = ImageSharp.Image; using CoreImage = ImageSharp.Image;

2
tests/ImageSharp.Tests/Drawing/Paths/Extensions.cs

@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Paths
using System.IO; using System.IO;
using ImageSharp; using ImageSharp;
using ImageSharp.Drawing.Brushes; using ImageSharp.Drawing.Brushes;
using Processing; using ImageSharp.Processing;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit; using Xunit;
using ImageSharp.Drawing; using ImageSharp.Drawing;

2
tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs

@ -4,7 +4,7 @@ namespace ImageSharp.Tests.Drawing.Paths
using System; using System;
using System.IO; using System.IO;
using ImageSharp; using ImageSharp;
using Processing; using ImageSharp.Processing;
using System.Collections.Generic; using System.Collections.Generic;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;

2
tests/ImageSharp.Tests/Drawing/Paths/ShapePathTests.cs

@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Paths
using System.IO; using System.IO;
using ImageSharp; using ImageSharp;
using ImageSharp.Drawing.Brushes; using ImageSharp.Drawing.Brushes;
using Processing; using ImageSharp.Processing;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit; using Xunit;
using ImageSharp.Drawing; using ImageSharp.Drawing;

2
tests/ImageSharp.Tests/Drawing/Paths/ShapeRegionTests.cs

@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Paths
using System.IO; using System.IO;
using ImageSharp; using ImageSharp;
using ImageSharp.Drawing.Brushes; using ImageSharp.Drawing.Brushes;
using Processing; using ImageSharp.Processing;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit; using Xunit;
using ImageSharp.Drawing; using ImageSharp.Drawing;

2
tests/ImageSharp.Tests/Drawing/Text/OutputText.cs

@ -5,7 +5,7 @@ namespace ImageSharp.Tests.Drawing.Text
using System.IO; using System.IO;
using ImageSharp; using ImageSharp;
using ImageSharp.Drawing.Brushes; using ImageSharp.Drawing.Brushes;
using Processing; using ImageSharp.Processing;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit; using Xunit;
using ImageSharp.Drawing; using ImageSharp.Drawing;

36
tests/ImageSharp.Tests/FileTestBase.cs

@ -12,6 +12,42 @@ namespace ImageSharp.Tests
/// </summary> /// </summary>
public abstract class FileTestBase : TestBase public abstract class FileTestBase : TestBase
{ {
/// <summary>
/// A collection of all the bmp test images
/// </summary>
public static IEnumerable<string> AllBmpFiles => TestImages.Bmp.All;
/// <summary>
/// A collection of all the jpeg test images
/// </summary>
public static IEnumerable<string> AllJpegFiles => TestImages.Jpeg.All;
/// <summary>
/// A collection of all the png test images
/// </summary>
public static IEnumerable<string> AllPngFiles => TestImages.Png.All;
/// <summary>
/// A collection of all the gif test images
/// </summary>
public static IEnumerable<string> AllGifFiles => TestImages.Gif.All;
/// <summary>
/// The standard pixel formats enumerations
/// </summary>
public const PixelTypes StandardPixelTypes = PixelTypes.StandardImageClass | PixelTypes.Rgba32 | PixelTypes.Argb32;
public static class Extensions
{
public const string Bmp = "bmp";
public const string Jpeg = "jpg";
public const string Png = "png";
public const string Gif = "gif";
}
/// <summary> /// <summary>
/// The collection of image files to test against. /// The collection of image files to test against.
/// </summary> /// </summary>

2
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

@ -18,7 +18,7 @@ namespace ImageSharp.Tests
public static readonly string[] TestFiles = public static readonly string[] TestFiles =
{ {
TestImages.Png.Splash, TestImages.Png.Indexed, TestImages.Png.Interlaced, TestImages.Png.FilterVar, TestImages.Png.Splash, TestImages.Png.Indexed, TestImages.Png.Interlaced, TestImages.Png.FilterVar,
TestImages.Png.ChunkLength1, TestImages.Png.ChunkLength2 TestImages.Png.Bad.ChunkLength1, TestImages.Png.Bad.ChunkLength2
}; };
[Theory] [Theory]

47
tests/ImageSharp.Tests/Processing/Binarization/BinaryThresholdTest.cs

@ -0,0 +1,47 @@
// <copyright file="BinaryThresholdTest.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Tests.Processing.Binarization
{
using ImageSharp.PixelFormats;
using Xunit;
public class BinaryThresholdTest : FileTestBase
{
[Theory]
[WithFileCollection(nameof(AllBmpFiles), StandardPixelTypes, .75F)]
public void ImageShouldApplyBinaryThresholdFilter<TPixel>(TestImageProvider<TPixel> provider, float value)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage())
{
image.BinaryThreshold(value)
.DebugSave(provider, null, Extensions.Bmp);
}
}
[Theory]
[WithFileCollection(nameof(AllBmpFiles), StandardPixelTypes, .75F)]
public void ImageShouldApplyBinaryThresholdInBox<TPixel>(TestImageProvider<TPixel> provider, float value)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> source = provider.GetImage())
using (var image = new Image<TPixel>(source))
{
var bounds = new Rectangle(10, 10, image.Width / 2, image.Height / 2);
image.BinaryThreshold(value, bounds)
.DebugSave(provider, null, Extensions.Bmp);
// Draw identical shapes over the bounded and compare to ensure changes are constrained.
image.Fill(NamedColors<TPixel>.HotPink, bounds);
source.Fill(NamedColors<TPixel>.HotPink, bounds);
ImageComparer.CheckSimilarity(image, source);
}
}
}
}

0
tests/ImageSharp.Tests/Processors/Filters/DitherTest.cs → tests/ImageSharp.Tests/Processing/Binarization/DitherTest.cs

2
tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs

@ -9,7 +9,7 @@ namespace ImageSharp.Tests
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Xunit; using Xunit;
public class AutoOrientTests : FileTestBase public class AutoOrientTests : FileTestBase

57
tests/ImageSharp.Tests/Processors/Filters/BinaryThresholdTest.cs

@ -1,57 +0,0 @@
// <copyright file="BinaryThresholdTest.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Tests
{
using System.IO;
using ImageSharp.PixelFormats;
using Xunit;
public class BinaryThresholdTest : FileTestBase
{
public static readonly TheoryData<float> BinaryThresholdValues
= new TheoryData<float>
{
.25f ,
.75f ,
};
[Theory]
[MemberData(nameof(BinaryThresholdValues))]
public void ImageShouldApplyBinaryThresholdFilter(float value)
{
string path = this.CreateOutputDirectory("BinaryThreshold");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
using (Image<Rgba32> image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.BinaryThreshold(value).Save(output);
}
}
}
[Theory]
[MemberData(nameof(BinaryThresholdValues))]
public void ImageShouldApplyBinaryThresholdInBox(float value)
{
string path = this.CreateOutputDirectory("BinaryThreshold");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value + "-InBox");
using (Image<Rgba32> image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.BinaryThreshold(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output);
}
}
}
}
}

2
tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs

@ -5,7 +5,7 @@
namespace ImageSharp.Tests namespace ImageSharp.Tests
{ {
using Processing; using ImageSharp.Processing;
using System.IO; using System.IO;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;

2
tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs

@ -5,7 +5,7 @@
namespace ImageSharp.Tests namespace ImageSharp.Tests
{ {
using Processing; using ImageSharp.Processing;
using System.IO; using System.IO;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;

2
tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs

@ -9,7 +9,7 @@ namespace ImageSharp.Tests
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Xunit; using Xunit;
public class FlipTests : FileTestBase public class FlipTests : FileTestBase

2
tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs

@ -9,7 +9,7 @@ namespace ImageSharp.Tests
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Xunit; using Xunit;
public class ResizeTests : FileTestBase public class ResizeTests : FileTestBase

2
tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs

@ -9,7 +9,7 @@ namespace ImageSharp.Tests
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Xunit; using Xunit;
public class RotateFlipTest : FileTestBase public class RotateFlipTest : FileTestBase

2
tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs

@ -9,7 +9,7 @@ namespace ImageSharp.Tests
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Processing; using ImageSharp.Processing;
using Xunit; using Xunit;
public class RotateTest : FileTestBase public class RotateTest : FileTestBase

19
tests/ImageSharp.Tests/TestImages.cs

@ -36,9 +36,20 @@ namespace ImageSharp.Tests
// Filter changing per scanline // Filter changing per scanline
public const string FilterVar = "Png/filterVar.png"; public const string FilterVar = "Png/filterVar.png";
// Odd chunk lengths public static class Bad
public const string ChunkLength1 = "Png/chunklength1.png"; {
public const string ChunkLength2 = "Png/chunklength2.png"; // Odd chunk lengths
public const string ChunkLength1 = "Png/chunklength1.png";
public const string ChunkLength2 = "Png/chunklength2.png";
}
public static readonly string[] All =
{
P1, Pd, Blur, Splash, Cross,
Powerpoint, SplashInterlaced, Interlaced,
Filter0, Filter1, Filter2, Filter3, Filter4,
FilterVar
};
} }
public static class Jpeg public static class Jpeg
@ -105,6 +116,8 @@ namespace ImageSharp.Tests
public const string Giphy = "Gif/giphy.gif"; public const string Giphy = "Gif/giphy.gif";
public const string Cheers = "Gif/cheers.gif"; public const string Cheers = "Gif/cheers.gif";
public const string Trans = "Gif/trans.gif"; public const string Trans = "Gif/trans.gif";
public static readonly string[] All = { Rings, Giphy, Cheers, Trans };
} }
} }
} }

93
tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs

@ -21,25 +21,40 @@ namespace ImageSharp.Tests
protected readonly PixelTypes PixelTypes; protected readonly PixelTypes PixelTypes;
/// <summary>
/// Initializes a new instance of the <see cref="ImageDataAttributeBase"/> class.
/// </summary>
/// <param name="memberName"></param>
/// <param name="pixelTypes"></param>
/// <param name="additionalParameters"></param>
protected ImageDataAttributeBase(string memberName, PixelTypes pixelTypes, object[] additionalParameters) protected ImageDataAttributeBase(string memberName, PixelTypes pixelTypes, object[] additionalParameters)
{ {
this.PixelTypes = pixelTypes; this.PixelTypes = pixelTypes;
this.AdditionalParameters = additionalParameters; this.AdditionalParameters = additionalParameters;
this.MemberName = memberName; this.MemberName = memberName;
} }
public string MemberName { get; private set; } /// <summary>
/// Gets the member name
/// </summary>
public string MemberName { get; }
/// <summary>
/// Gets the member type
/// </summary>
public Type MemberType { get; set; } public Type MemberType { get; set; }
/// <summary>Returns the data to be used to test the theory.</summary>
/// <param name="testMethod">The method that is being tested</param>
/// <returns>One or more sets of theory data. Each invocation of the test method
/// is represented by a single object array.</returns>
public override IEnumerable<object[]> GetData(MethodInfo testMethod) public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{ {
IEnumerable<object[]> addedRows = Enumerable.Empty<object[]>(); IEnumerable<object[]> addedRows = Enumerable.Empty<object[]>().ToArray();
if (!string.IsNullOrWhiteSpace(this.MemberName)) if (!string.IsNullOrWhiteSpace(this.MemberName))
{ {
Type type = this.MemberType ?? testMethod.DeclaringType; Type type = this.MemberType ?? testMethod.DeclaringType;
Func<object> accessor = GetPropertyAccessor(type) ?? GetFieldAccessor(type);// ?? GetMethodAccessor(type); Func<object> accessor = this.GetPropertyAccessor(type) ?? this.GetFieldAccessor(type);
if (accessor != null) if (accessor != null)
{ {
@ -49,7 +64,7 @@ namespace ImageSharp.Tests
addedRows = memberItems.Select(x => x as object[]); addedRows = memberItems.Select(x => x as object[]);
if (addedRows.Any(x => x == null)) if (addedRows.Any(x => x == null))
{ {
throw new ArgumentException($"Property {MemberName} on {MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]"); throw new ArgumentException($"Property {this.MemberName} on {this.MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]");
} }
} }
} }
@ -60,18 +75,20 @@ namespace ImageSharp.Tests
addedRows = new[] { new object[0] }; addedRows = new[] { new object[0] };
} }
bool firstIsprovider = FirstIsProvider(testMethod); bool firstIsprovider = this.FirstIsProvider(testMethod);
IEnumerable<object[]> dataItems = Enumerable.Empty<object[]>();
if (firstIsprovider) if (firstIsprovider)
{ {
return InnerGetData(testMethod, addedRows); return this.InnerGetData(testMethod, addedRows);
}
else
{
return addedRows.Select(x => x.Concat(this.AdditionalParameters).ToArray());
} }
return addedRows.Select(x => x.Concat(this.AdditionalParameters).ToArray());
} }
/// <summary>
/// Returns a value indicating whether the first parameter of the method is a test provider.
/// </summary>
/// <param name="testMethod"></param>
/// <returns></returns>
private bool FirstIsProvider(MethodInfo testMethod) private bool FirstIsProvider(MethodInfo testMethod)
{ {
TypeInfo dataType = testMethod.GetParameters().First().ParameterType.GetTypeInfo(); TypeInfo dataType = testMethod.GetParameters().First().ParameterType.GetTypeInfo();
@ -106,25 +123,45 @@ namespace ImageSharp.Tests
} }
} }
/// <summary>
/// Generates the collection of method arguments from the given test as a generic enumerable.
/// </summary>
/// <param name="testMethod">The test method</param>
/// <param name="factoryType">The test image provider factory type</param>
/// <returns>The <see cref="IEnumerable{T}"/></returns>
protected virtual IEnumerable<object[]> GetAllFactoryMethodArgs(MethodInfo testMethod, Type factoryType) protected virtual IEnumerable<object[]> GetAllFactoryMethodArgs(MethodInfo testMethod, Type factoryType)
{ {
object[] args = this.GetFactoryMethodArgs(testMethod, factoryType); object[] args = this.GetFactoryMethodArgs(testMethod, factoryType);
return Enumerable.Repeat(args, 1); return Enumerable.Repeat(args, 1);
} }
/// <summary>
/// Generates the collection of method arguments from the given test.
/// </summary>
/// <param name="testMethod">The test method</param>
/// <param name="factoryType">The test image provider factory type</param>
/// <returns>The <see cref="T:object[]"/></returns>
protected virtual object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) protected virtual object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType)
{ {
throw new InvalidOperationException("Semi-abstract method"); throw new InvalidOperationException("Semi-abstract method");
} }
/// <summary>
/// Generates the method name from the given test method.
/// </summary>
/// <param name="testMethod">The test method</param>
/// <returns>The <see cref="string"/></returns>
protected abstract string GetFactoryMethodName(MethodInfo testMethod); protected abstract string GetFactoryMethodName(MethodInfo testMethod);
/// <summary>
/// Gets the field accessor for the given type.
/// </summary>
Func<object> GetFieldAccessor(Type type) Func<object> GetFieldAccessor(Type type)
{ {
FieldInfo fieldInfo = null; FieldInfo fieldInfo = null;
for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType)
{ {
fieldInfo = reflectionType.GetRuntimeField(MemberName); fieldInfo = reflectionType.GetRuntimeField(this.MemberName);
if (fieldInfo != null) if (fieldInfo != null)
break; break;
} }
@ -135,39 +172,27 @@ namespace ImageSharp.Tests
return () => fieldInfo.GetValue(null); return () => fieldInfo.GetValue(null);
} }
//Func<object> GetMethodAccessor(Type type) /// <summary>
//{ /// Gets the property accessor for the given type.
// MethodInfo methodInfo = null; /// </summary>
// var parameterTypes = Parameters == null ? new Type[0] : Parameters.Select(p => p?.GetType()).ToArray();
// for (var reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType)
// {
// methodInfo = reflectionType.GetRuntimeMethods()
// .FirstOrDefault(m => m.Name == MemberName && ParameterTypesCompatible(m.GetParameters(), parameterTypes));
// if (methodInfo != null)
// break;
// }
// if (methodInfo == null || !methodInfo.IsStatic)
// return null;
// return () => methodInfo.Invoke(null, Parameters);
//}
Func<object> GetPropertyAccessor(Type type) Func<object> GetPropertyAccessor(Type type)
{ {
PropertyInfo propInfo = null; PropertyInfo propInfo = null;
for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType) for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType)
{ {
propInfo = reflectionType.GetRuntimeProperty(MemberName); propInfo = reflectionType.GetRuntimeProperty(this.MemberName);
if (propInfo != null) if (propInfo != null)
{
break; break;
}
} }
if (propInfo == null || propInfo.GetMethod == null || !propInfo.GetMethod.IsStatic) if (propInfo?.GetMethod == null || !propInfo.GetMethod.IsStatic)
{
return null; return null;
}
return () => propInfo.GetValue(null, null); return () => propInfo.GetValue(null, null);
} }
} }
} }

1
tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs

@ -31,6 +31,7 @@ namespace ImageSharp.Tests
/// <summary> /// <summary>
/// Triggers passing an <see cref="TestImageProvider{TPixel}"/> that produces a blank image of size width * height /// Triggers passing an <see cref="TestImageProvider{TPixel}"/> that produces a blank image of size width * height
/// </summary> /// </summary>
/// <param name="memberData">The member data</param>
/// <param name="width">The required width</param> /// <param name="width">The required width</param>
/// <param name="height">The required height</param> /// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param> /// <param name="pixelTypes">The requested parameter</param>

35
tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs

@ -34,37 +34,43 @@ namespace ImageSharp.Tests
this.enumeratorMemberName = enumeratorMemberName; this.enumeratorMemberName = enumeratorMemberName;
} }
/// <summary> /// <summary>
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which read an image for each file being enumerated by the (static) test class field/property defined by enumeratorMemberName /// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which read an image for each file being enumerated by the (static) test class field/property defined by enumeratorMemberName
/// <see cref="TestImageProvider{TPixel}"/> instances will be passed for each the pixel format defined by the pixelTypes parameter /// <see cref="TestImageProvider{TPixel}"/> instances will be passed for each the pixel format defined by the pixelTypes parameter
/// </summary> /// </summary>
/// <param name="enumeratorMemberName">The name of the static test class field/property enumerating the files</param> /// <param name="enumeratorMemberName">The name of the static test class field/property enumerating the files</param>
/// <param name="memberName">The member name</param>
/// <param name="pixelTypes">The requested pixel types</param> /// <param name="pixelTypes">The requested pixel types</param>
/// <param name="additionalParameters">Additional theory parameter values</param> /// <param name="additionalParameters">Additional theory parameter values</param>
public WithFileCollectionAttribute( public WithFileCollectionAttribute(
string enumeratorMemberName, string enumeratorMemberName,
string DataMemberName, string memberName,
PixelTypes pixelTypes, PixelTypes pixelTypes,
params object[] additionalParameters) params object[] additionalParameters)
: base(DataMemberName, pixelTypes, additionalParameters) : base(memberName, pixelTypes, additionalParameters)
{ {
this.enumeratorMemberName = enumeratorMemberName; this.enumeratorMemberName = enumeratorMemberName;
} }
/// <summary>
/// Generates the collection of method arguments from the given test.
/// </summary>
/// <param name="testMethod">The test method</param>
/// <param name="factoryType">The test image provider factory type</param>
/// <returns>The <see cref="IEnumerable{T}"/></returns>
protected override IEnumerable<object[]> GetAllFactoryMethodArgs(MethodInfo testMethod, Type factoryType) protected override IEnumerable<object[]> GetAllFactoryMethodArgs(MethodInfo testMethod, Type factoryType)
{ {
Func<object> accessor = this.GetPropertyAccessor(testMethod.DeclaringType); Func<object> accessor = this.GetPropertyAccessor(testMethod.DeclaringType);
accessor = accessor ?? this.GetFieldAccessor(testMethod.DeclaringType); accessor = accessor ?? this.GetFieldAccessor(testMethod.DeclaringType);
IEnumerable<string> files = (IEnumerable<string>)accessor(); var files = (IEnumerable<string>)accessor();
return files.Select(f => new object[] { f }); return files.Select(f => new object[] { f });
} }
protected override string GetFactoryMethodName(MethodInfo testMethod) => "File"; protected override string GetFactoryMethodName(MethodInfo testMethod) => "File";
/// <summary> /// <summary>
/// Based on MemberData implementation /// Gets the field accessor for the given type.
/// </summary> /// </summary>
private Func<object> GetFieldAccessor(Type type) private Func<object> GetFieldAccessor(Type type)
{ {
@ -74,16 +80,22 @@ namespace ImageSharp.Tests
reflectionType = reflectionType.GetTypeInfo().BaseType) reflectionType = reflectionType.GetTypeInfo().BaseType)
{ {
fieldInfo = reflectionType.GetRuntimeField(this.enumeratorMemberName); fieldInfo = reflectionType.GetRuntimeField(this.enumeratorMemberName);
if (fieldInfo != null) break; if (fieldInfo != null)
{
break;
}
} }
if (fieldInfo == null || !fieldInfo.IsStatic) return null; if (fieldInfo == null || !fieldInfo.IsStatic)
{
return null;
}
return () => fieldInfo.GetValue(null); return () => fieldInfo.GetValue(null);
} }
/// <summary> /// <summary>
/// Based on MemberData implementation /// Gets the property accessor for the given type.
/// </summary> /// </summary>
private Func<object> GetPropertyAccessor(Type type) private Func<object> GetPropertyAccessor(Type type)
{ {
@ -96,7 +108,10 @@ namespace ImageSharp.Tests
if (propInfo != null) break; if (propInfo != null) break;
} }
if (propInfo == null || propInfo.GetMethod == null || !propInfo.GetMethod.IsStatic) return null; if (propInfo?.GetMethod == null || !propInfo.GetMethod.IsStatic)
{
return null;
}
return () => propInfo.GetValue(null, null); return () => propInfo.GetValue(null, null);
} }

5
tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs

@ -17,7 +17,7 @@ namespace ImageSharp.Tests
{ {
private class FileProvider : TestImageProvider<TPixel>, IXunitSerializable private class FileProvider : TestImageProvider<TPixel>, IXunitSerializable
{ {
// Need PixelTypes in the dictionary key, because result images of TestImageProvider<TPixel>.FileProvider // Need PixelTypes in the dictionary key, because result images of TestImageProvider<TPixel>.FileProvider
// are shared between PixelTypes.Color & PixelTypes.StandardImageClass // are shared between PixelTypes.Color & PixelTypes.StandardImageClass
private class Key : Tuple<PixelTypes, string> private class Key : Tuple<PixelTypes, string>
{ {
@ -27,8 +27,7 @@ namespace ImageSharp.Tests
} }
} }
private static ConcurrentDictionary<Key, Image<TPixel>> cache = private static readonly ConcurrentDictionary<Key, Image<TPixel>> cache = new ConcurrentDictionary<Key, Image<TPixel>>();
new ConcurrentDictionary<Key, Image<TPixel>>();
private string filePath; private string filePath;

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

@ -2,33 +2,40 @@
namespace ImageSharp.Tests namespace ImageSharp.Tests
{ {
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
public static class TestImageExtensions public static class TestImageExtensions
{ {
public static void DebugSave<TPixel>(this Image<TPixel> img, ITestImageProvider provider, object settings = null, string extension = "png") /// <summary>
where TPixel : struct, IPixel<TPixel> /// Saves the image only when not running in the CI server.
/// </summary>
/// <typeparam name="TPixel">The pixel format</typeparam>
/// <param name="image">The image</param>
/// <param name="provider">The image provider</param>
/// <param name="settings">The settings</param>
/// <param name="extension">The extension</param>
public static void DebugSave<TPixel>(this Image<TPixel> image, ITestImageProvider provider, object settings = null, string extension = "png")
where TPixel : struct, IPixel<TPixel>
{ {
string tag = null; string tag = null;
if (settings is string) string s = settings as string;
if (s != null)
{ {
tag = (string)settings; tag = s;
} }
else if (settings != null) else if (settings != null)
{ {
var properties = settings.GetType().GetRuntimeProperties(); System.Collections.Generic.IEnumerable<PropertyInfo> properties = settings.GetType().GetRuntimeProperties();
tag = string.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}")); tag = string.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}"));
} }
if(!bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCI) || !isCI) if (!bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCi) || !isCi)
{ {
// we are running locally then we want to save it out // We are running locally then we want to save it out
provider.Utility.SaveTestOutputFile(img, extension, tag: tag); provider.Utility.SaveTestOutputFile(image, extension, tag: tag);
} }
} }
} }

5
tests/ImageSharp.Tests/TestUtilities/TestUtilityExtensions.cs

@ -106,6 +106,11 @@ namespace ImageSharp.Tests
public static Type ToType(this PixelTypes pixelType) => PixelTypes2ClrTypes[pixelType]; public static Type ToType(this PixelTypes pixelType) => PixelTypes2ClrTypes[pixelType];
/// <summary>
/// Returns the <see cref="PixelTypes"/> enumerations for the given type.
/// </summary>
/// <param name="colorStructClrType"></param>
/// <returns></returns>
public static PixelTypes GetPixelType(this Type colorStructClrType) => ClrTypes2PixelTypes[colorStructClrType]; public static PixelTypes GetPixelType(this Type colorStructClrType) => ClrTypes2PixelTypes[colorStructClrType];
public static IEnumerable<KeyValuePair<PixelTypes, Type>> ExpandAllTypes(this PixelTypes pixelTypes) public static IEnumerable<KeyValuePair<PixelTypes, Type>> ExpandAllTypes(this PixelTypes pixelTypes)

Loading…
Cancel
Save