| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- using QuestPDF.Infrastructure;
- namespace QuestPDF.LayoutTests.TestEngine;
- internal class LayoutTestValidator
- {
- public static void Validate(LayoutTestResult result)
- {
- if (result.ActualLayout.Count != result.ExpectedLayout.Count)
- throw new LayoutTestException($"Content return layout with {result.ActualLayout.Count} pages but expected {result.ExpectedLayout.Count} pages");
- var numberOfPages = result.ActualLayout.Count;
-
- foreach (var i in Enumerable.Range(0, numberOfPages))
- {
- try
- {
- var actualPage = result.ActualLayout.ElementAt(i);
- var expectedPage = result.ActualLayout.ElementAt(i);
- ValidatePage(actualPage, expectedPage);
- }
- catch (LayoutTestException exception)
- {
- throw new LayoutTestException($"Found issue on page number {i + 1}: {exception.Message}");
- }
- catch (Exception exception)
- {
- throw new LayoutTestException($"Encountered exception during validating page number {i + 1}", exception);
- }
- }
- static void ValidatePage(LayoutTestResult.PageLayoutSnapshot actualLayout, LayoutTestResult.PageLayoutSnapshot expectedLayout)
- {
- if (Math.Abs(actualLayout.RequiredArea.Width - expectedLayout.RequiredArea.Width) > Size.Epsilon)
- throw new LayoutTestException($"Taken horizontal area is equal to {actualLayout.RequiredArea.Width} but expected {expectedLayout.RequiredArea.Width}");
-
- if (Math.Abs(actualLayout.RequiredArea.Height - expectedLayout.RequiredArea.Height) > Size.Epsilon)
- throw new LayoutTestException($"Taken vertical area is equal to {actualLayout.RequiredArea.Height} but expected {expectedLayout.RequiredArea.Height}");
-
- if (actualLayout.MockPositions.Count != expectedLayout.MockPositions.Count)
- throw new LayoutTestException($"Visible {actualLayout.MockPositions.Count} mocks but expected {expectedLayout.MockPositions.Count}");
- ValidatePositionAndSizeOfMocks(actualLayout, expectedLayout);
- ValidateDrawingOrder(actualLayout, expectedLayout);
- }
- static void ValidatePositionAndSizeOfMocks(LayoutTestResult.PageLayoutSnapshot actualLayout, LayoutTestResult.PageLayoutSnapshot expectedLayout)
- {
- foreach (var expectedMock in expectedLayout.MockPositions)
- {
- var matchingActualMock = actualLayout
- .MockPositions
- .Where(x => x.MockId == expectedMock.MockId)
- .Where(x => Position.Equal(x.Position, expectedMock.Position))
- .Where(x => Size.Equal(x.Size, expectedMock.Size))
- .Count();
- if (matchingActualMock == 0)
- throw new Exception($"Cannot find '{expectedMock.MockId}' mock on position {expectedMock.Position} and size {expectedMock.Size}");
-
- if (matchingActualMock > 1)
- throw new Exception($"Found multiple '{expectedMock.MockId}' mocks on position {expectedMock.Position} and size {expectedMock.Size}");
- }
- }
- static void ValidateDrawingOrder(LayoutTestResult.PageLayoutSnapshot actualLayout, LayoutTestResult.PageLayoutSnapshot expectedLayout)
- {
- var actualOverlaps = GetOverlappingItems(actualLayout.MockPositions).ToList();
- var expectedOverlaps = GetOverlappingItems(expectedLayout.MockPositions).ToList();
-
- foreach (var expectedOverlap in expectedOverlaps)
- {
- var matchingActualElements = actualOverlaps.Count(actualOverlap => actualOverlap == expectedOverlap);
- if (matchingActualElements != 1)
- throw new Exception($"Mock '{expectedOverlap.belowMockId}' should be visible below '{expectedOverlap.aboveMockId}' mock");
- }
-
- IEnumerable<(string belowMockId, string aboveMockId)> GetOverlappingItems(ICollection<LayoutTestResult.MockLayoutPosition> items)
- {
- for (var i = 0; i < items.Count; i++)
- {
- for (var j = i; j < items.Count; j++)
- {
- var beforeChild = items.ElementAt(i);
- var afterChild = items.ElementAt(j);
- var beforeBoundingBox = BoundingBox.From(beforeChild.Position, beforeChild.Size);
- var afterBoundingBox = BoundingBox.From(afterChild.Position, afterChild.Size);
- var intersection = BoundingBoxExtensions.Intersection(beforeBoundingBox, afterBoundingBox);
-
- if (intersection == null)
- continue;
- yield return (beforeChild.MockId, afterChild.MockId);
- }
- }
- }
- }
- }
- }
|