// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; using System.Reflection; using Castle.Core.Internal; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests { public interface ITestImageProvider { PixelTypes PixelType { get; } ImagingTestCaseUtility Utility { get; } string SourceFileOrDescription { get; } Configuration Configuration { get; set; } } /// /// Provides instances for parametric unit tests. /// /// The pixel format of the image public abstract partial class TestImageProvider : ITestImageProvider where TPixel : struct, IPixel { public PixelTypes PixelType { get; private set; } = typeof(TPixel).GetPixelType(); public virtual string SourceFileOrDescription => ""; public Configuration Configuration { get; set; } = Configuration.CreateDefaultInstance(); /// /// Utility instance to provide information about the test image & manage input/output /// public ImagingTestCaseUtility Utility { get; private set; } public string TypeName { get; private set; } public string MethodName { get; private set; } public string OutputSubfolderName { get; private set; } public static TestImageProvider BasicTestPattern(int width, int height, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) => new BasicTestPatternProvider(width, height).Init(testMethod, pixelTypeOverride); public static TestImageProvider TestPattern( int width, int height, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) => new TestPatternProvider(width, height).Init(testMethod, pixelTypeOverride); public static TestImageProvider Blank( int width, int height, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) => new BlankProvider(width, height).Init(testMethod, pixelTypeOverride); public static TestImageProvider File( string filePath, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) { return new FileProvider(filePath).Init(testMethod, pixelTypeOverride); } public static TestImageProvider Lambda( Func> factoryFunc, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) => new LambdaProvider(factoryFunc).Init(testMethod, pixelTypeOverride); public static TestImageProvider Solid( int width, int height, byte r, byte g, byte b, byte a = 255, MethodInfo testMethod = null, PixelTypes pixelTypeOverride = PixelTypes.Undefined) { return new SolidProvider(width, height, r, g, b, a).Init(testMethod, pixelTypeOverride); } /// /// Returns an instance to the test case with the necessary traits. /// public abstract Image GetImage(); public virtual Image GetImage(IImageDecoder decoder) { throw new NotSupportedException($"Decoder specific GetImage() is not supported with {this.GetType().Name}!"); } /// /// Returns an instance to the test case with the necessary traits. /// public Image GetImage(Action operationsToApply) { Image img = this.GetImage(); img.Mutate(operationsToApply); return img; } public virtual void Deserialize(IXunitSerializationInfo info) { PixelTypes pixelType = info.GetValue("PixelType"); string typeName = info.GetValue("TypeName"); string methodName = info.GetValue("MethodName"); string outputSubfolderName = info.GetValue("OutputSubfolderName"); this.Init(typeName, methodName, outputSubfolderName, pixelType); } public virtual void Serialize(IXunitSerializationInfo info) { info.AddValue("PixelType", this.PixelType); info.AddValue("TypeName", this.TypeName); info.AddValue("MethodName", this.MethodName); info.AddValue("OutputSubfolderName", this.OutputSubfolderName); } protected TestImageProvider Init( string typeName, string methodName, string outputSubfolderName, PixelTypes pixelTypeOverride) { if (pixelTypeOverride != PixelTypes.Undefined) { this.PixelType = pixelTypeOverride; } this.TypeName = typeName; this.MethodName = methodName; this.OutputSubfolderName = outputSubfolderName; this.Utility = new ImagingTestCaseUtility { SourceFileOrDescription = this.SourceFileOrDescription, PixelTypeName = this.PixelType.ToString() }; if (methodName != null) { this.Utility.Init(typeName, methodName, outputSubfolderName); } return this; } protected TestImageProvider Init(MethodInfo testMethod, PixelTypes pixelTypeOverride) { string subfolder = testMethod?.DeclaringType.GetAttribute()?.Subfolder ?? string.Empty; return this.Init(testMethod?.DeclaringType.Name, testMethod?.Name, subfolder, pixelTypeOverride); } public override string ToString() { return $"{this.SourceFileOrDescription}[{this.PixelType}]"; } } }