Merge branch 'customRules' into refactor

This commit is contained in:
Gaël Métais
2014-12-19 15:01:37 +01:00
5 changed files with 180 additions and 29 deletions
@@ -1,4 +1,6 @@
{
var debug = require('debug')('ylt:policies');
var policies = {
"DOMelementsCount": {
"tool": "phantomas",
"label": "DOM elements count",
@@ -103,24 +105,61 @@
"isBadThreshold": 50,
"isAbnormalThreshold": 200
},
"inBodyDomManipulations": {
"tool": "ylt",
"label": "DOM manipulations in body",
"message": "<p>This metric counts the number of DOM queries, DOM inserts, binds, etc. made by the JavaScript before the DOMContentLoaded event.</p><p>Wait for this event before manipulating the DOM. Do not execute JavaScript in the middle of the BODY as it slows down the construction of the DOM and makes a poor maintainability. This is what i call spaghetti code.</p><p>The JS Timeline tab can help you identify what's happening.</p>",
"isOkThreshold": 10,
"isBadThreshold": 50,
"isAbnormalThreshold": 100
},
"jQueryVersion": {
"tool": "ylt",
"label": "jQuery version",
"message": "<p>Current latest versions of jQuery are 1.11 (with support for old IE versions) and 2.1 (without).</p><p>Each new version of jQuery optimizes performances. Do not keep an old version of jQuery. Updating can sometimes break a few things, but it is generally quite easy to fix them up. So don't hesitate.</p>",
"isOkThreshold": 1,
"isBadThreshold": 2,
"isAbnormalThreshold": 3
"scoreFn": function(data) {
var differentVersions = data.toolsResults.phantomas.metrics.jQueryDifferentVersions;
if (differentVersions === 0 || differentVersions > 1) {
// Not applicable
return null;
} else {
var value = data.toolsResults.phantomas.metrics.jQueryVersion;
var score;
if (value.indexOf('1.11.') === 0 ||
value.indexOf('1.12.') === 0 ||
value.indexOf('2.1.') === 0 ||
value.indexOf('2.2.') === 0 ||
value.indexOf('3.0.') === 0) {
score = 100;
} else if (value.indexOf('1.10.') === 0 ||
value.indexOf('2.0.') === 0) {
score = 90;
} else if (value.indexOf('1.9.') === 0) {
score = 70;
} else if (value.indexOf('1.8.') === 0) {
score = 50;
} else if (value.indexOf('1.7.') === 0) {
score = 40;
} else if (value.indexOf('1.6.') === 0) {
score = 30;
} else if (value.indexOf('1.5.') === 0) {
score = 20;
} else if (value.indexOf('1.4.') === 0) {
score = 10;
} else if (value.indexOf('1.3.') === 0) {
score = 0;
} else if (value.indexOf('1.2.') === 0) {
score = 0;
} else {
debug('Unknown jQuery version "%s"', value);
return null;
}
return {
value: value,
score: score,
bad: value < 100,
abnormal: false,
abnormalityScore: 0
};
}
}
},
"jQueryDifferentVersions": {
"tool": "ylt",
"tool": "phantomas",
"label": "Several versions loaded",
"message": "<p>jQuery is a heavy library. You should <b>never<b> load jQuery more than one on the same page.</p>",
"isOkThreshold": 1,
@@ -367,4 +406,6 @@
"isBadThreshold": 25,
"isAbnormalThreshold": 50
}
}
};
module.exports = policies;
+1 -2
View File
@@ -25,8 +25,7 @@
"evalCalls": 1,
"documentWriteCalls": 2,
"consoleMessages": 0.5,
"globalVariables": 0.5,
"inBodyDomManipulations": 1
"globalVariables": 0.5
}
},
"jQueryVersion": {
+27 -3
View File
@@ -12,12 +12,14 @@ var RulesChecker = function() {
for (var metricName in policies) {
var policy = policies[metricName];
var rule;
if (data.toolsResults[policy.tool] &&
if (policy.tool &&
data.toolsResults[policy.tool] &&
data.toolsResults[policy.tool].metrics &&
(data.toolsResults[policy.tool].metrics[metricName] || data.toolsResults[policy.tool].metrics[metricName] === 0)) {
var rule = {
rule = {
value: data.toolsResults[policy.tool].metrics[metricName],
policy: policy
};
@@ -40,7 +42,29 @@ var RulesChecker = function() {
rule.abnormalityScore = Math.min(Math.round(abnormalityScore), 0);
results[metricName] = rule;
debug('Metric %s calculated. Score: %d', metricName, rule.score);
} else if (policy.scoreFn) {
debug('Custom score function for %s', metricName);
// Custom score function
rule = policy.scoreFn(data);
// Check returned values (if the result is null, just don't save)
if (rule) {
rule.policy = {
label: policy.label,
message: policy.message
};
results[metricName] = rule;
debug('Metric %s calculated. Score: %d', metricName, rule.score);
} else {
debug('Metric %s is null. Ignored.', metricName);
}
} else {
debug('Metric %s not found for tool %s', metricName, policy.tool);
+9 -9
View File
@@ -21,11 +21,18 @@ var Runner = function(params) {
phantomasWrapper.execute(data).then(function(phantomasResults) {
data.toolsResults.phantomas = phantomasResults;
// Other tools go there
// Get the JS Execution Tree from offenders and put in the main object
try {
data.javascriptExecutionTree = JSON.parse(data.toolsResults.phantomas.offenders.javascriptExecutionTree[0]);
} catch(e) {
debug('Could not find nor parse phantomas.offenders.javascriptExecutionTree');
}
// Other tools go here
// Rules checker
var policies = require('./metadata/policies.json');
var policies = require('./metadata/policies');
data.rules = rulesChecker.check(data, policies);
@@ -35,13 +42,6 @@ var Runner = function(params) {
generic : scoreCalculator.calculate(data, scoreProfileGeneric)
};
// Get the JS Execution Tree from offenders and put in the main object
try {
data.javascriptExecutionTree = JSON.parse(data.toolsResults.phantomas.offenders.javascriptExecutionTree[0]);
} catch(e) {
debug('Could not find nor parse phantomas.offenders.javascriptExecutionTree');
}
delete data.toolsResults.phantomas.metrics.javascriptExecutionTree;
delete data.toolsResults.phantomas.offenders.javascriptExecutionTree;
+87
View File
@@ -0,0 +1,87 @@
var should = require('chai').should();
var rulesChecker = require('../../lib/rulesChecker');
describe('rulesChecker', function() {
var policies = require('../../lib/metadata/policies.js');
it('should grade correctly jQuery versions', function() {
var versions = {
'1.2.9': 0,
'1.3.9': 0,
'1.4.4': 10,
'1.5.0': 20,
'1.6.3': 30,
'1.7.0': 40,
'1.8.3a': 50,
'1.9.2': 70,
'1.10.1': 90,
'2.0.0-rc1': 90,
'1.11.1': 100,
'2.1.1-beta1': 100,
'3.0.0': 100
};
for (var version in versions) {
results = rulesChecker.check({
"toolsResults": {
"phantomas": {
"metrics": {
"jQueryVersion": version
}
}
}
}, policies);
results.jQueryVersion.score.should.equal(versions[version]);
}
// Unknown jQuery version
results = rulesChecker.check({
"toolsResults": {
"phantomas": {
"metrics": {
"jQueryVersion": "wooot"
}
}
}
}, policies);
results.should.deep.equals({});
// If jQueryDifferentVersions is 0
results = rulesChecker.check({
"toolsResults": {
"phantomas": {
"metrics": {
"jQueryVersion": "1.6.0",
"jQueryDifferentVersions": 0
}
}
}
}, policies);
results.should.not.have.a.property('jQueryVersion');
results.should.have.a.property('jQueryDifferentVersions');
results.jQueryDifferentVersions.should.have.a.property('score').that.equals(100);
// If there are more than 1 jQuery version
results = rulesChecker.check({
"toolsResults": {
"phantomas": {
"metrics": {
"jQueryVersion": "1.6.0",
"jQueryDifferentVersions": 2
}
}
}
}, policies);
results.should.not.have.a.property('jQueryVersion');
results.should.have.a.property('jQueryDifferentVersions');
results.jQueryDifferentVersions.should.have.a.property('score').that.equals(0);
results.jQueryDifferentVersions.should.have.a.property('abnormal').that.equals(true);
});
});