• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview "table reporter.
3 * @author Gajus Kuizinas <gajus@gajus.com>
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Requirements
9//------------------------------------------------------------------------------
10
11const chalk = require("chalk"),
12    table = require("table").table;
13
14//------------------------------------------------------------------------------
15// Helpers
16//------------------------------------------------------------------------------
17
18/**
19 * Given a word and a count, append an "s" if count is not one.
20 * @param {string} word A word.
21 * @param {number} count Quantity.
22 * @returns {string} The original word with an s on the end if count is not one.
23 */
24function pluralize(word, count) {
25    return (count === 1 ? word : `${word}s`);
26}
27
28/**
29 * Draws text table.
30 * @param {Array<Object>} messages Error messages relating to a specific file.
31 * @returns {string} A text table.
32 */
33function drawTable(messages) {
34    const rows = [];
35
36    if (messages.length === 0) {
37        return "";
38    }
39
40    rows.push([
41        chalk.bold("Line"),
42        chalk.bold("Column"),
43        chalk.bold("Type"),
44        chalk.bold("Message"),
45        chalk.bold("Rule ID")
46    ]);
47
48    messages.forEach(message => {
49        let messageType;
50
51        if (message.fatal || message.severity === 2) {
52            messageType = chalk.red("error");
53        } else {
54            messageType = chalk.yellow("warning");
55        }
56
57        rows.push([
58            message.line || 0,
59            message.column || 0,
60            messageType,
61            message.message,
62            message.ruleId || ""
63        ]);
64    });
65
66    return table(rows, {
67        columns: {
68            0: {
69                width: 8,
70                wrapWord: true
71            },
72            1: {
73                width: 8,
74                wrapWord: true
75            },
76            2: {
77                width: 8,
78                wrapWord: true
79            },
80            3: {
81                paddingRight: 5,
82                width: 50,
83                wrapWord: true
84            },
85            4: {
86                width: 20,
87                wrapWord: true
88            }
89        },
90        drawHorizontalLine(index) {
91            return index === 1;
92        }
93    });
94}
95
96/**
97 * Draws a report (multiple tables).
98 * @param {Array} results Report results for every file.
99 * @returns {string} A column of text tables.
100 */
101function drawReport(results) {
102    let files;
103
104    files = results.map(result => {
105        if (!result.messages.length) {
106            return "";
107        }
108
109        return `\n${result.filePath}\n\n${drawTable(result.messages)}`;
110    });
111
112    files = files.filter(content => content.trim());
113
114    return files.join("");
115}
116
117//------------------------------------------------------------------------------
118// Public Interface
119//------------------------------------------------------------------------------
120
121module.exports = function(report) {
122    let result,
123        errorCount,
124        warningCount;
125
126    result = "";
127    errorCount = 0;
128    warningCount = 0;
129
130    report.forEach(fileReport => {
131        errorCount += fileReport.errorCount;
132        warningCount += fileReport.warningCount;
133    });
134
135    if (errorCount || warningCount) {
136        result = drawReport(report);
137    }
138
139    result += `\n${table([
140        [
141            chalk.red(pluralize(`${errorCount} Error`, errorCount))
142        ],
143        [
144            chalk.yellow(pluralize(`${warningCount} Warning`, warningCount))
145        ]
146    ], {
147        columns: {
148            0: {
149                width: 110,
150                wrapWord: true
151            }
152        },
153        drawHorizontalLine() {
154            return true;
155        }
156    })}`;
157
158    return result;
159};
160