diff --git a/docs/metrics/readme.md b/docs/metrics/readme.md index cbe7fad..5b3671e 100644 --- a/docs/metrics/readme.md +++ b/docs/metrics/readme.md @@ -12,6 +12,7 @@ Parker has a suite of metrics that are useful for measuring stylesheets. What fo 4. [Total Declarations](#total-declarations) 5. [Selectors Per Rule](#selectors-per-rule) 6. [Identifiers Per Selectors](#identifiers-per-selector) + 7. [Declarations Per Rule](#declarations-per-rule) 3. [Specificity](#specificity) 1. [Specificity Per Selector](#specificity-per-selector) 2. [Top Selector Specificity](#top-selector-specificity) @@ -78,7 +79,7 @@ Measures the total number of rules. Each rule defines a specific behaviour of th - __aggregate__: sum - __format__: number - + #### Total Selectors Measures the total number of selectors. Each selector defines a group of elements affected by the design. Stylesheets with fewer selectors are simpler. @@ -108,6 +109,7 @@ Measures the total number of property declarations. Each property declaration de - __aggregate__: sum - __format__: number + #### Selectors Per Rule Measures the average number of selectors in every rule. Stylesheet rules can be applied to several groups of elements using multiple selectors, separated by a comma. Fewer selectors in a rule makes its properties specific to a smaller group of elements, and also makes a rule easier to read in text editors and developer tools. @@ -117,6 +119,7 @@ Measures the average number of selectors in every rule. Stylesheet rules can be - __aggregate__: sum - __format__: number + #### Identifiers Per Selector Measures the average number of identifiers in every selector. Selectors can be made more specific to combinations of elements by adding more identifiers to a selector. Fewer identifiers in a given selector reduces its dependency on certain DOM structures, allowing more changes to your HTML before being forced to change your CSS. Selectors with fewer identifiers are also more readable. @@ -126,6 +129,16 @@ Measures the average number of identifiers in every selector. Selectors can be m - __aggregate__: mean - __format__: number + +#### Declarations Per Rule +Measures the average number of declarations in every rule. Rules with fewer property declarations are simpler, and also makes rules easier to read in text editors and developer tools. + +- __id__: declarations-per-rule +- __name__: Declarations Per Rule +- __type__: rule +- __aggregate__: mean +- __format__: number + ### Specificity A rule can be overrided by another rule with a more specific selector. Complexity is added to stylesheets when multiple levels of cascading rules are used in stylesheets, because it becomes more difficult to predict which properties apply to a given element without keeping in mind other rules. diff --git a/metrics/All.js b/metrics/All.js index 06a995c..8d15702 100644 --- a/metrics/All.js +++ b/metrics/All.js @@ -15,6 +15,7 @@ module.exports = [ // Stylesheet Element Averages require('./SelectorsPerRule.js'), + require('./DeclarationsPerRule.js'), require('./IdentifiersPerSelector.js'), // Specificity diff --git a/metrics/DeclarationsPerRule.js b/metrics/DeclarationsPerRule.js new file mode 100644 index 0000000..1d26764 --- /dev/null +++ b/metrics/DeclarationsPerRule.js @@ -0,0 +1,16 @@ +/*! Parker v0.0.0 - MIT license */ + +'use strict'; + +var CssRule = require( "../lib/CssRule.js" ); + +module.exports = { + id: 'declarations-per-rule', + name: 'Declarations Per Rule', + type: 'rule', + aggregate: 'mean', + format: 'number', + measure: function (rule) { + return (new CssRule(rule)).getDeclarations().length; + } +}; diff --git a/test/DeclarationsPerRule.js b/test/DeclarationsPerRule.js new file mode 100644 index 0000000..9a7d1bf --- /dev/null +++ b/test/DeclarationsPerRule.js @@ -0,0 +1,52 @@ +/*! Parker v0.0.0 - MIT license */ + +var expect = require('chai').expect, + Parker = require('../lib/Parker.js'), + metric = require('../metrics/DeclarationsPerRule.js'); + + +describe('The declarations-per-rule metric', function () { + it('should provide a string identifier for the metric', function() { + expect(metric.id).to.be.a('string'); + }); + + it('should provide a metric type', function() { + expect(metric.aggregate).to.match(/sum|mean/g); + }); + + it('should return 0 for an empty string', function () { + expect(metric.measure('')).to.equal(0); + }); + + it('should return 1 for the selector "body {color:blue;}"', function() { + expect(metric.measure('body {color:blue;}')).to.equal(1); + }); + + it('should return 2 for the selector "body section {color:blue;background:yellow;}"', function() { + expect(metric.measure('body section {color:blue;background:yellow;}')).to.equal(2); + }); + + it('should return 2 for the selector "body section {color:blue;background:yellow;} body article h3 {text-align:center;color:red;}"', function() { + var parker = new Parker([metric]), + report = parker.run('body section {color:blue;background:yellow;} body article h3 {text-align:center;color:red;}'); + + expect(report).to.have.property('declarations-per-rule'); + expect(report['declarations-per-rule']).to.equal(2); + }); + + it('should return 1.5 for the selector "body section {color:blue;background:yellow;} body article h3 {text-align:center;}"', function() { + var parker = new Parker([metric]), + report = parker.run('body section {color:blue;background:yellow;} body article h3 {text-align:center;}'); + + expect(report).to.have.property('declarations-per-rule'); + expect(report['declarations-per-rule']).to.equal(1.5); + }); + + it('should return 2 for the selector "body section {-webkit-something:blue;-moz-anything:yellow;} body article h3 {text-align:center;color:red;}"', function() { + var parker = new Parker([metric]), + report = parker.run('body section {-webkit-something:blue;-moz-anything:yellow;} body article h3 {text-align:center;color:red;}'); + + expect(report).to.have.property('declarations-per-rule'); + expect(report['declarations-per-rule']).to.equal(2); + }); +});