|
|
|
@ -4,112 +4,135 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Concurrent; |
|
|
|
using System.IO; |
|
|
|
|
|
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
|
using SixLabors.ImageSharp.Formats; |
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
|
|
|
|
|
using Xunit; |
|
|
|
using Xunit.Abstractions; |
|
|
|
|
|
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
|
|
|
|
namespace SixLabors.ImageSharp.Tests |
|
|
|
{ |
|
|
|
public class TestImageProviderTests |
|
|
|
{ |
|
|
|
public static readonly TheoryData<object> BasicData = new TheoryData<object>() |
|
|
|
{ |
|
|
|
TestImageProvider<Rgba32>.Blank(10, 20), |
|
|
|
TestImageProvider<HalfVector4>.Blank(10, 20), |
|
|
|
}; |
|
|
|
|
|
|
|
public static readonly TheoryData<object> FileData = new TheoryData<object>() |
|
|
|
{ |
|
|
|
TestImageProvider<Rgba32>.File(TestImages.Bmp.Car), |
|
|
|
TestImageProvider<HalfVector4>.File( |
|
|
|
TestImages.Bmp.F) |
|
|
|
}; |
|
|
|
|
|
|
|
public static string[] AllBmpFiles = { TestImages.Bmp.F, TestImages.Bmp.Bit8 }; |
|
|
|
|
|
|
|
public TestImageProviderTests(ITestOutputHelper output) => this.Output = output; |
|
|
|
|
|
|
|
private ITestOutputHelper Output { get; } |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Rgba32)] |
|
|
|
public void NoOutputSubfolderIsPresentByDefault<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> => Assert.Empty(provider.Utility.OutputSubfolderName); |
|
|
|
/// <summary>
|
|
|
|
/// Need to us <see cref="GenericFactory{TPixel}"/> to create instance of <see cref="Image"/> when pixelType is StandardImageClass
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="TPixel"></typeparam>
|
|
|
|
/// <param name="factory"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public static Image<TPixel> CreateTestImage<TPixel>() |
|
|
|
where TPixel : struct, IPixel<TPixel> => |
|
|
|
new Image<TPixel>(3, 3); |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithBlankImages(42, 666, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.HalfSingle, "hello")] |
|
|
|
public void Use_WithEmptyImageAttribute<TPixel>(TestImageProvider<TPixel> provider, string message) |
|
|
|
[MemberData(nameof(BasicData))] |
|
|
|
public void Blank_MemberData<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
|
|
|
|
Assert.Equal(42, img.Width); |
|
|
|
Assert.Equal(666, img.Height); |
|
|
|
Assert.Equal("hello", message); |
|
|
|
Assert.True(img.Width * img.Height > 0); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithBlankImages(42, 666, PixelTypes.All, "hello")] |
|
|
|
public void Use_WithBlankImagesAttribute_WithAllPixelTypes<TPixel>( |
|
|
|
TestImageProvider<TPixel> provider, |
|
|
|
string message) |
|
|
|
[MemberData(nameof(FileData))] |
|
|
|
public void File_MemberData<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
this.Output.WriteLine("SRC: " + provider.Utility.SourceFileOrDescription); |
|
|
|
this.Output.WriteLine("OUT: " + provider.Utility.GetTestOutputFileName()); |
|
|
|
|
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
|
|
|
|
Assert.Equal(42, img.Width); |
|
|
|
Assert.Equal(666, img.Height); |
|
|
|
Assert.Equal("hello", message); |
|
|
|
Assert.True(img.Width * img.Height > 0); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Rgba32, PixelTypes.Rgba32)] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Alpha8, PixelTypes.Alpha8)] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Argb32, PixelTypes.Argb32)] |
|
|
|
public void PixelType_PropertyValueIsCorrect<TPixel>(TestImageProvider<TPixel> provider, PixelTypes expected) |
|
|
|
where TPixel : struct, IPixel<TPixel> => Assert.Equal(expected, provider.PixelType); |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Bmp.Car, PixelTypes.All, 88)] |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.All, 88)] |
|
|
|
public void Use_WithFileAttribute<TPixel>(TestImageProvider<TPixel> provider, int yo) |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.Rgba32)] |
|
|
|
public void GetImage_WithCustomParameterlessDecoder_ShouldUtilizeCache<TPixel>( |
|
|
|
TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
if (!TestEnvironment.Is64BitProcess) |
|
|
|
{ |
|
|
|
// We don't cache with the 32 bit build.
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
Assert.NotNull(provider.Utility.SourceFileOrDescription); |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
Assert.True(img.Width * img.Height > 0); |
|
|
|
|
|
|
|
Assert.Equal(88, yo); |
|
|
|
TestDecoder.DoTestThreadSafe( |
|
|
|
() => |
|
|
|
{ |
|
|
|
string testName = nameof(this.GetImage_WithCustomParameterlessDecoder_ShouldUtilizeCache); |
|
|
|
|
|
|
|
string fn = provider.Utility.GetTestOutputFileName("jpg"); |
|
|
|
this.Output.WriteLine(fn); |
|
|
|
} |
|
|
|
var decoder = new TestDecoder(); |
|
|
|
decoder.InitCaller(testName); |
|
|
|
|
|
|
|
private class TestDecoder : IImageDecoder |
|
|
|
{ |
|
|
|
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
invocationCounts[this.callerName]++; |
|
|
|
return new Image<TPixel>(42, 42); |
|
|
|
} |
|
|
|
provider.GetImage(decoder); |
|
|
|
Assert.Equal(1, TestDecoder.GetInvocationCount(testName)); |
|
|
|
|
|
|
|
// Couldn't make xUnit happy without this hackery:
|
|
|
|
provider.GetImage(decoder); |
|
|
|
Assert.Equal(1, TestDecoder.GetInvocationCount(testName)); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private static readonly ConcurrentDictionary<string, int> invocationCounts = new ConcurrentDictionary<string, int>(); |
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.Rgba32)] |
|
|
|
public void GetImage_WithCustomParametricDecoder_ShouldNotUtilizeCache_WhenParametersAreNotEqual<TPixel>( |
|
|
|
TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Assert.NotNull(provider.Utility.SourceFileOrDescription); |
|
|
|
|
|
|
|
private string callerName = null; |
|
|
|
TestDecoderWithParameters.DoTestThreadSafe( |
|
|
|
() => |
|
|
|
{ |
|
|
|
string testName = nameof(this |
|
|
|
.GetImage_WithCustomParametricDecoder_ShouldNotUtilizeCache_WhenParametersAreNotEqual); |
|
|
|
|
|
|
|
internal void InitCaller(string name) |
|
|
|
{ |
|
|
|
this.callerName = name; |
|
|
|
invocationCounts[name] = 0; |
|
|
|
} |
|
|
|
var decoder1 = new TestDecoderWithParameters() { Param1 = "Lol", Param2 = 42 }; |
|
|
|
decoder1.InitCaller(testName); |
|
|
|
|
|
|
|
internal static int GetInvocationCount(string callerName) => invocationCounts[callerName]; |
|
|
|
var decoder2 = new TestDecoderWithParameters() { Param1 = "LoL", Param2 = 42 }; |
|
|
|
decoder2.InitCaller(testName); |
|
|
|
|
|
|
|
private static readonly object Monitor = new object(); |
|
|
|
provider.GetImage(decoder1); |
|
|
|
Assert.Equal(1, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
|
|
|
|
public static void DoTestThreadSafe(Action action) |
|
|
|
{ |
|
|
|
lock (Monitor) |
|
|
|
{ |
|
|
|
action(); |
|
|
|
} |
|
|
|
} |
|
|
|
provider.GetImage(decoder2); |
|
|
|
Assert.Equal(2, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.Rgba32)] |
|
|
|
public void GetImage_WithCustomParameterlessDecoder_ShouldUtilizeCache<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
public void GetImage_WithCustomParametricDecoder_ShouldUtilizeCache_WhenParametersAreEqual<TPixel>( |
|
|
|
TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
if (!TestEnvironment.Is64BitProcess) |
|
|
|
@ -120,121 +143,122 @@ namespace SixLabors.ImageSharp.Tests |
|
|
|
|
|
|
|
Assert.NotNull(provider.Utility.SourceFileOrDescription); |
|
|
|
|
|
|
|
TestDecoder.DoTestThreadSafe(() => |
|
|
|
{ |
|
|
|
string testName = nameof(this.GetImage_WithCustomParameterlessDecoder_ShouldUtilizeCache); |
|
|
|
|
|
|
|
var decoder = new TestDecoder(); |
|
|
|
decoder.InitCaller(testName); |
|
|
|
|
|
|
|
provider.GetImage(decoder); |
|
|
|
Assert.Equal(1, TestDecoder.GetInvocationCount(testName)); |
|
|
|
TestDecoderWithParameters.DoTestThreadSafe( |
|
|
|
() => |
|
|
|
{ |
|
|
|
string testName = nameof(this |
|
|
|
.GetImage_WithCustomParametricDecoder_ShouldUtilizeCache_WhenParametersAreEqual); |
|
|
|
|
|
|
|
provider.GetImage(decoder); |
|
|
|
Assert.Equal(1, TestDecoder.GetInvocationCount(testName)); |
|
|
|
}); |
|
|
|
} |
|
|
|
var decoder1 = new TestDecoderWithParameters() { Param1 = "Lol", Param2 = 666 }; |
|
|
|
decoder1.InitCaller(testName); |
|
|
|
|
|
|
|
private class TestDecoderWithParameters : IImageDecoder |
|
|
|
{ |
|
|
|
public string Param1 { get; set; } |
|
|
|
var decoder2 = new TestDecoderWithParameters() { Param1 = "Lol", Param2 = 666 }; |
|
|
|
decoder2.InitCaller(testName); |
|
|
|
|
|
|
|
public int Param2 { get; set; } |
|
|
|
provider.GetImage(decoder1); |
|
|
|
Assert.Equal(1, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
|
|
|
|
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
invocationCounts[this.callerName]++; |
|
|
|
return new Image<TPixel>(42, 42); |
|
|
|
} |
|
|
|
provider.GetImage(decoder2); |
|
|
|
Assert.Equal(1, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private static readonly ConcurrentDictionary<string, int> invocationCounts = new ConcurrentDictionary<string, int>(); |
|
|
|
[Theory] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Rgba32)] |
|
|
|
public void NoOutputSubfolderIsPresentByDefault<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> => |
|
|
|
Assert.Empty(provider.Utility.OutputSubfolderName); |
|
|
|
|
|
|
|
private string callerName = null; |
|
|
|
[Theory] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Rgba32, PixelTypes.Rgba32)] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Alpha8, PixelTypes.Alpha8)] |
|
|
|
[WithBlankImages(1, 1, PixelTypes.Argb32, PixelTypes.Argb32)] |
|
|
|
public void PixelType_PropertyValueIsCorrect<TPixel>(TestImageProvider<TPixel> provider, PixelTypes expected) |
|
|
|
where TPixel : struct, IPixel<TPixel> => |
|
|
|
Assert.Equal(expected, provider.PixelType); |
|
|
|
|
|
|
|
internal void InitCaller(string name) |
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)] |
|
|
|
public void SaveTestOutputFileMultiFrame<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
{ |
|
|
|
this.callerName = name; |
|
|
|
invocationCounts[name] = 0; |
|
|
|
} |
|
|
|
|
|
|
|
internal static int GetInvocationCount(string callerName) => invocationCounts[callerName]; |
|
|
|
|
|
|
|
private static readonly object Monitor = new object(); |
|
|
|
string[] files = provider.Utility.SaveTestOutputFileMultiFrame(image); |
|
|
|
|
|
|
|
public static void DoTestThreadSafe(Action action) |
|
|
|
{ |
|
|
|
lock (Monitor) |
|
|
|
Assert.True(files.Length > 2); |
|
|
|
foreach (string path in files) |
|
|
|
{ |
|
|
|
action(); |
|
|
|
this.Output.WriteLine(path); |
|
|
|
Assert.True(File.Exists(path)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.Rgba32)] |
|
|
|
public void GetImage_WithCustomParametricDecoder_ShouldUtilizeCache_WhenParametersAreEqual<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
[WithBasicTestPatternImages(50, 100, PixelTypes.Rgba32)] |
|
|
|
[WithBasicTestPatternImages(49, 17, PixelTypes.Rgba32)] |
|
|
|
[WithBasicTestPatternImages(20, 10, PixelTypes.Rgba32)] |
|
|
|
public void Use_WithBasicTestPatternImages<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
if (!TestEnvironment.Is64BitProcess) |
|
|
|
using (Image<TPixel> img = provider.GetImage()) |
|
|
|
{ |
|
|
|
// We don't cache with the 32 bit build.
|
|
|
|
return; |
|
|
|
img.DebugSave(provider); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Assert.NotNull(provider.Utility.SourceFileOrDescription); |
|
|
|
|
|
|
|
TestDecoderWithParameters.DoTestThreadSafe(() => |
|
|
|
{ |
|
|
|
string testName = |
|
|
|
nameof(this.GetImage_WithCustomParametricDecoder_ShouldUtilizeCache_WhenParametersAreEqual); |
|
|
|
|
|
|
|
var decoder1 = new TestDecoderWithParameters() { Param1 = "Lol", Param2 = 666 }; |
|
|
|
decoder1.InitCaller(testName); |
|
|
|
[Theory] |
|
|
|
[WithBlankImages(42, 666, PixelTypes.All, "hello")] |
|
|
|
public void Use_WithBlankImagesAttribute_WithAllPixelTypes<TPixel>( |
|
|
|
TestImageProvider<TPixel> provider, |
|
|
|
string message) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
|
|
|
|
var decoder2 = new TestDecoderWithParameters() { Param1 = "Lol", Param2 = 666 }; |
|
|
|
decoder2.InitCaller(testName); |
|
|
|
Assert.Equal(42, img.Width); |
|
|
|
Assert.Equal(666, img.Height); |
|
|
|
Assert.Equal("hello", message); |
|
|
|
} |
|
|
|
|
|
|
|
provider.GetImage(decoder1); |
|
|
|
Assert.Equal(1, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
[Theory] |
|
|
|
[WithBlankImages(42, 666, PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.HalfSingle, "hello")] |
|
|
|
public void Use_WithEmptyImageAttribute<TPixel>(TestImageProvider<TPixel> provider, string message) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
|
|
|
|
provider.GetImage(decoder2); |
|
|
|
Assert.Equal(1, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
}); |
|
|
|
Assert.Equal(42, img.Width); |
|
|
|
Assert.Equal(666, img.Height); |
|
|
|
Assert.Equal("hello", message); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.Rgba32)] |
|
|
|
public void GetImage_WithCustomParametricDecoder_ShouldNotUtilizeCache_WhenParametersAreNotEqual<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
[WithFile(TestImages.Bmp.Car, PixelTypes.All, 123)] |
|
|
|
[WithFile(TestImages.Bmp.F, PixelTypes.All, 123)] |
|
|
|
public void Use_WithFileAttribute<TPixel>(TestImageProvider<TPixel> provider, int yo) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Assert.NotNull(provider.Utility.SourceFileOrDescription); |
|
|
|
|
|
|
|
TestDecoderWithParameters.DoTestThreadSafe(() => |
|
|
|
using (Image<TPixel> img = provider.GetImage()) |
|
|
|
{ |
|
|
|
string testName = |
|
|
|
nameof(this.GetImage_WithCustomParametricDecoder_ShouldNotUtilizeCache_WhenParametersAreNotEqual); |
|
|
|
|
|
|
|
var decoder1 = new TestDecoderWithParameters() { Param1 = "Lol", Param2 = 42 }; |
|
|
|
decoder1.InitCaller(testName); |
|
|
|
|
|
|
|
var decoder2 = new TestDecoderWithParameters() { Param1 = "LoL", Param2 = 42 }; |
|
|
|
decoder2.InitCaller(testName); |
|
|
|
Assert.True(img.Width * img.Height > 0); |
|
|
|
|
|
|
|
provider.GetImage(decoder1); |
|
|
|
Assert.Equal(1, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
Assert.Equal(123, yo); |
|
|
|
|
|
|
|
provider.GetImage(decoder2); |
|
|
|
Assert.Equal(2, TestDecoderWithParameters.GetInvocationCount(testName)); |
|
|
|
}); |
|
|
|
string fn = provider.Utility.GetTestOutputFileName("jpg"); |
|
|
|
this.Output.WriteLine(fn); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static string[] AllBmpFiles = |
|
|
|
{ |
|
|
|
TestImages.Bmp.F, |
|
|
|
TestImages.Bmp.Bit8 |
|
|
|
}; |
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Jpeg.Baseline.Testorig420, PixelTypes.Rgba32)] |
|
|
|
public void Use_WithFileAttribute_CustomConfig<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
EnsureCustomConfigurationIsApplied(provider); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.Argb32)] |
|
|
|
@ -249,20 +273,15 @@ namespace SixLabors.ImageSharp.Tests |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)] |
|
|
|
public void SaveTestOutputFileMultiFrame<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.All)] |
|
|
|
public void Use_WithMemberFactoryAttribute<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
Assert.Equal(3, img.Width); |
|
|
|
if (provider.PixelType == PixelTypes.Rgba32) |
|
|
|
{ |
|
|
|
string[] files = provider.Utility.SaveTestOutputFileMultiFrame(image); |
|
|
|
|
|
|
|
Assert.True(files.Length > 2); |
|
|
|
foreach (string path in files) |
|
|
|
{ |
|
|
|
this.Output.WriteLine(path); |
|
|
|
Assert.True(File.Exists(path)); |
|
|
|
} |
|
|
|
Assert.IsType<Image<Rgba32>>(img); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -291,89 +310,112 @@ namespace SixLabors.ImageSharp.Tests |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Need to us <see cref="GenericFactory{TPixel}"/> to create instance of <see cref="Image"/> when pixelType is StandardImageClass
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="TPixel"></typeparam>
|
|
|
|
/// <param name="factory"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public static Image<TPixel> CreateTestImage<TPixel>() |
|
|
|
where TPixel : struct, IPixel<TPixel> => new Image<TPixel>(3, 3); |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.All)] |
|
|
|
public void Use_WithMemberFactoryAttribute<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
[WithTestPatternImages(49, 20, PixelTypes.Rgba32)] |
|
|
|
public void Use_WithTestPatternImages<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
Assert.Equal(3, img.Width); |
|
|
|
if (provider.PixelType == PixelTypes.Rgba32) |
|
|
|
using (Image<TPixel> img = provider.GetImage()) |
|
|
|
{ |
|
|
|
Assert.IsType<Image<Rgba32>>(img); |
|
|
|
img.DebugSave(provider); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(49,20, PixelTypes.Rgba32)] |
|
|
|
public void Use_WithTestPatternImages<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
[WithTestPatternImages(20, 20, PixelTypes.Rgba32)] |
|
|
|
public void Use_WithTestPatternImages_CustomConfiguration<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> img = provider.GetImage()) |
|
|
|
{ |
|
|
|
img.DebugSave(provider); |
|
|
|
} |
|
|
|
EnsureCustomConfigurationIsApplied(provider); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithBasicTestPatternImages(50, 100, PixelTypes.Rgba32)] |
|
|
|
[WithBasicTestPatternImages(49,17, PixelTypes.Rgba32)] |
|
|
|
[WithBasicTestPatternImages(20, 10, PixelTypes.Rgba32)] |
|
|
|
public void Use_WithBasicTestPatternImages<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
private static void EnsureCustomConfigurationIsApplied<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> img = provider.GetImage()) |
|
|
|
using (var image1 = provider.GetImage()) |
|
|
|
{ |
|
|
|
img.DebugSave(provider); |
|
|
|
var customConfiguration = Configuration.CreateDefaultInstance(); |
|
|
|
provider.Configuration = customConfiguration; |
|
|
|
|
|
|
|
using (var image2 = provider.GetImage()) |
|
|
|
using (var image3 = provider.GetImage()) |
|
|
|
{ |
|
|
|
Assert.Same(customConfiguration, image2.GetConfiguration()); |
|
|
|
Assert.Same(customConfiguration, image3.GetConfiguration()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static readonly TheoryData<object> BasicData = new TheoryData<object>() |
|
|
|
private class TestDecoder : IImageDecoder |
|
|
|
{ |
|
|
|
TestImageProvider<Rgba32>.Blank(10, 20), |
|
|
|
TestImageProvider<HalfVector4>.Blank( |
|
|
|
10, |
|
|
|
20), |
|
|
|
}; |
|
|
|
// Couldn't make xUnit happy without this hackery:
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(BasicData))] |
|
|
|
public void Blank_MemberData<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
private static readonly ConcurrentDictionary<string, int> invocationCounts = |
|
|
|
new ConcurrentDictionary<string, int>(); |
|
|
|
|
|
|
|
Assert.True(img.Width * img.Height > 0); |
|
|
|
private static readonly object Monitor = new object(); |
|
|
|
|
|
|
|
private string callerName = null; |
|
|
|
|
|
|
|
public static void DoTestThreadSafe(Action action) |
|
|
|
{ |
|
|
|
lock (Monitor) |
|
|
|
{ |
|
|
|
action(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
invocationCounts[this.callerName]++; |
|
|
|
return new Image<TPixel>(42, 42); |
|
|
|
} |
|
|
|
|
|
|
|
internal static int GetInvocationCount(string callerName) => invocationCounts[callerName]; |
|
|
|
|
|
|
|
internal void InitCaller(string name) |
|
|
|
{ |
|
|
|
this.callerName = name; |
|
|
|
invocationCounts[name] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static readonly TheoryData<object> FileData = new TheoryData<object>() |
|
|
|
private class TestDecoderWithParameters : IImageDecoder |
|
|
|
{ |
|
|
|
TestImageProvider<Rgba32>.File(TestImages.Bmp.Car), |
|
|
|
TestImageProvider<HalfVector4>.File(TestImages.Bmp.F) |
|
|
|
}; |
|
|
|
private static readonly ConcurrentDictionary<string, int> invocationCounts = |
|
|
|
new ConcurrentDictionary<string, int>(); |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[MemberData(nameof(FileData))] |
|
|
|
public void File_MemberData<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
this.Output.WriteLine("SRC: " + provider.Utility.SourceFileOrDescription); |
|
|
|
this.Output.WriteLine("OUT: " + provider.Utility.GetTestOutputFileName()); |
|
|
|
private static readonly object Monitor = new object(); |
|
|
|
|
|
|
|
Image<TPixel> img = provider.GetImage(); |
|
|
|
private string callerName = null; |
|
|
|
|
|
|
|
Assert.True(img.Width * img.Height > 0); |
|
|
|
public string Param1 { get; set; } |
|
|
|
|
|
|
|
public int Param2 { get; set; } |
|
|
|
|
|
|
|
public static void DoTestThreadSafe(Action action) |
|
|
|
{ |
|
|
|
lock (Monitor) |
|
|
|
{ |
|
|
|
action(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
invocationCounts[this.callerName]++; |
|
|
|
return new Image<TPixel>(42, 42); |
|
|
|
} |
|
|
|
|
|
|
|
internal static int GetInvocationCount(string callerName) => invocationCounts[callerName]; |
|
|
|
|
|
|
|
internal void InitCaller(string name) |
|
|
|
{ |
|
|
|
this.callerName = name; |
|
|
|
invocationCounts[name] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |