diff --git a/src/complexity.js b/src/complexity.js index 4c7ad9d..5f70c67 100644 --- a/src/complexity.js +++ b/src/complexity.js @@ -13,6 +13,7 @@ const guards = [ id: 'MoreThanMostCommonSelectorComplexity', score: 0, value: result.selectors.total === 0 ? 0 : selectorsAboveMode / result.selectors.total, + actuals: result.selectors.complexity.items, } if (selectorsAboveMode > result.selectors.total * 0.1) { @@ -34,6 +35,7 @@ const guards = [ id: 'MoreThanMostCommonSelectorSpecificity', score: 0, value: result.selectors.total === 0 ? 0 : selectorsAboveMode / result.selectors.total, + actuals: result.selectors.specificity.items, } if (selectorsAboveMode > result.selectors.total * 0.1) { @@ -53,6 +55,7 @@ const guards = [ id: 'MaxSelectorComplexity', score: 0, value: result.selectors.complexity.max, + actuals: result.selectors.complexity.items, } // Deduct 0.5 points per complexity over 5, up to 5 points @@ -73,6 +76,7 @@ const guards = [ id: 'AverageSelectorComplexity', score: 0, value: actual, + actuals: result.selectors.complexity.items, } // Deduct 2 points per selector over 2 @@ -91,6 +95,7 @@ const guards = [ id: 'IdSelectorRatio', score: 0, value: actual, + actuals: Object.keys(result.selectors.id.unique) } if (actual > ALLOWED) { @@ -108,6 +113,7 @@ const guards = [ id: 'ImportantRatio', score: 0, value: actual, + actuals: result.declarations.importants.total, } if (actual > ALLOWED) { diff --git a/src/complexity.test.js b/src/complexity.test.js index d371e94..4f235bc 100644 --- a/src/complexity.test.js +++ b/src/complexity.test.js @@ -25,6 +25,7 @@ Complexity('should deduct points for a lot of Selectors more complex than most c id: 'MoreThanMostCommonSelectorComplexity', score: 5, value: 1 / 3, + actuals: (new Array(1000).fill(1)).concat(new Array(500).fill(2)), } ]) assert.is(actual.complexity.score, 95) @@ -51,6 +52,7 @@ Complexity('should deduct points for a lot of Selectors more complex than most c id: 'MoreThanMostCommonSelectorSpecificity', score: 2, value: 200 / 700, + actuals: (new Array(500).fill([0, 0, 1])).concat(new Array(200).fill([0, 1, 0])), } ]) assert.is(actual.complexity.score, 98) @@ -67,11 +69,13 @@ Complexity('deducts points for selectors with high complexity', () => { id: 'MaxSelectorComplexity', score: 3, value: 11, + actuals: [11], }, { id: 'AverageSelectorComplexity', score: 10, value: 11, + actuals: [11], } ]) assert.is(actual.complexity.score, 87) @@ -91,6 +95,7 @@ Complexity('deducts points for having a high ratio of ID selectors', () => { id: 'IdSelectorRatio', score: 2, value: 0.25, + actuals: ['#a'], } ]) assert.is(actual.complexity.score, 98) @@ -112,6 +117,7 @@ Complexity('deducts points for having a high ratio !importants', () => { id: 'ImportantRatio', score: 2, value: 0.25, + actuals: 1, } ]) assert.is(actual.complexity.score, 98) diff --git a/src/maintainability.js b/src/maintainability.js index 7133aeb..5e662c0 100644 --- a/src/maintainability.js +++ b/src/maintainability.js @@ -26,6 +26,7 @@ const guards = [ id: 'AverageSelectorsPerRule', score: 0, value: actual, + actuals: result.rules.selectors.items, } // Deduct 5 points per selector over 2 @@ -45,12 +46,13 @@ const guards = [ id: 'AverageDeclarationsPerRule', score: 0, value: result.rules.declarations.mean, + actuals: result.rules.declarations.items, } // Deduct 5 points per declaration over 5 if (result.rules.declarations.mean > ALLOWED_DECLARATIONS_PER_RULESET) { const score = Math.floor((result.rules.declarations.mean - ALLOWED_DECLARATIONS_PER_RULESET) * 5) - outcome.score = Math.min(15, 0) + outcome.score = Math.min(15, score) } return outcome @@ -64,6 +66,7 @@ const guards = [ id: 'MaxSelectorsPerRule', score: 0, value: result.rules.selectors.max, + actuals: result.rules.selectors.items, } // Deduct 0.5 points per selectors over 10 @@ -83,6 +86,7 @@ const guards = [ id: 'MaxDeclarationsPerRule', score: 0, value: result.rules.declarations.max, + actuals: result.rules.declarations.items, } // Deduct 0.5 points per declarations over 10 @@ -106,6 +110,7 @@ const guards = [ id: 'MoreThanMostCommonSelectorsPerRule', score: 0, value: result.rules.selectors.mode, + actuals: result.rules.selectors.items, } // if more than 10% of RuleSets has more Selectors than most common: @@ -129,6 +134,7 @@ const guards = [ id: 'MoreThanMostCommonDeclarationsPerRule', score: 0, value: result.rules.declarations.mode, + actuals: result.rules.declarations.items, } // if more than 10% of RuleSets has more Declarations than most common: diff --git a/src/maintainability.test.js b/src/maintainability.test.js index cb61924..9bbfd7b 100644 --- a/src/maintainability.test.js +++ b/src/maintainability.test.js @@ -59,6 +59,7 @@ Maintainability('deducts points for having too many Selectors per RuleSet', () = id: 'AverageSelectorsPerRule', score: 12, value: 4.5, + actuals: [4, 5], } ]) }) @@ -90,11 +91,13 @@ Maintainability('deducts points for having too many Selectors in a RuleSet', () id: 'AverageSelectorsPerRule', score: 15, value: 8, + actuals: [15, 1], }, { id: 'MaxSelectorsPerRule', score: 3, value: 15, + actuals: [15, 1], }, ]) }) @@ -114,12 +117,19 @@ Maintainability('deducts points for having too many Declarations in a single Rul ` const actual = calculate(fixture) - assert.is(actual.maintainability.score, 93) + assert.is(actual.maintainability.score, 78) assert.equal(actual.maintainability.violations, [ + { + id: "AverageDeclarationsPerRule", + score: 15, + value: 12, + actuals: [1, 23], + }, { id: 'MaxDeclarationsPerRule', score: 7, // Math.ceil((23 - 10) * 0.5) === Math.ceil(6.5) value: 23, + actuals: [1, 23], }, ]) }) @@ -145,6 +155,7 @@ Maintainability('deducts points for having RuleSets with more Selectors than wha id: 'MoreThanMostCommonSelectorsPerRule', score: 5, value: 1, + actuals: (new Array(1000).fill(1)).concat(new Array(500).fill(2)), }, ]) assert.is(actual.maintainability.score, 95) @@ -171,6 +182,7 @@ Maintainability('deducts points for having RuleSets with more Selectors than wha id: 'MoreThanMostCommonDeclarationsPerRule', score: 5, value: 1, + actuals: (new Array(1000).fill(1)).concat(new Array(500).fill(2)), }, ]) assert.is(actual.maintainability.score, 95) diff --git a/src/performance.js b/src/performance.js index d943b43..fd00fe8 100644 --- a/src/performance.js +++ b/src/performance.js @@ -5,6 +5,7 @@ const guards = [ id: 'Imports', score: result.atrules.import.total * 10, value: result.atrules.import.total, + actuals: Object.keys(result.atrules.import.unique), }), // Should not contain empty rules @@ -70,6 +71,7 @@ const guards = [ id: 'TooMuchEmbeddedContent', score: Math.min(20, Math.floor(size.total / 250)), value: size.total, + actuals: Object.keys(result.stylesheet.embeddedContent.unique), } }, ] diff --git a/src/performance.test.js b/src/performance.test.js index 959475b..ca2d6c9 100644 --- a/src/performance.test.js +++ b/src/performance.test.js @@ -23,6 +23,7 @@ Performance('deducts points for having a single @import', () => { id: 'Imports', value: 1, score: 10, + actuals: [`url('some-url')`], }, ]) }) @@ -39,6 +40,7 @@ Performance('deducts points for having multiple @imports', () => { id: 'Imports', value: 2, score: 20, + actuals: [`url('some-url')`, `url('another-url')`], }, ]) }) @@ -55,6 +57,13 @@ Performance('deducts points for having a single empty rule', () => { test { color: green; } `) assert.is(actual.performance.score, 99) + assert.equal(actual.performance.violations, [ + { + id: 'EmptyRules', + score: 1, + value: 1, + } + ]) }) Performance('deducts points for having multiple empty rules', () => { @@ -158,11 +167,14 @@ Performance('deducts points for having comments', () => { }) Performance('deducts points for having embedded content', () => { + function generateEmbed(index) { + return `data:image/svg+xml,%3Csvg%20id%3D%22Layer_${index}%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20195.6%20107.8%22%3E%3Cpath%20fill%3D%22%23B5B5B5%22%20class%3D%22st0%22%20d%3D%22M97.8%20107.8c-2.6%200-5.1-1-7.1-2.9L2.9%2017.1C-1%2013.2-1%206.8%202.9%202.9%206.8-1%2013.2-1%2017.1%202.9l80.7%2080.7%2080.7-80.7c3.9-3.9%2010.2-3.9%2014.1%200%203.9%203.9%203.9%2010.2%200%2014.1l-87.8%2087.8c-1.9%202-4.4%203-7%203z%22%2F%3E%3C%2Fsvg%3E` + } const fixture = new Array(100) .fill('') .map((_, index) => ` selector-${index} { - background: url(data:image/svg+xml,%3Csvg%20id%3D%22Layer_${index}%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20195.6%20107.8%22%3E%3Cpath%20fill%3D%22%23B5B5B5%22%20class%3D%22st0%22%20d%3D%22M97.8%20107.8c-2.6%200-5.1-1-7.1-2.9L2.9%2017.1C-1%2013.2-1%206.8%202.9%202.9%206.8-1%2013.2-1%2017.1%202.9l80.7%2080.7%2080.7-80.7c3.9-3.9%2010.2-3.9%2014.1%200%203.9%203.9%203.9%2010.2%200%2014.1l-87.8%2087.8c-1.9%202-4.4%203-7%203z%22%2F%3E%3C%2Fsvg%3E); + background: url(${generateEmbed(index)}); } `) .join('') @@ -174,6 +186,7 @@ Performance('deducts points for having embedded content', () => { id: 'TooMuchEmbeddedContent', score: 20, value: 45990, + actuals: new Array(100).fill('').map((_, index) => generateEmbed(index)), }, ]) })