From 36bc38b251b5f80a096f9c4119048c2294e296bd Mon Sep 17 00:00:00 2001 From: kirrg001 Date: Wed, 8 Aug 2018 20:39:19 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Added=20ability=20to=20sort=20by=20?= =?UTF-8?q?files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs #122 - `gscan.format` now accepts a new option to return a different format - sort by errors & warnings files (sortByFiles: true) - sort by rules by default - it's currently hard to sort the passed rules, because no rule is pushed with the file reference - too much effort for no usage --- lib/format.js | 79 +++++++++++++++++++++++++++++++++++++++++--- test/general.test.js | 48 +++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 5 deletions(-) diff --git a/lib/format.js b/lib/format.js index e8542e22..94e7dd40 100644 --- a/lib/format.js +++ b/lib/format.js @@ -31,8 +31,8 @@ calcScore = function calcScore(results, stats) { /** * TODO: This needs cleaning up, a lot */ -format = function format(theme, options) { - options = _.extend({onlyFatalErrors: false}, options); +format = function format(theme, options = {}) { + options = _.extend({onlyFatalErrors: false, sortByFiles: false}, options); const checkVersion = _.get(options, 'checkVersion', 'latest'); const ruleSet = spec.get([checkVersion]); @@ -67,7 +67,6 @@ format = function format(theme, options) { _.each(theme.results.pass, function (code, index) { const rule = ruleSet.rules[code]; - theme.results.pass[index] = _.extend({}, rule, {code: code}); stats[rule.level] += 1; processedCodes.push(code); @@ -80,8 +79,78 @@ format = function format(theme, options) { theme.results.score = calcScore(theme.results, stats); theme.results.hasFatalErrors = hasFatalErrors; - // SORT errors! - theme.results.error = _.orderBy(theme.results.error, 'fatal', 'desc'); + // CASE 1: sort by files (@TODO: sort by passed rules is not possible, because we don't push the file reference) + // CASE 2: (default): sort by rules + if (options.sortByFiles) { + const recommendationsByFile = {}; + const errorsByFile = {}; + const warningsByFile = {}; + + theme.results.error.forEach((error) => { + const failures = error.failures; + + if (!failures || !failures.length) { + return; + } + + failures.forEach((failure) => { + if (!errorsByFile.hasOwnProperty(failure.ref)) { + errorsByFile[failure.ref] = []; + } + + errorsByFile[failure.ref].push(error); + }); + }); + + theme.results.warning.forEach((warning) => { + const failures = warning.failures; + + if (!failures || !failures.length) { + return; + } + + failures.forEach((failure) => { + if (!warningsByFile.hasOwnProperty(failure.ref)) { + warningsByFile[failure.ref] = []; + } + + warningsByFile[failure.ref].push(warning); + }); + }); + + theme.results.recommendation.forEach((passed) => { + const failures = passed.failures; + + if (!failures || !failures.length) { + return; + } + + failures.forEach((failure) => { + if (!recommendationsByFile.hasOwnProperty(failure.ref)) { + recommendationsByFile[failure.ref] = []; + } + + recommendationsByFile[failure.ref].push(passed); + }); + }); + + theme.results.recommendation = { + all: theme.results.recommendation, + byFiles: recommendationsByFile + }; + + theme.results.error = { + all: theme.results.error, + byFiles: errorsByFile + }; + + theme.results.warning = { + all: theme.results.warning, + byFiles: warningsByFile + }; + } else { + theme.results.error = _.orderBy(theme.results.error, 'fatal', 'desc'); + } return theme; }; diff --git a/test/general.test.js b/test/general.test.js index 5196d652..0cbd724d 100644 --- a/test/general.test.js +++ b/test/general.test.js @@ -398,6 +398,7 @@ describe('format', function () { checker(themePath('005-compile/invalid')).then((theme) => { theme = format(theme); + theme.results.error.length.should.eql(10); theme.results.error[0].fatal.should.eql(true); theme.results.error[1].fatal.should.eql(false); theme.results.error[8].fatal.should.eql(false); @@ -420,4 +421,51 @@ describe('format', function () { done(); }); }); + + it('sort by files', function (done) { + checker(themePath('005-compile/invalid')).then((theme) => { + theme = format(theme, {sortByFiles: true}); + + theme.results.hasFatalErrors.should.be.true(); + + theme.results.recommendation.all.length.should.eql(1); + theme.results.recommendation.byFiles['package.json'].length.should.eql(1); + + theme.results.warning.all.length.should.eql(2); + theme.results.warning.byFiles['default.hbs'].length.should.eql(2); + + theme.results.error.all.length.should.eql(10); + + // 1 rule has file references + theme.results.error.byFiles['author.hbs'].length.should.eql(1); + theme.results.error.byFiles['page.hbs'].length.should.eql(1); + theme.results.error.byFiles['post.hbs'].length.should.eql(1); + theme.results.error.byFiles['index.hbs'].length.should.eql(1); + theme.results.error.byFiles['package.json'].length.should.eql(9); + + done(); + }); + }); + + it('sort by files', function (done) { + checker(themePath('001-deprecations/invalid')).then((theme) => { + theme = format(theme, {sortByFiles: true}); + + theme.results.hasFatalErrors.should.be.true(); + + theme.results.recommendation.all.length.should.eql(1); + theme.results.recommendation.byFiles['package.json'].length.should.eql(1); + + theme.results.error.all.length.should.eql(36); + theme.results.warning.all.length.should.eql(0); + + theme.results.error.byFiles['assets/my.css'].length.should.eql(5); + theme.results.error.byFiles['default.hbs'].length.should.eql(6); + theme.results.error.byFiles['post.hbs'].length.should.eql(17); + theme.results.error.byFiles['partials/mypartial.hbs'].length.should.eql(4); + theme.results.error.byFiles['index.hbs'].length.should.eql(7); + + done(); + }); + }); });