Browse Source

Merge 5a1aa3f095 into 9c41e9c12e

pull/2854/merge
Stefan Nikolei 1 month ago
committed by GitHub
parent
commit
dd78542eee
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .gitmodules
  2. 2
      shared-infrastructure
  3. 1
      tests/Directory.Build.targets
  4. 7
      tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
  5. 1
      tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs
  6. 1
      tests/ImageSharp.Tests/Common/NumericsTests.cs
  7. 1
      tests/ImageSharp.Tests/Common/SimdUtilsTests.cs
  8. 1
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
  9. 1
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
  10. 1
      tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
  11. 1
      tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs
  12. 1
      tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs
  13. 1
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  14. 1
      tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
  15. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs
  16. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
  17. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs
  18. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
  19. 1
      tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
  20. 1
      tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs
  21. 1
      tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
  22. 1
      tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs
  23. 1
      tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs
  24. 1
      tests/ImageSharp.Tests/Formats/Png/PngEncoderFilterTests.cs
  25. 8
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  26. 1
      tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs
  27. 1
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  28. 47
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs
  29. 75
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.cs
  30. 502
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs
  31. 2
      tests/ImageSharp.Tests/PixelFormats/L8Tests.cs
  32. 2
      tests/ImageSharp.Tests/PixelFormats/La16Tests.cs
  33. 1
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/Generated/PixelOperationsTests.Specialized.Generated.cs
  34. 67
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs
  35. 2
      tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs
  36. 4
      tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs
  37. 126
      tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs
  38. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs
  39. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ProjectiveTransformTests.cs
  40. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
  41. 2
      tests/ImageSharp.Tests/Processing/Processors/Transforms/RotateTests.cs
  42. 1
      tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs
  43. 1
      tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs
  44. 25
      tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
  45. 41
      tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs
  46. 2
      tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs
  47. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/BasicTestPatternProvider.cs
  48. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/BlankProvider.cs
  49. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/FileProvider.cs
  50. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/MemberMethodProvider.cs
  51. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs
  52. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs
  53. 2
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
  54. 1
      tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs
  55. 14
      tests/ImageSharp.Tests/TestUtilities/SixLaborsXunitTestFramework.cs
  56. 60
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs
  57. 2
      tests/ImageSharp.Tests/TestUtilities/TestPixel.cs
  58. 3
      tests/ImageSharp.Tests/TestUtilities/TestType.cs
  59. 2
      tests/ImageSharp.Tests/TestUtilities/TestVector4.cs
  60. 24
      tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs
  61. 2
      tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs
  62. 1
      tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs
  63. 1
      tests/ImageSharp.Tests/TestUtilities/Tests/MagickReferenceCodecTests.cs
  64. 1
      tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs
  65. 1
      tests/ImageSharp.Tests/TestUtilities/Tests/SystemDrawingReferenceCodecTests.cs
  66. 54
      tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs
  67. 25
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
  68. 1
      tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs
  69. 13
      tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalDiscovererException.cs
  70. 38
      tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalFact.cs
  71. 146
      tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalTestDiscoverer.cs
  72. 42
      tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalTheory.cs
  73. 64
      tests/ImageSharp.Tests/TestUtilities/XUnit/StaticReflectionConstants.cs
  74. 6
      tests/ImageSharp.Tests/ValidateDisposedMemoryAllocationsAttribute.cs

2
.gitmodules

@ -1,3 +1,3 @@
[submodule "shared-infrastructure"]
path = shared-infrastructure
url = https://github.com/SixLabors/SharedInfrastructure
url = https://github.com/stefannikolei/SharedInfrastructure

2
shared-infrastructure

@ -1 +1 @@
Subproject commit 7ac5703452348d9295db31fc0912c2bd9e419dc9
Subproject commit 6491506cf4a330de2d743453b30c506ed7c74af7

1
tests/Directory.Build.targets

@ -21,7 +21,6 @@
<PackageReference Update="Colourful" Version="3.2.0" />
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="14.11.1" />
<PackageReference Update="Microsoft.DotNet.RemoteExecutor" Version="10.0.0-beta.25563.105" />
<PackageReference Update="Microsoft.DotNet.XUnitExtensions" Version="8.0.0-beta.23580.1" />
<PackageReference Update="Moq" Version="4.20.72" />
<PackageReference Update="NetVips" Version="3.0.0" />
<PackageReference Update="NetVips.Native" Version="8.16.0" />

7
tests/ImageSharp.Tests.ProfilingSandbox/Program.cs

@ -4,7 +4,7 @@
using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations;
using SixLabors.ImageSharp.Tests.ProfilingBenchmarks;
using SixLabors.ImageSharp.Tests.ProfilingSandbox;
using Xunit.Abstractions;
using Xunit;
// in this file, comments are used for disabling stuff for local execution
#pragma warning disable SA1515
@ -32,7 +32,12 @@ static void RunToVector4ProfilingTest()
sealed class ConsoleOutput : ITestOutputHelper
{
public void Write(string message) => Console.Write(message);
public void Write(string format, params object[] args) => Console.Write(format, args);
public void WriteLine(string message) => Console.WriteLine(message);
public void WriteLine(string format, params object[] args) => Console.WriteLine(format, args);
public string Output { get; }
}

1
tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs

@ -6,7 +6,6 @@ using SixLabors.ImageSharp.ColorProfiles;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using Wacton.Unicolour;
using Wacton.Unicolour.Icc;
using Xunit.Abstractions;
using Rgb = SixLabors.ImageSharp.ColorProfiles.Rgb;
namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc;

1
tests/ImageSharp.Tests/Common/NumericsTests.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Common;

1
tests/ImageSharp.Tests/Common/SimdUtilsTests.cs

@ -7,7 +7,6 @@ using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Common;

1
tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs

@ -7,7 +7,6 @@ using System.Runtime.Intrinsics;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs

@ -2,7 +2,6 @@
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs

@ -6,7 +6,6 @@ using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Tests.ColorProfiles;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -9,7 +9,6 @@ using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs

@ -6,7 +6,6 @@ using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs

@ -4,7 +4,6 @@
// ReSharper disable InconsistentNaming
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs

@ -9,7 +9,6 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs

@ -7,7 +7,6 @@ using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs

@ -6,7 +6,6 @@ using System.Text;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;

1
tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs

@ -5,7 +5,6 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;

1
tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;

1
tests/ImageSharp.Tests/Formats/Png/PngEncoderFilterTests.cs

@ -6,7 +6,6 @@
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Png.Filters;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Png;

