VeraPdfConformanceTestRunner.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System.Diagnostics;
  2. using System.Text;
  3. using System.Text.Json;
  4. using QuestPDF.Fluent;
  5. using QuestPDF.Infrastructure;
  6. namespace QuestPDF.ConformanceTests.TestEngine;
  7. public static class VeraPdfConformanceTestRunner
  8. {
  9. public class ValidationResult
  10. {
  11. public bool IsDocumentValid => !FailedRules.Any();
  12. public ICollection<FailedRule> FailedRules { get; set; } = [];
  13. public class FailedRule
  14. {
  15. public string Profile { get; set; }
  16. public string Specification { get; set; }
  17. public string Clause { get; set; }
  18. public string Description { get; set; }
  19. public string ErrorMessage { get; set; }
  20. public string Context { get; set; }
  21. }
  22. public string GetErrorMessage()
  23. {
  24. var errorMessage = new StringBuilder();
  25. foreach (var failedRule in FailedRules)
  26. {
  27. errorMessage.AppendLine($"🟥\t{failedRule.Profile}");
  28. errorMessage.AppendLine($"\t{failedRule.Specification}");
  29. errorMessage.AppendLine($"\t{failedRule.Clause}");
  30. errorMessage.AppendLine($"\t{failedRule.Description}");
  31. errorMessage.AppendLine();
  32. errorMessage.AppendLine($"\t{failedRule.ErrorMessage}");
  33. errorMessage.AppendLine();
  34. errorMessage.AppendLine($"\t{failedRule.Context}");
  35. errorMessage.AppendLine();
  36. }
  37. return errorMessage.ToString();
  38. }
  39. }
  40. public static void TestConformanceWithVeraPdf(this IDocument document)
  41. {
  42. var filePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.pdf");
  43. document.GeneratePdf(filePath);
  44. var result = RunVeraPDF(filePath);
  45. if (!result.IsDocumentValid)
  46. {
  47. Console.WriteLine(result.GetErrorMessage());
  48. Assert.Fail();
  49. }
  50. File.Delete(filePath);
  51. }
  52. public static void TestConformance(string filePath)
  53. {
  54. var result = RunVeraPDF(filePath);
  55. if (!result.IsDocumentValid)
  56. {
  57. Console.WriteLine(result.GetErrorMessage());
  58. Assert.Fail();
  59. }
  60. }
  61. private static ValidationResult RunVeraPDF(string pdfFilePath)
  62. {
  63. if (!File.Exists(pdfFilePath))
  64. throw new FileNotFoundException($"PDF file not found: {pdfFilePath}");
  65. var arguments = $"--format json \"{pdfFilePath}\"";
  66. var process = new Process
  67. {
  68. StartInfo = new ProcessStartInfo
  69. {
  70. FileName = "verapdf",
  71. Arguments = arguments,
  72. RedirectStandardOutput = true,
  73. RedirectStandardError = true,
  74. UseShellExecute = false,
  75. CreateNoWindow = true
  76. }
  77. };
  78. process.Start();
  79. var output = process.StandardOutput.ReadToEnd();
  80. process.WaitForExit();
  81. var result = new ValidationResult();
  82. var profileResults = JsonDocument
  83. .Parse(output)
  84. .RootElement
  85. .GetProperty("report")
  86. .GetProperty("jobs")[0]
  87. .GetProperty("validationResult");
  88. foreach (var profileValidationResult in profileResults.EnumerateArray())
  89. {
  90. var failedRules = profileValidationResult
  91. .GetProperty("details")
  92. .GetProperty("ruleSummaries");
  93. foreach (var failedRule in failedRules.EnumerateArray())
  94. {
  95. foreach (var check in failedRule.GetProperty("checks").EnumerateArray())
  96. {
  97. result.FailedRules.Add(new ValidationResult.FailedRule
  98. {
  99. Profile = profileValidationResult.GetProperty("profileName").GetString().Split(" ").First(),
  100. Specification = failedRule.GetProperty("specification").GetString(),
  101. Clause = failedRule.GetProperty("clause").GetString(),
  102. Description = failedRule.GetProperty("description").GetString(),
  103. ErrorMessage = check.GetProperty("errorMessage").GetString(),
  104. Context = check.GetProperty("context").GetString()
  105. });
  106. }
  107. }
  108. }
  109. return result;
  110. }
  111. }