Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

Commit

Permalink
Merge pull request #155 from hcodes/reports
Browse files Browse the repository at this point in the history
Reports refactoring
  • Loading branch information
hcodes committed Apr 5, 2020
2 parents da153ff + 34df6d2 commit f4c5bb5
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 48 deletions.
2 changes: 1 addition & 1 deletion lib/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ if (!isStdin && !program.args.length) {
program.help();
}

reports.addReports(mergedOptions.report);
reports.set(mergedOptions.report);
reports.onStart();

async.series(
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function getMergedOptions(config) {
excludeFiles: mergedConfig.excludeFiles,
options: mergedConfig.options || {},

configDictionary: mergedOptions.dictionary,
configDictionary: mergedConfig.dictionary,
configRelativePath: mergedConfig.configRelativePath,
};

Expand Down
3 changes: 2 additions & 1 deletion lib/reports/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function getTyposByCode(code, data) {
}

module.exports = {
name: 'console',
onStart() {
consoleLog('Spelling check:');
},
Expand Down Expand Up @@ -109,7 +110,7 @@ module.exports = {
path += '"dictionary" property)';
consoleWarn(`Fix typo or add word to dictionary at ${path} if you are sure about spelling. Docs: ${packageJson.homepage}#configuration`);
}

if (!stats.errors) {
consoleOk('No errors.');
}
Expand Down
1 change: 1 addition & 0 deletions lib/reports/error_dictionary.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { consoleError, consoleInfo } = require('../helpers/console');
const filename = 'yaspeller_error_dictionary.json';

module.exports = {
name: 'error_dictionary',
onComplete(data) {
let buffer = [];

Expand Down
9 changes: 5 additions & 4 deletions lib/reports/example.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
'use strict';

module.exports = {
name: 'example',
onStart() {
console.log('oSstart');
console.log('onStart');
},
onResourceComplete(err, data) {
console.log('onResourceComplete: ', err, data);
onResourceComplete(error, data) {
console.log('onResourceComplete', error, data);
},
onComplete(data, stats) {
console.log('on: ', data, stats);
console.log('onComplete', data, stats);
}
};
1 change: 1 addition & 0 deletions lib/reports/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function loadFile(filename) {
const filename = 'yaspeller_report.html';

module.exports = {
name: 'html',
onResourceComplete(err, data) {
const html = [];
if (err) {
Expand Down
159 changes: 119 additions & 40 deletions lib/reports/index.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,152 @@
'use strict';

const program = require('commander');
const pth = require('path');

const { defaultConfig } = require('../config');

const { uniq } = require('../helpers/array');
const { consoleError } = require('../helpers/console');
const { splitByCommas } = require('../helpers/string');

const consoleReport = require('./console');
const errorDictionaryReport = require('./error_dictionary');
const htmlReport = require('./html');
const jsonReport = require('./json');
const markdownReport = require('./markdown');

class Reports {
constructor() {
this.buffer = [];

this.innerReports = [
consoleReport,
errorDictionaryReport,
htmlReport,
jsonReport,
markdownReport,
];

this.innerReportsByName = this.innerReports.reduce((acc, current) => {
acc[current.name] = current;

return acc;
}, {});

this.stats = {
errors: 0,
hasTypos: false,
ok: 0,
total: 0,
};

this.reports = [];
}

/**
* Set reports.
*
* @param {string|string[]|undefined} names
*/
set(names) {
this.reports = [];

if (typeof names === 'string') {
names = splitByCommas(names);
} else if (Array.isArray(names)) {
names = names.map(item => item.trim());
} else {
names = [];
}

names = uniq(names).filter(Boolean);
if (!names.length) {
names = defaultConfig.report;
}

names.forEach(name => {
const report = this.innerReportsByName[name] || this.loadExternalReport(name);
if (report) {
this.reports.push(report);
}
});
}

/**
* Load external report.
*
* @param {string} name
* @returns {Report|undefined}
*/
loadExternalReport(name) {
try {
const report = require(require.resolve(name, {
paths: ['./']
}));

const stats = {
errors: 0,
hasTypos: false,
ok: 0,
total: 0,
};
const reports = [];
const reportNames = new Set();
const buffer = [];

module.exports = {
addReports(names) {
names.forEach(function(name) {
const moduleName = pth.extname(name) === '.js' ? name : './' + name;

if (reportNames.has(moduleName)) {
if (!report.name) {
consoleError(`Missing "name" property in report module "${name}".`);
return;
}

try {
reports.push(require(moduleName));
reportNames.add(moduleName);
} catch (e) {
consoleError(`Can't load report module "${moduleName}".`);
consoleError(e);
if (!report.onStart && !report.onComplete && !report.onResourceComplete) {
consoleError(`Missing methods (onStart, onResourceComplete or onComplete) in report module "${name}".`);
return;
}
});
},

return report;
} catch (e) {
consoleError(e);
}
}

onStart() {
reports.forEach(function(name) {
name.onStart && name.onStart();
this.reports.forEach(report => {
report.onStart && report.onStart();
});
},
}

onResourceComplete(hasError, data, dictionary) {
stats.total++;
this.stats.total++;

const hasTypos = Boolean(data && data.data && data.data.length);

if (hasTypos) {
stats.hasTypos = true;
this.stats.hasTypos = true;
}

if (hasError || hasTypos) {
stats.errors++;
this.stats.errors++;

buffer.push([hasError, data]);
this.buffer.push([hasError, data]);
} else {
stats.ok++;
this.stats.ok++;

if (!program.onlyErrors) {
buffer.push([hasError, data]);
this.buffer.push([hasError, data]);
}
}

if (!program.onlyErrors || hasError || hasTypos) {
reports.forEach(function(name) {
name.onResourceComplete && name.onResourceComplete(hasError, data, dictionary);
this.reports.forEach(report => {
report.onResourceComplete && report.onResourceComplete(hasError, data, dictionary);
});
}
},
}

onComplete(configPath) {
reports.forEach(function(name) {
name.onComplete && name.onComplete(buffer, stats, configPath);
this.reports.forEach(report => {
report.onComplete && report.onComplete(this.buffer, this.stats, configPath);
});
}
};
}

module.exports = new Reports();

/**
@typedef Report
@type {Object}
@property {string} name
@property {Function?} onStart
@property {Function?} onResourceComplete
@property {Function?} onComplete
*/
1 change: 1 addition & 0 deletions lib/reports/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { consoleError, consoleInfo } = require('../helpers/console');
const filename = 'yaspeller_report.json';

module.exports = {
name: 'json',
onComplete(data) {
try {
fs.writeFileSync(filename, jsonStringify(data));
Expand Down
1 change: 1 addition & 0 deletions lib/reports/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function prepareResource(resource) {
const filename = 'yaspeller_report.md';

module.exports = {
name: 'markdown',
onResourceComplete(err, data) {
const text = [];
if (err) {
Expand Down
2 changes: 1 addition & 1 deletion lib/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function onResource(err, data, originalText) {
process.exitCode = exitCodes.ERROR_LOADING;
}

reports.onResouceComplete(err, data);
reports.onResourceComplete(err, data);
}

module.exports = {
Expand Down
55 changes: 55 additions & 0 deletions test/reports.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const assert = require('chai').assert;
const reports = require('../lib/reports');

describe('Reports', () => {
it('should set default report', () => {
reports.set();

assert.equal(reports.reports.length, 1);
assert.equal(reports.reports[0].name, 'console');
});

it('should set inner reports', () => {
reports.set('console,html');

assert.equal(reports.reports.length, 2);
assert.equal(reports.reports[0].name, 'console');
assert.equal(reports.reports[1].name, 'html');

});

it('should set inner reports as array of strings', () => {
reports.set(['console', 'html']);

assert.equal(reports.reports.length, 2);
assert.equal(reports.reports[0].name, 'console');
assert.equal(reports.reports[1].name, 'html');
});

it('should set internal and external report', () => {
reports.set(['console', './test/reports/example']);

assert.equal(reports.reports.length, 2);
assert.equal(reports.reports[0].name, 'console');
assert.equal(reports.reports[1].name, 'example');
});

it('should set internal and unknown external report', () => {
reports.set(['console', './test/reports/example_unknown']);

assert.equal(reports.reports.length, 1);
assert.equal(reports.reports[0].name, 'console');
});

it('should not set external report without name property', () => {
reports.set(['./test/reports/without_name']);

assert.equal(reports.reports.length, 0);
});

it('should not set external report without methods', () => {
reports.set(['./test/reports/without_methods']);

assert.equal(reports.reports.length, 0);
});
});
14 changes: 14 additions & 0 deletions test/reports/example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

module.exports = {
name: 'example',
onStart() {
console.log('onStart');
},
onResourceComplete(error, data) {
console.log('onResourceComplete', error, data);
},
onComplete(data, stats) {
console.log('onComplete', data, stats);
}
};
5 changes: 5 additions & 0 deletions test/reports/without_methods.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
name: 'example',
};
3 changes: 3 additions & 0 deletions test/reports/without_name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict';

module.exports = {};

0 comments on commit f4c5bb5

Please sign in to comment.