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