Skip to content

Commit

Permalink
feat: generated impacts as a part of rule descriptions (#898)
Browse files Browse the repository at this point in the history
* fix: update rule descriptions with impacts.

* fix: generate impact column in rule description as part of build.

* refactor: parseImpactForRule for building rule descriptions.

* fix: update impact generation to consolidate any, all, none impacts.

* fix: ci build. Cannot require axe in configure task. Fallback to local constant.

* refactor: cater to comments.
  • Loading branch information
jeeyyy authored May 25, 2018
1 parent 13c9605 commit 6265608
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 101 deletions.
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*eslint complexity: ["error",12], max-statements: ["error", 30],
camelcase: ["error", {"properties": "never"}]*/
camelcase: ["error", {"properties": "never"}]*/
var testConfig = require('./build/test/config');

module.exports = function (grunt) {
Expand Down
114 changes: 84 additions & 30 deletions build/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ var clone = require('clone');
var dot = require('dot');
var templates = require('./templates');
var buildManual = require('./build-manual');
var entities = new (require('html-entities').AllHtmlEntities)();
var entities = new (require('html-entities').AllHtmlEntities)();

var descriptionHeaders = '| Rule ID | Description | Tags | Enabled by default |\n| :------- | :------- | :------- | :------- |\n';
var descriptionHeaders = '| Rule ID | Description | Impact | Tags | Enabled by default |\n| :------- | :------- | :------- | :------- | :------- |\n';

dot.templateSettings.strip = false;

Expand All @@ -24,10 +24,29 @@ function getLocale(grunt, options) {
}

function buildRules(grunt, options, commons, callback) {
var axeImpact = Object.freeze(['minor', 'moderate', 'serious', 'critical']); // TODO: require('../axe') does not work if grunt configure is moved after uglify, npm test breaks with undefined. Complicated grunt concurrency issue.
var locale = getLocale(grunt, options);
options.getFiles = false;
buildManual(grunt, options, commons, function (result) {

var metadata = {
rules: {},
checks: {}
};
var descriptions = [];
var tags = options.tags ? options.tags.split(/\s*,\s*/) : [];
var rules = result.rules;
var checks = result.checks;

// Translate checks
if (locale && locale.checks) {
checks.forEach(function (check) {
if (locale.checks[check.id] && check.metadata) {
check.metadata.messages = locale.checks[check.id];
}
})
}

function parseMetaData(source, propType) {
var data = source.metadata
var key = source.id || source.type
Expand Down Expand Up @@ -64,15 +83,14 @@ function buildRules(grunt, options, commons, callback) {

function getIncompleteMsg(summaries) {
var result = {};
summaries.forEach(function(summary) {
summaries.forEach(function (summary) {
if (summary.incompleteFallbackMessage) {
result = dot.template(summary.incompleteFallbackMessage).toString();
}
})
return result;
}


function replaceFunctions(string) {
return string.replace(/"(evaluate|after|gather|matches|source|commons)":\s*("[^"]+?")/g, function (m, p1, p2) {
return m.replace(p2, getSource(p2.replace(/^"|"$/g, ''), p1));
Expand All @@ -81,7 +99,6 @@ function buildRules(grunt, options, commons, callback) {
}).replace(/"(\(function \(\) {)([\s\S]+?)(}\)\(\))"/g, function (m) {
return JSON.parse(m);
});

}

function getSource(file, type) {
Expand All @@ -107,27 +124,6 @@ function buildRules(grunt, options, commons, callback) {
return v;
}

var metadata = {
rules: {},
checks: {}
};

var descriptions = [];

var tags = options.tags ? options.tags.split(/\s*,\s*/) : [];

var rules = result.rules;
var checks = result.checks;

// Translate checks
if (locale && locale.checks) {
checks.forEach(function (check) {
if (locale.checks[check.id] && check.metadata) {
check.metadata.messages = locale.checks[check.id]
}
})
}

function parseChecks(collection) {
return collection.map(function (check) {
var c = {};
Expand All @@ -145,19 +141,77 @@ function buildRules(grunt, options, commons, callback) {

return c.options === undefined ? id : c;
});
}

function parseImpactForRule(rule) {


function capitalize(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}

function getUniqueArr(arr) {
return arr.filter(function (value, index, self) {
return self.indexOf(value) === index;
})
}

function getImpactScores(checkCollection) {
return checkCollection.reduce(function (out, check) {
var id = typeof check === 'string' ? check : check.id;
var definition = clone(findCheck(checks, id));
if (!definition) {
grunt.log.error('check ' + id + ' not found');
}
if (definition && definition.metadata && definition.metadata.impact) {
var impactScore = axeImpact.indexOf(definition.metadata.impact);
out.push(impactScore);
}
return out;
}, []);
}

function getScore(checkCollection, onlyHighestScore) {
var scores = getImpactScores(checkCollection);
if (scores && scores.length) {
return onlyHighestScore
? [Math.max.apply(null, scores)]
: getUniqueArr(scores);
} else {
return [];
}
}

var highestImpactForRuleTypeAny = getScore(rule.any, true);
var allUniqueImpactsForRuleTypeAll = getScore(rule.all, false);
var allUniqueImpactsForRuleTypeNone = getScore(rule.none, false);
var cumulativeImpacts = highestImpactForRuleTypeAny.concat(allUniqueImpactsForRuleTypeAll).concat(allUniqueImpactsForRuleTypeNone);
var cumulativeScores = getUniqueArr(cumulativeImpacts).sort(); //order lowest to highest

return cumulativeScores.reduce(function (out, cV) {
return out.length
? out + ', ' + capitalize(axeImpact[cV])
: capitalize(axeImpact[cV]);
}, '');
}


rules.map(function (rule) {

var impact = parseImpactForRule(rule);
rule.any = parseChecks(rule.any);
rule.all = parseChecks(rule.all);
rule.none = parseChecks(rule.none);

if (rule.metadata && !metadata.rules[rule.id]) {
// Translate rules
metadata.rules[rule.id] = parseMetaData(rule, 'rules');
metadata.rules[rule.id] = parseMetaData(rule, 'rules'); // Translate rules
}
descriptions.push([rule.id, entities.encode(rule.metadata.description), rule.tags.join(', '), rule.enabled === false ? false : true]);
descriptions.push([
rule.id,
entities.encode(rule.metadata.description),
impact,
rule.tags.join(', '),
rule.enabled === false ? false : true
]);
if (tags.length) {
rule.enabled = !!rule.tags.filter(function (t) {
return tags.indexOf(t) !== -1;
Expand Down
Loading

0 comments on commit 6265608

Please sign in to comment.