TestPlan.cs 8.9 KB

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