diff --git a/AMWD.Common.Test/SnapshotAssert.cs b/AMWD.Common.Test/SnapshotAssert.cs new file mode 100644 index 0000000..4da74bd --- /dev/null +++ b/AMWD.Common.Test/SnapshotAssert.cs @@ -0,0 +1,87 @@ +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace AMWD.Common.Test +{ + /// + /// Implements a snapshot comparison for content aggregation (e.g. files). + /// + public sealed class SnapshotAssert + { + /// + /// Tests whether the specified string is equal to the saved snapshot. + /// + /// The current aggregated content string. + /// An error message. + /// The absolute file path of the calling file (filled automatically by the compiler service). + /// The name of the calling method (filled automatically by the compiler service). + public static void AreEqual(string actual, string message = null, [CallerFilePath] string callerFilePath = null, [CallerMemberName] string callerMemberName = null) + { + string cleanLineEnding = actual + .Replace("\r\n", "\n") // Windows + .Replace("\r", "\n"); // old MacOS + AreEqual(Encoding.UTF8.GetBytes(cleanLineEnding), message, callerFilePath, callerMemberName); + } + + /// + /// Tests whether the specified byte array is equal to the saved snapshot. + /// + /// The current aggregated content bytes. + /// An error message. + /// The absolute file path of the calling file (filled automatically by the compiler service). + /// The name of the calling method (filled automatically by the compiler service). + public static void AreEqual(byte[] actual, string message = null, [CallerFilePath] string callerFilePath = null, [CallerMemberName] string callerMemberName = null) + => AreEqual(actual, 0, -1, message, callerFilePath, callerMemberName); + + /// + /// Tests whether the specified byte array is equal to the saved snapshot. + /// + /// + /// The past has shown, that e.g. wkhtmltopdf prints the current timestamp at the beginning of the PDF file. + /// Therefore only a specific part of that file can be asserted to be equal. + /// + /// The current aggregated content bytes. + /// The first byte to compare. + /// The last byte to compare. + /// An error message. + /// The absolute file path of the calling file (filled automatically by the compiler service). + /// The name of the calling method (filled automatically by the compiler service). + public static void AreEqual(byte[] actual, int firstByteIndex, int lastByteIndex, string message = null, [CallerFilePath] string callerFilePath = null, [CallerMemberName] string callerMemberName = null) + { + string callerDir = Path.GetDirectoryName(callerFilePath); + string callerFile = Path.GetFileNameWithoutExtension(callerFilePath); + + string snapshotDir = Path.Combine(callerDir, "Snapshots", callerFile); + string snapshotFile = Path.Combine(snapshotDir, $"{callerMemberName}.snap"); + + if (File.Exists(snapshotFile)) + { + byte[] expected = File.ReadAllBytes(snapshotFile); + + var actualBytes = actual.Skip(firstByteIndex); + var expectedBytes = expected.Skip(firstByteIndex); + + if (lastByteIndex > firstByteIndex) + { + actualBytes = actualBytes.Take(lastByteIndex - firstByteIndex); + expectedBytes = expectedBytes.Take(lastByteIndex - firstByteIndex); + } + + if (message == null) + CollectionAssert.AreEqual(expectedBytes.ToArray(), actualBytes.ToArray()); + else + CollectionAssert.AreEqual(expectedBytes.ToArray(), actualBytes.ToArray(), message); + } + else + { + if (!Directory.Exists(snapshotDir)) + Directory.CreateDirectory(snapshotDir); + + File.WriteAllBytes(snapshotFile, actual); + } + } + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b4645a..55a3e68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Upcoming Test](https://git.am-wd.de/AM.WD/common/compare/test/v2.0.0...test/v2.1.0) - 0000-00-00 + +### Added + +- Added `SnapshotAssert` for better UnitTesting + + ## [Upcoming](https://git.am-wd.de/AM.WD/common/compare/v2.0.0...main) - 0000-00-00 ### Changed