forked from dequelabs/axe-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaggregate-checks.js
More file actions
90 lines (77 loc) · 2.66 KB
/
aggregate-checks.js
File metadata and controls
90 lines (77 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import constants from '../constants';
import aggregate from './aggregate';
const { CANTTELL_PRIO, FAIL_PRIO } = constants;
const checkMap = [];
checkMap[constants.PASS_PRIO] = true;
checkMap[constants.CANTTELL_PRIO] = null;
checkMap[constants.FAIL_PRIO] = false;
/**
* Map over the any / all / none properties
*/
const checkTypes = ['any', 'all', 'none'];
function anyAllNone(obj, functor) {
return checkTypes.reduce((out, type) => {
out[type] = (obj[type] || []).map(val => functor(val, type));
return out;
}, {});
}
function aggregateChecks(nodeResOriginal) {
// Create a copy
const nodeResult = Object.assign({}, nodeResOriginal);
// map each result value to a priority
anyAllNone(nodeResult, (check, type) => {
const i =
typeof check.result === 'undefined' ? -1 : checkMap.indexOf(check.result);
// default to cantTell
check.priority = i !== -1 ? i : constants.CANTTELL_PRIO;
if (type === 'none') {
// For none, swap pass and fail outcomes.
// none-type checks should pass when result is false rather than true.
if (check.priority === constants.PASS_PRIO) {
check.priority = constants.FAIL_PRIO;
} else if (check.priority === constants.FAIL_PRIO) {
check.priority = constants.PASS_PRIO;
}
}
});
// Find the result with the highest priority
const priorities = {
all: nodeResult.all.reduce((a, b) => Math.max(a, b.priority), 0),
none: nodeResult.none.reduce((a, b) => Math.max(a, b.priority), 0),
// get the lowest passing of 'any' defaulting
// to 0 by wrapping around 4 to 0 (inapplicable)
any: nodeResult.any.reduce((a, b) => Math.min(a, b.priority), 4) % 4
};
nodeResult.priority = Math.max(
priorities.all,
priorities.none,
priorities.any
);
// Of each type, filter out all results not matching the final priority
const impacts = [];
checkTypes.forEach(type => {
nodeResult[type] = nodeResult[type].filter(check => {
return (
check.priority === nodeResult.priority &&
check.priority === priorities[type]
);
});
nodeResult[type].forEach(check => impacts.push(check.impact));
});
// for failed nodes, define the impact
if ([CANTTELL_PRIO, FAIL_PRIO].includes(nodeResult.priority)) {
nodeResult.impact = aggregate(constants.impact, impacts);
} else {
nodeResult.impact = null;
}
// Delete the old result and priority properties
anyAllNone(nodeResult, c => {
delete c.result;
delete c.priority;
});
// Convert the index to a result string value
nodeResult.result = constants.results[nodeResult.priority];
delete nodeResult.priority;
return nodeResult;
}
export default aggregateChecks;