SemanticTreeTestRunner.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using QuestPDF.Drawing;
  2. using QuestPDF.Infrastructure;
  3. namespace QuestPDF.ConformanceTests.TestEngine;
  4. internal static class SemanticTreeTestRunner
  5. {
  6. public static void TestSemanticTree(this IDocument document, SemanticTreeNode? semanticTreeRootNode)
  7. {
  8. Settings.EnableCaching = false;
  9. Settings.EnableDebugging = false;
  10. var canvas = new SemanticAwareDocumentCanvas();
  11. var settings = new DocumentSettings { PDFA_Conformance = PDFA_Conformance.PDFA_3A };
  12. DocumentGenerator.RenderDocument(canvas, document, settings);
  13. CompareSemanticTrees(canvas.SemanticTree, semanticTreeRootNode);
  14. }
  15. private static void CompareSemanticTrees(SemanticTreeNode? actual, SemanticTreeNode? expected)
  16. {
  17. if (expected == null && actual == null)
  18. return;
  19. if (expected == null)
  20. Assert.Fail($"Expected null but got node of type '{actual?.Type}'");
  21. if (actual == null)
  22. Assert.Fail($"Expected node of type '{expected.Type}' but got null");
  23. Assert.That(actual.Type, Is.EqualTo(expected.Type), $"Node type mismatch");
  24. Assert.That(actual.Alt, Is.EqualTo(expected.Alt), $"Alt mismatch for node type '{expected.Type}'");
  25. Assert.That(actual.Lang, Is.EqualTo(expected.Lang), $"Lang mismatch for node type '{expected.Type}'");
  26. CompareAttributes(actual.Attributes, expected.Attributes, expected.Type);
  27. Assert.That(actual.Children.Count, Is.EqualTo(expected.Children.Count), $"Children count mismatch for node type '{expected.Type}'");
  28. foreach (var (actualChild, expectedChild) in actual.Children.Zip(expected.Children))
  29. CompareSemanticTrees(actualChild, expectedChild);
  30. static void CompareAttributes(ICollection<SemanticTreeNode.Attribute> actual, ICollection<SemanticTreeNode.Attribute> expected, string nodeType)
  31. {
  32. Assert.That(actual.Count, Is.EqualTo(expected.Count), $"Attribute count mismatch for node type '{nodeType}'");
  33. var actualList = actual.OrderBy(a => a.Owner).ThenBy(a => a.Name).ToList();
  34. var expectedList = expected.OrderBy(a => a.Owner).ThenBy(a => a.Name).ToList();
  35. for (var i = 0; i < expectedList.Count; i++)
  36. {
  37. var actualAttr = actualList[i];
  38. var expectedAttr = expectedList[i];
  39. Assert.That(actualAttr.Owner, Is.EqualTo(expectedAttr.Owner), $"Attribute owner mismatch for node type '{nodeType}'");
  40. Assert.That(actualAttr.Name, Is.EqualTo(expectedAttr.Name), $"Attribute name mismatch for node type '{nodeType}'");
  41. Assert.That(actualAttr.Value, Is.EqualTo(expectedAttr.Value), $"Attribute value mismatch for '{expectedAttr.Owner}:{expectedAttr.Name}' in node type '{nodeType}'");
  42. }
  43. }
  44. }
  45. }
  46. internal static class ExpectedSemanticTree
  47. {
  48. public static SemanticTreeNode DocumentRoot(Action<SemanticTreeNode> configuration)
  49. {
  50. var root = new SemanticTreeNode
  51. {
  52. Type = "Document"
  53. };
  54. configuration(root);
  55. return root;
  56. }
  57. public static void Child(this SemanticTreeNode parent, string type, Action<SemanticTreeNode>? configuration = null)
  58. {
  59. var child = new SemanticTreeNode
  60. {
  61. Type = type
  62. };
  63. configuration?.Invoke(child);
  64. parent.Children.Add(child);
  65. }
  66. public static SemanticTreeNode Attribute(this SemanticTreeNode node, string owner, string name, string value)
  67. {
  68. var attribute = new SemanticTreeNode.Attribute
  69. {
  70. Owner = owner,
  71. Name = name,
  72. Value = value
  73. };
  74. node.Attributes.Add(attribute);
  75. return node;
  76. }
  77. public static SemanticTreeNode Alt(this SemanticTreeNode node, string alt)
  78. {
  79. node.Alt = alt;
  80. return node;
  81. }
  82. public static SemanticTreeNode Lang(this SemanticTreeNode node, string lang)
  83. {
  84. node.Lang = lang;
  85. return node;
  86. }
  87. }