tap.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /**
  2. * @fileoverview TAP reporter
  3. * @author Jonathan Kingston
  4. */
  5. "use strict";
  6. const yaml = require("js-yaml");
  7. //------------------------------------------------------------------------------
  8. // Helper Functions
  9. //------------------------------------------------------------------------------
  10. /**
  11. * Returns a canonical error level string based upon the error message passed in.
  12. * @param {Object} message Individual error message provided by eslint
  13. * @returns {string} Error level string
  14. */
  15. function getMessageType(message) {
  16. if (message.fatal || message.severity === 2) {
  17. return "error";
  18. }
  19. return "warning";
  20. }
  21. /**
  22. * Takes in a JavaScript object and outputs a TAP diagnostics string
  23. * @param {Object} diagnostic JavaScript object to be embedded as YAML into output.
  24. * @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant
  25. */
  26. function outputDiagnostics(diagnostic) {
  27. const prefix = " ";
  28. let output = `${prefix}---\n`;
  29. output += prefix + yaml.safeDump(diagnostic).split("\n").join(`\n${prefix}`);
  30. output += "...\n";
  31. return output;
  32. }
  33. //------------------------------------------------------------------------------
  34. // Public Interface
  35. //------------------------------------------------------------------------------
  36. module.exports = function(results) {
  37. let output = `TAP version 13\n1..${results.length}\n`;
  38. results.forEach((result, id) => {
  39. const messages = result.messages;
  40. let testResult = "ok";
  41. let diagnostics = {};
  42. if (messages.length > 0) {
  43. messages.forEach(message => {
  44. const severity = getMessageType(message);
  45. const diagnostic = {
  46. message: message.message,
  47. severity,
  48. data: {
  49. line: message.line || 0,
  50. column: message.column || 0,
  51. ruleId: message.ruleId || ""
  52. }
  53. };
  54. // This ensures a warning message is not flagged as error
  55. if (severity === "error") {
  56. testResult = "not ok";
  57. }
  58. /*
  59. * If we have multiple messages place them under a messages key
  60. * The first error will be logged as message key
  61. * This is to adhere to TAP 13 loosely defined specification of having a message key
  62. */
  63. if ("message" in diagnostics) {
  64. if (typeof diagnostics.messages === "undefined") {
  65. diagnostics.messages = [];
  66. }
  67. diagnostics.messages.push(diagnostic);
  68. } else {
  69. diagnostics = diagnostic;
  70. }
  71. });
  72. }
  73. output += `${testResult} ${id + 1} - ${result.filePath}\n`;
  74. // If we have an error include diagnostics
  75. if (messages.length > 0) {
  76. output += outputDiagnostics(diagnostics);
  77. }
  78. });
  79. return output;
  80. };