VeraPdfConformanceTestRunner.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 executablePath = Environment.GetEnvironmentVariable("VERAPDF_EXECUTABLE_PATH");
  67. if (string.IsNullOrEmpty(executablePath))
  68. throw new Exception("The location path of the VeraPDF executable is not set. Set the VERAPDF_EXECUTABLE_PATH environment variable to the path of the VeraPDF executable.");
  69. var process = new Process
  70. {
  71. StartInfo = new ProcessStartInfo
  72. {
  73. FileName = executablePath,
  74. Arguments = arguments,
  75. RedirectStandardOutput = true,
  76. RedirectStandardError = true,
  77. UseShellExecute = false,
  78. CreateNoWindow = true
  79. }
  80. };
  81. process.Start();
  82. var output = process.StandardOutput.ReadToEnd();
  83. process.WaitForExit();
  84. var result = new ValidationResult();
  85. var profileResults = JsonDocument
  86. .Parse(output)
  87. .RootElement
  88. .GetProperty("report")
  89. .GetProperty("jobs")[0]
  90. .GetProperty("validationResult");
  91. foreach (var profileValidationResult in profileResults.EnumerateArray())
  92. {
  93. var failedRules = profileValidationResult
  94. .GetProperty("details")
  95. .GetProperty("ruleSummaries");
  96. foreach (var failedRule in failedRules.EnumerateArray())
  97. {
  98. foreach (var check in failedRule.GetProperty("checks").EnumerateArray())
  99. {
  100. result.FailedRules.Add(new ValidationResult.FailedRule
  101. {
  102. Profile = profileValidationResult.GetProperty("profileName").GetString().Split(" ").First(),
  103. Specification = failedRule.GetProperty("specification").GetString(),
  104. Clause = failedRule.GetProperty("clause").GetString(),
  105. Description = failedRule.GetProperty("description").GetString(),
  106. ErrorMessage = check.GetProperty("errorMessage").GetString(),
  107. Context = check.GetProperty("context").GetString()
  108. });
  109. }
  110. }
  111. }
  112. return result;
  113. }
  114. }