Skip to content

Commit

Permalink
Merge pull request #10 from sven-piller/features/stats
Browse files Browse the repository at this point in the history
Features/stats; closes #4
  • Loading branch information
sven-piller authored Jun 26, 2016
2 parents 86761b3 + af02504 commit 0a63f50
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 13 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Feel free to contribute!

## Release History

- 1.0.0 Release with Stats in Summary
- 0.11.0 Added Sorting
- 0.10.0 Added Tests
- 0.9.1 Improvements in Documentation, [Issue #2](https://github.com/sven-piller/eslint-formatter-markdown/issues/2)
- 0.9.0 Initial release
Expand Down
93 changes: 91 additions & 2 deletions markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ var files = {
tmplPage: 'templates/md-template-page.md',
tmplResult: 'templates/md-template-result.md',
tmplTH: 'templates/md-template-message.table-header.md',
tmplTR: 'templates/md-template-message.table-row.md'
tmplTR: 'templates/md-template-message.table-row.md',
tmplStats: 'templates/md-template-stats.md',
tmplStatsRow: 'templates/md-template-stats-row.md'
};


Expand All @@ -25,6 +27,8 @@ var pageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, files.tm
var resultTemplate = lodash.template(fs.readFileSync(path.join(__dirname, files.tmplResult), 'utf-8'));
var tableHeaderTemplate = lodash.template(fs.readFileSync(path.join(__dirname, files.tmplTH), 'utf-8'));
var tableRowTemplate = lodash.template(fs.readFileSync(path.join(__dirname, files.tmplTR), 'utf-8'));
var statsTemplate = lodash.template(fs.readFileSync(path.join(__dirname, files.tmplStats), 'utf-8'));
var statsRowTemplate = lodash.template(fs.readFileSync(path.join(__dirname, files.tmplStatsRow), 'utf-8'));

/**
* Given a word and a count, append an s if count is not one.
Expand Down Expand Up @@ -52,6 +56,58 @@ function renderSummary(totalErrors, totalWarnings) {
return renderedText;
}

/**
* Renders MARKDOWN for stats
* @param {Object} stats the rules and their stats
* @returns {string} The formatted string, pluralized where necessary
*/
function renderStats(stats) {

/**
* Creates table Header if necessary
* @param {string} type error or warning
* @returns {string} The formatted string
*/
function injectHeader(type) {
return (stats[type]) ? '| rule | count | visual |\n| --- | --- | --- |\n' : '';
}

/**
* renders templates for each rule
* @param {string} type error or warning
* @returns {string} The formatted string, pluralized where necessary
*/
function output(type) {
var statstype = stats[type];
return injectHeader(type) + lodash.map(statstype, function (ruleStats, ruleId) {
return statsRowTemplate({
ruleId: ruleId,
ruleCount: ruleStats,
visual: lodash.repeat('X', lodash.min([ruleStats, 20]))
});
}, '').join('');
}

/**
* render template for severity
* @param {string} type severity
* @returns {string} template
*/
function renderTemplate(type) {
var lcType = lodash.lowerCase(type);
if (lodash.size(stats[lcType])) {
return statsTemplate({
title: '### ' + type,
items: output(lcType)
});
} else {
return '';
}
}

return renderTemplate('Errors') + renderTemplate('Warnings');
}

/**
* Get the color based on whether there are errors/warnings...
* @param {string} totalErrors Total errors
Expand Down Expand Up @@ -190,13 +246,45 @@ function sortResults(results) {
return lodash.concat(fileArray.error, fileArray.warning, fileArray.clean);
}

/**
* Calculate stats
* @param {Array} results results
* @returns {Object} stats
*/
function getStats(results) {

/**
* calculate stats for each severity
* @param {string} type severity
* @returns {Object} stats
*/
function filterMessages(type) {
return lodash(results)
.map('messages')
.flatten()
.filter(function (message) { return message.severity === type; })
.groupBy('ruleId')
.mapValues(function (ruleMessages) {
return ruleMessages.length;
})
.value();
}
return {
errors: filterMessages(2),
warnings: filterMessages(1)
};
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

module.exports = function (results) {
var totalErrors = 0;
var totalWarnings = 0;
var stats = getStats(results);

// console.log(stats);

// Iterate over results to get totals
results.forEach(function (result) {
Expand All @@ -209,6 +297,7 @@ module.exports = function (results) {
date: new Date(),
reportColor: renderSummaryColor(totalErrors, totalWarnings),
reportSummary: renderSummary(totalErrors, totalWarnings),
results: renderResults(results)
results: renderResults(results),
stats: renderStats(stats)
});
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-formatter-markdown",
"version": "0.11.0",
"version": "1.0.0",
"description": "Markdown ESLint formatter (reporter)",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 2 additions & 0 deletions templates/md-template-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

<%= reportSummary %>

<%= stats %>

## Details

<%= results %>
Expand Down
1 change: 1 addition & 0 deletions templates/md-template-stats-row.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| <%= ruleId %> | <%= ruleCount %> | <%= visual %> |
3 changes: 3 additions & 0 deletions templates/md-template-stats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= title %>

<%= items %>
104 changes: 94 additions & 10 deletions test/markdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,8 @@ context('Init', function () {
});
});
});
});

