TestPlan.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text.Json;
  4. using FluentAssertions;
  5. using NUnit.Framework;
  6. using QuestPDF.Drawing;
  7. using QuestPDF.Elements;
  8. using QuestPDF.Helpers;
  9. using QuestPDF.Infrastructure;
  10. using QuestPDF.UnitTests.TestEngine.Operations;
  11. namespace QuestPDF.UnitTests.TestEngine
  12. {
  13. internal class TestPlan
  14. {
  15. private const string DefaultChildName = "child";
  16. private static Random Random { get; } = new Random();
  17. private Element Element { get; set; }
  18. private ICanvas Canvas { get; }
  19. private Size OperationInput { get; set; }
  20. private Queue<OperationBase> Operations { get; } = new Queue<OperationBase>();
  21. public TestPlan()
  22. {
  23. Canvas = CreateCanvas();
  24. }
  25. public static TestPlan For(Func<TestPlan, Element> create)
  26. {
  27. var plan = new TestPlan();
  28. plan.Element = create(plan);
  29. return plan;
  30. }
  31. private T GetExpected<T>() where T : OperationBase
  32. {
  33. if (Operations.TryDequeue(out var value) && value is T result)
  34. return result;
  35. var gotType = value?.GetType()?.Name ?? "null";
  36. Assert.Fail($"Expected: {typeof(T).Name}, got {gotType}: {JsonSerializer.Serialize(value)}");
  37. return null;
  38. }
  39. private ICanvas CreateCanvas()
  40. {
  41. return new MockCanvas
  42. {
  43. TranslateFunc = position =>
  44. {
  45. var expected = GetExpected<CanvasTranslateOperation>();
  46. Assert.AreEqual(expected.Position.X, position.X, "Translate X");
  47. Assert.AreEqual(expected.Position.Y, position.Y, "Translate Y");
  48. },
  49. RotateFunc = angle =>
  50. {
  51. var expected = GetExpected<CanvasRotateOperation>();
  52. Assert.AreEqual(expected.Angle, angle, "Rotate angle");
  53. },
  54. ScaleFunc = (scaleX, scaleY) =>
  55. {
  56. var expected = GetExpected<CanvasScaleOperation>();
  57. Assert.AreEqual(expected.ScaleX, scaleX, "Scale X");
  58. Assert.AreEqual(expected.ScaleY, scaleY, "Scale Y");
  59. },
  60. DrawRectFunc = (position, size, color) =>
  61. {
  62. var expected = GetExpected<CanvasDrawRectangleOperation>();
  63. Assert.AreEqual(expected.Position.X, position.X, "Draw rectangle: X");
  64. Assert.AreEqual(expected.Position.Y, position.Y, "Draw rectangle: Y");
  65. Assert.AreEqual(expected.Size.Width, size.Width, "Draw rectangle: width");
  66. Assert.AreEqual(expected.Size.Height, size.Height, "Draw rectangle: height");
  67. Assert.AreEqual(expected.Color, color, "Draw rectangle: color");
  68. },
  69. DrawImageFunc = (image, position, size) =>
  70. {
  71. var expected = GetExpected<CanvasDrawImageOperation>();
  72. Assert.AreEqual(expected.Position.X, position.X, "Draw image: X");
  73. Assert.AreEqual(expected.Position.Y, position.Y, "Draw image: Y");
  74. Assert.AreEqual(expected.Size.Width, size.Width, "Draw image: width");
  75. Assert.AreEqual(expected.Size.Height, size.Height, "Draw image: height");
  76. }
  77. };
  78. }
  79. public Element CreateChild() => CreateChild(DefaultChildName);
  80. public Element CreateChild(string id)
  81. {
  82. return new ElementMock
  83. {
  84. Id = id,
  85. MeasureFunc = availableSpace =>
  86. {
  87. var expected = GetExpected<ChildMeasureOperation>();
  88. Assert.AreEqual(expected.ChildId, id);
  89. Assert.AreEqual(expected.Input.Width, availableSpace.Width, $"Measure: width of child '{expected.ChildId}'");
  90. Assert.AreEqual(expected.Input.Height, availableSpace.Height, $"Measure: height of child '{expected.ChildId}'");
  91. return expected.Output;
  92. },
  93. DrawFunc = availableSpace =>
  94. {
  95. var expected = GetExpected<ChildDrawOperation>();
  96. Assert.AreEqual(expected.ChildId, id);
  97. Assert.AreEqual(expected.Input.Width, availableSpace.Width, $"Draw: width of child '{expected.ChildId}'");
  98. Assert.AreEqual(expected.Input.Height, availableSpace.Height, $"Draw: width of child '{expected.ChildId}'");
  99. }
  100. };
  101. }
  102. public TestPlan MeasureElement(Size input)
  103. {
  104. OperationInput = input;
  105. return this;
  106. }
  107. public TestPlan DrawElement(Size input)
  108. {
  109. OperationInput = input;
  110. return this;
  111. }
  112. private TestPlan AddOperation(OperationBase operationBase)
  113. {
  114. Operations.Enqueue(operationBase);
  115. return this;
  116. }
  117. public TestPlan ExpectChildMeasure(Size expectedInput, SpacePlan returns)
  118. {
  119. return ExpectChildMeasure(DefaultChildName, expectedInput, returns);
  120. }
  121. public TestPlan ExpectChildMeasure(string child, Size expectedInput, SpacePlan returns)
  122. {
  123. return AddOperation(new ChildMeasureOperation(child, expectedInput, returns));
  124. }
  125. public TestPlan ExpectChildDraw(Size expectedInput)
  126. {
  127. return ExpectChildDraw(DefaultChildName, expectedInput);
  128. }
  129. public TestPlan ExpectChildDraw(string child, Size expectedInput)
  130. {
  131. return AddOperation(new ChildDrawOperation(child, expectedInput));
  132. }
  133. public TestPlan ExpectCanvasTranslate(Position position)
  134. {
  135. return AddOperation(new CanvasTranslateOperation(position));
  136. }
  137. public TestPlan ExpectCanvasTranslate(float left, float top)
  138. {
  139. return AddOperation(new CanvasTranslateOperation(new Position(left, top)));
  140. }
  141. public TestPlan ExpectCanvasScale(float scaleX, float scaleY)
  142. {
  143. return AddOperation(new CanvasScaleOperation(scaleX, scaleY));
  144. }
  145. public TestPlan ExpectCanvasRotate(float angle)
  146. {
  147. return AddOperation(new CanvasRotateOperation(angle));
  148. }
  149. public TestPlan ExpectCanvasDrawRectangle(Position position, Size size, string color)
  150. {
  151. return AddOperation(new CanvasDrawRectangleOperation(position, size, color));
  152. }
  153. public TestPlan ExpectCanvasDrawImage(Position position, Size size)
  154. {
  155. return AddOperation(new CanvasDrawImageOperation(position, size));
  156. }
  157. public TestPlan CheckMeasureResult(SpacePlan expected)
  158. {
  159. Element.VisitChildren(x => x?.Initialize(null, Canvas));
  160. var actual = Element.Measure(OperationInput);
  161. Assert.AreEqual(expected.GetType(), actual.GetType());
  162. Assert.AreEqual(expected.Width, actual.Width, "Measure: width");
  163. Assert.AreEqual(expected.Height, actual.Height, "Measure: height");
  164. Assert.AreEqual(expected.Type, actual.Type, "Measure: height");
  165. return this;
  166. }
  167. public TestPlan CheckDrawResult()
  168. {
  169. Element.VisitChildren(x => x?.Initialize(null, Canvas));
  170. Element.Draw(OperationInput);
  171. return this;
  172. }
  173. public TestPlan CheckState(Func<Element, bool> condition)
  174. {
  175. Assert.IsTrue(condition(Element), "Checking condition");
  176. return this;
  177. }
  178. public TestPlan CheckState<T>(Func<T, bool> condition) where T : Element
  179. {
  180. Assert.IsTrue(Element is T);
  181. Assert.IsTrue(condition(Element as T), "Checking condition");
  182. return this;
  183. }
  184. public static Element CreateUniqueElement()
  185. {
  186. return new Constrained
  187. {
  188. MinWidth = 90,
  189. MinHeight = 60,
  190. Child = new DynamicImage
  191. {
  192. Source = Placeholders.Image
  193. }
  194. };
  195. }
  196. public static void CompareOperations(Element value, Element expected, Size? availableSpace = null)
  197. {
  198. CompareMeasureOperations(value, expected, availableSpace);
  199. CompareDrawOperations(value, expected, availableSpace);
  200. }
  201. private static void CompareMeasureOperations(Element value, Element expected, Size? availableSpace = null)
  202. {
  203. availableSpace ??= new Size(400, 300);
  204. var canvas = new FreeCanvas();
  205. value.VisitChildren(x => x.Initialize(null, canvas));
  206. var valueMeasure = value.Measure(availableSpace.Value);
  207. expected.VisitChildren(x => x.Initialize(null, canvas));
  208. var expectedMeasure = expected.Measure(availableSpace.Value);
  209. valueMeasure.Should().BeEquivalentTo(expectedMeasure);
  210. }
  211. private static void CompareDrawOperations(Element value, Element expected, Size? availableSpace = null)
  212. {
  213. availableSpace ??= new Size(400, 300);
  214. var valueCanvas = new OperationRecordingCanvas();
  215. value.VisitChildren(x => x.Initialize(null, valueCanvas));
  216. value.Draw(availableSpace.Value);
  217. var expectedCanvas = new OperationRecordingCanvas();
  218. expected.VisitChildren(x => x.Initialize(null, expectedCanvas));
  219. expected.Draw(availableSpace.Value);
  220. valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations);
  221. }
  222. }
  223. }