8
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -200,14 +200,14 @@ public partial class PngEncoderTests
return;
}
foreach (object[] filterMethod in PngFilterMethods)
foreach (TheoryDataRow<PngFilterMethod> filterMethod in PngFilterMethods)
{
foreach (PngInterlaceMode interlaceMode in InterlaceMode)
{
TestPngEncoderCore(
provider,
pngColorType,
(PngFilterMethod)filterMethod[0],
filterMethod.Data,
pngBitDepth,
interlaceMode,
appendPngColorType: true,
@ -236,14 +236,14 @@ public partial class PngEncoderTests
public void WorksWithAllBitDepthsAndExcludeAllFilter<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType, PngBitDepth pngBitDepth)
where TPixel : unmanaged, IPixel<TPixel>
{
foreach (object[] filterMethod in PngFilterMethods)
foreach (TheoryDataRow<PngFilterMethod> filterMethod in PngFilterMethods)
{
foreach (PngInterlaceMode interlaceMode in InterlaceMode)
{
TestPngEncoderCore(
provider,
pngColorType,
(PngFilterMethod)filterMethod[0],
filterMethod.Data,
pngBitDepth,
interlaceMode,
appendPngColorType: true,

1
tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs

@ -7,7 +7,6 @@ using Castle.Core.Configuration;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Helpers;

1
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -45,7 +45,6 @@
<PackageReference Include="BenchmarkDotNet" Version="0.13.0" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" />
<PackageReference Include="Microsoft.DotNet.RemoteExecutor" />
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" />
<PackageReference Include="Moq" />
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Condition="'$(IsOSX)'=='true'" />
<PackageReference Include="SharpZipLib" />

47
tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs

@ -14,9 +14,7 @@ public partial class UniformUnmanagedMemoryPoolTests
public class Trim
{
[CollectionDefinition(nameof(NonParallelTests), DisableParallelization = true)]
public class NonParallelTests
{
}
public class NonParallelTests { }
[Fact]
public void TrimPeriodElapsed_TrimsHalfOfUnusedArrays()
@ -24,7 +22,10 @@ public partial class UniformUnmanagedMemoryPoolTests
RemoteExecutor.Invoke(RunTest).Dispose();
static void RunTest()
{
UniformUnmanagedMemoryPool.TrimSettings trimSettings = new() { TrimPeriodMilliseconds = 5_000 };
UniformUnmanagedMemoryPool.TrimSettings trimSettings = new()
{
TrimPeriodMilliseconds = 5_000,
};
UniformUnmanagedMemoryPool pool = new(128, 256, trimSettings);
UnmanagedMemoryHandle[] a = pool.Rent(64);
@ -37,7 +38,8 @@ public partial class UniformUnmanagedMemoryPoolTests
// 128 - 32 - 16 = 80
Assert.True(
UnmanagedMemoryHandle.TotalOutstandingHandles <= 80,
$"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 80");
$"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 80"
);
pool.Return(b);
}
}
@ -46,14 +48,12 @@ public partial class UniformUnmanagedMemoryPoolTests
// MultiplePoolInstances_TrimPeriodElapsed_AllAreTrimmed,
// which is strongly timing-sensitive, and might be flaky under high load.
[CollectionDefinition(nameof(NonParallelCollection), DisableParallelization = true)]
public class NonParallelCollection
{
}
public class NonParallelCollection { }
[Collection(nameof(NonParallelCollection))]
public class NonParallel
{
public static readonly bool IsNotMacOS = !TestEnvironment.IsMacOS;
public static bool IsNotMacOS => !TestEnvironment.IsMacOS;
// TODO: Investigate failures on macOS. All handles are released after GC.
// (It seems to happen more consistently on .NET 6.)
@ -77,10 +77,16 @@ public partial class UniformUnmanagedMemoryPoolTests
static void RunTest()
{
UniformUnmanagedMemoryPool.TrimSettings trimSettings1 = new() { TrimPeriodMilliseconds = 6_000 };
UniformUnmanagedMemoryPool.TrimSettings trimSettings1 = new()
{
TrimPeriodMilliseconds = 6_000,
};
UniformUnmanagedMemoryPool pool1 = new(128, 256, trimSettings1);
Thread.Sleep(8_000); // Let some callbacks fire already
UniformUnmanagedMemoryPool.TrimSettings trimSettings2 = new() { TrimPeriodMilliseconds = 3_000 };
UniformUnmanagedMemoryPool.TrimSettings trimSettings2 = new()
{
TrimPeriodMilliseconds = 3_000,
};
UniformUnmanagedMemoryPool pool2 = new(128, 256, trimSettings2);
pool1.Return(pool1.Rent(64));
@ -96,7 +102,8 @@ public partial class UniformUnmanagedMemoryPoolTests
Thread.Sleep(15_000);
Assert.True(
UnmanagedMemoryHandle.TotalOutstandingHandles <= 64,
$"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 64");
$"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 64"
);
GC.KeepAlive(pool1);
GC.KeepAlive(pool2);
}
@ -104,13 +111,16 @@ public partial class UniformUnmanagedMemoryPoolTests
[MethodImpl(MethodImplOptions.NoInlining)]
static void LeakPoolInstance()
{
UniformUnmanagedMemoryPool.TrimSettings trimSettings = new() { TrimPeriodMilliseconds = 4_000 };
UniformUnmanagedMemoryPool.TrimSettings trimSettings = new()
{
TrimPeriodMilliseconds = 4_000,
};
_ = new UniformUnmanagedMemoryPool(128, 256, trimSettings);
}
}
}
public static readonly bool Is32BitProcess = !Environment.Is64BitProcess;
public static bool Is32BitProcess => !Environment.Is64BitProcess;
private static readonly List<byte[]> PressureArrays = [];
[Fact]
@ -129,11 +139,16 @@ public partial class UniformUnmanagedMemoryPoolTests
Assert.False(Environment.Is64BitProcess);
const int oneMb = 1 << 20;
UniformUnmanagedMemoryPool.TrimSettings trimSettings = new() { HighPressureThresholdRate = 0.2f };
UniformUnmanagedMemoryPool.TrimSettings trimSettings = new()
{
HighPressureThresholdRate = 0.2f,
};
GCMemoryInfo memInfo = GC.GetGCMemoryInfo();
int highLoadThreshold = (int)(memInfo.HighMemoryLoadThresholdBytes / oneMb);
highLoadThreshold = (int)(trimSettings.HighPressureThresholdRate * highLoadThreshold);
highLoadThreshold = (int)(
trimSettings.HighPressureThresholdRate * highLoadThreshold
);
UniformUnmanagedMemoryPool pool = new(oneMb, 16, trimSettings);
pool.Return(pool.Rent(16));

75
tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.cs

@ -5,7 +5,6 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Memory.Internals;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Memory.Allocators;
@ -28,11 +27,13 @@ public partial class UniformUnmanagedMemoryPoolTests
public void Register(UnmanagedMemoryHandle handle) => this.handlesToDestroy.Add(handle);
public void Register(IEnumerable<UnmanagedMemoryHandle> handles) => this.handlesToDestroy.AddRange(handles);
public void Register(IEnumerable<UnmanagedMemoryHandle> handles) =>
this.handlesToDestroy.AddRange(handles);
public void Register(IntPtr memoryPtr) => this.ptrsToDestroy.Add(memoryPtr);
public void Register(IEnumerable<IntPtr> memoryPtrs) => this.ptrsToDestroy.AddRange(memoryPtrs);
public void Register(IEnumerable<IntPtr> memoryPtrs) =>
this.ptrsToDestroy.AddRange(memoryPtrs);
public void Dispose()
{
@ -94,7 +95,11 @@ public partial class UniformUnmanagedMemoryPoolTests
}
}
private static void CheckBuffer(int length, UniformUnmanagedMemoryPool pool, UnmanagedMemoryHandle h)
private static void CheckBuffer(
int length,
UniformUnmanagedMemoryPool pool,
UnmanagedMemoryHandle h
)
{
Assert.False(h.IsInvalid);
Span<byte> span = GetSpan(h, pool.BufferLength);
@ -105,7 +110,8 @@ public partial class UniformUnmanagedMemoryPoolTests
Assert.True(span.SequenceEqual(expected));
}
private static unsafe Span<byte> GetSpan(UnmanagedMemoryHandle h, int length) => new(h.Pointer, length);
private static unsafe Span<byte> GetSpan(UnmanagedMemoryHandle h, int length) =>
new(h.Pointer, length);
[Theory]
[InlineData(1, 1)]
@ -210,7 +216,11 @@ public partial class UniformUnmanagedMemoryPoolTests
[InlineData(0, 6, 5)]
[InlineData(5, 1, 5)]
[InlineData(4, 7, 10)]
public void Rent_MultiBuffer_OverCapacity_ReturnsNull(int initialRent, int attempt, int capacity)
public void Rent_MultiBuffer_OverCapacity_ReturnsNull(
int initialRent,
int attempt,
int capacity
)
{
UniformUnmanagedMemoryPool pool = new(128, capacity);
using CleanupUtil cleanup = new(pool);
@ -238,7 +248,7 @@ public partial class UniformUnmanagedMemoryPoolTests
cleanup.Register(b1);
}
public static readonly bool IsNotMacOS = !TestEnvironment.IsMacOS;
public static bool IsNotMacOS => !TestEnvironment.IsMacOS;
// TODO: Investigate macOS failures
[ConditionalTheory(nameof(IsNotMacOS))]
@ -261,7 +271,10 @@ public partial class UniformUnmanagedMemoryPoolTests
pool.Release();
// Do some unmanaged allocations to make sure new pool buffers are different:
IntPtr[] dummy = Enumerable.Range(0, 100).Select(_ => Marshal.AllocHGlobal(16)).ToArray();
IntPtr[] dummy = Enumerable
.Range(0, 100)
.Select(_ => Marshal.AllocHGlobal(16))
.ToArray();
cleanup.Register(dummy);
if (bool.Parse(multipleInner))
@ -310,34 +323,38 @@ public partial class UniformUnmanagedMemoryPoolTests
using CleanupUtil cleanup = new(pool);
Random rnd = new(0);
Parallel.For(0, Environment.ProcessorCount, (int i) =>
{
List<UnmanagedMemoryHandle> allHandles = new();
int pauseAt = rnd.Next(100);
for (int j = 0; j < 100; j++)
Parallel.For(
0,
Environment.ProcessorCount,
(int i) =>
{
UnmanagedMemoryHandle[] data = pool.Rent(2);
List<UnmanagedMemoryHandle> allHandles = new();
int pauseAt = rnd.Next(100);
for (int j = 0; j < 100; j++)
{
UnmanagedMemoryHandle[] data = pool.Rent(2);
GetSpan(data[0], pool.BufferLength).Fill((byte)i);
GetSpan(data[1], pool.BufferLength).Fill((byte)i);
allHandles.Add(data[0]);
allHandles.Add(data[1]);
GetSpan(data[0], pool.BufferLength).Fill((byte)i);
GetSpan(data[1], pool.BufferLength).Fill((byte)i);
allHandles.Add(data[0]);
allHandles.Add(data[1]);
if (j == pauseAt)
{
Thread.Sleep(15);
if (j == pauseAt)
{
Thread.Sleep(15);
}
}
}
Span<byte> expected = new byte[8];
expected.Fill((byte)i);
Span<byte> expected = new byte[8];
expected.Fill((byte)i);
foreach (UnmanagedMemoryHandle h in allHandles)
{
Assert.True(expected.SequenceEqual(GetSpan(h, pool.BufferLength)));
pool.Return(new[] { h });
foreach (UnmanagedMemoryHandle h in allHandles)
{
Assert.True(expected.SequenceEqual(GetSpan(h, pool.BufferLength)));
pool.Return(new[] { h });
}
}
});
);
}
[Theory]

502
tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs

@ -11,329 +11,329 @@ public class ExifValuesTests
{
public static TheoryData<ExifTag> ByteTags => new()
{
{ ExifTag.FaxProfile },
{ ExifTag.ModeNumber },
{ ExifTag.GPSAltitudeRef }
{ (ExifTag)ExifTag.FaxProfile },
{ (ExifTag)ExifTag.ModeNumber },
{ (ExifTag)ExifTag.GPSAltitudeRef }
};
public static TheoryData<ExifTag> ByteArrayTags => new()
{
{ ExifTag.ClipPath },
{ ExifTag.VersionYear },
{ ExifTag.XMP },
{ ExifTag.CFAPattern2 },
{ ExifTag.TIFFEPStandardID },
{ ExifTag.GPSVersionID },
{ (ExifTag)ExifTag.ClipPath },
{ (ExifTag)ExifTag.VersionYear },
{ (ExifTag)ExifTag.XMP },
{ (ExifTag)ExifTag.CFAPattern2 },
{ (ExifTag)ExifTag.TIFFEPStandardID },
{ (ExifTag)ExifTag.GPSVersionID },
};
public static TheoryData<ExifTag> DoubleArrayTags => new()
{
{ ExifTag.PixelScale },
{ ExifTag.IntergraphMatrix },
{ ExifTag.ModelTiePoint },
{ ExifTag.ModelTransform }
{ (ExifTag)ExifTag.PixelScale },
{ (ExifTag)ExifTag.IntergraphMatrix },
{ (ExifTag)ExifTag.ModelTiePoint },
{ (ExifTag)ExifTag.ModelTransform }
};
public static TheoryData<ExifTag> LongTags => new()
{
{ ExifTag.SubfileType },
{ ExifTag.SubIFDOffset },
{ ExifTag.GPSIFDOffset },
{ ExifTag.T4Options },
{ ExifTag.T6Options },
{ ExifTag.XClipPathUnits },
{ ExifTag.YClipPathUnits },
{ ExifTag.ProfileType },
{ ExifTag.CodingMethods },
{ ExifTag.T82ptions },
{ ExifTag.JPEGInterchangeFormat },
{ ExifTag.JPEGInterchangeFormatLength },
{ ExifTag.MDFileTag },
{ ExifTag.StandardOutputSensitivity },
{ ExifTag.RecommendedExposureIndex },
{ ExifTag.ISOSpeed },
{ ExifTag.ISOSpeedLatitudeyyy },
{ ExifTag.ISOSpeedLatitudezzz },
{ ExifTag.FaxRecvParams },
{ ExifTag.FaxRecvTime },
{ ExifTag.ImageNumber },
{ (ExifTag)ExifTag.SubfileType },
{ (ExifTag)ExifTag.SubIFDOffset },
{ (ExifTag)ExifTag.GPSIFDOffset },
{ (ExifTag)ExifTag.T4Options },
{ (ExifTag)ExifTag.T6Options },
{ (ExifTag)ExifTag.XClipPathUnits },
{ (ExifTag)ExifTag.YClipPathUnits },
{ (ExifTag)ExifTag.ProfileType },
{ (ExifTag)ExifTag.CodingMethods },
{ (ExifTag)ExifTag.T82ptions },
{ (ExifTag)ExifTag.JPEGInterchangeFormat },
{ (ExifTag)ExifTag.JPEGInterchangeFormatLength },
{ (ExifTag)ExifTag.MDFileTag },
{ (ExifTag)ExifTag.StandardOutputSensitivity },
{ (ExifTag)ExifTag.RecommendedExposureIndex },
{ (ExifTag)ExifTag.ISOSpeed },
{ (ExifTag)ExifTag.ISOSpeedLatitudeyyy },
{ (ExifTag)ExifTag.ISOSpeedLatitudezzz },
{ (ExifTag)ExifTag.FaxRecvParams },
{ (ExifTag)ExifTag.FaxRecvTime },
{ (ExifTag)ExifTag.ImageNumber },
};
public static TheoryData<ExifTag> LongArrayTags => new()
{
{ ExifTag.FreeOffsets },
{ ExifTag.FreeByteCounts },
{ ExifTag.ColorResponseUnit },
{ ExifTag.SMinSampleValue },
{ ExifTag.SMaxSampleValue },
{ ExifTag.JPEGQTables },
{ ExifTag.JPEGDCTables },
{ ExifTag.JPEGACTables },
{ ExifTag.StripRowCounts },
{ ExifTag.IntergraphRegisters }
{ (ExifTag)ExifTag.FreeOffsets },
{ (ExifTag)ExifTag.FreeByteCounts },
{ (ExifTag)ExifTag.ColorResponseUnit },
{ (ExifTag)ExifTag.SMinSampleValue },
{ (ExifTag)ExifTag.SMaxSampleValue },
{ (ExifTag)ExifTag.JPEGQTables },
{ (ExifTag)ExifTag.JPEGDCTables },
{ (ExifTag)ExifTag.JPEGACTables },
{ (ExifTag)ExifTag.StripRowCounts },
{ (ExifTag)ExifTag.IntergraphRegisters }
};
public static TheoryData<ExifTag> NumberTags => new()
{
{ ExifTag.ImageWidth },
{ ExifTag.ImageLength },
{ ExifTag.TileWidth },
{ ExifTag.TileLength },
{ ExifTag.BadFaxLines },
{ ExifTag.ConsecutiveBadFaxLines },
{ ExifTag.PixelXDimension },
{ ExifTag.PixelYDimension }
{ (ExifTag)ExifTag.ImageWidth },
{ (ExifTag)ExifTag.ImageLength },
{ (ExifTag)ExifTag.TileWidth },
{ (ExifTag)ExifTag.TileLength },
{ (ExifTag)ExifTag.BadFaxLines },
{ (ExifTag)ExifTag.ConsecutiveBadFaxLines },
{ (ExifTag)ExifTag.PixelXDimension },
{ (ExifTag)ExifTag.PixelYDimension }
};
public static TheoryData<ExifTag> NumberArrayTags => new()
{
{ ExifTag.StripOffsets },
{ ExifTag.StripByteCounts },
{ ExifTag.TileByteCounts },
{ ExifTag.TileOffsets },
{ ExifTag.ImageLayer }
{ (ExifTag)ExifTag.StripOffsets },
{ (ExifTag)ExifTag.StripByteCounts },
{ (ExifTag)ExifTag.TileByteCounts },
{ (ExifTag)ExifTag.TileOffsets },
{ (ExifTag)ExifTag.ImageLayer }
};
public static TheoryData<ExifTag> RationalTags => new()
{
{ ExifTag.XPosition },
{ ExifTag.YPosition },
{ ExifTag.XResolution },
{ ExifTag.YResolution },
{ ExifTag.BatteryLevel },
{ ExifTag.ExposureTime },
{ ExifTag.FNumber },
{ ExifTag.MDScalePixel },
{ ExifTag.CompressedBitsPerPixel },
{ ExifTag.ApertureValue },
{ ExifTag.MaxApertureValue },
{ ExifTag.SubjectDistance },
{ ExifTag.FocalLength },
{ ExifTag.FlashEnergy2 },
{ ExifTag.FocalPlaneXResolution2 },
{ ExifTag.FocalPlaneYResolution2 },
{ ExifTag.ExposureIndex2 },
{ ExifTag.Humidity },
{ ExifTag.Pressure },
{ ExifTag.Acceleration },
{ ExifTag.FlashEnergy },
{ ExifTag.FocalPlaneXResolution },
{ ExifTag.FocalPlaneYResolution },
{ ExifTag.ExposureIndex },
{ ExifTag.DigitalZoomRatio },
{ ExifTag.GPSAltitude },
{ ExifTag.GPSDOP },
{ ExifTag.GPSSpeed },
{ ExifTag.GPSTrack },
{ ExifTag.GPSImgDirection },
{ ExifTag.GPSDestBearing },
{ ExifTag.GPSDestDistance },
{ ExifTag.GPSHPositioningError },
{ (ExifTag)ExifTag.XPosition },
{ (ExifTag)ExifTag.YPosition },
{ (ExifTag)ExifTag.XResolution },
{ (ExifTag)ExifTag.YResolution },
{ (ExifTag)ExifTag.BatteryLevel },
{ (ExifTag)ExifTag.ExposureTime },
{ (ExifTag)ExifTag.FNumber },
{ (ExifTag)ExifTag.MDScalePixel },
{ (ExifTag)ExifTag.CompressedBitsPerPixel },
{ (ExifTag)ExifTag.ApertureValue },
{ (ExifTag)ExifTag.MaxApertureValue },
{ (ExifTag)ExifTag.SubjectDistance },
{ (ExifTag)ExifTag.FocalLength },
{ (ExifTag)ExifTag.FlashEnergy2 },
{ (ExifTag)ExifTag.FocalPlaneXResolution2 },
{ (ExifTag)ExifTag.FocalPlaneYResolution2 },
{ (ExifTag)ExifTag.ExposureIndex2 },
{ (ExifTag)ExifTag.Humidity },
{ (ExifTag)ExifTag.Pressure },
{ (ExifTag)ExifTag.Acceleration },
{ (ExifTag)ExifTag.FlashEnergy },
{ (ExifTag)ExifTag.FocalPlaneXResolution },
{ (ExifTag)ExifTag.FocalPlaneYResolution },
{ (ExifTag)ExifTag.ExposureIndex },
{ (ExifTag)ExifTag.DigitalZoomRatio },
{ (ExifTag)ExifTag.GPSAltitude },
{ (ExifTag)ExifTag.GPSDOP },
{ (ExifTag)ExifTag.GPSSpeed },
{ (ExifTag)ExifTag.GPSTrack },
{ (ExifTag)ExifTag.GPSImgDirection },
{ (ExifTag)ExifTag.GPSDestBearing },
{ (ExifTag)ExifTag.GPSDestDistance },
{ (ExifTag)ExifTag.GPSHPositioningError },
};
public static TheoryData<ExifTag> RationalArrayTags => new()
{
{ ExifTag.WhitePoint },
{ ExifTag.PrimaryChromaticities },
{ ExifTag.YCbCrCoefficients },
{ ExifTag.ReferenceBlackWhite },
{ ExifTag.GPSLatitude },
{ ExifTag.GPSLongitude },
{ ExifTag.GPSTimestamp },
{ ExifTag.GPSDestLatitude },
{ ExifTag.GPSDestLongitude },
{ ExifTag.LensSpecification }
{ (ExifTag)ExifTag.WhitePoint },
{ (ExifTag)ExifTag.PrimaryChromaticities },
{ (ExifTag)ExifTag.YCbCrCoefficients },
{ (ExifTag)ExifTag.ReferenceBlackWhite },
{ (ExifTag)ExifTag.GPSLatitude },
{ (ExifTag)ExifTag.GPSLongitude },
{ (ExifTag)ExifTag.GPSTimestamp },
{ (ExifTag)ExifTag.GPSDestLatitude },
{ (ExifTag)ExifTag.GPSDestLongitude },
{ (ExifTag)ExifTag.LensSpecification }
};
public static TheoryData<ExifTag> ShortTags => new()
{
{ ExifTag.OldSubfileType },
{ ExifTag.Compression },
{ ExifTag.PhotometricInterpretation },
{ ExifTag.Thresholding },
{ ExifTag.CellWidth },
{ ExifTag.CellLength },
{ ExifTag.FillOrder },
{ ExifTag.Orientation },
{ ExifTag.SamplesPerPixel },
{ ExifTag.PlanarConfiguration },
{ ExifTag.Predictor },
{ ExifTag.GrayResponseUnit },
{ ExifTag.ResolutionUnit },
{ ExifTag.CleanFaxData },
{ ExifTag.InkSet },
{ ExifTag.NumberOfInks },
{ ExifTag.DotRange },
{ ExifTag.Indexed },
{ ExifTag.OPIProxy },
{ ExifTag.JPEGProc },
{ ExifTag.JPEGRestartInterval },
{ ExifTag.YCbCrPositioning },
{ ExifTag.Rating },
{ ExifTag.RatingPercent },
{ ExifTag.ExposureProgram },
{ ExifTag.Interlace },
{ ExifTag.SelfTimerMode },
{ ExifTag.SensitivityType },
{ ExifTag.MeteringMode },
{ ExifTag.LightSource },
{ ExifTag.FocalPlaneResolutionUnit2 },
{ ExifTag.SensingMethod2 },
{ ExifTag.Flash },
{ ExifTag.ColorSpace },
{ ExifTag.FocalPlaneResolutionUnit },
{ ExifTag.SensingMethod },
{ ExifTag.CustomRendered },
{ ExifTag.ExposureMode },
{ ExifTag.WhiteBalance },
{ ExifTag.FocalLengthIn35mmFilm },
{ ExifTag.SceneCaptureType },
{ ExifTag.GainControl },
{ ExifTag.Contrast },
{ ExifTag.Saturation },
{ ExifTag.Sharpness },
{ ExifTag.SubjectDistanceRange },
{ ExifTag.GPSDifferential }
{ (ExifTag)ExifTag.OldSubfileType },
{ (ExifTag)ExifTag.Compression },
{ (ExifTag)ExifTag.PhotometricInterpretation },
{ (ExifTag)ExifTag.Thresholding },
{ (ExifTag)ExifTag.CellWidth },
{ (ExifTag)ExifTag.CellLength },
{ (ExifTag)ExifTag.FillOrder },
{ (ExifTag)ExifTag.Orientation },
{ (ExifTag)ExifTag.SamplesPerPixel },
{ (ExifTag)ExifTag.PlanarConfiguration },
{ (ExifTag)ExifTag.Predictor },
{ (ExifTag)ExifTag.GrayResponseUnit },
{ (ExifTag)ExifTag.ResolutionUnit },
{ (ExifTag)ExifTag.CleanFaxData },
{ (ExifTag)ExifTag.InkSet },
{ (ExifTag)ExifTag.NumberOfInks },
{ (ExifTag)ExifTag.DotRange },
{ (ExifTag)ExifTag.Indexed },
{ (ExifTag)ExifTag.OPIProxy },
{ (ExifTag)ExifTag.JPEGProc },
{ (ExifTag)ExifTag.JPEGRestartInterval },
{ (ExifTag)ExifTag.YCbCrPositioning },
{ (ExifTag)ExifTag.Rating },
{ (ExifTag)ExifTag.RatingPercent },
{ (ExifTag)ExifTag.ExposureProgram },
{ (ExifTag)ExifTag.Interlace },
{ (ExifTag)ExifTag.SelfTimerMode },
{ (ExifTag)ExifTag.SensitivityType },
{ (ExifTag)ExifTag.MeteringMode },
{ (ExifTag)ExifTag.LightSource },
{ (ExifTag)ExifTag.FocalPlaneResolutionUnit2 },
{ (ExifTag)ExifTag.SensingMethod2 },
{ (ExifTag)ExifTag.Flash },
{ (ExifTag)ExifTag.ColorSpace },
{ (ExifTag)ExifTag.FocalPlaneResolutionUnit },
{ (ExifTag)ExifTag.SensingMethod },
{ (ExifTag)ExifTag.CustomRendered },
{ (ExifTag)ExifTag.ExposureMode },
{ (ExifTag)ExifTag.WhiteBalance },
{ (ExifTag)ExifTag.FocalLengthIn35mmFilm },
{ (ExifTag)ExifTag.SceneCaptureType },
{ (ExifTag)ExifTag.GainControl },
{ (ExifTag)ExifTag.Contrast },
{ (ExifTag)ExifTag.Saturation },
{ (ExifTag)ExifTag.Sharpness },
{ (ExifTag)ExifTag.SubjectDistanceRange },
{ (ExifTag)ExifTag.GPSDifferential }
};
public static TheoryData<ExifTag> ShortArrayTags => new()
{
{ ExifTag.BitsPerSample },
{ ExifTag.MinSampleValue },
{ ExifTag.MaxSampleValue },
{ ExifTag.GrayResponseCurve },
{ ExifTag.ColorMap },
{ ExifTag.ExtraSamples },
{ ExifTag.PageNumber },
{ ExifTag.TransferFunction },
{ ExifTag.HalftoneHints },
{ ExifTag.SampleFormat },
{ ExifTag.TransferRange },
{ ExifTag.DefaultImageColor },
{ ExifTag.JPEGLosslessPredictors },
{ ExifTag.JPEGPointTransforms },
{ ExifTag.YCbCrSubsampling },
{ ExifTag.CFARepeatPatternDim },
{ ExifTag.IntergraphPacketData },
{ ExifTag.ISOSpeedRatings },
{ ExifTag.SubjectArea },
{ ExifTag.SubjectLocation }
{ (ExifTag)ExifTag.BitsPerSample },
{ (ExifTag)ExifTag.MinSampleValue },
{ (ExifTag)ExifTag.MaxSampleValue },
{ (ExifTag)ExifTag.GrayResponseCurve },
{ (ExifTag)ExifTag.ColorMap },
{ (ExifTag)ExifTag.ExtraSamples },
{ (ExifTag)ExifTag.PageNumber },
{ (ExifTag)ExifTag.TransferFunction },
{ (ExifTag)ExifTag.HalftoneHints },
{ (ExifTag)ExifTag.SampleFormat },
{ (ExifTag)ExifTag.TransferRange },
{ (ExifTag)ExifTag.DefaultImageColor },
{ (ExifTag)ExifTag.JPEGLosslessPredictors },
{ (ExifTag)ExifTag.JPEGPointTransforms },
{ (ExifTag)ExifTag.YCbCrSubsampling },
{ (ExifTag)ExifTag.CFARepeatPatternDim },
{ (ExifTag)ExifTag.IntergraphPacketData },
{ (ExifTag)ExifTag.ISOSpeedRatings },
{ (ExifTag)ExifTag.SubjectArea },
{ (ExifTag)ExifTag.SubjectLocation }
};
public static TheoryData<ExifTag> SignedRationalTags => new()
{
{ ExifTag.ShutterSpeedValue },
{ ExifTag.BrightnessValue },
{ ExifTag.ExposureBiasValue },
{ ExifTag.AmbientTemperature },
{ ExifTag.WaterDepth },
{ ExifTag.CameraElevationAngle }
{ (ExifTag)ExifTag.ShutterSpeedValue },
{ (ExifTag)ExifTag.BrightnessValue },
{ (ExifTag)ExifTag.ExposureBiasValue },
{ (ExifTag)ExifTag.AmbientTemperature },
{ (ExifTag)ExifTag.WaterDepth },
{ (ExifTag)ExifTag.CameraElevationAngle }
};
public static TheoryData<ExifTag> SignedRationalArrayTags => new()
{
{ ExifTag.Decode }
{ (ExifTag)ExifTag.Decode }
};
public static TheoryData<ExifTag> SignedShortArrayTags => new()
{
{ ExifTag.TimeZoneOffset }
{ (ExifTag)ExifTag.TimeZoneOffset }
};
public static TheoryData<ExifTag> StringTags => new()
{
{ ExifTag.ImageDescription },
{ ExifTag.Make },
{ ExifTag.Model },
{ ExifTag.Software },
{ ExifTag.DateTime },
{ ExifTag.Artist },
{ ExifTag.HostComputer },
{ ExifTag.Copyright },
{ ExifTag.DocumentName },
{ ExifTag.PageName },
{ ExifTag.InkNames },
{ ExifTag.TargetPrinter },
{ ExifTag.ImageID },
{ ExifTag.MDLabName },
{ ExifTag.MDSampleInfo },
{ ExifTag.MDPrepDate },
{ ExifTag.MDPrepTime },
{ ExifTag.MDFileUnits },
{ ExifTag.SEMInfo },
{ ExifTag.SpectralSensitivity },
{ ExifTag.DateTimeOriginal },
{ ExifTag.DateTimeDigitized },
{ ExifTag.SubsecTime },
{ ExifTag.SubsecTimeOriginal },
{ ExifTag.SubsecTimeDigitized },
{ ExifTag.RelatedSoundFile },
{ ExifTag.FaxSubaddress },
{ ExifTag.OffsetTime },
{ ExifTag.OffsetTimeOriginal },
{ ExifTag.OffsetTimeDigitized },
{ ExifTag.SecurityClassification },
{ ExifTag.ImageHistory },
{ ExifTag.ImageUniqueID },
{ ExifTag.OwnerName },
{ ExifTag.SerialNumber },
{ ExifTag.LensMake },
{ ExifTag.LensModel },
{ ExifTag.LensSerialNumber },
{ ExifTag.GDALMetadata },
{ ExifTag.GDALNoData },
{ ExifTag.GPSLatitudeRef },
{ ExifTag.GPSLongitudeRef },
{ ExifTag.GPSSatellites },
{ ExifTag.GPSStatus },
{ ExifTag.GPSMeasureMode },
{ ExifTag.GPSSpeedRef },
{ ExifTag.GPSTrackRef },
{ ExifTag.GPSImgDirectionRef },
{ ExifTag.GPSMapDatum },
{ ExifTag.GPSDestLatitudeRef },
{ ExifTag.GPSDestLongitudeRef },
{ ExifTag.GPSDestBearingRef },
{ ExifTag.GPSDestDistanceRef },
{ ExifTag.GPSDateStamp },
{ (ExifTag)ExifTag.ImageDescription },
{ (ExifTag)ExifTag.Make },
{ (ExifTag)ExifTag.Model },
{ (ExifTag)ExifTag.Software },
{ (ExifTag)ExifTag.DateTime },
{ (ExifTag)ExifTag.Artist },
{ (ExifTag)ExifTag.HostComputer },
{ (ExifTag)ExifTag.Copyright },
{ (ExifTag)ExifTag.DocumentName },
{ (ExifTag)ExifTag.PageName },
{ (ExifTag)ExifTag.InkNames },
{ (ExifTag)ExifTag.TargetPrinter },
{ (ExifTag)ExifTag.ImageID },
{ (ExifTag)ExifTag.MDLabName },
{ (ExifTag)ExifTag.MDSampleInfo },
{ (ExifTag)ExifTag.MDPrepDate },
{ (ExifTag)ExifTag.MDPrepTime },
{ (ExifTag)ExifTag.MDFileUnits },
{ (ExifTag)ExifTag.SEMInfo },
{ (ExifTag)ExifTag.SpectralSensitivity },
{ (ExifTag)ExifTag.DateTimeOriginal },
{ (ExifTag)ExifTag.DateTimeDigitized },
{ (ExifTag)ExifTag.SubsecTime },
{ (ExifTag)ExifTag.SubsecTimeOriginal },
{ (ExifTag)ExifTag.SubsecTimeDigitized },
{ (ExifTag)ExifTag.RelatedSoundFile },
{ (ExifTag)ExifTag.FaxSubaddress },
{ (ExifTag)ExifTag.OffsetTime },
{ (ExifTag)ExifTag.OffsetTimeOriginal },
{ (ExifTag)ExifTag.OffsetTimeDigitized },
{ (ExifTag)ExifTag.SecurityClassification },
{ (ExifTag)ExifTag.ImageHistory },
{ (ExifTag)ExifTag.ImageUniqueID },
{ (ExifTag)ExifTag.OwnerName },
{ (ExifTag)ExifTag.SerialNumber },
{ (ExifTag)ExifTag.LensMake },
{ (ExifTag)ExifTag.LensModel },
{ (ExifTag)ExifTag.LensSerialNumber },
{ (ExifTag)ExifTag.GDALMetadata },
{ (ExifTag)ExifTag.GDALNoData },
{ (ExifTag)ExifTag.GPSLatitudeRef },
{ (ExifTag)ExifTag.GPSLongitudeRef },
{ (ExifTag)ExifTag.GPSSatellites },
{ (ExifTag)ExifTag.GPSStatus },
{ (ExifTag)ExifTag.GPSMeasureMode },
{ (ExifTag)ExifTag.GPSSpeedRef },
{ (ExifTag)ExifTag.GPSTrackRef },
{ (ExifTag)ExifTag.GPSImgDirectionRef },
{ (ExifTag)ExifTag.GPSMapDatum },
{ (ExifTag)ExifTag.GPSDestLatitudeRef },
{ (ExifTag)ExifTag.GPSDestLongitudeRef },
{ (ExifTag)ExifTag.GPSDestBearingRef },
{ (ExifTag)ExifTag.GPSDestDistanceRef },
{ (ExifTag)ExifTag.GPSDateStamp },
};
public static TheoryData<ExifTag> UndefinedTags => new()
{
{ ExifTag.FileSource },
{ ExifTag.SceneType }
{ (ExifTag)ExifTag.FileSource },
{ (ExifTag)ExifTag.SceneType }
};
public static TheoryData<ExifTag> UndefinedArrayTags => new()
{
{ ExifTag.JPEGTables },
{ ExifTag.OECF },
{ ExifTag.ExifVersion },
{ ExifTag.ComponentsConfiguration },
{ ExifTag.MakerNote },
{ ExifTag.FlashpixVersion },
{ ExifTag.SpatialFrequencyResponse },
{ ExifTag.SpatialFrequencyResponse2 },
{ ExifTag.Noise },
{ ExifTag.CFAPattern },
{ ExifTag.DeviceSettingDescription },
{ ExifTag.ImageSourceData },
{ (ExifTag)ExifTag.JPEGTables },
{ (ExifTag)ExifTag.OECF },
{ (ExifTag)ExifTag.ExifVersion },
{ (ExifTag)ExifTag.ComponentsConfiguration },
{ (ExifTag)ExifTag.MakerNote },
{ (ExifTag)ExifTag.FlashpixVersion },
{ (ExifTag)ExifTag.SpatialFrequencyResponse },
{ (ExifTag)ExifTag.SpatialFrequencyResponse2 },
{ (ExifTag)ExifTag.Noise },
{ (ExifTag)ExifTag.CFAPattern },
{ (ExifTag)ExifTag.DeviceSettingDescription },
{ (ExifTag)ExifTag.ImageSourceData },
};
public static TheoryData<ExifTag> EncodedStringTags => new()
{
{ ExifTag.UserComment },
{ ExifTag.GPSProcessingMethod },
{ ExifTag.GPSAreaInformation }
{ (ExifTag)ExifTag.UserComment },
{ (ExifTag)ExifTag.GPSProcessingMethod },
{ (ExifTag)ExifTag.GPSAreaInformation }
};
public static TheoryData<ExifTag> Ucs2StringTags => new()
{
{ ExifTag.XPTitle },
{ ExifTag.XPComment },
{ ExifTag.XPAuthor },
{ ExifTag.XPKeywords },
{ ExifTag.XPSubject },
{ (ExifTag)ExifTag.XPTitle },
{ (ExifTag)ExifTag.XPComment },
{ (ExifTag)ExifTag.XPAuthor },
{ (ExifTag)ExifTag.XPKeywords },
{ (ExifTag)ExifTag.XPSubject },
};
[Theory]

2
tests/ImageSharp.Tests/PixelFormats/L8Tests.cs

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats;
public class L8Tests
{
public static readonly TheoryData<byte> LuminanceData
= new() { 0, 1, 2, 3, 5, 13, 31, 71, 73, 79, 83, 109, 127, 128, 131, 199, 250, 251, 254, 255 };
= new() { (byte)0, (byte)1, (byte)2, (byte)3, (byte)5, (byte)13, (byte)31, (byte)71, (byte)73, (byte)79, (byte)83, (byte)109, (byte)127, (byte)128, (byte)131, (byte)199, (byte)250, (byte)251, (byte)254, (byte)255 };
[Theory]
[InlineData(0)]

2
tests/ImageSharp.Tests/PixelFormats/La16Tests.cs

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats;
public class La16Tests
{
public static readonly TheoryData<byte> LuminanceData
= new() { 0, 1, 2, 3, 5, 13, 31, 71, 73, 79, 83, 109, 127, 128, 131, 199, 250, 251, 254, 255 };
= new() { (byte)0, (byte)1, (byte)2, (byte)3, (byte)5, (byte)13, (byte)31, (byte)71, (byte)73, (byte)79, (byte)83, (byte)109, (byte)127, (byte)128, (byte)131, (byte)199, (byte)250, (byte)251, (byte)254, (byte)255 };
[Theory]
[InlineData(0, 0)]

1
tests/ImageSharp.Tests/PixelFormats/PixelOperations/Generated/PixelOperationsTests.Specialized.Generated.cs

@ -5,7 +5,6 @@
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations;

67
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

@ -10,7 +10,6 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Common;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations;
@ -313,38 +312,40 @@ public abstract class PixelOperationsTests<TPixel> : MeasureFixture
(s, d) => this.Operations.ToVector4(this.Configuration, s, d.GetSpan()));
}
public static readonly TheoryData<object> Generic_To_Data = new()
{
new TestPixel<A8>(),
new TestPixel<Abgr32>(),
new TestPixel<Argb32>(),
new TestPixel<Bgr24>(),
new TestPixel<Bgr565>(),
new TestPixel<Bgra32>(),
new TestPixel<Bgra4444>(),
new TestPixel<Bgra5551>(),
new TestPixel<Byte4>(),
new TestPixel<HalfSingle>(),
new TestPixel<HalfVector2>(),
new TestPixel<HalfVector4>(),
new TestPixel<L16>(),
new TestPixel<L8>(),
new TestPixel<La16>(),
new TestPixel<La32>(),
new TestPixel<NormalizedByte2>(),
new TestPixel<NormalizedByte4>(),
new TestPixel<NormalizedShort2>(),
new TestPixel<NormalizedShort4>(),
new TestPixel<Rg32>(),
new TestPixel<Rgb24>(),
new TestPixel<Rgb48>(),
new TestPixel<Rgba1010102>(),
new TestPixel<Rgba32>(),
new TestPixel<Rgba64>(),
new TestPixel<RgbaVector>(),
new TestPixel<Short2>(),
new TestPixel<Short4>(),
};
public static readonly TheoryData<object> Generic_To_Data = new(
new object[]
{
new TestPixel<A8>(),
new TestPixel<Abgr32>(),
new TestPixel<Argb32>(),
new TestPixel<Bgr24>(),
new TestPixel<Bgr565>(),
new TestPixel<Bgra32>(),
new TestPixel<Bgra4444>(),
new TestPixel<Bgra5551>(),
new TestPixel<Byte4>(),
new TestPixel<HalfSingle>(),
new TestPixel<HalfVector2>(),
new TestPixel<HalfVector4>(),
new TestPixel<L16>(),
new TestPixel<L8>(),
new TestPixel<La16>(),
new TestPixel<La32>(),
new TestPixel<NormalizedByte2>(),
new TestPixel<NormalizedByte4>(),
new TestPixel<NormalizedShort2>(),
new TestPixel<NormalizedShort4>(),
new TestPixel<Rg32>(),
new TestPixel<Rgb24>(),
new TestPixel<Rgb48>(),
new TestPixel<Rgba1010102>(),
new TestPixel<Rgba32>(),
new TestPixel<Rgba64>(),
new TestPixel<RgbaVector>(),
new TestPixel<Short2>(),
new TestPixel<Short4>(),
}
);
[Theory]
[MemberData(nameof(Generic_To_Data))]

2
tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs

@ -8,7 +8,7 @@ using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Convolution;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution;

4
tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs

@ -43,8 +43,8 @@ public class DitherTests
public static readonly TheoryData<IDither> DefaultInstanceDitherers
= new()
{
default(ErrorDither),
default(OrderedDither)
(IDither)default(ErrorDither),
(IDither)default(OrderedDither)
};
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05f);

126
tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs

@ -74,79 +74,79 @@ public class QuantizerTests
= new()
{
// Known uses error diffusion by default.
KnownQuantizers.Hexadecatree,
KnownQuantizers.WebSafe,
KnownQuantizers.Werner,
KnownQuantizers.Wu,
new HexadecatreeQuantizer(NoDitherOptions),
new WebSafePaletteQuantizer(NoDitherOptions),
new WernerPaletteQuantizer(NoDitherOptions),
new WuQuantizer(NoDitherOptions),
new HexadecatreeQuantizer(OrderedDitherOptions),
new WebSafePaletteQuantizer(OrderedDitherOptions),
new WernerPaletteQuantizer(OrderedDitherOptions),
new WuQuantizer(OrderedDitherOptions)
(IQuantizer)KnownQuantizers.Hexadecatree,
(IQuantizer)KnownQuantizers.WebSafe,
(IQuantizer)KnownQuantizers.Werner,
(IQuantizer)KnownQuantizers.Wu,
(IQuantizer)new HexadecatreeQuantizer(NoDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(NoDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(NoDitherOptions),
(IQuantizer)new WuQuantizer(NoDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(OrderedDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WuQuantizer(OrderedDitherOptions)
};
public static readonly TheoryData<IQuantizer> DitherScaleQuantizers
= new()
{
new HexadecatreeQuantizer(Diffuser0_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_ScaleDitherOptions),
new WuQuantizer(Diffuser0_ScaleDitherOptions),
new HexadecatreeQuantizer(Diffuser0_25_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
new WuQuantizer(Diffuser0_25_ScaleDitherOptions),
new HexadecatreeQuantizer(Diffuser0_5_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
new WuQuantizer(Diffuser0_5_ScaleDitherOptions),
new HexadecatreeQuantizer(Diffuser0_75_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
new WuQuantizer(Diffuser0_75_ScaleDitherOptions),
new HexadecatreeQuantizer(DiffuserDitherOptions),
new WebSafePaletteQuantizer(DiffuserDitherOptions),
new WernerPaletteQuantizer(DiffuserDitherOptions),
new WuQuantizer(DiffuserDitherOptions),
new HexadecatreeQuantizer(Ordered0_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_ScaleDitherOptions),
new WuQuantizer(Ordered0_ScaleDitherOptions),
new HexadecatreeQuantizer(Ordered0_25_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_25_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_25_ScaleDitherOptions),
new WuQuantizer(Ordered0_25_ScaleDitherOptions),
new HexadecatreeQuantizer(Ordered0_5_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_5_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_5_ScaleDitherOptions),
new WuQuantizer(Ordered0_5_ScaleDitherOptions),
new HexadecatreeQuantizer(Ordered0_75_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_75_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_75_ScaleDitherOptions),
new WuQuantizer(Ordered0_75_ScaleDitherOptions),
new HexadecatreeQuantizer(OrderedDitherOptions),
new WebSafePaletteQuantizer(OrderedDitherOptions),
new WernerPaletteQuantizer(OrderedDitherOptions),
new WuQuantizer(OrderedDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(DiffuserDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(DiffuserDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(DiffuserDitherOptions),
(IQuantizer)new WuQuantizer(DiffuserDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(OrderedDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WuQuantizer(OrderedDitherOptions),
};
public static readonly TheoryData<IDither> DefaultInstanceDitherers
= new()
{
default(ErrorDither),
default(OrderedDither)
(IDither)default(ErrorDither),
(IDither)default(OrderedDither)
};
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05F);

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs

@ -7,7 +7,6 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Processing.Transforms;

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/ProjectiveTransformTests.cs

@ -9,7 +9,6 @@ using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms;

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs

@ -4,7 +4,6 @@
using System.Text;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms;

2
tests/ImageSharp.Tests/Processing/Processors/Transforms/RotateTests.cs

@ -15,7 +15,7 @@ public class RotateTests
public static readonly TheoryData<float> RotateAngles
= new()
{
50, -50, 170, -170
50f, -50f, 170f, -170f
};
public static readonly TheoryData<RotateMode> RotateEnumValues

1
tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Processing;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks;

1
tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks;

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

@ -3,6 +3,7 @@
using System.Reflection;
using Xunit.Sdk;
using Xunit.v3;
namespace SixLabors.ImageSharp.Tests;
@ -42,11 +43,22 @@ public abstract class ImageDataAttributeBase : DataAttribute
/// </summary>
public Type MemberType { get; set; }
/// <inheritdoc/>
public override bool SupportsDiscoveryEnumeration() => true;
/// <inheritdoc/>
public override ValueTask<IReadOnlyCollection<ITheoryDataRow?>> GetData(MethodInfo testMethod, DisposalTracker disposalTracker)
{
IEnumerable<object[]> rows = this.GetDataRows(testMethod);
IReadOnlyCollection<ITheoryDataRow?> result = rows.Select(row => ConvertDataRow(row)).ToList();
return new ValueTask<IReadOnlyCollection<ITheoryDataRow?>>(result);
}
/// <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)
private IEnumerable<object[]> GetDataRows(MethodInfo testMethod)
{
IEnumerable<object[]> addedRows = Enumerable.Empty<object[]>().ToArray();
if (!string.IsNullOrWhiteSpace(this.MemberName))
@ -59,11 +71,14 @@ public abstract class ImageDataAttributeBase : DataAttribute
object obj = accessor();
if (obj is IEnumerable<object> memberItems)
{
addedRows = memberItems.Select(x => x as object[]);
if (addedRows.Any(x => x == null))
// In xunit.v3, TheoryData<T...> yields ITheoryDataRow, not object[].
// Call GetData() to unpack the row's values.
addedRows = memberItems.Select(x =>
{
addedRows = memberItems.Select(x => new[] { x });
}
if (x is ITheoryDataRow row) return row.GetData();
if (x is object[] arr) return arr;
return new[] { x };
});
}
}
}

41
tests/ImageSharp.Tests/TestUtilities/BasicSerializer.cs

@ -2,7 +2,7 @@
// Licensed under the Six Labors Split License.
using System.ComponentModel;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.TestUtilities;
@ -13,8 +13,11 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities;
/// </summary>
internal class BasicSerializer : IXunitSerializationInfo
{
private readonly Dictionary<string, string> map = [];
// Stores (string representation, type) per key.
private readonly Dictionary<string, (string str, Type type)> map = [];
// Separator between key, type AQN and value in the dump format.
// ':' is safe because AssemblyQualifiedName and converter output don't contain it.
public const char Separator = ':';
private string DumpToString(Type type)
@ -22,14 +25,16 @@ internal class BasicSerializer : IXunitSerializationInfo
using MemoryStream ms = new();
using StreamWriter writer = new(ms);
writer.WriteLine(type.FullName);
foreach (KeyValuePair<string, string> kv in this.map)
foreach (KeyValuePair<string, (string str, Type t)> kv in this.map)
{
writer.WriteLine($"{kv.Key}{Separator}{kv.Value}");
// Format: key:TypeAssemblyQualifiedName:value
writer.WriteLine(
$"{kv.Key}{Separator}{kv.Value.t.AssemblyQualifiedName}{Separator}{kv.Value.str}"
);
}
writer.Flush();
byte[] data = ms.ToArray();
return Convert.ToBase64String(data);
return Convert.ToBase64String(ms.ToArray());
}
private Type LoadDump(string dump)
@ -41,8 +46,13 @@ internal class BasicSerializer : IXunitSerializationInfo
Type type = Type.GetType(reader.ReadLine());
for (string s = reader.ReadLine(); s != null; s = reader.ReadLine())
{
string[] kv = s.Split(Separator);
this.map[kv[0]] = kv[1];
// Format: key:TypeAssemblyQualifiedName:value
string[] parts = s.Split(Separator, 3);
if (parts.Length == 3)
{
Type valueType = Type.GetType(parts[1]) ?? typeof(string);
this.map[parts[0]] = (parts[2], valueType);
}
}
return type;
@ -66,6 +76,7 @@ internal class BasicSerializer : IXunitSerializationInfo
return result;
}
/// <inheritdoc/>
public void AddValue(string key, object value, Type type = null)
{
Guard.NotNull(key, nameof(key));
@ -75,21 +86,19 @@ internal class BasicSerializer : IXunitSerializationInfo
}
type ??= value.GetType();
this.map[key] = TypeDescriptor.GetConverter(type).ConvertToInvariantString(value);
this.map[key] = (TypeDescriptor.GetConverter(type).ConvertToInvariantString(value), type);
}
public object GetValue(string key, Type type)
/// <inheritdoc/>
public object GetValue(string key)
{
Guard.NotNull(key, nameof(key));
if (!this.map.TryGetValue(key, out string str))
if (!this.map.TryGetValue(key, out (string str, Type type) entry))
{
return type.IsValueType ? Activator.CreateInstance(type) : null;
return null;
}
return TypeDescriptor.GetConverter(type).ConvertFromInvariantString(str);
return TypeDescriptor.GetConverter(entry.type).ConvertFromInvariantString(entry.str);
}
public T GetValue<T>(string key) => (T)this.GetValue(key, typeof(T));
}

2
tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs

@ -4,7 +4,7 @@
using System.Diagnostics;
using System.Globalization;
using Microsoft.DotNet.RemoteExecutor;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.TestUtilities;

2
tests/ImageSharp.Tests/TestUtilities/ImageProviders/BasicTestPatternProvider.cs

@ -2,7 +2,7 @@
// Licensed under the Six Labors Split License.
using System.Numerics;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests;

2
tests/ImageSharp.Tests/TestUtilities/ImageProviders/BlankProvider.cs

@ -2,8 +2,8 @@
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Sdk;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests;

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

@ -6,8 +6,8 @@ using System.Reflection;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Sdk;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests;

2
tests/ImageSharp.Tests/TestUtilities/ImageProviders/MemberMethodProvider.cs

@ -3,7 +3,7 @@
using System.Reflection;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests;

2
tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs

@ -3,7 +3,7 @@
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests;

2
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs

@ -7,8 +7,8 @@ using Castle.Core.Internal;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit.Sdk;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests;

2
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs

@ -4,7 +4,7 @@
using System.Numerics;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests;

1
tests/ImageSharp.Tests/TestUtilities/MeasureFixture.cs

@ -3,7 +3,6 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests;

14
tests/ImageSharp.Tests/TestUtilities/SixLaborsXunitTestFramework.cs

@ -3,22 +3,16 @@
using BenchmarkDotNet.Environments;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
using Xunit.Sdk;
using Xunit.v3;
[assembly: Xunit.TestFramework(SixLaborsXunitTestFramework.Type, SixLaborsXunitTestFramework.Assembly)]
[assembly: Xunit.TestFramework(typeof(SixLaborsXunitTestFramework))]
namespace SixLabors.ImageSharp.Tests.TestUtilities;
public class SixLaborsXunitTestFramework : XunitTestFramework
{
public const string Type = "SixLabors.ImageSharp.Tests.TestUtilities.SixLaborsXunitTestFramework";
public const string Assembly = "SixLabors.ImageSharp.Tests";
public SixLaborsXunitTestFramework(IMessageSink messageSink)
: base(messageSink)
public SixLaborsXunitTestFramework()
{
DiagnosticMessage message = new(HostEnvironmentInfo.GetInformation());
messageSink.OnMessage(message);
Console.Error.WriteLine(HostEnvironmentInfo.GetInformation());
}
}

60
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs

@ -15,11 +15,14 @@ public static partial class TestEnvironment
private const string ActualOutputDirectoryRelativePath = @"tests\Images\ActualOutput";
private const string ReferenceOutputDirectoryRelativePath = @"tests\Images\External\ReferenceOutput";
private const string ReferenceOutputDirectoryRelativePath =
@"tests\Images\External\ReferenceOutput";
private const string ToolsDirectoryRelativePath = @"tests\Images\External\tools";
private static readonly Lazy<string> SolutionDirectoryFullPathLazy = new(GetSolutionDirectoryFullPathImpl);
private static readonly Lazy<string> SolutionDirectoryFullPathLazy = new(
GetSolutionDirectoryFullPathImpl
);
private static readonly Lazy<Version> NetCoreVersionLazy = new(GetNetCoreVersion);
@ -52,7 +55,9 @@ public static partial class TestEnvironment
internal static string SolutionDirectoryFullPath => SolutionDirectoryFullPathLazy.Value;
private static readonly FileInfo TestAssemblyFile = new(typeof(TestEnvironment).GetTypeInfo().Assembly.Location);
private static readonly FileInfo TestAssemblyFile = new(
typeof(TestEnvironment).GetTypeInfo().Assembly.Location
);
private static string GetSolutionDirectoryFullPathImpl()
{
@ -68,12 +73,15 @@ public static partial class TestEnvironment
{
throw new DirectoryNotFoundException(
$"Unable to find ImageSharp solution directory from {TestAssemblyFile} because of {ex.GetType().Name}!",
ex);
ex
);
}
if (directory == null)
{
throw new DirectoryNotFoundException($"Unable to find ImageSharp solution directory from {TestAssemblyFile}!");
throw new DirectoryNotFoundException(
$"Unable to find ImageSharp solution directory from {TestAssemblyFile}!"
);
}
}
@ -82,7 +90,7 @@ public static partial class TestEnvironment
private static string GetFullPath(string relativePath) =>
Path.Combine(SolutionDirectoryFullPath, relativePath)
.Replace('\\', Path.DirectorySeparatorChar);
.Replace('\\', Path.DirectorySeparatorChar);
/// <summary>
/// Gets the correct full path to the Input Images directory.
@ -92,17 +100,21 @@ public static partial class TestEnvironment
/// <summary>
/// Gets the correct full path to the Actual Output directory. (To be written to by the test cases.)
/// </summary>
internal static string ActualOutputDirectoryFullPath => GetFullPath(ActualOutputDirectoryRelativePath);
internal static string ActualOutputDirectoryFullPath =>
GetFullPath(ActualOutputDirectoryRelativePath);
/// <summary>
/// Gets the correct full path to the Expected Output directory. (To compare the test results to.)
/// </summary>
internal static string ReferenceOutputDirectoryFullPath => GetFullPath(ReferenceOutputDirectoryRelativePath);
internal static string ReferenceOutputDirectoryFullPath =>
GetFullPath(ReferenceOutputDirectoryRelativePath);
internal static string ToolsDirectoryFullPath => GetFullPath(ToolsDirectoryRelativePath);
internal static string GetReferenceOutputFileName(string actualOutputFileName) =>
actualOutputFileName.Replace("ActualOutput", @"External\ReferenceOutput").Replace('\\', Path.DirectorySeparatorChar);
actualOutputFileName
.Replace("ActualOutput", @"External\ReferenceOutput")
.Replace('\\', Path.DirectorySeparatorChar);
internal static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
@ -110,7 +122,7 @@ public static partial class TestEnvironment
internal static bool IsMono => Type.GetType("Mono.Runtime") != null; // https://stackoverflow.com/a/721194
internal static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
internal static bool Is64BitProcess => IntPtr.Size == 8;
@ -123,9 +135,7 @@ public static partial class TestEnvironment
/// <summary>
/// A dummy operation to enforce the execution of the static constructor.
/// </summary>
internal static void EnsureSharedInitializersDone()
{
}
internal static void EnsureSharedInitializersDone() { }
/// <summary>
/// Creates the image output directory.
@ -164,8 +174,10 @@ public static partial class TestEnvironment
return;
}
string remoteExecutorConfigPath =
Path.Combine(TestAssemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe.config");
string remoteExecutorConfigPath = Path.Combine(
TestAssemblyFile.DirectoryName,
"Microsoft.DotNet.RemoteExecutor.exe.config"
);
if (File.Exists(remoteExecutorConfigPath))
{
@ -196,11 +208,15 @@ public static partial class TestEnvironment
string windowsSdksDir = Path.Combine(
Environment.GetEnvironmentVariable("PROGRAMFILES(x86)"),
"Microsoft SDKs",
"Windows");
"Windows"
);
FileInfo corFlagsFile = Find(new DirectoryInfo(windowsSdksDir), "CorFlags.exe");
string remoteExecutorPath = Path.Combine(TestAssemblyFile.DirectoryName, "Microsoft.DotNet.RemoteExecutor.exe");
string remoteExecutorPath = Path.Combine(
TestAssemblyFile.DirectoryName,
"Microsoft.DotNet.RemoteExecutor.exe"
);
string remoteExecutorTmpPath = $"{remoteExecutorPath}._tmp";
@ -220,7 +236,7 @@ public static partial class TestEnvironment
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
RedirectStandardError = true,
};
using Process proc = Process.Start(si);
@ -231,7 +247,8 @@ public static partial class TestEnvironment
if (proc.ExitCode != 0)
{
throw new Exception(
$@"Failed to run {si.FileName} {si.Arguments}:\n STDOUT: {standardOutput}\n STDERR: {standardError}");
$@"Failed to run {si.FileName} {si.Arguments}:\n STDOUT: {standardOutput}\n STDERR: {standardError}"
);
}
File.Delete(remoteExecutorPath);
@ -265,7 +282,10 @@ public static partial class TestEnvironment
private static Version GetNetCoreVersion()
{
Assembly assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
string[] assemblyPath = assembly.Location.Split(['/', '\\'], StringSplitOptions.RemoveEmptyEntries);
string[] assemblyPath = assembly.Location.Split(
['/', '\\'],
StringSplitOptions.RemoveEmptyEntries
);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
{

2
tests/ImageSharp.Tests/TestUtilities/TestPixel.cs

@ -3,7 +3,7 @@
using System.Numerics;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.TestUtilities;

3
tests/ImageSharp.Tests/TestUtilities/TestType.cs

@ -1,7 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.TestUtilities;

2
tests/ImageSharp.Tests/TestUtilities/TestVector4.cs

@ -2,7 +2,7 @@
// Licensed under the Six Labors Split License.
using System.Numerics;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.TestUtilities;

24
tests/ImageSharp.Tests/TestUtilities/Tests/BasicSerializerTests.cs

@ -2,7 +2,7 @@
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests;
@ -18,16 +18,16 @@ public class BasicSerializerTests
public virtual void Deserialize(IXunitSerializationInfo info)
{
info.AddValue(nameof(this.Length), this.Length);
info.AddValue(nameof(this.Name), this.Name);
info.AddValue(nameof(this.Lives), this.Lives);
this.Length = info.GetValue<double>(nameof(this.Length));
this.Name = info.GetValue<string>(nameof(this.Name));
this.Lives = info.GetValue<int>(nameof(this.Lives));
}
public virtual void Serialize(IXunitSerializationInfo info)
{
this.Length = info.GetValue<double>(nameof(this.Length));
this.Name = info.GetValue<string>(nameof(this.Name));
this.Lives = info.GetValue<int>(nameof(this.Lives));
info.AddValue(nameof(this.Length), this.Length);
info.AddValue(nameof(this.Name), this.Name);
info.AddValue(nameof(this.Lives), this.Lives);
}
}
@ -37,8 +37,8 @@ public class BasicSerializerTests
public override void Deserialize(IXunitSerializationInfo info)
{
this.Strength = info.GetValue<double>(nameof(this.Strength));
base.Deserialize(info);
this.Strength = info.GetValue<double>(nameof(this.Strength));
}
public override void Serialize(IXunitSerializationInfo info)
@ -51,7 +51,13 @@ public class BasicSerializerTests
[Fact]
public void SerializeDeserialize_ShouldPreserveValues()
{
DerivedObj obj = new() { Length = 123.1, Name = "Lol123!", Lives = 7, Strength = 4.8 };
DerivedObj obj = new()
{
Length = 123.1,
Name = "Lol123!",
Lives = 7,
Strength = 4.8,
};
string str = BasicSerializer.Serialize(obj);
BaseObj mirrorBase = BasicSerializer.Deserialize<BaseObj>(str);

2
tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs

@ -4,8 +4,8 @@
using System.Numerics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
using Xunit.Abstractions;
using Aes = System.Runtime.Intrinsics.X86.Aes;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests;

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

@ -5,7 +5,6 @@ using Moq;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests;

1
tests/ImageSharp.Tests/TestUtilities/Tests/MagickReferenceCodecTests.cs

@ -5,7 +5,6 @@ using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests;

1
tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests;

1
tests/ImageSharp.Tests/TestUtilities/Tests/SystemDrawingReferenceCodecTests.cs

@ -8,7 +8,6 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests;

54
tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs

@ -2,22 +2,19 @@
// Licensed under the Six Labors Split License.
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests;
public class TestEnvironmentTests
{
public TestEnvironmentTests(ITestOutputHelper output)
=> this.Output = output;
public TestEnvironmentTests(ITestOutputHelper output) => this.Output = output;
private ITestOutputHelper Output { get; }
@ -28,21 +25,24 @@ public class TestEnvironmentTests
}
[Fact]
public void SolutionDirectoryFullPath()
=> this.CheckPath(TestEnvironment.SolutionDirectoryFullPath);
public void SolutionDirectoryFullPath() =>
this.CheckPath(TestEnvironment.SolutionDirectoryFullPath);
[Fact]
public void InputImagesDirectoryFullPath()
=> this.CheckPath(TestEnvironment.InputImagesDirectoryFullPath);
public void InputImagesDirectoryFullPath() =>
this.CheckPath(TestEnvironment.InputImagesDirectoryFullPath);
[Fact]
public void ExpectedOutputDirectoryFullPath()
=> this.CheckPath(TestEnvironment.ReferenceOutputDirectoryFullPath);
public void ExpectedOutputDirectoryFullPath() =>
this.CheckPath(TestEnvironment.ReferenceOutputDirectoryFullPath);
[Fact]
public void GetReferenceOutputFileName()
{
string actual = Path.Combine(TestEnvironment.ActualOutputDirectoryFullPath, @"foo\bar\lol.jpeg");
string actual = Path.Combine(
TestEnvironment.ActualOutputDirectoryFullPath,
@"foo\bar\lol.jpeg"
);
string expected = TestEnvironment.GetReferenceOutputFileName(actual);
this.Output.WriteLine(expected);
@ -55,7 +55,10 @@ public class TestEnvironmentTests
[InlineData("lol/Baz.JPG", typeof(JpegEncoder))]
[InlineData("lol/Baz.gif", typeof(GifEncoder))]
[InlineData("lol/foobar.webp", typeof(WebpEncoder))]
public void GetReferenceEncoder_ReturnsCorrectEncoders_Windows(string fileName, Type expectedEncoderType)
public void GetReferenceEncoder_ReturnsCorrectEncoders_Windows(
string fileName,
Type expectedEncoderType
)
{
if (!TestEnvironment.IsWindows)
{
@ -72,7 +75,10 @@ public class TestEnvironmentTests
[InlineData("lol/Baz.JPG", typeof(JpegDecoder))]
[InlineData("lol/Baz.gif", typeof(GifDecoder))]
[InlineData("lol/foobar.webp", typeof(WebpDecoder))]
public void GetReferenceDecoder_ReturnsCorrectDecoders_Windows(string fileName, Type expectedDecoderType)
public void GetReferenceDecoder_ReturnsCorrectDecoders_Windows(
string fileName,
Type expectedDecoderType
)
{
if (!TestEnvironment.IsWindows)
{
@ -89,7 +95,10 @@ public class TestEnvironmentTests
[InlineData("lol/Baz.JPG", typeof(JpegEncoder))]
[InlineData("lol/Baz.gif", typeof(GifEncoder))]
[InlineData("lol/foobar.webp", typeof(WebpEncoder))]
public void GetReferenceEncoder_ReturnsCorrectEncoders_Linux(string fileName, Type expectedEncoderType)
public void GetReferenceEncoder_ReturnsCorrectEncoders_Linux(
string fileName,
Type expectedEncoderType
)
{
if (!TestEnvironment.IsLinux)
{
@ -106,7 +115,10 @@ public class TestEnvironmentTests
[InlineData("lol/Baz.JPG", typeof(JpegDecoder))]
[InlineData("lol/Baz.gif", typeof(GifDecoder))]
[InlineData("lol/foobar.webp", typeof(WebpDecoder))]
public void GetReferenceDecoder_ReturnsCorrectDecoders_Linux(string fileName, Type expectedDecoderType)
public void GetReferenceDecoder_ReturnsCorrectDecoders_Linux(
string fileName,
Type expectedDecoderType
)
{
if (!TestEnvironment.IsLinux)
{
@ -119,9 +131,13 @@ public class TestEnvironmentTests
// RemoteExecutor does not work with "dotnet xunit" used to run tests on 32 bit .NET Framework:
// https://github.com/SixLabors/ImageSharp/blob/381dff8640b721a34b1227c970fcf6ad6c5e3e72/ci-test.ps1#L30
public static bool IsNot32BitNetFramework = !TestEnvironment.IsFramework || TestEnvironment.Is64BitProcess;
public static bool IsNot32BitNetFramework =>
!TestEnvironment.IsFramework || TestEnvironment.Is64BitProcess;
[ConditionalFact(nameof(IsNot32BitNetFramework))]
[Fact(
Skip = "Not supported on 32-bit .NET Framework",
SkipUnless = nameof(IsNot32BitNetFramework)
)]
public void RemoteExecutor_FailingRemoteTestShouldFailLocalTest()
{
static void FailingCode()
@ -129,6 +145,8 @@ public class TestEnvironmentTests
Assert.False(true);
}
Assert.ThrowsAny<RemoteExecutionException>(() => RemoteExecutor.Invoke(FailingCode).Dispose());
Assert.ThrowsAny<RemoteExecutionException>(() =>
RemoteExecutor.Invoke(FailingCode).Dispose()
);
}
}

25
tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

@ -8,24 +8,27 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests;
public class TestImageProviderTests
{
public static readonly TheoryData<object> BasicData = new()
{
TestImageProvider<Rgba32>.Blank(10, 20),
TestImageProvider<HalfVector4>.Blank(10, 20),
};
public static readonly TheoryData<object> BasicData = new(
new object[]
{
TestImageProvider<Rgba32>.Blank(10, 20),
TestImageProvider<HalfVector4>.Blank(10, 20),
}
);
public static readonly TheoryData<object> FileData = new()
{
TestImageProvider<Rgba32>.File(TestImages.Bmp.Car),
TestImageProvider<HalfVector4>.File(TestImages.Bmp.F)
};
public static readonly TheoryData<object> FileData = new(
new object[]
{
TestImageProvider<Rgba32>.File(TestImages.Bmp.Car),
TestImageProvider<HalfVector4>.File(TestImages.Bmp.F),
}
);
public static string[] AllBmpFiles = [TestImages.Bmp.F, TestImages.Bmp.Bit8];

1
tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs

@ -5,7 +5,6 @@ using System.Numerics;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests;

13
tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalDiscovererException.cs

@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Microsoft.DotNet.XUnitExtensions
{
internal class ConditionalDiscovererException : Exception
{
public ConditionalDiscovererException(string message)
: base(message) { }
}
}

38
tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalFact.cs

@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.DotNet.XUnitExtensions;
using Xunit.Sdk;
namespace Xunit
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ConditionalFactAttribute : FactAttribute
{
[DynamicallyAccessedMembers(StaticReflectionConstants.ConditionalMemberKinds)]
public Type CalleeType { get; private set; }
public string[] ConditionMemberNames { get; private set; }
public ConditionalFactAttribute(
[DynamicallyAccessedMembers(StaticReflectionConstants.ConditionalMemberKinds)]
Type calleeType,
params string[] conditionMemberNames)
{
CalleeType = calleeType;
ConditionMemberNames = conditionMemberNames;
string skipReason = ConditionalTestDiscoverer.EvaluateSkipConditions(calleeType, conditionMemberNames);
if (skipReason != null)
Skip = skipReason;
}
[Obsolete(
"Use the overload that takes a Type parameter: ConditionalFact(typeof(MyClass), nameof(MyCondition)).")]
public ConditionalFactAttribute(params string[] conditionMemberNames)
{
ConditionMemberNames = conditionMemberNames;
}
}
}

146
tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalTestDiscoverer.cs

@ -0,0 +1,146 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using Xunit.Sdk;
namespace Microsoft.DotNet.XUnitExtensions
{
// Internal helper class for code common to conditional test discovery through
// [ConditionalFact] and [ConditionalTheory]
internal static class ConditionalTestDiscoverer
{
/// <summary>
/// Evaluates skip conditions given an explicit callee type and condition member names.
/// Used by attribute constructors in xunit v3 where discoverers are not needed.
/// </summary>
internal static string EvaluateSkipConditions(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type calleeType,
string[] conditionMemberNames
)
{
if (
calleeType == null
|| conditionMemberNames == null
|| conditionMemberNames.Length == 0
)
return null;
List<string> falseConditions = new(conditionMemberNames.Length);
foreach (string entry in conditionMemberNames)
{
if (string.IsNullOrWhiteSpace(entry))
continue;
Func<bool> conditionFunc = LookupConditionalMember(calleeType, entry);
if (conditionFunc == null)
throw new ConditionalDiscovererException(
GetFailedLookupString(entry, calleeType)
);
try
{
if (!conditionFunc())
falseConditions.Add(entry);
}
catch (Exception exc)
{
falseConditions.Add($"{entry} ({exc.GetType().Name})");
}
}
return falseConditions.Count > 0
? string.Format(
"Condition(s) not met: \"{0}\"",
string.Join("\", \"", falseConditions)
)
: null;
}
internal static string GetFailedLookupString(string name, Type type)
{
return $"An appropriate member '{name}' could not be found. "
+ $"The conditional method needs to be a static method, property, or field on the type {type} or any ancestor, "
+ "of any visibility, accepting zero arguments, and having a return type of Boolean.";
}
internal static Func<bool> LookupConditionalMember(Type t, string name)
{
if (t == null || name == null)
return null;
TypeInfo ti = t.GetTypeInfo();
MethodInfo mi = ti.GetDeclaredMethod(name);
if (
mi != null
&& mi.IsStatic
&& mi.GetParameters().Length == 0
&& mi.ReturnType == typeof(bool)
)
return () => (bool)mi.Invoke(null, null);
PropertyInfo pi = ti.GetDeclaredProperty(name);
if (
pi != null
&& pi.PropertyType == typeof(bool)
&& pi.GetMethod != null
&& pi.GetMethod.IsStatic
&& pi.GetMethod.GetParameters().Length == 0
)
return () => (bool)pi.GetValue(null);
FieldInfo fi = ti.GetDeclaredField(name);
if (fi != null && fi.FieldType == typeof(bool) && fi.IsStatic)
return () => (bool)fi.GetValue(null);
return LookupConditionalMember(ti.BaseType, name);
}
internal static bool CheckInputToSkipExecution(
object[] conditionArguments,
ref Type calleeType,
ref string[] conditionMemberNames,
object testMethod = null
)
{
// A null or empty list of conditionArguments is treated as "no conditions".
// and the test cases will be executed.
// Example: [ConditionalClass()]
if (conditionArguments == null || conditionArguments.Length == 0)
return true;
calleeType = conditionArguments[0] as Type;
if (calleeType != null)
{
if (conditionArguments.Length < 2)
{
// [ConditionalFact(typeof(x))] no provided methods.
return true;
}
// [ConditionalFact(typeof(x), "MethodName")]
conditionMemberNames = conditionArguments[1] as string[];
}
else
{
// For [ConditionalClass], unable to get the Type info. All test cases will be executed.
if (testMethod == null)
return true;
// [ConditionalFact("MethodName")]
conditionMemberNames = conditionArguments[0] as string[];
}
// [ConditionalFact((string[]) null)]
if (conditionMemberNames == null || conditionMemberNames.Count() == 0)
return true;
return false;
}
}
}

42
tests/ImageSharp.Tests/TestUtilities/XUnit/ConditionalTheory.cs

@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.DotNet.XUnitExtensions;
using Xunit.Sdk;
namespace Xunit
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ConditionalTheoryAttribute : TheoryAttribute
{
[DynamicallyAccessedMembers(StaticReflectionConstants.ConditionalMemberKinds)]
public Type CalleeType { get; private set; }
public string[] ConditionMemberNames { get; private set; }
public ConditionalTheoryAttribute(
[DynamicallyAccessedMembers(StaticReflectionConstants.ConditionalMemberKinds)]
Type calleeType,
params string[] conditionMemberNames
)
{
CalleeType = calleeType;
ConditionMemberNames = conditionMemberNames;
string skipReason = ConditionalTestDiscoverer.EvaluateSkipConditions(
calleeType,
conditionMemberNames
);
if (skipReason != null)
Skip = skipReason;
}
[Obsolete(
"Use the overload that takes a Type parameter: ConditionalTheory(typeof(MyClass), nameof(MyCondition))."
)]
public ConditionalTheoryAttribute(params string[] conditionMemberNames)
{
ConditionMemberNames = conditionMemberNames;
}
}
}

64
tests/ImageSharp.Tests/TestUtilities/XUnit/StaticReflectionConstants.cs

@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
namespace Xunit
{
internal static class StaticReflectionConstants
{
// ConditionalTestDiscoverer looks at all fields/methods/properties, recursively.
internal const DynamicallyAccessedMemberTypes ConditionalMemberKinds =
DynamicallyAccessedMemberTypes.AllMethods
| DynamicallyAccessedMemberTypes.AllFields
| DynamicallyAccessedMemberTypes.AllProperties;
}
}
namespace System.Diagnostics.CodeAnalysis
{
// This is a copy of the attribute from CoreLib. The attribute shipped in .NET 5.
// The tooling looks for the attribute by name, so we can define a local copy.
// This copy can be deleted once we stop supporting anything below .NET 5.
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
{
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) =>
MemberTypes = memberTypes;
public DynamicallyAccessedMemberTypes MemberTypes { get; }
}
internal enum DynamicallyAccessedMemberTypes
{
None = 0,
PublicParameterlessConstructor = 0x0001,
PublicConstructors = 0x0002 | PublicParameterlessConstructor,
NonPublicConstructors = 0x0004,
PublicMethods = 0x0008,
NonPublicMethods = 0x0010,
PublicFields = 0x0020,
NonPublicFields = 0x0040,
PublicNestedTypes = 0x0080,
NonPublicNestedTypes = 0x0100,
PublicProperties = 0x0200,
NonPublicProperties = 0x0400,
PublicEvents = 0x0800,
NonPublicEvents = 0x1000,
Interfaces = 0x2000,
NonPublicConstructorsWithInherited = NonPublicConstructors | 0x4000,
NonPublicMethodsWithInherited = NonPublicMethods | 0x8000,
NonPublicFieldsWithInherited = NonPublicFields | 0x10000,
NonPublicNestedTypesWithInherited = NonPublicNestedTypes | 0x20000,
NonPublicPropertiesWithInherited = NonPublicProperties | 0x40000,
NonPublicEventsWithInherited = NonPublicEvents | 0x80000,
PublicConstructorsWithInherited = PublicConstructors | 0x100000,
PublicNestedTypesWithInherited = PublicNestedTypes | 0x200000,
AllConstructors = PublicConstructorsWithInherited | NonPublicConstructorsWithInherited,
AllMethods = PublicMethods | NonPublicMethodsWithInherited,
AllFields = PublicFields | NonPublicFieldsWithInherited,
AllNestedTypes = PublicNestedTypesWithInherited | NonPublicNestedTypesWithInherited,
AllProperties = PublicProperties | NonPublicPropertiesWithInherited,
AllEvents = PublicEvents | NonPublicEventsWithInherited,
All = ~None,
}
}

6
tests/ImageSharp.Tests/ValidateDisposedMemoryAllocationsAttribute.cs

@ -2,7 +2,7 @@
// Licensed under the Six Labors Split License.
using System.Reflection;
using Xunit.Sdk;
using Xunit.v3;
namespace SixLabors.ImageSharp.Tests;
@ -19,10 +19,10 @@ public class ValidateDisposedMemoryAllocationsAttribute : BeforeAfterTestAttribu
public ValidateDisposedMemoryAllocationsAttribute(int expected)
=> this.expected = expected;
public override void Before(MethodInfo methodUnderTest)
public override void Before(MethodInfo methodUnderTest, IXunitTest test)
=> MemoryAllocatorValidator.MonitorAllocations();
public override void After(MethodInfo methodUnderTest)
public override void After(MethodInfo methodUnderTest, IXunitTest test)
{
MemoryAllocatorValidator.ValidateAllocations(this.expected);
MemoryAllocatorValidator.StopMonitoringAllocations();

Loading…
Cancel
Save