context('Formatter tests', function () {
describe('Loading formatters', function () {
describe('Formatter tests', function () {
it('load "compact" formatter (buildin)', function () {
var engine1 = new CLIEngine();
var formatter1 = engine1.getFormatter('compact');
Expand Down Expand Up @@ -411,13 +409,23 @@ context('File tests', function () {
testRegex(output, '/quotes', true, 2);
});
});
});

describe.only('Testing sorting', function () {
before(function (done) {
done();
});
context('Functionality tests', function () {
before(function (done) {
engine = new CLIEngine();
formatter = engine.getFormatter(dir.formatter);
done();
});

after(function (done) {
after(function (done) {
engine = null;
formatter = null;
done();
});

describe('Testing sorting', function () {
afterEach(function (done) {
report = null;
output = null;
done();
Expand All @@ -427,7 +435,7 @@ context('File tests', function () {
report = engine.executeOnFiles([
path.join(dir.fixtures, dir.yellow),
path.join(dir.fixtures, dir.red)
]);
]);
output = formatter(report.results);
testRegex(output, '```Error```[^]+?```Warning```', true, 1);
testRegex(output, '```Warning```[^]+?```Error```', false);
Expand All @@ -439,10 +447,86 @@ context('File tests', function () {
path.join(dir.fixtures, dir.red),
path.join(dir.fixtures, dir.orange),
path.join(dir.fixtures, dir.green)
]);
]);
output = formatter(report.results);
testRegex(output, '```Error```[^]+?```Warning```', true, 1);
testRegex(output, '```Warning```[^]+?```Error```', false);
});
});

describe('Testing stats', function () {
afterEach(function (done) {
report = null;
output = null;
done();
});

it('should have no warnings and errors (green)', function () {
report = engine.executeOnFiles([
path.join(dir.fixtures, dir.green)
]);
output = formatter(report.results);
testRegex(output, '### Errors', false);
testRegex(output, '### Warnings', false);
testRegex(output, '\\| rule \\| count \\| visual \\|', false);
testRegex(output, '\\| quotes \\| 1 \\| X \\|', false);
testRegex(output, '\\| no-trailing-spaces \\| 2 \\| XX \\|', false);
testRegex(output, '\\| indent \\| 1 \\| X \\|', false);
});

it('should have warnings (yellow)', function () {
report = engine.executeOnFiles([
path.join(dir.fixtures, dir.yellow)
]);
output = formatter(report.results);
testRegex(output, '### Errors', false);
testRegex(output, '### Warnings', true, 1);
testRegex(output, '\\| rule \\| count \\| visual \\|', true, 1);
testRegex(output, '\\| quotes \\| 1 \\| X \\|', false);
testRegex(output, '\\| no-trailing-spaces \\| 2 \\| XX \\|', true, 1);
testRegex(output, '\\| indent \\| 1 \\| X \\|', true, 1);
});

it('should have errors (red)', function () {
report = engine.executeOnFiles([
path.join(dir.fixtures, dir.red)
]);
output = formatter(report.results);
testRegex(output, '### Errors', true, 1);
testRegex(output, '### Warnings', false);
testRegex(output, '\\| rule \\| count \\| visual \\|', true, 1);
testRegex(output, '\\| quotes \\| 1 \\| X \\|', true, 1);
testRegex(output, '\\| no-trailing-spaces \\| 2 \\| XX \\|', false);
testRegex(output, '\\| indent \\| 1 \\| X \\|', false);
});

it('should have errors and warnings (orange)', function () {
report = engine.executeOnFiles([
path.join(dir.fixtures, dir.orange)
]);
output = formatter(report.results);
testRegex(output, '### Errors', true, 1);
testRegex(output, '### Warnings', true, 1);
testRegex(output, '\\| rule \\| count \\| visual \\|', true, 2);
testRegex(output, '\\| quotes \\| 1 \\| X \\|', true, 1);
testRegex(output, '\\| no-trailing-spaces \\| 2 \\| XX \\|', true, 1);
testRegex(output, '\\| indent \\| 1 \\| X \\|', true, 1);
});

it('should have errors and warnings (all files)', function () {
report = engine.executeOnFiles([
path.join(dir.fixtures, dir.yellow),
path.join(dir.fixtures, dir.red),
path.join(dir.fixtures, dir.orange),
path.join(dir.fixtures, dir.green)
]);
output = formatter(report.results);
testRegex(output, '### Errors', true, 1);
testRegex(output, '### Warnings', true, 1);
testRegex(output, '\\| rule \\| count \\| visual \\|', true, 2);
testRegex(output, '\\| quotes \\| 2 \\| XX \\|', true, 1);
testRegex(output, '\\| no-trailing-spaces \\| 4 \\| XXXX \\|', true, 1);
testRegex(output, '\\| indent \\| 2 \\| XX \\|', true, 1);
});
});
});

0 comments on commit 0a63f50

Please sign in to comment.