| 11 | namespace CodeCave.Revit.Toolkit.Tests |
| 12 | { |
| 13 | public class ThumbnailFixture |
| 14 | { |
| 15 | private static readonly string PathToValidFiles; |
| 16 | |
| 17 | /// <summary> |
| 18 | /// Initializes static members of the <see cref="ThumbnailFixture"/> class. |
| 19 | /// </summary> |
| 20 | static ThumbnailFixture() |
| 21 | { |
| 22 | var filesForThumbnails = Path.Combine(Environment.CurrentDirectory, "Resources", nameof(Thumbnails)); |
| 23 | PathToValidFiles = Path.Combine(filesForThumbnails, "Valid"); |
| 24 | } |
| 25 | |
| 26 | /// <summary>The thumbnails are generated for DWGs.</summary> |
| 27 | /// <param name="dwgRelativePath">The DWG relative path.</param> |
| 28 | [Theory] |
| 29 | [InlineData("Thumbnails/Valid/A1ANG-3.dwg")] |
| 30 | [InlineData("Thumbnails/Valid/7-PS-66_R3.dwg")] |
| 31 | [InlineData("Thumbnails/Valid/U0000850_7-PS-66.DWG")] |
| 32 | public void DwgThumbnailIsGenerated(string dwgRelativePath) |
| 33 | { |
| 34 | // Setup |
| 35 | dwgRelativePath = dwgRelativePath?.Replace('/', Path.DirectorySeparatorChar); |
| 36 | var dwgFilePath = Directory.GetFiles(PathToValidFiles, "*.dwg").FirstOrDefault(f => f.EndsWith(dwgRelativePath)); |
| 37 | var dwgThumbnailPath = Path.ChangeExtension(dwgFilePath, "png"); |
| 38 | |
| 39 | // Act |
| 40 | var dwgThumbnailer = new DwgThumbnailExtractor(); |
| 41 | var thumbDwgBytes = dwgThumbnailer.ExtractThumbnailBytes(dwgFilePath); |
| 42 | var thumbPngBytes = File.ReadAllBytes(dwgThumbnailPath); |
| 43 | |
| 44 | // Assert |
| 45 | Assert.NotEmpty(thumbDwgBytes); |
| 46 | |
| 47 | // The DWG thumbnail is re-encoded to PNG by the extractor, and PNG encoders produce |
| 48 | // slightly different (but equally valid) byte streams across .NET Framework / .NET 8, |
| 49 | // so compare decoded pixels instead of raw bytes |
| 50 | AssertImagePixelsEqual(thumbPngBytes, thumbDwgBytes); |
| 51 | } |
| 52 | |
| 53 | /// <summary>Asserts that two PNG byte arrays decode to images with identical dimensions and pixels.</summary> |
| 54 | /// <param name="expectedImageBytes">The expected image bytes.</param> |
| 55 | /// <param name="actualImageBytes">The actual image bytes.</param> |
| 56 | private static void AssertImagePixelsEqual(byte[] expectedImageBytes, byte[] actualImageBytes) |
| 57 | { |
| 58 | using var expectedStream = new MemoryStream(expectedImageBytes); |
| 59 | using var actualStream = new MemoryStream(actualImageBytes); |
| 60 | using var expected = new Bitmap(expectedStream); |
| 61 | using var actual = new Bitmap(actualStream); |
| 62 | |
| 63 | Assert.Equal(expected.Size, actual.Size); |
| 64 | |
| 65 | for (var y = 0; y < expected.Height; y++) |
| 66 | { |
| 67 | for (var x = 0; x < expected.Width; x++) |
| 68 | { |
| 69 | if (expected.GetPixel(x, y) != actual.GetPixel(x, y)) |
| 70 | { |
nothing calls this directly
no outgoing calls
no test coverage detected