This repository has been archived by the owner on Apr 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #155 from hcodes/reports
Reports refactoring
- Loading branch information
Showing
14 changed files
with
210 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use strict'; | ||
|
||
module.exports = { | ||
name: 'example', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict'; | ||
|
||
module.exports = {}; |